{-# LANGUAGE ExistentialQuantification, PatternGuards, Rank2Types #-}
module Lambdabot.Plugin.Haskell.Pl.Rules (RewriteRule(..), fire, rules) where
import Lambdabot.Plugin.Haskell.Pl.Common
import Lambdabot.Plugin.Haskell.Pl.RuleLib
import Lambdabot.Plugin.Haskell.Pl.Names
collapseLists :: Expr -> Maybe Expr
collapseLists :: Expr -> Maybe Expr
collapseLists (Var Fixity
_ [Char]
"++" `App` Expr
e1 `App` Expr
e2)
| ([Expr]
xs,Expr
x) <- Expr -> ([Expr], Expr)
getList Expr
e1, Expr
xExpr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
==Expr
nil,
([Expr]
ys,Expr
y) <- Expr -> ([Expr], Expr)
getList Expr
e2, Expr
yExpr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
==Expr
nil = Expr -> Maybe Expr
forall a. a -> Maybe a
Just (Expr -> Maybe Expr) -> Expr -> Maybe Expr
forall a b. (a -> b) -> a -> b
$ [Expr] -> Expr
makeList ([Expr] -> Expr) -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$ [Expr]
xs [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ [Expr]
ys
collapseLists Expr
_ = Maybe Expr
forall a. Maybe a
Nothing
data Binary = forall a b c. (Read a, Show a, Read b, Show b, Read c, Show c) => BA (a -> b -> c)
evalBinary :: [(String, Binary)] -> Expr -> Maybe Expr
evalBinary :: [([Char], Binary)] -> Expr -> Maybe Expr
evalBinary [([Char], Binary)]
fs (Var Fixity
_ [Char]
f' `App` Var Fixity
_ [Char]
x' `App` Var Fixity
_ [Char]
y')
| Just (BA a -> b -> c
f) <- [Char] -> [([Char], Binary)] -> Maybe Binary
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup [Char]
f' [([Char], Binary)]
fs = (Fixity -> [Char] -> Expr
Var Fixity
Pref ([Char] -> Expr) -> (c -> [Char]) -> c -> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. c -> [Char]
forall a. Show a => a -> [Char]
show) (c -> Expr) -> Maybe c -> Maybe Expr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` (a -> b -> c) -> Maybe a -> Maybe b -> Maybe c
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 a -> b -> c
f ([Char] -> Maybe a
forall a (m :: * -> *). (Read a, Alternative m) => [Char] -> m a
readM [Char]
x') ([Char] -> Maybe b
forall a (m :: * -> *). (Read a, Alternative m) => [Char] -> m a
readM [Char]
y')
evalBinary [([Char], Binary)]
_ Expr
_ = Maybe Expr
forall a. Maybe a
Nothing
data Unary = forall a b. (Read a, Show a, Read b, Show b) => UA (a -> b)
evalUnary :: [(String, Unary)] -> Expr -> Maybe Expr
evalUnary :: [([Char], Unary)] -> Expr -> Maybe Expr
evalUnary [([Char], Unary)]
fs (Var Fixity
_ [Char]
f' `App` Var Fixity
_ [Char]
x')
| Just (UA a -> b
f) <- [Char] -> [([Char], Unary)] -> Maybe Unary
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup [Char]
f' [([Char], Unary)]
fs = (Fixity -> [Char] -> Expr
Var Fixity
Pref ([Char] -> Expr) -> (a -> [Char]) -> a -> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> [Char]
forall a. Show a => a -> [Char]
show (b -> [Char]) -> (a -> b) -> a -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) (a -> Expr) -> Maybe a -> Maybe Expr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` [Char] -> Maybe a
forall a (m :: * -> *). (Read a, Alternative m) => [Char] -> m a
readM [Char]
x'
evalUnary [([Char], Unary)]
_ Expr
_ = Maybe Expr
forall a. Maybe a
Nothing
assocR, assocL, assoc :: [String] -> Expr -> Maybe Expr
assocR :: [[Char]] -> Expr -> Maybe Expr
assocR [[Char]]
ops (Var Fixity
f1 [Char]
op1 `App` (Var Fixity
f2 [Char]
op2 `App` Expr
e1 `App` Expr
e2) `App` Expr
e3)
| [Char]
op1 [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
op2 Bool -> Bool -> Bool
&& [Char]
op1 [Char] -> [[Char]] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [[Char]]
ops
= Expr -> Maybe Expr
forall a. a -> Maybe a
Just (Fixity -> [Char] -> Expr
Var Fixity
f1 [Char]
op1 Expr -> Expr -> Expr
`App` Expr
e1 Expr -> Expr -> Expr
`App` (Fixity -> [Char] -> Expr
Var Fixity
f2 [Char]
op2 Expr -> Expr -> Expr
`App` Expr
e2 Expr -> Expr -> Expr
`App` Expr
e3))
assocR [[Char]]
_ Expr
_ = Maybe Expr
forall a. Maybe a
Nothing
assocL :: [[Char]] -> Expr -> Maybe Expr
assocL [[Char]]
ops (Var Fixity
f1 [Char]
op1 `App` Expr
e1 `App` (Var Fixity
f2 [Char]
op2 `App` Expr
e2 `App` Expr
e3))
| [Char]
op1 [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
op2 Bool -> Bool -> Bool
&& [Char]
op1 [Char] -> [[Char]] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [[Char]]
ops
= Expr -> Maybe Expr
forall a. a -> Maybe a
Just (Fixity -> [Char] -> Expr
Var Fixity
f1 [Char]
op1 Expr -> Expr -> Expr
`App` (Fixity -> [Char] -> Expr
Var Fixity
f2 [Char]
op2 Expr -> Expr -> Expr
`App` Expr
e1 Expr -> Expr -> Expr
`App` Expr
e2) Expr -> Expr -> Expr
`App` Expr
e3)
assocL [[Char]]
_ Expr
_ = Maybe Expr
forall a. Maybe a
Nothing
assoc :: [[Char]] -> Expr -> Maybe Expr
assoc [[Char]]
ops (Var Fixity
_ [Char]
"." `App` (Var Fixity
f1 [Char]
op1 `App` Expr
e1) `App` (Var Fixity
f2 [Char]
op2 `App` Expr
e2))
| [Char]
op1 [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
op2 Bool -> Bool -> Bool
&& [Char]
op1 [Char] -> [[Char]] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [[Char]]
ops
= Expr -> Maybe Expr
forall a. a -> Maybe a
Just (Fixity -> [Char] -> Expr
Var Fixity
f1 [Char]
op1 Expr -> Expr -> Expr
`App` (Fixity -> [Char] -> Expr
Var Fixity
f2 [Char]
op2 Expr -> Expr -> Expr
`App` Expr
e1 Expr -> Expr -> Expr
`App` Expr
e2))
assoc [[Char]]
_ Expr
_ = Maybe Expr
forall a. Maybe a
Nothing
commutative :: [String] -> Expr -> Maybe Expr
commutative :: [[Char]] -> Expr -> Maybe Expr
commutative [[Char]]
ops (Var Fixity
f [Char]
op `App` Expr
e1 `App` Expr
e2)
| [Char]
op [Char] -> [[Char]] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [[Char]]
ops = Expr -> Maybe Expr
forall a. a -> Maybe a
Just (Fixity -> [Char] -> Expr
Var Fixity
f [Char]
op Expr -> Expr -> Expr
`App` Expr
e2 Expr -> Expr -> Expr
`App` Expr
e1)
commutative [[Char]]
ops (Var Fixity
_ [Char]
"flip" `App` e :: Expr
e@(Var Fixity
_ [Char]
op)) | [Char]
op [Char] -> [[Char]] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [[Char]]
ops = Expr -> Maybe Expr
forall a. a -> Maybe a
Just Expr
e
commutative [[Char]]
_ Expr
_ = Maybe Expr
forall a. Maybe a
Nothing
{-# INLINE simplifies #-}
simplifies :: RewriteRule
simplifies :: RewriteRule
simplifies = [RewriteRule] -> RewriteRule
Or [
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
f MExpr
g MExpr
x -> (MExpr
f MExpr -> MExpr -> MExpr
`c` MExpr
g) MExpr -> MExpr -> MExpr
`a` MExpr
x)
(\MExpr
f MExpr
g MExpr
x -> MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
g MExpr -> MExpr -> MExpr
`a` MExpr
x)),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
x -> MExpr
idE MExpr -> MExpr -> MExpr
`a` MExpr
x)
(\MExpr
x -> MExpr
x),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x -> MExpr
flipE MExpr -> MExpr -> MExpr
`a` (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
x))
(\MExpr
x -> MExpr
x),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
f MExpr
x -> (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
idE MExpr -> MExpr -> MExpr
`a` MExpr
x) MExpr -> MExpr -> MExpr
`c` MExpr
f)
(\MExpr
f MExpr
x -> MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
f -> MExpr
idE MExpr -> MExpr -> MExpr
`c` MExpr
f)
(\MExpr
f -> MExpr
f),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
f -> MExpr
f MExpr -> MExpr -> MExpr
`c` MExpr
idE)
(\MExpr
f -> MExpr
f),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
x MExpr
y -> MExpr
constE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y)
(\MExpr
x MExpr
_ -> MExpr
x),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x -> MExpr
notE MExpr -> MExpr -> MExpr
`a` (MExpr
notE MExpr -> MExpr -> MExpr
`a` MExpr
x))
(\MExpr
x -> MExpr
x),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x MExpr
y -> MExpr
fstE MExpr -> MExpr -> MExpr
`a` (MExpr
commaE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y))
(\MExpr
x MExpr
_ -> MExpr
x),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x MExpr
y -> MExpr
sndE MExpr -> MExpr -> MExpr
`a` (MExpr
commaE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y))
(\MExpr
_ MExpr
y -> MExpr
y),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x MExpr
xs -> MExpr
headE MExpr -> MExpr -> MExpr
`a` (MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
xs))
(\MExpr
x MExpr
_ -> MExpr
x),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x MExpr
xs -> MExpr
tailE MExpr -> MExpr -> MExpr
`a` (MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
xs))
(\MExpr
_ MExpr
xs -> MExpr
xs),
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr1 (\MExpr
f MExpr
x MExpr
y -> MExpr
uncurryE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
commaE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y))
(\MExpr
f MExpr
x MExpr
y -> MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y),
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (MExpr
uncurryE MExpr -> MExpr -> MExpr
`a` MExpr
commaE)
(MExpr
idE),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr1 (\MExpr
f MExpr
g -> (MExpr
uncurryE MExpr -> MExpr -> MExpr
`a` MExpr
f) MExpr -> MExpr -> MExpr
`c` (MExpr
sE MExpr -> MExpr -> MExpr
`a` MExpr
commaE MExpr -> MExpr -> MExpr
`a` MExpr
g))
(\MExpr
f MExpr
g -> MExpr
sE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
g),
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (MExpr
curryE MExpr -> MExpr -> MExpr
`a` MExpr
fstE) (MExpr
constE),
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (MExpr
curryE MExpr -> MExpr -> MExpr
`a` MExpr
sndE) (MExpr
constE MExpr -> MExpr -> MExpr
`a` MExpr
idE),
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
f MExpr
g MExpr
x -> MExpr
sE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
g MExpr -> MExpr -> MExpr
`a` MExpr
x)
(\MExpr
f MExpr
g MExpr
x -> MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` (MExpr
g MExpr -> MExpr -> MExpr
`a` MExpr
x)),
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
f MExpr
x MExpr
y -> MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y)
(\MExpr
f MExpr
x MExpr
y -> MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
y MExpr -> MExpr -> MExpr
`a` MExpr
x),
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
extE)
MExpr
bindE,
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (MExpr
fmapE MExpr -> MExpr -> MExpr
`a` MExpr
idE)
(MExpr
idE),
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (MExpr
mapE MExpr -> MExpr -> MExpr
`a` MExpr
idE)
(MExpr
idE),
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
f MExpr
g MExpr
h -> (MExpr
f MExpr -> MExpr -> MExpr
`c` MExpr
g) MExpr -> MExpr -> MExpr
`c` MExpr
h)
(\MExpr
f MExpr
g MExpr
h -> MExpr
f MExpr -> MExpr -> MExpr
`c` (MExpr
g MExpr -> MExpr -> MExpr
`c` MExpr
h)),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
f MExpr
g -> MExpr
fmapE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`c` MExpr
fmapE MExpr -> MExpr -> MExpr
`a` MExpr
g)
(\MExpr
f MExpr
g -> MExpr
fmapE MExpr -> MExpr -> MExpr
`a` (MExpr
f MExpr -> MExpr -> MExpr
`c` MExpr
g)),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
f MExpr
g -> MExpr
mapE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`c` MExpr
mapE MExpr -> MExpr -> MExpr
`a` MExpr
g)
(\MExpr
f MExpr
g -> MExpr
mapE MExpr -> MExpr -> MExpr
`a` (MExpr
f MExpr -> MExpr -> MExpr
`c` MExpr
g))
]
onceRewrites :: RewriteRule
onceRewrites :: RewriteRule
onceRewrites = RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$ [RewriteRule] -> RewriteRule
Or [
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (MExpr
dollarE)
MExpr
idE,
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr MExpr
concatMapE MExpr
extE,
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr MExpr
concatE MExpr
joinE,
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr MExpr
liftME MExpr
fmapE,
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr MExpr
mapE MExpr
fmapE,
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr MExpr
subtractE
(MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
minusE)
]
rules :: RewriteRule
rules :: RewriteRule
rules = [RewriteRule] -> RewriteRule
Or [
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
g MExpr
x -> MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
g MExpr -> MExpr -> MExpr
`a` MExpr
x))
(\MExpr
f MExpr
g MExpr
x -> (MExpr
f MExpr -> MExpr -> MExpr
`c` MExpr
g) MExpr -> MExpr -> MExpr
`a` MExpr
x),
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr MExpr
bindE
(MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
extE),
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (MExpr
compE MExpr -> MExpr -> MExpr
`a` MExpr
idE)
MExpr
idE,
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x -> MExpr
appendE MExpr -> MExpr -> MExpr
`a` (MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
nilE))
(\MExpr
x -> MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x),
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (MExpr
extE MExpr -> MExpr -> MExpr
`a` MExpr
returnE)
MExpr
idE,
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
x -> MExpr
extE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
returnE MExpr -> MExpr -> MExpr
`a` MExpr
x))
(\MExpr
f MExpr
x -> MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
g -> MExpr
extE MExpr -> MExpr -> MExpr
`a` ((MExpr
extE MExpr -> MExpr -> MExpr
`a` MExpr
f) MExpr -> MExpr -> MExpr
`c` MExpr
g))
(\MExpr
f MExpr
g -> (MExpr
extE MExpr -> MExpr -> MExpr
`a` MExpr
f) MExpr -> MExpr -> MExpr
`c` (MExpr
extE MExpr -> MExpr -> MExpr
`a` MExpr
g)),
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
g -> MExpr
flipE MExpr -> MExpr -> MExpr
`a` (MExpr
f MExpr -> MExpr -> MExpr
`c` MExpr
g))
(\MExpr
f MExpr
g -> (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
compE MExpr -> MExpr -> MExpr
`a` MExpr
g) MExpr -> MExpr -> MExpr
`c` (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
f)),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
compE MExpr -> MExpr -> MExpr
`a` MExpr
f) MExpr -> MExpr -> MExpr
`c` (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
idE))
(\MExpr
f -> MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
f),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
compE MExpr -> MExpr -> MExpr
`a` MExpr
f) MExpr -> MExpr -> MExpr
`c` (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
flipE))
(\MExpr
f -> MExpr
flipE MExpr -> MExpr -> MExpr
`a` (MExpr
flipE MExpr -> MExpr -> MExpr
`c` MExpr
f)),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr1 (\MExpr
f MExpr
g -> MExpr
flipE MExpr -> MExpr -> MExpr
`a` (MExpr
flipE MExpr -> MExpr -> MExpr
`a` (MExpr
flipE MExpr -> MExpr -> MExpr
`c` MExpr
f) MExpr -> MExpr -> MExpr
`a` MExpr
g))
(\MExpr
f MExpr
g -> MExpr
flipE MExpr -> MExpr -> MExpr
`a` (MExpr
flipE MExpr -> MExpr -> MExpr
`c` MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
f) MExpr -> MExpr -> MExpr
`a` MExpr
g),
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
compE MExpr -> MExpr -> MExpr
`a` MExpr
idE)
MExpr
idE,
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (MExpr
compE MExpr -> MExpr -> MExpr
`c` (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
idE))
(MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
flipE),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x MExpr
y -> MExpr
sE MExpr -> MExpr -> MExpr
`a` MExpr
constE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y)
(\MExpr
_ MExpr
y -> MExpr
y),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr1 (\MExpr
f MExpr
g -> MExpr
sE MExpr -> MExpr -> MExpr
`a` (MExpr
constE MExpr -> MExpr -> MExpr
`c` MExpr
f) MExpr -> MExpr -> MExpr
`a` MExpr
g)
(\MExpr
f MExpr
_ -> MExpr
f),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
sE MExpr -> MExpr -> MExpr
`a` (MExpr
constE MExpr -> MExpr -> MExpr
`a` MExpr
f))
(\MExpr
f -> MExpr
compE MExpr -> MExpr -> MExpr
`a` MExpr
f),
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
g MExpr
h -> (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
sE MExpr -> MExpr -> MExpr
`a` MExpr
f) MExpr -> MExpr -> MExpr
`c` (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
compE MExpr -> MExpr -> MExpr
`a` MExpr
g) MExpr -> MExpr -> MExpr
`c` MExpr
constE MExpr -> MExpr -> MExpr
`c` MExpr
h)
(\MExpr
f MExpr
_ MExpr
h -> (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
compE MExpr -> MExpr -> MExpr
`a` MExpr
f) MExpr -> MExpr -> MExpr
`c` MExpr
h),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
sE MExpr -> MExpr -> MExpr
`a` (MExpr
f MExpr -> MExpr -> MExpr
`c` MExpr
fstE) MExpr -> MExpr -> MExpr
`a` MExpr
sndE)
(\MExpr
f -> MExpr
uncurryE MExpr -> MExpr -> MExpr
`a` MExpr
f),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x -> MExpr
fstE MExpr -> MExpr -> MExpr
`a` (MExpr
joinE MExpr -> MExpr -> MExpr
`a` MExpr
commaE MExpr -> MExpr -> MExpr
`a` MExpr
x))
(\MExpr
x -> MExpr
x),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x -> MExpr
sndE MExpr -> MExpr -> MExpr
`a` (MExpr
joinE MExpr -> MExpr -> MExpr
`a` MExpr
commaE MExpr -> MExpr -> MExpr
`a` MExpr
x))
(\MExpr
x -> MExpr
x),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
curryE MExpr -> MExpr -> MExpr
`a` (MExpr
uncurryE MExpr -> MExpr -> MExpr
`a` MExpr
f))
(\MExpr
f -> MExpr
f),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
uncurryE MExpr -> MExpr -> MExpr
`a` (MExpr
curryE MExpr -> MExpr -> MExpr
`a` MExpr
f))
(\MExpr
f -> MExpr
f),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> (MExpr
constE MExpr -> MExpr -> MExpr
`a` MExpr
idE) MExpr -> MExpr -> MExpr
`c` MExpr
f)
(\MExpr
_ -> MExpr
constE MExpr -> MExpr -> MExpr
`a` MExpr
idE),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x MExpr
f -> MExpr
constE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`c` MExpr
f)
(\MExpr
x MExpr
_ -> MExpr
constE MExpr -> MExpr -> MExpr
`a` MExpr
x),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
compE MExpr -> MExpr -> MExpr
`a` MExpr
f) MExpr -> MExpr -> MExpr
`c` MExpr
constE)
(\MExpr
_ -> MExpr
constE),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
g -> (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
compE MExpr -> MExpr -> MExpr
`a` MExpr
f) MExpr -> MExpr -> MExpr
`c` MExpr
constE MExpr -> MExpr -> MExpr
`c` MExpr
g)
(\MExpr
_ MExpr
g -> MExpr
constE MExpr -> MExpr -> MExpr
`c` MExpr
g),
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
f -> MExpr
fixE MExpr -> MExpr -> MExpr
`a` MExpr
f)
(\MExpr
f -> MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
fixE MExpr -> MExpr -> MExpr
`a` MExpr
f)),
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
f -> MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
fixE MExpr -> MExpr -> MExpr
`a` MExpr
f))
(\MExpr
f -> MExpr
fixE MExpr -> MExpr -> MExpr
`a` MExpr
f),
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
f -> MExpr
fixE MExpr -> MExpr -> MExpr
`a` MExpr
f)
(\MExpr
f -> MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
fixE MExpr -> MExpr -> MExpr
`a` MExpr
f))),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
fixE MExpr -> MExpr -> MExpr
`a` (MExpr
constE MExpr -> MExpr -> MExpr
`a` MExpr
f))
(\MExpr
f -> MExpr
f),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x -> MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
constE MExpr -> MExpr -> MExpr
`a` MExpr
x)
(\MExpr
_ -> MExpr
idE),
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
constE MExpr -> MExpr -> MExpr
`c` MExpr
f)
(\MExpr
f -> MExpr
flipE MExpr -> MExpr -> MExpr
`a` (MExpr
constE MExpr -> MExpr -> MExpr
`a` MExpr
f)),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr2 (\MExpr
x MExpr
y -> MExpr
notE MExpr -> MExpr -> MExpr
`a` (MExpr
equalsE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y))
(\MExpr
x MExpr
y -> MExpr
nequalsE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr2 (\MExpr
x MExpr
y -> MExpr
notE MExpr -> MExpr -> MExpr
`a` (MExpr
nequalsE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y))
(\MExpr
x MExpr
y -> MExpr
equalsE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y),
RewriteRule -> RewriteRule -> RewriteRule
If ([RewriteRule] -> RewriteRule
Or [MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr MExpr
plusE MExpr
plusE, MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr MExpr
minusE MExpr
minusE, MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr MExpr
multE MExpr
multE]) (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$ RewriteRule -> RewriteRule
down (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$ [RewriteRule] -> RewriteRule
Or [
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x -> MExpr
plusE MExpr -> MExpr -> MExpr
`a` MExpr
zeroE MExpr -> MExpr -> MExpr
`a` MExpr
x)
(\MExpr
x -> MExpr
x),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x -> MExpr
multE MExpr -> MExpr -> MExpr
`a` MExpr
zeroE MExpr -> MExpr -> MExpr
`a` MExpr
x)
(\MExpr
_ -> MExpr
zeroE),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x -> MExpr
multE MExpr -> MExpr -> MExpr
`a` MExpr
oneE MExpr -> MExpr -> MExpr
`a` MExpr
x)
(\MExpr
x -> MExpr
x),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x -> MExpr
minusE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
x)
(\MExpr
_ -> MExpr
zeroE),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
y MExpr
x -> MExpr
plusE MExpr -> MExpr -> MExpr
`a` (MExpr
minusE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y) MExpr -> MExpr -> MExpr
`a` MExpr
y)
(\MExpr
_ MExpr
x -> MExpr
x),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
y MExpr
x -> MExpr
minusE MExpr -> MExpr -> MExpr
`a` (MExpr
plusE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y) MExpr -> MExpr -> MExpr
`a` MExpr
y)
(\MExpr
_ MExpr
x -> MExpr
x),
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x MExpr
y MExpr
z -> MExpr
plusE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` (MExpr
minusE MExpr -> MExpr -> MExpr
`a` MExpr
y MExpr -> MExpr -> MExpr
`a` MExpr
z))
(\MExpr
x MExpr
y MExpr
z -> MExpr
minusE MExpr -> MExpr -> MExpr
`a` (MExpr
plusE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y) MExpr -> MExpr -> MExpr
`a` MExpr
z),
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x MExpr
y MExpr
z -> MExpr
minusE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` (MExpr
plusE MExpr -> MExpr -> MExpr
`a` MExpr
y MExpr -> MExpr -> MExpr
`a` MExpr
z))
(\MExpr
x MExpr
y MExpr
z -> MExpr
minusE MExpr -> MExpr -> MExpr
`a` (MExpr
minusE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y) MExpr -> MExpr -> MExpr
`a` MExpr
z),
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x MExpr
y MExpr
z -> MExpr
minusE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` (MExpr
minusE MExpr -> MExpr -> MExpr
`a` MExpr
y MExpr -> MExpr -> MExpr
`a` MExpr
z))
(\MExpr
x MExpr
y MExpr
z -> MExpr
minusE MExpr -> MExpr -> MExpr
`a` (MExpr
plusE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y) MExpr -> MExpr -> MExpr
`a` MExpr
z)
],
RewriteRule -> RewriteRule
Hard RewriteRule
onceRewrites,
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
x -> MExpr
joinE MExpr -> MExpr -> MExpr
`a` (MExpr
fmapE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x))
(\MExpr
f MExpr
x -> MExpr
extE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x),
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (MExpr
extE MExpr -> MExpr -> MExpr
`a` MExpr
idE) MExpr
joinE,
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr MExpr
joinE (MExpr
extE MExpr -> MExpr -> MExpr
`a` MExpr
idE),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x -> MExpr
joinE MExpr -> MExpr -> MExpr
`a` (MExpr
returnE MExpr -> MExpr -> MExpr
`a` MExpr
x))
(\MExpr
x -> MExpr
x),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
m -> MExpr
extE MExpr -> MExpr -> MExpr
`a` (MExpr
returnE MExpr -> MExpr -> MExpr
`c` MExpr
f) MExpr -> MExpr -> MExpr
`a` MExpr
m)
(\MExpr
f MExpr
m -> MExpr
fmapIE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
m),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
x -> MExpr
bindE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`c` (MExpr
compE MExpr -> MExpr -> MExpr
`a` MExpr
returnE) MExpr -> MExpr -> MExpr
`c` MExpr
f)
(\MExpr
f MExpr
x -> MExpr
flipE MExpr -> MExpr -> MExpr
`a` (MExpr
fmapIE MExpr -> MExpr -> MExpr
`c` MExpr
f) MExpr -> MExpr -> MExpr
`a` MExpr
x),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
bindE MExpr -> MExpr -> MExpr
`a` (MExpr
returnE MExpr -> MExpr -> MExpr
`a` MExpr
f))
(\MExpr
f -> MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
idE MExpr -> MExpr -> MExpr
`a` MExpr
f),
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
x -> MExpr
liftM2E MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x)
(\MExpr
f MExpr
x -> MExpr
apE MExpr -> MExpr -> MExpr
`a` (MExpr
fmapIE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x)),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
x -> MExpr
liftM2E MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
returnE MExpr -> MExpr -> MExpr
`a` MExpr
x))
(\MExpr
f MExpr
x -> MExpr
fmapIE MExpr -> MExpr -> MExpr
`a` (MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x)),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
x -> MExpr
fmapE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
returnE MExpr -> MExpr -> MExpr
`a` MExpr
x))
(\MExpr
f MExpr
x -> MExpr
returnE MExpr -> MExpr -> MExpr
`a` (MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x)),
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
extE MExpr -> MExpr -> MExpr
`c` MExpr
flipE MExpr -> MExpr -> MExpr
`a` (MExpr
fmapE MExpr -> MExpr -> MExpr
`c` MExpr
f))
(\MExpr
f -> MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
liftM2E MExpr -> MExpr -> MExpr
`a` MExpr
f),
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr MExpr
compE MExpr
fmapE,
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
xs MExpr
ys -> MExpr
mapE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
zipE MExpr -> MExpr -> MExpr
`a` MExpr
xs MExpr -> MExpr -> MExpr
`a` MExpr
ys))
(\MExpr
f MExpr
xs MExpr
ys -> MExpr
zipWithE MExpr -> MExpr -> MExpr
`a` (MExpr
curryE MExpr -> MExpr -> MExpr
`a` MExpr
f) MExpr -> MExpr -> MExpr
`a` MExpr
xs MExpr -> MExpr -> MExpr
`a` MExpr
ys),
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (MExpr
zipWithE MExpr -> MExpr -> MExpr
`a` MExpr
commaE) MExpr
zipE,
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
allE MExpr -> MExpr -> MExpr
`a` MExpr
f)
(\MExpr
f -> MExpr
andE MExpr -> MExpr -> MExpr
`c` MExpr
mapE MExpr -> MExpr -> MExpr
`a` MExpr
f),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
andE MExpr -> MExpr -> MExpr
`c` MExpr
mapE MExpr -> MExpr -> MExpr
`a` MExpr
f)
(\MExpr
f -> MExpr
allE MExpr -> MExpr -> MExpr
`a` MExpr
f),
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
anyE MExpr -> MExpr -> MExpr
`a` MExpr
f)
(\MExpr
f -> MExpr
orE MExpr -> MExpr -> MExpr
`c` MExpr
mapE MExpr -> MExpr -> MExpr
`a` MExpr
f),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
orE MExpr -> MExpr -> MExpr
`c` MExpr
mapE MExpr -> MExpr -> MExpr
`a` MExpr
f)
(\MExpr
f -> MExpr
anyE MExpr -> MExpr -> MExpr
`a` MExpr
f),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
x -> MExpr
apE MExpr -> MExpr -> MExpr
`a` (MExpr
returnE MExpr -> MExpr -> MExpr
`a` MExpr
f) MExpr -> MExpr -> MExpr
`a` MExpr
x)
(\MExpr
f MExpr
x -> MExpr
fmapIE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
x -> MExpr
apE MExpr -> MExpr -> MExpr
`a` (MExpr
fmapIE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x))
(\MExpr
f MExpr
x -> MExpr
liftM2E MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x),
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
x -> MExpr
apE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x)
(\MExpr
f MExpr
x -> MExpr
extE MExpr -> MExpr -> MExpr
`a` (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
fmapIE MExpr -> MExpr -> MExpr
`a` MExpr
x) MExpr -> MExpr -> MExpr
`a` MExpr
f),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
x -> MExpr
extE MExpr -> MExpr -> MExpr
`a` (MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
fmapIE MExpr -> MExpr -> MExpr
`a` MExpr
x) MExpr -> MExpr -> MExpr
`a` MExpr
f)
(\MExpr
f MExpr
x -> MExpr
apE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
x -> MExpr
bindE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`c` MExpr
flipE MExpr -> MExpr -> MExpr
`a` (MExpr
fmapE MExpr -> MExpr -> MExpr
`c` MExpr
f))
(\MExpr
f MExpr
x -> MExpr
liftM2E MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x),
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
f MExpr
m MExpr
x -> MExpr
extE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
m MExpr -> MExpr -> MExpr
`a` MExpr
x)
(\MExpr
f MExpr
m MExpr
x -> MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
m MExpr -> MExpr -> MExpr
`a` MExpr
x) MExpr -> MExpr -> MExpr
`a` MExpr
x),
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
f MExpr
g MExpr
x -> MExpr
fmapE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
g MExpr -> MExpr -> MExpr
`a` MExpr
x)
(\MExpr
f MExpr
g MExpr
x -> MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
g MExpr -> MExpr -> MExpr
`a` MExpr
x)),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
y MExpr
x -> MExpr
returnE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
y)
(\MExpr
y MExpr
_ -> MExpr
y),
(MExpr -> MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
f MExpr
g MExpr
h MExpr
x -> MExpr
liftM2E MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
g MExpr -> MExpr -> MExpr
`a` MExpr
h MExpr -> MExpr -> MExpr
`a` MExpr
x)
(\MExpr
f MExpr
g MExpr
h MExpr
x -> MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
g MExpr -> MExpr -> MExpr
`a` MExpr
x) MExpr -> MExpr -> MExpr
`a` (MExpr
h MExpr -> MExpr -> MExpr
`a` MExpr
x)),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
apE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
idE)
(\MExpr
f -> MExpr
joinE MExpr -> MExpr -> MExpr
`a` MExpr
f),
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
q MExpr
p -> MExpr
extE MExpr -> MExpr -> MExpr
`a` (MExpr
constE MExpr -> MExpr -> MExpr
`a` MExpr
q) MExpr -> MExpr -> MExpr
`a` MExpr
p)
(\MExpr
q MExpr
p -> MExpr
seqME MExpr -> MExpr -> MExpr
`a` MExpr
p MExpr -> MExpr -> MExpr
`a` MExpr
q),
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
p MExpr
q -> MExpr
seqME MExpr -> MExpr -> MExpr
`a` MExpr
p MExpr -> MExpr -> MExpr
`a` MExpr
q)
(\MExpr
p MExpr
q -> MExpr
extE MExpr -> MExpr -> MExpr
`a` (MExpr
constE MExpr -> MExpr -> MExpr
`a` MExpr
q) MExpr -> MExpr -> MExpr
`a` MExpr
p),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
g -> MExpr
uncurryE MExpr -> MExpr -> MExpr
`a` ((MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
compE MExpr -> MExpr -> MExpr
`a` MExpr
g) MExpr -> MExpr -> MExpr
`c` MExpr
commaE MExpr -> MExpr -> MExpr
`c` MExpr
f))
(\MExpr
f MExpr
g -> MExpr
crossE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
g),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
uncurryE MExpr -> MExpr -> MExpr
`a` (MExpr
commaE MExpr -> MExpr -> MExpr
`c` MExpr
f))
(\MExpr
f -> MExpr
firstE MExpr -> MExpr -> MExpr
`a` MExpr
f),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
g -> MExpr
uncurryE MExpr -> MExpr -> MExpr
`a` ((MExpr
flipE MExpr -> MExpr -> MExpr
`a` MExpr
compE MExpr -> MExpr -> MExpr
`a` MExpr
g) MExpr -> MExpr -> MExpr
`c` MExpr
commaE))
(\MExpr
g -> MExpr
secondE MExpr -> MExpr -> MExpr
`a` MExpr
g),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
uncurryE MExpr -> MExpr -> MExpr
`a` (MExpr
constE MExpr -> MExpr -> MExpr
`a` MExpr
f))
(\MExpr
f -> MExpr
f MExpr -> MExpr -> MExpr
`c` MExpr
sndE),
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (MExpr
uncurryE MExpr -> MExpr -> MExpr
`a` MExpr
constE)
(MExpr
fstE),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
uncurryE MExpr -> MExpr -> MExpr
`a` (MExpr
constE MExpr -> MExpr -> MExpr
`c` MExpr
f))
(\MExpr
f -> MExpr
f MExpr -> MExpr -> MExpr
`c` MExpr
fstE),
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x -> MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
nilE)
(\MExpr
x -> MExpr
returnE MExpr -> MExpr -> MExpr
`a` MExpr
x),
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$
RewriteRule -> RewriteRule -> RewriteRule
If ([RewriteRule] -> RewriteRule
Or [MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr MExpr
consE MExpr
consE, MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr MExpr
nilE MExpr
nilE]) (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$ [RewriteRule] -> RewriteRule
Or [
RewriteRule -> RewriteRule
down (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$ [RewriteRule] -> RewriteRule
Or [
MExpr -> MExpr -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (MExpr
lengthE MExpr -> MExpr -> MExpr
`a` MExpr
nilE)
MExpr
zeroE,
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
x MExpr
xs -> MExpr
lengthE MExpr -> MExpr -> MExpr
`a` (MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
xs))
(\MExpr
_ MExpr
xs -> MExpr
plusE MExpr -> MExpr -> MExpr
`a` MExpr
oneE MExpr -> MExpr -> MExpr
`a` (MExpr
lengthE MExpr -> MExpr -> MExpr
`a` MExpr
xs))
],
RewriteRule -> RewriteRule
down (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$ [RewriteRule] -> RewriteRule
Or [
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
x MExpr
xs -> MExpr
mapE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
xs))
(\MExpr
f MExpr
x MExpr
xs -> MExpr
consE MExpr -> MExpr -> MExpr
`a` (MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x) MExpr -> MExpr -> MExpr
`a` (MExpr
mapE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
xs)),
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
x MExpr
xs -> MExpr
fmapE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
xs))
(\MExpr
f MExpr
x MExpr
xs -> MExpr
consE MExpr -> MExpr -> MExpr
`a` (MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x) MExpr -> MExpr -> MExpr
`a` (MExpr
fmapE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
xs)),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
mapE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
nilE)
(\MExpr
_ -> MExpr
nilE),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f -> MExpr
fmapE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
nilE)
(\MExpr
_ -> MExpr
nilE)
],
RewriteRule -> RewriteRule
down (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$ [RewriteRule] -> RewriteRule
Or [
(MExpr -> MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
x MExpr
xs MExpr
z -> (MExpr
foldrE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
z) MExpr -> MExpr -> MExpr
`a` (MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
xs))
(\MExpr
f MExpr
x MExpr
xs MExpr
z -> (MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x) MExpr -> MExpr -> MExpr
`a` (MExpr
foldrE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
z MExpr -> MExpr -> MExpr
`a` MExpr
xs)),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
z -> MExpr
foldrE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
z MExpr -> MExpr -> MExpr
`a` MExpr
nilE)
(\MExpr
_ MExpr
z -> MExpr
z)
],
RewriteRule -> RewriteRule
down (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$ RewriteRule -> RewriteRule
Opt ((Expr -> Maybe Expr) -> RewriteRule
CRR ((Expr -> Maybe Expr) -> RewriteRule)
-> (Expr -> Maybe Expr) -> RewriteRule
forall a b. (a -> b) -> a -> b
$ [[Char]] -> Expr -> Maybe Expr
assocL [[Char]
"."]) RewriteRule -> RewriteRule -> RewriteRule
`Then` [RewriteRule] -> RewriteRule
Or [
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
xs -> MExpr
sumE MExpr -> MExpr -> MExpr
`a` MExpr
xs)
(\MExpr
xs -> MExpr
foldlE MExpr -> MExpr -> MExpr
`a` MExpr
plusE MExpr -> MExpr -> MExpr
`a` MExpr
zeroE MExpr -> MExpr -> MExpr
`a` MExpr
xs),
(MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
xs -> MExpr
productE MExpr -> MExpr -> MExpr
`a` MExpr
xs)
(\MExpr
xs -> MExpr
foldlE MExpr -> MExpr -> MExpr
`a` MExpr
multE MExpr -> MExpr -> MExpr
`a` MExpr
oneE MExpr -> MExpr -> MExpr
`a` MExpr
xs),
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
x MExpr
xs -> MExpr
foldl1E MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
xs))
(\MExpr
f MExpr
x MExpr
xs -> MExpr
foldlE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
xs),
(MExpr -> MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
z MExpr
x MExpr
xs -> (MExpr
foldlE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
z) MExpr -> MExpr -> MExpr
`a` (MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
xs))
(\MExpr
f MExpr
z MExpr
x MExpr
xs -> MExpr
foldlE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` (MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
z MExpr -> MExpr -> MExpr
`a` MExpr
x) MExpr -> MExpr -> MExpr
`a` MExpr
xs),
(MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
z -> MExpr
foldlE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
z MExpr -> MExpr -> MExpr
`a` MExpr
nilE)
(\MExpr
_ MExpr
z -> MExpr
z),
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
z MExpr
x -> MExpr
foldlE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
z MExpr -> MExpr -> MExpr
`a` (MExpr
returnE MExpr -> MExpr -> MExpr
`a` MExpr
x))
(\MExpr
f MExpr
z MExpr
x -> MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
z MExpr -> MExpr -> MExpr
`a` MExpr
x),
(MExpr -> MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr (\MExpr
f MExpr
z MExpr
x -> MExpr
foldlE MExpr -> MExpr -> MExpr
`a` MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
z MExpr -> MExpr -> MExpr
`a` (MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
nilE))
(\MExpr
f MExpr
z MExpr
x -> MExpr
f MExpr -> MExpr -> MExpr
`a` MExpr
z MExpr -> MExpr -> MExpr
`a` MExpr
x)
] RewriteRule -> RewriteRule -> RewriteRule
`OrElse` (
RewriteRule -> RewriteRule
Opt ((MExpr -> MExpr) -> (MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
x -> MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x)
(\MExpr
x -> MExpr
appendE MExpr -> MExpr -> MExpr
`a` (MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
nilE))) RewriteRule -> RewriteRule -> RewriteRule
`Then`
RewriteRule -> RewriteRule
up ((MExpr -> MExpr -> MExpr)
-> (MExpr -> MExpr -> MExpr) -> RewriteRule
forall a. RewriteC a => a -> a -> RewriteRule
rr0 (\MExpr
x MExpr
ys -> (MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x) MExpr -> MExpr -> MExpr
`c` (MExpr
appendE MExpr -> MExpr -> MExpr
`a` MExpr
ys))
(\MExpr
x MExpr
ys -> MExpr
appendE MExpr -> MExpr -> MExpr
`a` (MExpr
consE MExpr -> MExpr -> MExpr
`a` MExpr
x MExpr -> MExpr -> MExpr
`a` MExpr
ys)))
)
],
(Expr -> Maybe Expr) -> RewriteRule
CRR (Expr -> Maybe Expr
collapseLists),
RewriteRule -> RewriteRule
up (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$ [RewriteRule] -> RewriteRule
Or [(Expr -> Maybe Expr) -> RewriteRule
CRR ([([Char], Unary)] -> Expr -> Maybe Expr
evalUnary [([Char], Unary)]
unaryBuiltins), (Expr -> Maybe Expr) -> RewriteRule
CRR ([([Char], Binary)] -> Expr -> Maybe Expr
evalBinary [([Char], Binary)]
binaryBuiltins)],
RewriteRule -> RewriteRule
up (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$ (Expr -> Maybe Expr) -> RewriteRule
CRR ([[Char]] -> Expr -> Maybe Expr
assoc [[Char]]
assocOps),
RewriteRule -> RewriteRule
up (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$ (Expr -> Maybe Expr) -> RewriteRule
CRR ([[Char]] -> Expr -> Maybe Expr
assocL [[Char]]
assocOps),
RewriteRule -> RewriteRule
up (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$ (Expr -> Maybe Expr) -> RewriteRule
CRR ([[Char]] -> Expr -> Maybe Expr
assocR [[Char]]
assocOps),
RewriteRule -> RewriteRule -> RewriteRule
Up ((Expr -> Maybe Expr) -> RewriteRule
CRR ([[Char]] -> Expr -> Maybe Expr
commutative [[Char]]
commutativeOps)) (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$ RewriteRule -> RewriteRule
down (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$ [RewriteRule] -> RewriteRule
Or [(Expr -> Maybe Expr) -> RewriteRule
CRR ((Expr -> Maybe Expr) -> RewriteRule)
-> (Expr -> Maybe Expr) -> RewriteRule
forall a b. (a -> b) -> a -> b
$ [[Char]] -> Expr -> Maybe Expr
assocL [[Char]]
assocLOps,
(Expr -> Maybe Expr) -> RewriteRule
CRR ((Expr -> Maybe Expr) -> RewriteRule)
-> (Expr -> Maybe Expr) -> RewriteRule
forall a b. (a -> b) -> a -> b
$ [[Char]] -> Expr -> Maybe Expr
assocR [[Char]]
assocROps],
RewriteRule -> RewriteRule
Hard (RewriteRule -> RewriteRule) -> RewriteRule -> RewriteRule
forall a b. (a -> b) -> a -> b
$ RewriteRule
simplifies
] RewriteRule -> RewriteRule -> RewriteRule
`Then` RewriteRule -> RewriteRule
Opt (RewriteRule -> RewriteRule
up RewriteRule
simplifies)
assocLOps, assocROps, assocOps :: [String]
assocLOps :: [[Char]]
assocLOps = [[Char]
"+", [Char]
"*", [Char]
"&&", [Char]
"||", [Char]
"max", [Char]
"min"]
assocROps :: [[Char]]
assocROps = [[Char]
".", [Char]
"++"]
assocOps :: [[Char]]
assocOps = [[Char]]
assocLOps [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ [[Char]]
assocROps
commutativeOps :: [String]
commutativeOps :: [[Char]]
commutativeOps = [[Char]
"*", [Char]
"+", [Char]
"==", [Char]
"/=", [Char]
"max", [Char]
"min"]
unaryBuiltins :: [(String,Unary)]
unaryBuiltins :: [([Char], Unary)]
unaryBuiltins = [
([Char]
"not", (Bool -> Bool) -> Unary
forall a b. (Read a, Show a, Read b, Show b) => (a -> b) -> Unary
UA (Bool -> Bool
not :: Bool -> Bool)),
([Char]
"negate", (Integer -> Integer) -> Unary
forall a b. (Read a, Show a, Read b, Show b) => (a -> b) -> Unary
UA (Integer -> Integer
forall a. Num a => a -> a
negate :: Integer -> Integer)),
([Char]
"signum", (Integer -> Integer) -> Unary
forall a b. (Read a, Show a, Read b, Show b) => (a -> b) -> Unary
UA (Integer -> Integer
forall a. Num a => a -> a
signum :: Integer -> Integer)),
([Char]
"abs", (Integer -> Integer) -> Unary
forall a b. (Read a, Show a, Read b, Show b) => (a -> b) -> Unary
UA (Integer -> Integer
forall a. Num a => a -> a
abs :: Integer -> Integer))
]
binaryBuiltins :: [(String,Binary)]
binaryBuiltins :: [([Char], Binary)]
binaryBuiltins = [
([Char]
"+", (Integer -> Integer -> Integer) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+) :: Integer -> Integer -> Integer)),
([Char]
"-", (Integer -> Integer -> Integer) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA ((-) :: Integer -> Integer -> Integer)),
([Char]
"*", (Integer -> Integer -> Integer) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(*) :: Integer -> Integer -> Integer)),
([Char]
"^", (Integer -> Integer -> Integer) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA (Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
(^) :: Integer -> Integer -> Integer)),
([Char]
"<", (Integer -> Integer -> Bool) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA (Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
(<) :: Integer -> Integer -> Bool)),
([Char]
">", (Integer -> Integer -> Bool) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA (Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
(>) :: Integer -> Integer -> Bool)),
([Char]
"==", (Integer -> Integer -> Bool) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA (Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
(==) :: Integer -> Integer -> Bool)),
([Char]
"/=", (Integer -> Integer -> Bool) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA (Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
(/=) :: Integer -> Integer -> Bool)),
([Char]
"<=", (Integer -> Integer -> Bool) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA (Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
(<=) :: Integer -> Integer -> Bool)),
([Char]
">=", (Integer -> Integer -> Bool) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA (Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
(>=) :: Integer -> Integer -> Bool)),
([Char]
"div", (Integer -> Integer -> Integer) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA (Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
div :: Integer -> Integer -> Integer)),
([Char]
"mod", (Integer -> Integer -> Integer) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA (Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
mod :: Integer -> Integer -> Integer)),
([Char]
"max", (Integer -> Integer -> Integer) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA (Integer -> Integer -> Integer
forall a. Ord a => a -> a -> a
max :: Integer -> Integer -> Integer)),
([Char]
"min", (Integer -> Integer -> Integer) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA (Integer -> Integer -> Integer
forall a. Ord a => a -> a -> a
min :: Integer -> Integer -> Integer)),
([Char]
"&&", (Bool -> Bool -> Bool) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA (Bool -> Bool -> Bool
(&&) :: Bool -> Bool -> Bool)),
([Char]
"||", (Bool -> Bool -> Bool) -> Binary
forall a b c.
(Read a, Show a, Read b, Show b, Read c, Show c) =>
(a -> b -> c) -> Binary
BA (Bool -> Bool -> Bool
(||) :: Bool -> Bool -> Bool))
]