43 lines
1.5 KiB
Plaintext
43 lines
1.5 KiB
Plaintext
module Language.Bergamot.Rules where
|
|
|
|
import Prelude
|
|
|
|
import Language.Bergamot.Syntax (Expr)
|
|
|
|
import Control.Monad.State.Trans (runStateT)
|
|
import Control.Monad.State.Class (class MonadState, gets, modify)
|
|
import Control.Monad.Unify.Class (class MonadUnify, fresh)
|
|
import Data.List (List)
|
|
import Data.Traversable (class Traversable, traverse)
|
|
import Data.Foldable (class Foldable)
|
|
import Data.Map (Map, lookup, insert)
|
|
import Data.Map as Map
|
|
import Data.Tuple (fst)
|
|
import Data.Newtype (class Newtype)
|
|
import Data.Maybe (Maybe(..))
|
|
|
|
newtype Rule k = MkRule { name :: String, head :: Expr k, tail :: List (Expr k) }
|
|
derive instance Newtype (Rule k) _
|
|
derive instance Functor Rule
|
|
derive instance Foldable Rule
|
|
derive instance Traversable Rule
|
|
|
|
type Metavariable = String
|
|
type Metavariables k = Map Metavariable k
|
|
|
|
newtype ProofTree k = MkProofTree { claim :: Expr k, rule :: Rule Metavariable, witnesses :: List (ProofTree k) }
|
|
|
|
metavariable :: forall k f m. MonadState (Metavariables k) m => MonadUnify k f m => Metavariable -> m k
|
|
metavariable s = do
|
|
r <- gets (lookup s)
|
|
case r of
|
|
Just v -> pure v
|
|
Nothing -> do
|
|
v <- fresh
|
|
modify (insert s v) *> pure v
|
|
|
|
-- note: unification expression ef not the same as functor-to-instantiate f, this way we can instantiate
|
|
-- things that contain expression etc.
|
|
instantiate :: forall k f ef m. Traversable f => MonadUnify k ef m => f Metavariable -> m (f k)
|
|
instantiate f = map fst $ runStateT (traverse metavariable f) Map.empty
|