diff --git a/src/Analysis/Abstract/Caching.hs b/src/Analysis/Abstract/Caching.hs index d53d6f234..03654cffb 100644 --- a/src/Analysis/Abstract/Caching.hs +++ b/src/Analysis/Abstract/Caching.hs @@ -80,7 +80,7 @@ instance ( Corecursive t , Semigroup (Cell (LocationFor v) v) ) => MonadAnalysis t v (CachingAnalysis t v) where - evaluateTerm = foldSubterms $ \e -> do + analyzeTerm e = do c <- getConfiguration (embedSubterm e) -- Convergence here is predicated upon an Eq instance, not α-equivalence cache <- converge (\ prevCache -> do diff --git a/src/Analysis/Abstract/Dead.hs b/src/Analysis/Abstract/Dead.hs index 1c8bf8c66..a31dadabc 100644 --- a/src/Analysis/Abstract/Dead.hs +++ b/src/Analysis/Abstract/Dead.hs @@ -79,6 +79,6 @@ instance ( Corecursive t , Semigroup (Cell (LocationFor v) v) ) => MonadAnalysis t v (DeadCodeAnalysis t v) where - evaluateTerm = foldSubterms (\ term -> do + analyzeTerm term = do revive (embedSubterm term) - eval term) + eval term diff --git a/src/Analysis/Abstract/Evaluating.hs b/src/Analysis/Abstract/Evaluating.hs index 6e61efa34..af6a43c6b 100644 --- a/src/Analysis/Abstract/Evaluating.hs +++ b/src/Analysis/Abstract/Evaluating.hs @@ -76,4 +76,4 @@ instance ( Evaluatable (Base t) , Semigroup (Cell (LocationFor v) v) ) => MonadAnalysis t v (Evaluation t v) where - evaluateTerm = foldSubterms eval + analyzeTerm = eval diff --git a/src/Control/Abstract/Analysis.hs b/src/Control/Abstract/Analysis.hs index 0c24aec5a..540b0fdfd 100644 --- a/src/Control/Abstract/Analysis.hs +++ b/src/Control/Abstract/Analysis.hs @@ -1,9 +1,18 @@ -{-# LANGUAGE FunctionalDependencies #-} +{-# LANGUAGE DefaultSignatures, FunctionalDependencies #-} module Control.Abstract.Analysis where +import Prologue + -- | A 'Monad' in which one can evaluate some specific term type to some specific value type. -- -- This typeclass is left intentionally unconstrained to avoid circular dependencies between it and other typeclasses. class Monad m => MonadAnalysis term value m | m -> term, m -> value where - -- | Evaluate a term to a value using the semantics of the current analysis. This should always be used instead of explicitly folding 'eval' over subterms, except in 'MonadAnalysis' instances themselves. - evaluateTerm :: term -> m value + -- | Analyze a term using the semantics of the current analysis. This should generally only be called by definitions of 'evaluateTerm' and 'analyzeTerm' in this or other instances. + analyzeTerm :: SubtermAlgebra (Base term) term (m value) + + -- | Evaluate a term to a value using the semantics of the current analysis. + -- + -- This should always be called instead of explicitly folding either 'eval' or 'analyzeTerm' over subterms, except in 'MonadAnalysis' instances themselves. + evaluateTerm :: MonadAnalysis term value m => term -> m value + default evaluateTerm :: (MonadAnalysis term value m, Recursive term) => term -> m value + evaluateTerm = foldSubterms analyzeTerm