module Data.Express.Match
( match
, matchWith
, isInstanceOf
, hasInstanceOf
, isSubexprOf
, encompasses
)
where
import Data.Express.Core
import Data.Express.Utils
match :: Expr -> Expr -> Maybe [(Expr,Expr)]
match :: Expr -> Expr -> Maybe [(Expr, Expr)]
match = [(Expr, Expr)] -> Expr -> Expr -> Maybe [(Expr, Expr)]
matchWith []
matchWith :: [(Expr,Expr)] -> Expr -> Expr -> Maybe [(Expr,Expr)]
matchWith :: [(Expr, Expr)] -> Expr -> Expr -> Maybe [(Expr, Expr)]
matchWith [(Expr, Expr)]
bs Expr
e1' Expr
e2' = Expr -> Expr -> [(Expr, Expr)] -> Maybe [(Expr, Expr)]
m Expr
e1' Expr
e2' [(Expr, Expr)]
bs
where
m :: Expr -> Expr -> [(Expr,Expr)] -> Maybe [(Expr,Expr)]
m :: Expr -> Expr -> [(Expr, Expr)] -> Maybe [(Expr, Expr)]
m (Expr
f1 :$ Expr
x1) (Expr
f2 :$ Expr
x2) = Expr -> Expr -> [(Expr, Expr)] -> Maybe [(Expr, Expr)]
m Expr
f1 Expr
f2 ([(Expr, Expr)] -> Maybe [(Expr, Expr)])
-> ([(Expr, Expr)] -> Maybe [(Expr, Expr)])
-> [(Expr, Expr)]
-> Maybe [(Expr, Expr)]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Expr -> Expr -> [(Expr, Expr)] -> Maybe [(Expr, Expr)]
m Expr
x1 Expr
x2
m Expr
e1 Expr
e2
| Expr -> Bool
isVar Expr
e2 Bool -> Bool -> Bool
&& Expr -> Maybe TypeRep
mtyp Expr
e1 Maybe TypeRep -> Maybe TypeRep -> Bool
forall a. Eq a => a -> a -> Bool
== Expr -> Maybe TypeRep
mtyp Expr
e2 = (Expr, Expr) -> [(Expr, Expr)] -> Maybe [(Expr, Expr)]
updateAssignments (Expr
e2,Expr
e1)
| Expr
e1 Expr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
== Expr
e2 = [(Expr, Expr)] -> Maybe [(Expr, Expr)]
forall a. a -> Maybe a
Just
| Bool
otherwise = Maybe [(Expr, Expr)] -> [(Expr, Expr)] -> Maybe [(Expr, Expr)]
forall a b. a -> b -> a
const Maybe [(Expr, Expr)]
forall a. Maybe a
Nothing
updateAssignments :: (Expr,Expr) -> [(Expr,Expr)] -> Maybe [(Expr,Expr)]
updateAssignments :: (Expr, Expr) -> [(Expr, Expr)] -> Maybe [(Expr, Expr)]
updateAssignments (Expr
e,Expr
e') = \[(Expr, Expr)]
bs ->
case Expr -> [(Expr, Expr)] -> Maybe Expr
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Expr
e [(Expr, Expr)]
bs of
Maybe Expr
Nothing -> [(Expr, Expr)] -> Maybe [(Expr, Expr)]
forall a. a -> Maybe a
Just ((Expr
e,Expr
e')(Expr, Expr) -> [(Expr, Expr)] -> [(Expr, Expr)]
forall a. a -> [a] -> [a]
:[(Expr, Expr)]
bs)
Just Expr
e'' -> if Expr
e'' Expr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
== Expr
e'
then [(Expr, Expr)] -> Maybe [(Expr, Expr)]
forall a. a -> Maybe a
Just [(Expr, Expr)]
bs
else Maybe [(Expr, Expr)]
forall a. Maybe a
Nothing
isInstanceOf :: Expr -> Expr -> Bool
Expr
e1 isInstanceOf :: Expr -> Expr -> Bool
`isInstanceOf` Expr
e2 = Maybe [(Expr, Expr)] -> Bool
forall a. Maybe a -> Bool
isJust (Maybe [(Expr, Expr)] -> Bool) -> Maybe [(Expr, Expr)] -> Bool
forall a b. (a -> b) -> a -> b
$ Expr
e1 Expr -> Expr -> Maybe [(Expr, Expr)]
`match` Expr
e2
encompasses :: Expr -> Expr -> Bool
encompasses :: Expr -> Expr -> Bool
encompasses = (Expr -> Expr -> Bool) -> Expr -> Expr -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Expr -> Expr -> Bool
isInstanceOf
hasInstanceOf :: Expr -> Expr -> Bool
Expr
e1 hasInstanceOf :: Expr -> Expr -> Bool
`hasInstanceOf` Expr
e2 = (Expr -> Bool) -> [Expr] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Expr -> Expr -> Bool
`isInstanceOf` Expr
e2) (Expr -> [Expr]
subexprs Expr
e1)
isSubexprOf :: Expr -> Expr -> Bool
isSubexprOf :: Expr -> Expr -> Bool
isSubexprOf Expr
e = (Expr
e Expr -> [Expr] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem`) ([Expr] -> Bool) -> (Expr -> [Expr]) -> Expr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr -> [Expr]
subexprs