3 import Language.Pointwise.Syntax as Pointwise
4 import Language.Pointfree.Syntax as Pointfree hiding (Term)
6 import Control.Monad.State
9 -- Hylomorphism derivation a la Hu, Iwasaki, and Takeichi
11 derivable :: Term -> Bool
12 derivable (Pointwise.Fix (Lam f (Lam x l))) = branch l
13 where branch (Case m (Lam _ n) (Lam _ o)) =
14 (f `notElem` free m) && branch n && branch o
17 leaf (Pointwise.Const _) = True
18 leaf (Var y) = (y /= f)
19 leaf (Var g :@: n) | (g == f) = leaf n && (f `notElem` free n)
21 leaf (n :@: m) = leaf n && leaf m
22 leaf (n :&: m) = leaf n && leaf m
32 getVar :: String -> State Int String
33 getVar x = do seed <- get
35 return (x ++ show seed)
37 fun :: Term -> String -> Funct
38 fun l r = evalState (aux l) 0
39 where aux (Case _ (Lam x m) (Lam y n)) =
43 aux Unit = return (Pointfree.Const One)
44 aux (Pointwise.Const _) = return (Pointfree.Const One)
45 aux (Var x) = liftM (Pointfree.Const . Base) (getVar "a")
46 aux (Var x :@: n) | x == r = return Id
47 aux (m :@: n) | null (free n) = aux m
48 | null (free m) = aux n
49 | otherwise = do f <- aux m
52 aux (m :&: n) | null (free n) = aux m
53 | null (free m) = aux n
54 | otherwise = do f <- aux m
64 coa :: Term -> String -> Term
66 where aux (Case l (Lam x m) (Lam y n)) =
69 in Case l (Lam x (Inl f)) (Lam y (Inr g))
71 aux (Pointwise.Const _) = Unit
73 aux (Var x :@: n) | x == r = n
74 aux (m :@: n) | null (free n) = aux m
75 | null (free m) = aux n
76 | otherwise = let f = aux m
79 aux (m :&: n) | null (free n) = aux m
80 | null (free m) = aux n
81 | otherwise = let f = aux m
91 alg :: Term -> String -> Term -> Term
93 where aux (Case l (Lam x m) (Lam y n)) (Var p) =
98 in Case (Var p) (Lam vl f) (Lam vr g)
100 aux (Pointwise.Const f) _ = Pointwise.Const f
102 aux (Var x :@: n) p | x == r = p
103 aux (m :@: n) p | null (free n) = let f = aux m p
106 | null (free m) = let f = aux m p
109 | otherwise = let f = aux m (Fst p)
112 aux (m :&: n) p | null (free n) = let f = aux m p
115 | null (free m) = let f = aux m p
118 | otherwise = let f = aux m (Fst p)
121 aux (Fst n) p = Fst (aux n p)
122 aux (Snd n) p = Snd (aux n p)
123 aux (Inl n) p = Inl (aux n p)
124 aux (Inr n) p = Inr (aux n p)
125 aux (In n) p = In (aux n p)
126 aux (Out n) p = Out (aux n p)