1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
module ReadFlatTRS(readRules,readRulesAndData,readFlatCurryRules) where
import qualified TRS
import FlatCurry.Types as FC
import FlatCurry.Files (readFlatCurry)
import OrCaseLifter
readRules :: String -> IO [TRS.Rule]
readRules prog = do
putStrLn $ "Reading rules from Curry program " ++ prog ++ "..."
flatprog <- readFlatCurry prog
return (fst (curry2rules flatprog))
readRulesAndData :: String -> IO ([TRS.Rule],[TypeDecl])
readRulesAndData prog = do
putStrLn $ "Reading rules from Curry program " ++ prog ++ "..."
flatprog <- readFlatCurry prog
return (curry2rules flatprog)
readFlatCurryRules :: String -> IO (Prog,[TRS.Rule])
readFlatCurryRules prog = do
putStrLn $ "Reading rules from Curry program " ++ prog ++ "..."
flatprog <- readFlatCurry prog
return (flatprog, fst $ curry2rules flatprog)
curry2rules (Prog modname _ tdecls fdecls _) =
if any TRS.containsApply crules
then (TRS.addApplyRules crules, tdecls)
else (crules, tdecls)
where
rules = concatMap fdecl2rules (liftNestedOrCase (modname,"ORCASE_") fdecls)
crules = if any TRS.containsChoice rules then TRS.addChoiceRules rules
else rules
fdecl2rules (FC.Func (_,fname) arity _ _ (External _)) =
[TRS.Rule fname (genArgs arity) (TRS.Func TRS.Def "EXTERNAL" [])]
where
genArgs n = map TRS.Var [1..n]
fdecl2rules (FC.Func fname _ _ _ (FC.Rule lhs rhs)) =
map patternrule2rule patternrules
where
patternrules = rule2equations (Comb FuncCall fname (map Var lhs)) rhs
patternrule2rule (l,r) =
let (TRS.Func _ f args) = transExp l
in TRS.Rule f args (transExp r)
transExp (FC.Var i) = TRS.Var i
transExp (Lit (Intc i)) = TRS.Func TRS.Cons (show i) []
transExp (Lit (Floatc f)) = TRS.Func TRS.Cons (show f) []
transExp (Lit (Charc c)) = TRS.Func TRS.Cons ['\'',c,'\''] []
transExp (Comb ct (_,f) args) =
TRS.Func (if ct==FuncCall then TRS.Def else TRS.Cons) f (map transExp args)
transExp (Free _ exp) = transExp exp
transExp (Let _ _) = error "Let not yet supported"
transExp (FC.Or _ _) = error "Or not yet supported"
transExp (Case _ _ _) = error "Case not yet supported"
rule2equations :: Expr -> Expr -> [(Expr,Expr)]
rule2equations lhs (FC.Or e1 e2) =
rule2equations lhs e1 ++ rule2equations lhs e2
rule2equations lhs (Case ctype e bs) =
if isVarExpr e then let Var i = e in caseIntoLhs lhs i bs
else [(lhs,Case ctype e bs)]
rule2equations lhs (Var i) = [(lhs,Var i)]
rule2equations lhs (Lit l) = [(lhs,Lit l)]
rule2equations lhs (Comb ct name args) = [(lhs,Comb ct name args)]
rule2equations lhs (Free vs e) = [(lhs,Free vs e)]
rule2equations lhs (Let bs e) = [(lhs,Let bs e)]
caseIntoLhs _ _ [] = []
caseIntoLhs lhs vi (Branch (Pattern c vs) e : bs) =
rule2equations (substitute [vi] [shallowPattern2Expr c vs] lhs) e
++ caseIntoLhs lhs vi bs
caseIntoLhs lhs vi (Branch (LPattern lit) e : bs) =
rule2equations (substitute [vi] [Lit lit] lhs) e
++ caseIntoLhs lhs vi bs
shallowPattern2Expr name vars = Comb ConsCall name (map (\i->Var i) vars)
substitute vars exps expr = substituteAll vars exps 0 expr
substituteAll :: [Int] -> [Expr] -> Int -> Expr -> Expr
substituteAll vars exps b (Var i) = replaceVar vars exps i
where replaceVar [] [] var = Var (b+var)
replaceVar (v:vs) (e:es) var = if v==var then e
else replaceVar vs es var
substituteAll _ _ _ (Lit l) = Lit l
substituteAll vs es b (Comb combtype c exps) =
Comb combtype c (map (substituteAll vs es b) exps)
substituteAll vs es b (Let bindings exp) =
Let (map (\(x,e)->(x+b,substituteAll vs es b e)) bindings)
(substituteAll vs es b exp)
substituteAll vs es b (Free vars e) =
Free (map (+b) vars) (substituteAll vs es b e)
substituteAll vs es b (FC.Or e1 e2) =
FC.Or (substituteAll vs es b e1) (substituteAll vs es b e2)
substituteAll vs es b (Case ctype e cases) =
Case ctype (substituteAll vs es b e) (map (substituteAllCase vs es b) cases)
substituteAllCase vs es b (Branch (Pattern l pvs) e) =
Branch (Pattern l (map (+b) pvs)) (substituteAll vs es b e)
substituteAllCase vs es b (Branch (LPattern l) e) =
Branch (LPattern l) (substituteAll vs es b e)
isGuardedExpr :: Expr -> Bool
isGuardedExpr e = case e of
Comb _ f _ -> f == ("Prelude","cond")
_ -> False
isVarExpr :: Expr -> Bool
isVarExpr e = case e of
Var _ -> True
_ -> False
|