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
|
module Analysis.RootReplaced
( rootReplAnalysis, showRootRepl
, rootCyclicAnalysis, showRootCyclic
)
where
import Analysis.Types
import Analysis.ProgInfo
import FlatCurry.Types
import Data.List
type RootReplaced = ([QName],[Int])
showRootRepl :: AOutFormat -> RootReplaced -> String
showRootRepl AText ([],_) = "no root replacements"
showRootRepl ANote ([],_) = ""
showRootRepl AText (xs@(_:_),_) =
"root replacements: " ++ intercalate "," (map (\ (mn,fn) -> mn++"."++fn) xs)
showRootRepl ANote (xs@(_:_),_) = "[" ++ intercalate "," (map snd xs) ++ "]"
rootReplAnalysis :: Analysis RootReplaced
rootReplAnalysis = dependencyFuncAnalysis "RootReplaced" ([],[]) rrFunc
rrFunc :: FuncDecl -> [(QName,RootReplaced)] -> RootReplaced
rrFunc (Func _ _ _ _ rule) calledFuncs = rrFuncRule calledFuncs rule
rrFuncRule :: [(QName,RootReplaced)] -> Rule -> RootReplaced
rrFuncRule _ (External _) = ([],[])
rrFuncRule calledFuncs (Rule args rhs) = rrOfExp rhs
where
rrOfExp exp = case exp of
Var v -> maybe ([],[]) (\i -> ([],[i])) (elemIndex v args)
Lit _ -> ([],[])
Comb ct g gargs ->
if ct == FuncCall
then maybe (error $ "Abstract value of " ++ show g ++ " not found!")
(\ (grrs,gps) ->
foldr lub (if g `elem` grrs
then grrs
else insertBy (<=) g grrs, [])
(map (\pi -> rrOfExp (gargs!!pi)) gps))
(lookup g calledFuncs)
else ([],[])
Typed e _ -> rrOfExp e
Free _ e -> rrOfExp e
Let _ e -> rrOfExp e
Or e1 e2 -> lub (rrOfExp e1) (rrOfExp e2)
Case _ e bs -> foldr lub (rrOfExp e)
(map (\ (Branch _ be) -> rrOfExp be) bs)
lub (rr1,p1) (rr2,p2) = (sort (union rr1 rr2), sort (union p1 p2))
showRootCyclic :: AOutFormat -> Bool -> String
showRootCyclic AText False = "no cycles at the root"
showRootCyclic ANote False = ""
showRootCyclic AText True = "possible cyclic root replacement"
showRootCyclic ANote True = "root-cyclic"
rootCyclicAnalysis :: Analysis Bool
rootCyclicAnalysis =
combinedSimpleFuncAnalysis "RootCyclic" rootReplAnalysis rcFunc
rcFunc :: ProgInfo RootReplaced -> FuncDecl -> Bool
rcFunc _ (Func _ _ _ _ (External _)) = False
rcFunc rrinfo (Func qf _ _ _ (Rule _ _)) =
maybe True
(\rrfuncs -> qf `elem` (fst rrfuncs)
|| any (\rrf -> maybe True
(\fs -> rrf `elem` (fst fs))
(lookupProgInfo rrf rrinfo))
(fst rrfuncs))
(lookupProgInfo qf rrinfo)
|