module MagicHaskeller.Analytical.FMExpr where
import qualified Data.IntMap as IntMap
import qualified MagicHaskeller.Types as Types
import MagicHaskeller.Analytical.Syntax
iopsToVisFME :: TBS -> [IOPair a] -> FMExpr [IOPair a]
iopsToVisFME :: TBS -> [IOPair a] -> FMExpr [IOPair a]
iopsToVisFME TBS
tbs = [IOPair a] -> FMExpr [IOPair a]
forall a. [IOPair a] -> FMExpr [IOPair a]
iopsToFME ([IOPair a] -> FMExpr [IOPair a])
-> ([IOPair a] -> [IOPair a]) -> [IOPair a] -> FMExpr [IOPair a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IOPair a -> IOPair a) -> [IOPair a] -> [IOPair a]
forall a b. (a -> b) -> [a] -> [b]
map (TBS -> IOPair a -> IOPair a
forall a. TBS -> IOPair a -> IOPair a
visIOP TBS
tbs)
iopsToFME :: [IOPair a] -> FMExpr [IOPair a]
iopsToFME :: [IOPair a] -> FMExpr [IOPair a]
iopsToFME = [(Expr a, IOPair a)] -> FMExpr [IOPair a]
forall b a. [(Expr b, a)] -> FMExpr [a]
assocsToFME ([(Expr a, IOPair a)] -> FMExpr [IOPair a])
-> ([IOPair a] -> [(Expr a, IOPair a)])
-> [IOPair a]
-> FMExpr [IOPair a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IOPair a -> (Expr a, IOPair a))
-> [IOPair a] -> [(Expr a, IOPair a)]
forall a b. (a -> b) -> [a] -> [b]
map IOPair a -> (Expr a, IOPair a)
forall a. IOPair a -> (Expr a, IOPair a)
iop2Assoc
visIOP :: TBS -> IOPair a -> IOPair a
visIOP :: TBS -> IOPair a -> IOPair a
visIOP TBS
tbs IOPair a
iop = IOPair a
iop {inputs :: [Expr a]
inputs = TBS -> [Expr a] -> [Expr a]
forall a. TBS -> [a] -> [a]
visibles TBS
tbs ([Expr a] -> [Expr a]) -> [Expr a] -> [Expr a]
forall a b. (a -> b) -> a -> b
$ IOPair a -> [Expr a]
forall a. IOPair a -> [Expr a]
inputs IOPair a
iop}
iop2Assoc :: IOPair a -> (Expr a, IOPair a)
iop2Assoc :: IOPair a -> (Expr a, IOPair a)
iop2Assoc IOPair a
iop = (IOPair a -> Expr a
forall a. IOPair a -> Expr a
output IOPair a
iop, IOPair a
iop)
data FMExpr a = EmptyFME
| FME { FMExpr a -> IntMap a
existentialFME :: IntMap.IntMap a, FMExpr a -> [a]
universalFME :: [a], FMExpr a -> IntMap (FMExprs a)
conApFME :: IntMap.IntMap (FMExprs a) } deriving Int -> FMExpr a -> ShowS
[FMExpr a] -> ShowS
FMExpr a -> String
(Int -> FMExpr a -> ShowS)
-> (FMExpr a -> String) -> ([FMExpr a] -> ShowS) -> Show (FMExpr a)
forall a. Show a => Int -> FMExpr a -> ShowS
forall a. Show a => [FMExpr a] -> ShowS
forall a. Show a => FMExpr a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FMExpr a] -> ShowS
$cshowList :: forall a. Show a => [FMExpr a] -> ShowS
show :: FMExpr a -> String
$cshow :: forall a. Show a => FMExpr a -> String
showsPrec :: Int -> FMExpr a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> FMExpr a -> ShowS
Show
data FMExprs a = EmptyFMEs
| FMEs { FMExprs a -> a
nilFMEs :: a, FMExprs a -> FMExpr (FMExprs a)
consFMEs :: FMExpr (FMExprs a) } deriving Int -> FMExprs a -> ShowS
[FMExprs a] -> ShowS
FMExprs a -> String
(Int -> FMExprs a -> ShowS)
-> (FMExprs a -> String)
-> ([FMExprs a] -> ShowS)
-> Show (FMExprs a)
forall a. Show a => Int -> FMExprs a -> ShowS
forall a. Show a => [FMExprs a] -> ShowS
forall a. Show a => FMExprs a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FMExprs a] -> ShowS
$cshowList :: forall a. Show a => [FMExprs a] -> ShowS
show :: FMExprs a -> String
$cshow :: forall a. Show a => FMExprs a -> String
showsPrec :: Int -> FMExprs a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> FMExprs a -> ShowS
Show
instance Functor FMExpr where
fmap :: (a -> b) -> FMExpr a -> FMExpr b
fmap a -> b
_ FMExpr a
EmptyFME = FMExpr b
forall a. FMExpr a
EmptyFME
fmap a -> b
f (FME {existentialFME :: forall a. FMExpr a -> IntMap a
existentialFME=IntMap a
e, universalFME :: forall a. FMExpr a -> [a]
universalFME=[a]
u, conApFME :: forall a. FMExpr a -> IntMap (FMExprs a)
conApFME=IntMap (FMExprs a)
c}) = FME :: forall a. IntMap a -> [a] -> IntMap (FMExprs a) -> FMExpr a
FME{existentialFME :: IntMap b
existentialFME = (a -> b) -> IntMap a -> IntMap b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f IntMap a
e, universalFME :: [b]
universalFME = (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f [a]
u, conApFME :: IntMap (FMExprs b)
conApFME = (FMExprs a -> FMExprs b)
-> IntMap (FMExprs a) -> IntMap (FMExprs b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b) -> FMExprs a -> FMExprs b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f) IntMap (FMExprs a)
c}
instance Functor FMExprs where
fmap :: (a -> b) -> FMExprs a -> FMExprs b
fmap a -> b
f FMExprs a
EmptyFMEs = FMExprs b
forall a. FMExprs a
EmptyFMEs
fmap a -> b
f (FMEs {nilFMEs :: forall a. FMExprs a -> a
nilFMEs = a
n, consFMEs :: forall a. FMExprs a -> FMExpr (FMExprs a)
consFMEs = FMExpr (FMExprs a)
c}) = FMEs :: forall a. a -> FMExpr (FMExprs a) -> FMExprs a
FMEs {nilFMEs :: b
nilFMEs = a -> b
f a
n, consFMEs :: FMExpr (FMExprs b)
consFMEs = (FMExprs a -> FMExprs b)
-> FMExpr (FMExprs a) -> FMExpr (FMExprs b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b) -> FMExprs a -> FMExprs b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f) FMExpr (FMExprs a)
c}
assocsToFME :: [(Expr b, a)] -> FMExpr [a]
assocsToFME :: [(Expr b, a)] -> FMExpr [a]
assocsToFME = ((Expr b, a) -> FMExpr [a] -> FMExpr [a])
-> FMExpr [a] -> [(Expr b, a)] -> FMExpr [a]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\(Expr b
k,a
v) -> ([a] -> [a]) -> [a] -> Expr b -> FMExpr [a] -> FMExpr [a]
forall a b. (a -> a) -> a -> Expr b -> FMExpr a -> FMExpr a
updateFME (a
va -> [a] -> [a]
forall a. a -> [a] -> [a]
:) [] Expr b
k) FMExpr [a]
forall a. FMExpr a
emptyFME
updateFME :: (a->a) -> a -> Expr b -> FMExpr a -> FMExpr a
updateFME :: (a -> a) -> a -> Expr b -> FMExpr a -> FMExpr a
updateFME a -> a
f a
x Expr b
t FMExpr a
EmptyFME = (a -> a) -> a -> Expr b -> FMExpr a -> FMExpr a
forall a b. (a -> a) -> a -> Expr b -> FMExpr a -> FMExpr a
updateFME a -> a
f a
x Expr b
t FMExpr a
forall a. FMExpr a
emptyFME
updateFME a -> a
f a
x (E b
_ Int
i) FMExpr a
fme = FMExpr a
fme { existentialFME :: IntMap a
existentialFME = (a -> a -> a) -> Int -> a -> IntMap a -> IntMap a
forall a. (a -> a -> a) -> Int -> a -> IntMap a -> IntMap a
IntMap.insertWith (\a
_ -> a -> a
f) Int
i (a -> a
f a
x) (IntMap a -> IntMap a) -> IntMap a -> IntMap a
forall a b. (a -> b) -> a -> b
$ FMExpr a -> IntMap a
forall a. FMExpr a -> IntMap a
existentialFME FMExpr a
fme }
updateFME a -> a
f a
x (U b
_ Int
i) FMExpr a
fme = FMExpr a
fme { universalFME :: [a]
universalFME = (a -> a) -> a -> Int -> [a] -> [a]
forall t. (t -> t) -> t -> Int -> [t] -> [t]
insertNth a -> a
f a
x Int
i ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ FMExpr a -> [a]
forall a. FMExpr a -> [a]
universalFME FMExpr a
fme }
updateFME a -> a
f a
x (C b
_ Int
_ (Constr
c Types.:::Type
_) [Expr b]
fs) FMExpr a
fme = FMExpr a
fme { conApFME :: IntMap (FMExprs a)
conApFME = (FMExprs a -> FMExprs a -> FMExprs a)
-> Int -> FMExprs a -> IntMap (FMExprs a) -> IntMap (FMExprs a)
forall a. (a -> a -> a) -> Int -> a -> IntMap a -> IntMap a
IntMap.insertWith (\FMExprs a
_ -> (a -> a) -> a -> [Expr b] -> FMExprs a -> FMExprs a
forall a b. (a -> a) -> a -> [Expr b] -> FMExprs a -> FMExprs a
updateFMEs a -> a
f a
x [Expr b]
fs) (Constr -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Constr
c) ((a -> a) -> a -> [Expr b] -> FMExprs a -> FMExprs a
forall a b. (a -> a) -> a -> [Expr b] -> FMExprs a -> FMExprs a
updateFMEs a -> a
f a
x [Expr b]
fs FMExprs a
forall a. FMExprs a
EmptyFMEs) (IntMap (FMExprs a) -> IntMap (FMExprs a))
-> IntMap (FMExprs a) -> IntMap (FMExprs a)
forall a b. (a -> b) -> a -> b
$ FMExpr a -> IntMap (FMExprs a)
forall a. FMExpr a -> IntMap (FMExprs a)
conApFME FMExpr a
fme }
updateFMEs :: (a -> a) -> a -> [Expr b] -> FMExprs a -> FMExprs a
updateFMEs a -> a
f a
x [Expr b]
es FMExprs a
EmptyFMEs = (a -> a) -> a -> [Expr b] -> FMExprs a -> FMExprs a
updateFMEs a -> a
f a
x [Expr b]
es FMEs :: forall a. a -> FMExpr (FMExprs a) -> FMExprs a
FMEs{nilFMEs :: a
nilFMEs = a
x, consFMEs :: FMExpr (FMExprs a)
consFMEs = FMExpr (FMExprs a)
forall a. FMExpr a
EmptyFME}
updateFMEs a -> a
f a
x [] FMExprs a
fmes = FMExprs a
fmes { nilFMEs :: a
nilFMEs = a -> a
f (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ FMExprs a -> a
forall a. FMExprs a -> a
nilFMEs FMExprs a
fmes }
updateFMEs a -> a
f a
x (Expr b
e:[Expr b]
es) FMExprs a
fmes = FMExprs a
fmes { consFMEs :: FMExpr (FMExprs a)
consFMEs = (FMExprs a -> FMExprs a)
-> FMExprs a -> Expr b -> FMExpr (FMExprs a) -> FMExpr (FMExprs a)
forall a b. (a -> a) -> a -> Expr b -> FMExpr a -> FMExpr a
updateFME ((a -> a) -> a -> [Expr b] -> FMExprs a -> FMExprs a
updateFMEs a -> a
f a
x [Expr b]
es) FMExprs a
forall a. FMExprs a
EmptyFMEs Expr b
e (FMExpr (FMExprs a) -> FMExpr (FMExprs a))
-> FMExpr (FMExprs a) -> FMExpr (FMExprs a)
forall a b. (a -> b) -> a -> b
$ FMExprs a -> FMExpr (FMExprs a)
forall a. FMExprs a -> FMExpr (FMExprs a)
consFMEs FMExprs a
fmes }
emptyFME :: FMExpr a
emptyFME = FME :: forall a. IntMap a -> [a] -> IntMap (FMExprs a) -> FMExpr a
FME{ existentialFME :: IntMap a
existentialFME = IntMap a
forall a. IntMap a
IntMap.empty, universalFME :: [a]
universalFME = [], conApFME :: IntMap (FMExprs a)
conApFME = IntMap (FMExprs a)
forall a. IntMap a
IntMap.empty }
insertNth :: (t -> t) -> t -> Int -> [t] -> [t]
insertNth t -> t
upd t
zero Int
n [] = Int -> t -> [t]
forall a. Int -> a -> [a]
replicate Int
n t
zero [t] -> [t] -> [t]
forall a. [a] -> [a] -> [a]
++ [t -> t
upd t
zero]
insertNth t -> t
upd t
zero Int
0 (t
x:[t]
xs) = t -> t
upd t
x t -> [t] -> [t]
forall a. a -> [a] -> [a]
: [t]
xs
insertNth t -> t
upd t
zero Int
n (t
x:[t]
xs) = t
x t -> [t] -> [t]
forall a. a -> [a] -> [a]
: (t -> t) -> t -> Int -> [t] -> [t]
insertNth t -> t
upd t
zero (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) [t]
xs
unifyFME :: Expr b -> FMExpr a -> [(a, Subst b)]
unifyFME :: Expr b -> FMExpr a -> [(a, Subst b)]
unifyFME Expr b
x FMExpr a
fme = Expr b -> FMExpr a -> Subst b -> [(a, Subst b)]
forall b a. Expr b -> FMExpr a -> Subst b -> [(a, Subst b)]
unifyFME' Expr b
x FMExpr a
fme Subst b
forall a. [a]
emptySubst
unifyFME' :: Expr b -> FMExpr a -> Subst b -> [(a, Subst b)]
unifyFME' :: Expr b -> FMExpr a -> Subst b -> [(a, Subst b)]
unifyFME' Expr b
x FMExpr a
EmptyFME Subst b
s = []
unifyFME' (E{}) FMExpr a
fme Subst b
s = [ (a
x, Subst b
s) | a
x <- FMExpr a -> [a]
forall a. FMExpr a -> [a]
valsFME FMExpr a
fme ]
unifyFME' x :: Expr b
x@(U b
_ Int
i) FMExpr a
fme Subst b
s = [ (a
v, Subst b
subst Subst b -> Subst b -> Subst b
forall a. Subst a -> Subst a -> Subst a
`plusSubst` Subst b
s)
| (Int
k,a
v) <- [Int] -> [a] -> [(Int, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] (FMExpr a -> [a]
forall a. FMExpr a -> [a]
universalFME FMExpr a
fme)
, Subst b
subst <- case Int -> Subst b -> Maybe (Expr b)
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Int
k Subst b
s of Maybe (Expr b)
Nothing -> [[(Int
k,Expr b
x)]]
Just (E{iD :: forall a. Expr a -> Int
iD=Int
j}) -> [[(Int
j,Expr b
x)]]
Just (U{iD :: forall a. Expr a -> Int
iD=Int
j}) | Int
iInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
j -> [[]]
Maybe (Expr b)
_ -> []
]
unifyFME' x :: Expr b
x@(C b
_ Int
_sz (Constr
c Types.::: Type
_) [Expr b]
xs) FMExpr a
fme Subst b
s = [(a, Subst b)]
matchExistential [(a, Subst b)] -> [(a, Subst b)] -> [(a, Subst b)]
forall a. [a] -> [a] -> [a]
++ [(a, Subst b)]
matchConstr
where matchExistential :: [(a, Subst b)]
matchExistential = [ (a
v, Subst b
subst Subst b -> Subst b -> Subst b
forall a. Subst a -> Subst a -> Subst a
`plusSubst` Subst b
s)
| (Int
k,a
v) <- [Int] -> [a] -> [(Int, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] (FMExpr a -> [a]
forall a. FMExpr a -> [a]
universalFME FMExpr a
fme)
, Subst b
subst <- case Int -> Subst b -> Maybe (Expr b)
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Int
k Subst b
s of Maybe (Expr b)
Nothing -> [[(Int
k,Expr b
x)]]
Just Expr b
e -> Expr b -> Expr b -> [Subst b]
forall (m :: * -> *) a.
MonadPlus m =>
Expr a -> Expr a -> m [(Int, Expr a)]
unify Expr b
e Expr b
x
]
matchConstr :: [(a, Subst b)]
matchConstr = case Int -> IntMap (FMExprs a) -> Maybe (FMExprs a)
forall a. Int -> IntMap a -> Maybe a
IntMap.lookup (Constr -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Constr
c) (FMExpr a -> IntMap (FMExprs a)
forall a. FMExpr a -> IntMap (FMExprs a)
conApFME FMExpr a
fme) of
Maybe (FMExprs a)
Nothing -> []
Just FMExprs a
fmes -> [Expr b] -> FMExprs a -> Subst b -> [(a, Subst b)]
forall b a. [Expr b] -> FMExprs a -> Subst b -> [(a, Subst b)]
unifyFMEs [Expr b]
xs FMExprs a
fmes Subst b
s
unifyFMEs :: [Expr b] -> FMExprs a -> Subst b -> [(a, Subst b)]
unifyFMEs :: [Expr b] -> FMExprs a -> Subst b -> [(a, Subst b)]
unifyFMEs [Expr b]
_ FMExprs a
EmptyFMEs Subst b
_ = []
unifyFMEs [] FMExprs a
fmes Subst b
s = [ (FMExprs a -> a
forall a. FMExprs a -> a
nilFMEs FMExprs a
fmes, Subst b
s) ]
unifyFMEs (Expr b
x:[Expr b]
xs) FMExprs a
fmes Subst b
s = [ (a, Subst b)
t | (FMExprs a
fmes', Subst b
s') <- Expr b -> FMExpr (FMExprs a) -> Subst b -> [(FMExprs a, Subst b)]
forall b a. Expr b -> FMExpr a -> Subst b -> [(a, Subst b)]
unifyFME' Expr b
x (FMExprs a -> FMExpr (FMExprs a)
forall a. FMExprs a -> FMExpr (FMExprs a)
consFMEs FMExprs a
fmes) Subst b
s, (a, Subst b)
t <- [Expr b] -> FMExprs a -> Subst b -> [(a, Subst b)]
forall b a. [Expr b] -> FMExprs a -> Subst b -> [(a, Subst b)]
unifyFMEs [Expr b]
xs FMExprs a
fmes' Subst b
s' ]
valsFME :: FMExpr a -> [a]
valsFME :: FMExpr a -> [a]
valsFME FMExpr a
EmptyFME = []
valsFME FMExpr a
fme = IntMap a -> [a]
forall a. IntMap a -> [a]
IntMap.elems (FMExpr a -> IntMap a
forall a. FMExpr a -> IntMap a
existentialFME FMExpr a
fme) [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ FMExpr a -> [a]
forall a. FMExpr a -> [a]
universalFME FMExpr a
fme
[a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [ a
v | FMExprs a
fmes <- IntMap (FMExprs a) -> [FMExprs a]
forall a. IntMap a -> [a]
IntMap.elems (FMExpr a -> IntMap (FMExprs a)
forall a. FMExpr a -> IntMap (FMExprs a)
conApFME FMExpr a
fme), a
v <- FMExprs a -> [a]
forall a. FMExprs a -> [a]
valsFMEs FMExprs a
fmes ]
valsFMEs :: FMExprs a -> [a]
valsFMEs :: FMExprs a -> [a]
valsFMEs FMExprs a
EmptyFMEs = []
valsFMEs FMExprs a
fmes = FMExprs a -> a
forall a. FMExprs a -> a
nilFMEs FMExprs a
fmes a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [ a
v | FMExprs a
fmes' <- FMExpr (FMExprs a) -> [FMExprs a]
forall a. FMExpr a -> [a]
valsFME (FMExprs a -> FMExpr (FMExprs a)
forall a. FMExprs a -> FMExpr (FMExprs a)
consFMEs FMExprs a
fmes), a
v <- FMExprs a -> [a]
forall a. FMExprs a -> [a]
valsFMEs FMExprs a
fmes' ]
matchFME :: Expr b -> FMExpr a -> [(a, Subst b)]
matchFME :: Expr b -> FMExpr a -> [(a, Subst b)]
matchFME Expr b
x FMExpr a
fme = Expr b -> FMExpr a -> Subst b -> [(a, Subst b)]
forall b a. Expr b -> FMExpr a -> Subst b -> [(a, Subst b)]
matchFME' Expr b
x FMExpr a
fme Subst b
forall a. [a]
emptySubst
matchFME' :: Expr b -> FMExpr a -> Subst b -> [(a, Subst b)]
matchFME' :: Expr b -> FMExpr a -> Subst b -> [(a, Subst b)]
matchFME' Expr b
x FMExpr a
EmptyFME Subst b
s = []
matchFME' (E {}) FMExpr a
fme Subst b
s = [ (a
x, Subst b
s) | a
x <- FMExpr a -> [a]
forall a. FMExpr a -> [a]
valsFME FMExpr a
fme ]
matchFME' x :: Expr b
x@(U{}) FMExpr a
fme Subst b
s = Expr b -> FMExpr a -> Subst b -> [(a, Subst b)]
forall b a. Expr b -> FMExpr a -> Subst b -> [(a, Subst b)]
matchExistential Expr b
x FMExpr a
fme Subst b
s
matchFME' x :: Expr b
x@(C b
_ Int
_sz (Constr
c Types.::: Type
_) [Expr b]
xs) FMExpr a
fme Subst b
s = Expr b -> FMExpr a -> Subst b -> [(a, Subst b)]
forall b a. Expr b -> FMExpr a -> Subst b -> [(a, Subst b)]
matchExistential Expr b
x FMExpr a
fme Subst b
s [(a, Subst b)] -> [(a, Subst b)] -> [(a, Subst b)]
forall a. [a] -> [a] -> [a]
++ [(a, Subst b)]
matchConstr
where matchConstr :: [(a, Subst b)]
matchConstr = case Int -> IntMap (FMExprs a) -> Maybe (FMExprs a)
forall a. Int -> IntMap a -> Maybe a
IntMap.lookup (Constr -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Constr
c) (FMExpr a -> IntMap (FMExprs a)
forall a. FMExpr a -> IntMap (FMExprs a)
conApFME FMExpr a
fme) of
Maybe (FMExprs a)
Nothing -> []
Just FMExprs a
fmes -> [Expr b] -> FMExprs a -> Subst b -> [(a, Subst b)]
forall b a. [Expr b] -> FMExprs a -> Subst b -> [(a, Subst b)]
matchFMEs [Expr b]
xs FMExprs a
fmes Subst b
s
matchExistential :: Expr a -> FMExpr a -> [(Int, Expr a)] -> [(a, [(Int, Expr a)])]
matchExistential Expr a
x FMExpr a
fme [(Int, Expr a)]
s = [ (a
v, [(Int, Expr a)]
subst [(Int, Expr a)] -> [(Int, Expr a)] -> [(Int, Expr a)]
forall a. Subst a -> Subst a -> Subst a
`plusSubst` [(Int, Expr a)]
s)
| (Int
k,a
v) <- [Int] -> [a] -> [(Int, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..] (FMExpr a -> [a]
forall a. FMExpr a -> [a]
universalFME FMExpr a
fme)
, [(Int, Expr a)]
subst <- case Int -> [(Int, Expr a)] -> Maybe (Expr a)
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Int
k [(Int, Expr a)]
s of Maybe (Expr a)
Nothing -> [[(Int
k,Expr a
x)]]
Just Expr a
e -> Expr a -> Expr a -> [[(Int, Expr a)]]
forall (m :: * -> *) a.
MonadPlus m =>
Expr a -> Expr a -> m [(Int, Expr a)]
unify Expr a
e Expr a
x
]
matchFMEs :: [Expr b] -> FMExprs a -> Subst b -> [(a, Subst b)]
matchFMEs :: [Expr b] -> FMExprs a -> Subst b -> [(a, Subst b)]
matchFMEs [Expr b]
_ FMExprs a
EmptyFMEs Subst b
_ = []
matchFMEs [] FMExprs a
fmes Subst b
s = [ (FMExprs a -> a
forall a. FMExprs a -> a
nilFMEs FMExprs a
fmes, Subst b
s) ]
matchFMEs (Expr b
x:[Expr b]
xs) FMExprs a
fmes Subst b
s = [ (a, Subst b)
t | (FMExprs a
fmes', Subst b
s') <- Expr b -> FMExpr (FMExprs a) -> Subst b -> [(FMExprs a, Subst b)]
forall b a. Expr b -> FMExpr a -> Subst b -> [(a, Subst b)]
matchFME' Expr b
x (FMExprs a -> FMExpr (FMExprs a)
forall a. FMExprs a -> FMExpr (FMExprs a)
consFMEs FMExprs a
fmes) Subst b
s, (a, Subst b)
t <- [Expr b] -> FMExprs a -> Subst b -> [(a, Subst b)]
forall b a. [Expr b] -> FMExprs a -> Subst b -> [(a, Subst b)]
matchFMEs [Expr b]
xs FMExprs a
fmes' Subst b
s' ]