packages feed

cg-0.0.9.0: CG/Prover/Ins.hs

module CG.Prover.Ins (Ins,runIns,ins) where


import Control.Monad.State (MonadState(..),StateT,execStateT,liftM,liftM2)
import Data.IntMap as IM (lookup,empty,insert)
import Data.Void (Void)
import CG.Prover.Base


type Ins c a = StateT (VMap c Void) Maybe a


runIns :: Ins c a -> Maybe (VMap c Void)
runIns x = execStateT x IM.empty


ins :: (Eq c) => Term c Void -> Term c Int -> Ins c (Term c Void)
ins   (Con x xs) (Con y ys) | x == y = liftM (Con x) (insAll xs ys)
ins x@(Con _ _ ) (Var i   )          = do vm <- get
                                          case IM.lookup i vm of
                                           Just y -> if x == y
                                                     then return x
                                                     else fail "cannot insantiate"
                                           _      -> do put (IM.insert i x vm)
                                                        return x
ins _            _                   = fail "cannot insantiate"


insAll :: (Eq c) => [Term c Void] -> [Term c Int] -> Ins c [Term c Void]
insAll    []     []  = return []
insAll (x:xs) (y:ys) = liftM2 (:) (ins x y) (insAll xs ys)
insAll  _      _     = fail "cannot instantiate"