Skip to content
This repository was archived by the owner on Apr 1, 2025. It is now read-only.

Commit 368fc7b

Browse files
authored
Merge pull request #204 from github/sequence-values-in-the-abstract-domain
Sequence values in the abstract domain
2 parents 7482c84 + c2e620a commit 368fc7b

File tree

3 files changed

+31
-18
lines changed

3 files changed

+31
-18
lines changed

semantic-core/src/Analysis/Concrete.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{-# LANGUAGE FlexibleContexts, FlexibleInstances, LambdaCase, MultiParamTypeClasses, NamedFieldPuns, OverloadedStrings, RecordWildCards, TypeApplications, TypeOperators, UndecidableInstances #-}
1+
{-# LANGUAGE DerivingVia, FlexibleContexts, FlexibleInstances, LambdaCase, MultiParamTypeClasses, NamedFieldPuns, OverloadedStrings, RecordWildCards, TypeApplications, TypeOperators, UndecidableInstances #-}
22
module Analysis.Concrete
33
( Concrete(..)
44
, concrete
@@ -28,6 +28,7 @@ import qualified Data.IntSet as IntSet
2828
import Data.Loc
2929
import qualified Data.Map as Map
3030
import Data.Name
31+
import Data.Semigroup (Last (..))
3132
import qualified Data.Set as Set
3233
import Data.Term
3334
import Data.Text (Text, pack)
@@ -47,6 +48,8 @@ data Concrete
4748
| String Text
4849
| Record Env
4950
deriving (Eq, Ord, Show)
51+
-- NB: We derive the 'Semigroup' instance for 'Concrete' to take the second argument. This is equivalent to stating that the return value of an imperative sequence of statements is the value of its final statement.
52+
deriving Semigroup via Last Concrete
5053

5154
recordFrame :: Concrete -> Maybe Env
5255
recordFrame (Record frame) = Just frame

semantic-core/src/Analysis/Eval.hs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import Prelude hiding (fail)
3030
eval :: ( Carrier sig m
3131
, Member (Reader Loc) sig
3232
, MonadFail m
33+
, Semigroup value
3334
)
3435
=> Analysis address value m
3536
-> (Term Core User -> m value)
@@ -41,12 +42,15 @@ eval Analysis{..} eval = \case
4142
addr <- alloc n
4243
v <- bind n addr (eval (instantiate1 (pure n) b))
4344
v <$ assign addr v
44-
a :>> b -> eval a >> eval b
45+
-- NB: Combining the results of the evaluations allows us to model effects in abstract domains. This in turn means that we can define an abstract domain modelling the types-and-effects of computations by means of a 'Semigroup' instance which takes the type of its second operand and the union of both operands’ effects.
46+
--
47+
-- It’s also worth noting that we use a semigroup instead of a semilattice because the lattice structure of our abstract domains is instead modelled by nondeterminism effects used by some of them.
48+
a :>> b -> (<>) <$> eval a <*> eval b
4549
Named (Ignored n) a :>>= b -> do
4650
a' <- eval a
4751
addr <- alloc n
4852
assign addr a'
49-
bind n addr (eval (instantiate1 (pure n) b))
53+
bind n addr ((a' <>) <$> eval (instantiate1 (pure n) b))
5054
Lam (Named (Ignored n) b) -> abstract eval n (instantiate1 (pure n) b)
5155
f :$ a -> do
5256
f' <- eval f
@@ -210,18 +214,18 @@ ruby = fromBody $ annWith callStack (rec (named' __semantic_global) (do' stateme
210214

211215

212216
data Analysis address value m = Analysis
213-
{ alloc :: User -> m address
214-
, bind :: forall a . User -> address -> m a -> m a
215-
, lookupEnv :: User -> m (Maybe address)
216-
, deref :: address -> m (Maybe value)
217-
, assign :: address -> value -> m ()
218-
, abstract :: (Term Core User -> m value) -> User -> Term Core User -> m value
219-
, apply :: (Term Core User -> m value) -> value -> value -> m value
220-
, unit :: m value
221-
, bool :: Bool -> m value
222-
, asBool :: value -> m Bool
223-
, string :: Text -> m value
224-
, asString :: value -> m Text
225-
, record :: [(User, value)] -> m value
226-
, (...) :: address -> User -> m (Maybe address)
217+
{ alloc :: User -> m address
218+
, bind :: forall a . User -> address -> m a -> m a
219+
, lookupEnv :: User -> m (Maybe address)
220+
, deref :: address -> m (Maybe value)
221+
, assign :: address -> value -> m ()
222+
, abstract :: (Term Core User -> m value) -> User -> Term Core User -> m value
223+
, apply :: (Term Core User -> m value) -> value -> value -> m value
224+
, unit :: m value
225+
, bool :: Bool -> m value
226+
, asBool :: value -> m Bool
227+
, string :: Text -> m value
228+
, asString :: value -> m Text
229+
, record :: [(User, value)] -> m value
230+
, (...) :: address -> User -> m (Maybe address)
227231
}

semantic-core/src/Analysis/Typecheck.hs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{-# LANGUAGE DeriveGeneric, DeriveTraversable, FlexibleContexts, FlexibleInstances, LambdaCase, OverloadedStrings, QuantifiedConstraints, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TypeApplications, TypeOperators #-}
1+
{-# LANGUAGE DeriveGeneric, DeriveTraversable, DerivingVia, FlexibleContexts, FlexibleInstances, LambdaCase, OverloadedStrings, QuantifiedConstraints, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TypeApplications, TypeOperators #-}
22
module Analysis.Typecheck
33
( Monotype (..)
44
, Meta
@@ -30,6 +30,7 @@ import qualified Data.Map as Map
3030
import Data.Maybe (fromJust, fromMaybe)
3131
import Data.Name as Name
3232
import Data.Scope
33+
import Data.Semigroup (Last (..))
3334
import qualified Data.Set as Set
3435
import Data.Term
3536
import Data.Void
@@ -44,6 +45,11 @@ data Monotype f a
4445
| Record (Map.Map User (f a))
4546
deriving (Foldable, Functor, Generic1, Traversable)
4647

48+
-- FIXME: Union the effects/annotations on the operands.
49+
50+
-- | We derive the 'Semigroup' instance for types to take the second argument. This is equivalent to stating that the type of an imperative sequence of statements is the type of its final statement.
51+
deriving via (Last (Term Monotype a)) instance Semigroup (Term Monotype a)
52+
4753
deriving instance (Eq a, forall a . Eq a => Eq (f a), Monad f) => Eq (Monotype f a)
4854
deriving instance (Ord a, forall a . Eq a => Eq (f a)
4955
, forall a . Ord a => Ord (f a), Monad f) => Ord (Monotype f a)

0 commit comments

Comments
 (0)