mirror of
https://github.com/github/semantic.git
synced 2025-01-03 13:02:37 +03:00
Abstract abstraction.
This commit is contained in:
parent
898c80a9b9
commit
518848a6e8
@ -71,7 +71,7 @@ moduleName term = let [n] = toList (freeVariables term) in BC.unpack n
|
|||||||
evaluate :: forall v term.
|
evaluate :: forall v term.
|
||||||
( Ord v
|
( Ord v
|
||||||
, Ord (LocationFor v)
|
, Ord (LocationFor v)
|
||||||
, AbstractValue term v
|
, AbstractFunction (Evaluating v) term v
|
||||||
, Evaluatable (Evaluating v) term v (Base term)
|
, Evaluatable (Evaluating v) term v (Base term)
|
||||||
, FreeVariables term
|
, FreeVariables term
|
||||||
, Recursive term
|
, Recursive term
|
||||||
@ -84,7 +84,7 @@ evaluate = run @(Evaluating v) . foldSubterms eval
|
|||||||
evaluates :: forall v term.
|
evaluates :: forall v term.
|
||||||
( Ord v
|
( Ord v
|
||||||
, Ord (LocationFor v)
|
, Ord (LocationFor v)
|
||||||
, AbstractValue term v
|
, AbstractFunction (Evaluating v) term v
|
||||||
, FreeVariables term
|
, FreeVariables term
|
||||||
, Evaluatable (Evaluating v) term v (Base term)
|
, Evaluatable (Evaluating v) term v (Base term)
|
||||||
, Recursive term
|
, Recursive term
|
||||||
|
@ -1,18 +1,23 @@
|
|||||||
{-# LANGUAGE MultiParamTypeClasses, Rank2Types, GADTs, TypeOperators, DefaultSignatures, UndecidableInstances, ScopedTypeVariables #-}
|
{-# LANGUAGE DataKinds, FunctionalDependencies, MultiParamTypeClasses, Rank2Types, GADTs, TypeOperators, DefaultSignatures, UndecidableInstances, ScopedTypeVariables #-}
|
||||||
{-# LANGUAGE TypeApplications #-}
|
{-# LANGUAGE TypeApplications #-}
|
||||||
module Control.Monad.Effect.Evaluatable
|
module Control.Monad.Effect.Evaluatable
|
||||||
( Evaluatable(..)
|
( Evaluatable(..)
|
||||||
, Recursive(..)
|
, Recursive(..)
|
||||||
, Base
|
, Base
|
||||||
, Subterm(..)
|
, Subterm(..)
|
||||||
|
, AbstractFunction(..)
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
import Control.Monad.Effect.Addressable
|
||||||
import Control.Monad.Effect.Fail
|
import Control.Monad.Effect.Fail
|
||||||
|
import Control.Monad.Effect.Fresh
|
||||||
import Control.Monad.Effect.Internal
|
import Control.Monad.Effect.Internal
|
||||||
|
import Control.Monad.Effect.NonDetEff
|
||||||
import Control.Monad.Effect.Reader
|
import Control.Monad.Effect.Reader
|
||||||
import Control.Monad.Effect.State
|
import Control.Monad.Effect.State
|
||||||
import Data.Abstract.Environment
|
import Data.Abstract.Environment
|
||||||
import Data.Abstract.FreeVariables
|
import Data.Abstract.FreeVariables
|
||||||
|
import Data.Abstract.Type as Type
|
||||||
import Data.Abstract.Value
|
import Data.Abstract.Value
|
||||||
import Data.Algebra
|
import Data.Algebra
|
||||||
import Data.Functor.Classes
|
import Data.Functor.Classes
|
||||||
@ -26,7 +31,7 @@ import qualified Data.Union as U
|
|||||||
|
|
||||||
-- | The 'Evaluatable' class defines the necessary interface for a term to be evaluated. While a default definition of 'eval' is given, instances with computational content must implement 'eval' to perform their small-step operational semantics.
|
-- | The 'Evaluatable' class defines the necessary interface for a term to be evaluated. While a default definition of 'eval' is given, instances with computational content must implement 'eval' to perform their small-step operational semantics.
|
||||||
class Evaluatable effects term value constr where
|
class Evaluatable effects term value constr where
|
||||||
eval :: (AbstractValue term value, FreeVariables term) => SubtermAlgebra constr term (Eff effects value)
|
eval :: (AbstractFunction effects term value, FreeVariables term) => SubtermAlgebra constr term (Eff effects value)
|
||||||
default eval :: (Fail :< effects, FreeVariables term, Show1 constr) => SubtermAlgebra constr term (Eff effects value)
|
default eval :: (Fail :< effects, FreeVariables term, Show1 constr) => SubtermAlgebra constr term (Eff effects value)
|
||||||
eval expr = fail $ "Eval unspecialized for " ++ liftShowsPrec (const (const id)) (const id) 0 expr ""
|
eval expr = fail $ "Eval unspecialized for " ++ liftShowsPrec (const (const id)) (const id) 0 expr ""
|
||||||
|
|
||||||
@ -67,3 +72,20 @@ instance ( Ord (LocationFor v)
|
|||||||
-- environment each time where the free variables in those terms are bound
|
-- environment each time where the free variables in those terms are bound
|
||||||
-- to the global environment.
|
-- to the global environment.
|
||||||
local (const (bindEnv (liftFreeVariables (freeVariables . subterm) xs) env)) (eval xs)
|
local (const (bindEnv (liftFreeVariables (freeVariables . subterm) xs) env)) (eval xs)
|
||||||
|
|
||||||
|
class AbstractValue v => AbstractFunction effects t v | v -> t where
|
||||||
|
abstract :: [Name] -> (t, Eff effects v) -> Eff effects v
|
||||||
|
|
||||||
|
instance Reader (EnvironmentFor (Value location t)) :< effects => AbstractFunction effects t (Value location t) where
|
||||||
|
abstract names (body, _) = inj . Closure names body <$> ask @(EnvironmentFor (Value location t))
|
||||||
|
|
||||||
|
instance Members '[Fresh, NonDetEff, Reader (EnvironmentFor (Type t)), State (StoreFor (Type t))] effects => AbstractFunction effects t (Type t) where
|
||||||
|
abstract names (_, body) = do
|
||||||
|
(env, tvars) <- foldr (\ name rest -> do
|
||||||
|
a <- alloc name
|
||||||
|
tvar <- Var <$> fresh
|
||||||
|
assign a tvar
|
||||||
|
(env, tvars) <- rest
|
||||||
|
pure (envInsert name a env, tvar : tvars)) (pure mempty) names
|
||||||
|
ret <- local (mappend env) body
|
||||||
|
pure (Type.Product tvars :-> ret)
|
||||||
|
@ -97,7 +97,7 @@ class ValueRoots l v | v -> l where
|
|||||||
valueRoots :: v -> Live l v
|
valueRoots :: v -> Live l v
|
||||||
|
|
||||||
-- | An interface for constructing abstract values.
|
-- | An interface for constructing abstract values.
|
||||||
class AbstractValue t v | v -> t where
|
class AbstractValue v where
|
||||||
-- | Construct an abstract unit value.
|
-- | Construct an abstract unit value.
|
||||||
unit :: v
|
unit :: v
|
||||||
|
|
||||||
@ -110,8 +110,6 @@ class AbstractValue t v | v -> t where
|
|||||||
-- | Construct an abstract string value.
|
-- | Construct an abstract string value.
|
||||||
string :: ByteString -> v
|
string :: ByteString -> v
|
||||||
|
|
||||||
-- abstract :: Monad m => [Name] -> (t, m v) -> m v
|
|
||||||
|
|
||||||
|
|
||||||
-- Instances
|
-- Instances
|
||||||
|
|
||||||
@ -122,18 +120,17 @@ instance (FreeVariables term, Ord location) => ValueRoots location (Value locati
|
|||||||
| otherwise = mempty
|
| otherwise = mempty
|
||||||
|
|
||||||
-- | Construct a 'Value' wrapping the value arguments (if any).
|
-- | Construct a 'Value' wrapping the value arguments (if any).
|
||||||
instance AbstractValue term (Value location term) where
|
instance AbstractValue (Value location term) where
|
||||||
unit = inj Unit
|
unit = inj Unit
|
||||||
integer = inj . Integer
|
integer = inj . Integer
|
||||||
boolean = inj . Boolean
|
boolean = inj . Boolean
|
||||||
string = inj . String
|
string = inj . String
|
||||||
-- abstract names (term, _) = inj . Closure names term <$> ask
|
|
||||||
|
|
||||||
instance ValueRoots Monovariant (Type.Type term) where
|
instance ValueRoots Monovariant (Type.Type term) where
|
||||||
valueRoots _ = mempty
|
valueRoots _ = mempty
|
||||||
|
|
||||||
-- | Discard the value arguments (if any), constructing a 'Type.Type' instead.
|
-- | Discard the value arguments (if any), constructing a 'Type.Type' instead.
|
||||||
instance AbstractValue term (Type.Type term) where
|
instance AbstractValue (Type.Type term) where
|
||||||
unit = Type.Unit
|
unit = Type.Unit
|
||||||
integer _ = Type.Int
|
integer _ = Type.Int
|
||||||
boolean _ = Type.Bool
|
boolean _ = Type.Bool
|
||||||
|
Loading…
Reference in New Issue
Block a user