Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parametric modular interpretation #659

Merged
merged 37 commits into from
Aug 24, 2021

Conversation

robrix
Copy link
Contributor

@robrix robrix commented Jul 28, 2021

This PR migrates semantic-analysis over to the parametric modular abstract interpretation framework I’ve been building. It remains superficially similar, but has a better basis for the domain effect, better ergonomics via labelled effects for the store &c., and provides an operation analogous to linking, allowing out-of-order program analysis and (typically file-level) incremental updating.

@robrix robrix dismissed a stale review via e1dade3 August 19, 2021 13:24
Copy link
Contributor Author

@robrix robrix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ready for review.

Comment on lines -23 to -27

source-repository-package
type: git
location: https://github.com/antitypical/fused-syntax.git
tag: 4a383d57c8fd7592f54a33f43eb9666314a6e80e
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥

fused-syntax had been used for Core (along with a few other things), but it never worked the way I wanted and I don’t think it’s a good idea to try to continue maintaining it for the sake of this, so 🔥

@@ -22,7 +22,6 @@ newtype EnvC m a = EnvC { runEnv :: m a }
instance Algebra sig m
=> Algebra (Env Name :+: sig) (EnvC m) where
alg hdl sig ctx = case sig of
L (Alloc name) -> pure (name <$ ctx)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should never have been here.

Comment on lines +24 to +37
runFail :: FailC m a -> m (Either (Reference, String) a)
runFail = runError . runFailC

newtype FailC m a = FailC { runFailC :: ErrorC (Reference, String) m a }
deriving (Alternative, Applicative, Functor, Monad)

instance Has (Reader Reference) sig m => MonadFail (FailC m) where
fail s = do
ref <- ask
FailC (throwError (ref :: Reference, s))

instance Has (Reader Reference) sig m => Algebra (Fail :+: sig) (FailC m) where
alg _ (L (Fail s)) _ = fail s
alg hdl (R other) ctx = FailC (alg (runFailC . hdl) (R other) ctx)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This used to live elsewhere in the project. I’ve moved it here, and simplified it slightly by use of the Reference type (introduced in this PR, see below).

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Analysis.Carrier.Heap.Monovariant
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Heap isn’t standard nomenclature when talking abstract interpretation; Store is.
  2. This was unnecessarily hard to use as defined. The Store effect and carrier that replace it are more ergonomic.

R other -> alg (runStoreC . hdl) other ctx


-- Env carrier
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For convenience, I’ve placed both the Store and Env carriers in a single module. This makes it very slightly less convenient to mix-and-match, but that’s not something we expect to do in the short to medium term anyway.

Comment on lines +99 to 107
abstract :: Eq a => a -> Polytype a -> Polytype (Maybe a)
abstract n = fmap (\ a -> a <$ guard (a == n))


forAll :: Eq a => a -> Polytype a -> Polytype a
forAll n body = PForAll (abstract n body)

forAlls :: (Eq a, Foldable t) => t a -> Polytype a -> Polytype a
forAlls ns body = foldr forAll body ns
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the I Am Not a Number, I Am a Free Variable approach. It doesn’t give the fastest abstraction and substitution (relative to e.g. bound, but a) that doesn’t actually matter at all for our purposes, and b) the smarter next move would be HOAS anyway.

Comment on lines -168 to -169
data Constraint = Type :===: Type
deriving (Eq, Ord, Show)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was, alas, too cute to live.

Comment on lines -48 to -49
Core.Parser
Core.Pretty
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pouring one out.

Comment on lines +18 to +26
data Expr
= Var Name
| Abs Name Expr
| App Expr Expr
| Let Name Expr Expr
| Lit Int
| If Expr Expr Expr
| Die String
deriving (Eq, Ord, Show)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a minimalistic reference calculus that exercises the evaluation interfaces fully.

Comment on lines +43 to +45
and', or' :: Expr
and' = Abs "a" (Abs "b" (Var "a" $$ true $$ Var "b"))
or' = Abs "a" (Abs "b" (Var "a" $$ Var "b" $$ false))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As seen on a blog post I wrote one time!

@robrix robrix marked this pull request as ready for review August 19, 2021 22:08
@robrix robrix requested a review from a team as a code owner August 19, 2021 22:08
@robrix robrix mentioned this pull request Aug 23, 2021
patrickt
patrickt previously approved these changes Aug 23, 2021
Copy link
Contributor

@patrickt patrickt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks terrific!

| String Text
| Record Env
| Neutral Name (Snoc (Elim Concrete))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get a bit of documentation on this declaration? It’s different enough from its surroundings that some context would be welcome.

Comment on lines +114 to +122
-- This applies the Kleene fixed-point theorem to finitize a monotone action. cf https://en.wikipedia.org/wiki/Kleene_fixed-point_theorem
convergeEither
:: Monad m
=> (a -> m (Either b a)) -- ^ A monadic action to perform at each iteration, starting from the result of the previous iteration or from the seed value for the first iteration. Returns of 'Left' end iteration, while 'Right' begins another iteration.
-> a -- ^ An initial seed value to iterate from.
-> m b -- ^ A computation producing the least fixed point (the first value at which the actions converge).
convergeEither f = loop
where
loop = either pure loop <=< f
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏🏻

@robrix robrix merged commit e4281d5 into master Aug 24, 2021
@robrix robrix deleted the abstract-normalization-by-abstract-evaluation branch August 24, 2021 15:42
@robrix robrix mentioned this pull request Feb 10, 2022
@robrix robrix mentioned this pull request Feb 25, 2022
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants