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
|
module Rewriting.Rules
( Rule, TRS
, showRule, showTRS, rRoot, rCons, rVars, maxVarInRule, minVarInRule
, maxVarInTRS, minVarInTRS, renameRuleVars, renameTRSVars, normalizeRule
, normalizeTRS, isVariantOf, isLeftLinear, isLeftNormal, isRedex, isPattern
, isConsBased, isDemandedAt
) where
import Data.Function (on)
import Data.Tuple.Extra (both)
import Data.List (union, maximum, minimum)
import Data.Maybe (mapMaybe)
import Rewriting.Substitution (listToSubst, applySubst)
import Rewriting.Term
type Rule f = (Term f, Term f)
type TRS f = [Rule f]
showRule :: (f -> String) -> Rule f -> String
showRule s (l, r) = (showTerm s l) ++ " \8594 " ++ (showTerm s r)
showTRS :: (f -> String) -> TRS f -> String
showTRS s = unlines . (map (showRule s))
rRoot :: Rule f -> Either VarIdx f
rRoot (l, _) = tRoot l
rCons :: Eq f => Rule f -> [f]
rCons (l, r) = union (tCons l) (tCons r)
rVars :: Rule _ -> [VarIdx]
rVars (l, _) = tVars l
maxVarInRule :: Rule _ -> Maybe VarIdx
maxVarInRule (l, _) = maxVarInTerm l
minVarInRule :: Rule _ -> Maybe VarIdx
minVarInRule (l, _) = minVarInTerm l
maxVarInTRS :: TRS _ -> Maybe VarIdx
maxVarInTRS trs = case mapMaybe maxVarInRule trs of
[] -> Nothing
vs@(_:_) -> Just (maximum vs)
minVarInTRS :: TRS _ -> Maybe VarIdx
minVarInTRS trs = case mapMaybe minVarInRule trs of
[] -> Nothing
vs@(_:_) -> Just (minimum vs)
renameRuleVars :: Int -> Rule f -> Rule f
renameRuleVars i = both (renameTermVars i)
renameTRSVars :: Int -> TRS f -> TRS f
renameTRSVars i = map (renameRuleVars i)
normalizeRule :: Rule f -> Rule f
normalizeRule r = let sub = listToSubst (zip (rVars r) (map TermVar [0..]))
in both (applySubst sub) r
normalizeTRS :: TRS f -> TRS f
normalizeTRS = map normalizeRule
isVariantOf :: Eq f => Rule f -> Rule f -> Bool
isVariantOf = on (==) normalizeRule
isLeftLinear :: TRS _ -> Bool
isLeftLinear = all (isLinear . fst)
isLeftNormal :: TRS _ -> Bool
isLeftNormal = all (isNormal . fst)
isRedex :: Eq f => TRS f -> Term f -> Bool
isRedex trs t = any ((eqConsPattern t) . fst) trs
isPattern :: Eq f => TRS f -> Term f -> Bool
isPattern _ (TermVar _) = False
isPattern trs t@(TermCons _ ts) = isRedex trs t && all isVarOrCons ts
where
isVarOrCons (TermVar _) = True
isVarOrCons t'@(TermCons _ ts') = not (isRedex trs t') && all isVarOrCons ts'
isConsBased :: Eq f => TRS f -> Bool
isConsBased trs = all ((isPattern trs) . fst) trs
isDemandedAt :: Int -> Rule _ -> Bool
isDemandedAt _ (TermVar _, _) = False
isDemandedAt i (TermCons _ ts, _) =
i > 0 && i <= length ts && isConsTerm (ts !! (i - 1))
|