-
Notifications
You must be signed in to change notification settings - Fork 0
/
StripLemma.hs
144 lines (127 loc) · 6.15 KB
/
StripLemma.hs
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
{-
Copyright (C) 2010, 2011, 2012 Jeroen Ketema and Jakob Grue Simonsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-}
-- This module implements the Strip Lemma for reductions up to length omega.
module StripLemma (
stripLemma
) where
import SignatureAndVariables
import Term
import PositionAndSubterm
import RuleAndSystem
import SystemOfNotation
import Reduction
import ParallelReduction
import Omega
import Prelude
import Data.List
-- The function bottomList computes the bottom reduction from the Strip Lemma.
-- The steps of the reduction are returned as a list of lists of steps, where it
-- is ensured for the ith item in the list that all its steps occur at depth
-- at least i.
--
-- The function gather has four arguments: depth, number of used parallel steps,
-- unused parallel steps, previous parallel steps.
--
-- For the modulus use the observation that in the worst case a variable in the
-- left-hand side of a rewrite rule is moved all the way to the root of the
-- right-hand side.
bottomList :: RewriteSystem s v r
=> CReduction s v r -> Step s v -> Term s v -> [[Step s v]]
bottomList (CRCons (RCons _ ss) phi) step@(_, Rule l _) final
= gather 0 0 psteps_all []
where psteps_all = project (getFrom ss ordZero) step
height = termHeight l
gather d p_used unused psteps
= steps_d : gather (d + 1) p_used' unused' psteps'
where (steps_d, psteps') = parallelNeededSteps psteps_new ps
ps = posToDepth final d
psteps_new = psteps ++ used
(used, unused') = genericSplitAt p_new unused
p_new = p_used' - p_used
p_used' = max p_used modulus
modulus = ord2Int (phi ordZero (d + height))
-- Project the steps from the top reduction to obtain the parallel steps that
-- form the bottom reduction.
project :: (Signature s, Variables v)
=> [Step s v] -> Step s v -> [ParallelStep s v]
project steps (position, rule) = project' steps pstep
where pstep = (pos2PosFun position, rule)
project' [] _ = []
project' (s:ss) ps = s_projected : project' ss ps_projected
where (ps_projected, s_projected) = diamondProperty s ps
-- Concatenate the lists produced by bottomList to obtain all steps of the
-- bottom reduction.
bottomSteps :: RewriteSystem s v r
=> CReduction s v r -> Step s v -> Term s v -> [Step s v]
bottomSteps reduction step final = concat steps_list
where steps_list = bottomList reduction step final
-- Compute the modulus of the bottom reduction using that the ith element of
-- the list produced by bottomList contains only steps at depth at least i.
bottomModulus :: RewriteSystem s v r
=> CReduction s v r -> Step s v -> Term s v -> Modulus Omega
bottomModulus reduction step final = constructModulus phi
where phi n = genericLength $ concat $ genericTake (n + 1) steps_list
steps_list = bottomList reduction step final
-- Yield the bottom reduction of the Strip Lemma.
bottomReduction :: RewriteSystem s v r
=> CReduction s v r -> Step s v -> Term s v -> CReduction s v r
bottomReduction reduction step final = CRCons (RCons ts ss) phi
where ts = constructSequence terms
ss = constructSequence steps
phi = bottomModulus reduction step final
terms = rewriteSteps initial steps
initial = rewriteStep (initialTerm reduction) step
steps = bottomSteps reduction step final
-- The function rightList computes the right-most reduction of the Strip
-- Lemma. The steps of the reduction are returned as a list of lists of steps,
-- where it is ensured for the ith item in the list that all steps occur at
-- depth i.
rightList :: RewriteSystem s v r
=> CReduction s v r -> Step s v -> [[Step s v]]
rightList reduction (position, rule) = map (map pair) pf_d
where pf = pos2PosFun position
pf_d = descendants reduction pf
pair p = (p, rule)
-- Concatenate the lists produced by rightList to obtain all steps of the
-- right-most reduction.
rightSteps :: RewriteSystem s v r
=> CReduction s v r -> Step s v -> [Step s v]
rightSteps reduction step = concat steps_list
where steps_list = rightList reduction step
-- Compute the modulus of the right-most reduction using that the ith element
-- of the list produced by rightList contains all steps at depth i.
rightModulus :: RewriteSystem s v r
=> CReduction s v r -> Step s v -> Modulus Omega
rightModulus reduction step = constructModulus phi_new
where phi_new n = genericLength $ concat $ genericTake (n + 1) steps_list
steps_list = rightList reduction step
-- Yield the right-most reduction of the Strip Lemma.
rightReduction :: RewriteSystem s v r
=> CReduction s v r -> Step s v -> CReduction s v r
rightReduction reduction step = CRCons (RCons ts ss) phi
where ts = constructSequence terms
ss = constructSequence steps
phi = rightModulus reduction step
terms = rewriteSteps (finalTerm reduction) steps
steps = rightSteps reduction step
-- The Strip Lemma for orthogonal systems.
--
-- It is assumed the input reduction has at most length omega.
stripLemma :: RewriteSystem s v r
=> r -> CReduction s v r -> Step s v -> (CReduction s v r, CReduction s v r)
stripLemma _ reduction step
| atMostLengthOmega reduction = (bottom, right)
| otherwise = error "Reduction too long"
where bottom = bottomReduction reduction step (finalTerm right)
right = rightReduction reduction step