2 Module : Functional.Language
3 Copyright : (c) Miguel Vilaça 2007
5 Maintainer : jmvilaca@di.uminho.pt
6 Stability : experimental
10 Small Functional Language
13 module Functional.Language where
20 type Variable = String
22 data CallBy = Value | Name | Need deriving (Eq, Show)
24 data FuncLang = Var Variable -- 1 (precedences)
25 | Abst Variable FuncLang -- 7
26 | Appl FuncLang FuncLang -- 10
29 | IterBool FuncLang FuncLang FuncLang -- 5
32 | IterNat Variable FuncLang FuncLang FuncLang -- 5
34 | Cons FuncLang FuncLang -- 3
35 | IterList Variable Variable FuncLang FuncLang FuncLang -- 5
38 -- | Default names and expressions for 'FuncLang' terms.
39 listLangConstructors :: [(String, FuncLang)]
40 listLangConstructors =
41 [ ("Abstraction" , Abst "x" (Var "t"))
42 , ("Application" , Appl (Var "t") (Var "u"))
45 , ("If then else" , IterBool (Var "V") (Var "F") (Var "b"))
47 , ("successor" , Succ (Var "t"))
48 , ("Nat iterator" , IterNat "x" (Var "S") (Var "Z") (Var "t"))
50 , (":" , Cons (Var "H") (Var "T"))
51 , ("List iterator", IterList "x" "y" (Var "C") (Var "N") (Var "t"))
54 instance Show FuncLang where
55 -- precedence 9 is a special one; means that it is inside an abstraction
56 showsPrec 9 (Abst v t) =
60 showsPrec 9 x = showChar ']' . showsPrec 0 x
61 showsPrec d (Abst v t) =
66 -- elements of precedence 1; those never surrounded by parenthesis
67 showsPrec _ (Var x) = showString x
68 showsPrec _ TT = showString "tt"
69 showsPrec _ FF = showString "ff"
70 showsPrec _ Zero = showString "0"
71 showsPrec _ Nil = showString "nil"
72 -- elements of precedence 3
73 showsPrec _ (Succ n) =
77 showsPrec _ (Cons h t) =
83 -- elements of precedence 5
84 showsPrec _ (IterBool v f b) =
85 showString "iterbool("
92 showsPrec _ (IterNat x s z n) =
94 . showsPrec 0 (Abst x s)
100 showsPrec _ (IterList h t c n l) =
101 showString "iterlist("
102 . showsPrec 0 (Abst h $ Abst t c)
108 -- elements of precedence 10
109 showsPrec d (Appl u v) =
115 -- | Show iter_TYPE symbols.
116 showAgent :: FuncLang -> String
117 showAgent t@(IterBool v f (Var "")) = show t
118 showAgent t@(IterNat x s z (Var "")) = show t
119 showAgent t@(IterList h r c n (Var "")) = show t
120 showAgent _ = error "unexpected functional term here"
122 cata :: (Variable -> r) -- ^ Var
123 -> (Variable -> r -> r) -- ^ Abstraction
124 -> (r -> r -> r) -- ^ Application
127 -> (r -> r -> r -> r) -- ^ IterBool
129 -> (r -> r) -- ^ Succ
130 -> (Variable -> r -> r -> r -> r) -- ^ IterNat
132 -> (r -> r -> r) -- ^ Cons
133 -> (Variable -> Variable -> r -> r -> r -> r) -- ^ IterList
134 -> FuncLang -- ^ term
136 cata fVar fAbst fAppl fTT fFF fIB fZ fS fIN fN fC fIL = cata'
140 Abst var t -> fAbst var (cata' t)
141 Appl t1 t2 -> fAppl (cata' t1) (cata' t2)
144 IterBool t1 t2 t3 -> fIB (cata' t1) (cata' t2) (cata' t3)
146 Succ t -> fS (cata' t)
147 IterNat var t1 t2 t3 -> fIN var (cata' t1) (cata' t2) (cata' t3)
149 Cons t1 t2 -> fC (cata' t1) (cata' t2)
150 IterList var1 var2 t1 t2 t3 -> fIL var1 var2 (cata' t1) (cata' t2) (cata' t3)
155 -- | Collect all the symbols in a term.
156 -- The possible symbols are:
157 -- * @ IterBool t1 t2 (Var \"\") @
158 -- * @ IterNat v t1 t2 (Var \"\") @
159 -- * @ IterList v1 v2 t1 t2 (Var \"\") @
160 listIteratorSymbols,listSymbs :: FuncLang -> [FuncLang]
161 listIteratorSymbols = listSymbs
166 Abst _var t -> listSymbs t
167 Appl t1 t2 -> (listSymbs t1) `join` (listSymbs t2)
170 IterBool t1 t2 t3 -> [IterBool t1 t2 eVar] `join` (listSymbs t1) `join` (listSymbs t2) `join` (listSymbs t3)
172 Succ t -> listSymbs t
173 IterNat var t1 t2 t3 -> [IterNat var t1 t2 eVar] `join` (listSymbs t1) `join` (listSymbs t2) `join` (listSymbs t3)
175 Cons t1 t2 -> (listSymbs t1) `join` (listSymbs t2)
176 IterList var1 var2 t1 t2 t3 -> [IterList var1 var2 t1 t2 eVar] `join` (listSymbs t1) `join` (listSymbs t2) `join` (listSymbs t3)
179 -- | Give some sequential names to symbols.
180 giveNames :: [FuncLang] -> [(FuncLang, String)]
181 giveNames = snd . mapAccumL f 1
182 where f acc x = (acc+1,(x,"Iter_" ++ show acc))
185 -- | List the free variables of a term; the result is a set.
186 freeVars :: FuncLang -> [String]
187 freeVars = cata singleton delete union [] [] fIB [] id fIN [] union fIL
189 fIB r1 r2 r3 = r1 `union` r2 `union` r3
190 fIN v r1 r2 r3 = (delete v r1) `union` r2 `union` r3
191 fIL x y r1 r2 r3 = ( r1\\[x,y] ) `union` r2 `union` r3
193 -- | Special lookup function for iterators with an equality.
194 lookupIterName :: FuncLang -> [(FuncLang, String)] -> Maybe String
195 lookupIterName term [] = Nothing
196 lookupIterName term ((term2,str):xs) | term `equal` term2 = Just str
197 | otherwise = lookupIterName term xs
199 equal :: FuncLang -> FuncLang -> Bool
200 equal (IterBool v1 f1 _) (IterBool v2 f2 _) = v1==v2 && f1==f2
201 equal (IterNat x1 s1 z1 _) (IterNat x2 s2 z2 _) = x1==x2 && s1==s2 && z1==z2
202 equal (IterList x1 y1 c1 n1 _) (IterList x2 y2 c2 n2 _) = x1==x2 && y1==y2 && c1==c2 && n1==n2