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
|
module Analysis.RightLinearity
(rlinAnalysis,hasRightLinearRules,linearExpr,showRightLinear) where
import Analysis.Types
import FlatCurry.Types
import Maybe
import List
rlinAnalysis :: Analysis Bool
rlinAnalysis = dependencyFuncAnalysis "RightLinear" True rlFunc
rlFunc :: FuncDecl -> [(QName,Bool)] -> Bool
rlFunc func calledFuncs =
hasRightLinearRules func && all snd calledFuncs
showRightLinear :: AOutFormat -> Bool -> String
showRightLinear _ True = "right-linear"
showRightLinear AText False = "not defined by right-linear rules"
showRightLinear ANote False = ""
hasRightLinearRules :: FuncDecl -> Bool
hasRightLinearRules (Func _ _ _ _ rule) = isRightLinearRule rule
isRightLinearRule :: Rule -> Bool
isRightLinearRule (Rule _ e) = linearExpr e
isRightLinearRule (External _) = True
linearExpr :: Expr -> Bool
linearExpr e = maybe False (const True) (linearVariables e)
linearVariables :: Expr -> Maybe [Int]
linearVariables (Var i) = Just [i]
linearVariables (Lit _) = Just []
linearVariables (Comb _ f es)
| f==("Prelude","?") && length es == 2
= linearVariables (Or (head es) (head (tail es)))
| otherwise
= mapMMaybe linearVariables es >>- \esvars ->
let vars = concat esvars
in if nub vars == vars
then Just vars
else Nothing
linearVariables (Free vs e) =
linearVariables e >>- \evars -> Just (evars \\ vs)
linearVariables (Let bs e) =
mapMMaybe linearVariables (map snd bs) >>- \bsvars ->
linearVariables e >>- \evars ->
let vars = concat (evars : bsvars)
in if nub vars == vars
then Just (vars \\ (map fst bs))
else Nothing
linearVariables (Or e1 e2) =
linearVariables e1 >>- \e1vars ->
linearVariables e2 >>- \e2vars ->
Just (union e1vars e2vars)
linearVariables (Case _ e bs) =
linearVariables e >>- \evars ->
mapMMaybe linearVariables (map (\ (Branch _ be) -> be) bs) >>- \bsvars ->
let vars = foldr union [] (map (\ (branch,bsv) -> bsv \\ patternVars branch)
(zip bs bsvars)) ++ evars
in if nub vars == vars
then Just vars
else Nothing
where
patternVars (Branch (Pattern _ vs) _) = vs
patternVars (Branch (LPattern _) _) = []
linearVariables (Typed e _) = linearVariables e
|