2 ||M|| This file is part of HELM, an Hypertextual, Electronic
3 ||A|| Library of Mathematics, developed at the Computer Science
4 ||T|| Department, University of Bologna, Italy.
6 ||T|| HELM is free software; you can redistribute it and/or
7 ||A|| modify it under the terms of the GNU General Public License
8 \ / version 2 or (at your option) any later version.
9 \ / This software is distributed as is, NO WARRANTY.
10 V_______________________________________________________________ *)
17 module E = BrgEnvironment
19 exception LRefNotFound of B.message
28 | LRef_ of int * B.term option
29 | GRef_ of int * B.bind
30 | Bind_ of B.id * B.term * B.term
36 (* Internal functions *******************************************************)
40 let error i = raise (LRefNotFound (L.items1 (string_of_int i)))
42 let empty_machine = {c = B.empty_context; s = []}
49 let f gl _ = if i < gl then B.get f c i else B.get f m.c (i - gl) in
53 let f gl ges = B.contents (f gl ges) m.c in
56 let unwind_to_context f c m = B.append f c m.c
58 let unwind_to_term f m t =
59 let map f t (id, b) = f (B.Bind (id, b, t)) in
60 let f _ mc = C.list_fold_left f map t mc in
63 let rec lref_map_bind f map b = match b with
65 let f v' = f (S.sh1 v v' b B.abbr) in
68 let f w' = f (S.sh1 w w' b B.abst) in
72 and lref_map f map t = match t with
73 | B.LRef i -> f (B.LRef (map i))
77 let f w' u' = f (S.sh2 w w' u u' t B.cast) in
78 let f w' = lref_map (f w') map u in
81 let f w' u' = f (S.sh2 w w' u u' t B.appl) in
82 let f w' = lref_map (f w') map u in
84 | B.Bind (id, b, u) ->
85 let f b' u' = f (S.sh2 b b' u u' t (B.bind id)) in
86 let f b' = lref_map (f b') map u in
92 let map i = if i >= gl then succ i else i in
94 | id, B.Abbr t -> let f t = f (id, B.Abbr t) in lref_map f map t
97 let f mc = f {m with c = mc} in
106 if i < gl || i > gl + ll then i else
107 if i >= gl && i < gl + ll then succ i else gl
113 let push f c m id w t =
115 let f c m = xchg (f c m) c m t in
116 let f c = lift (f c) c m in
117 let f w = B.push f c id (B.Abst w) in
121 let rec whd f c m x = match x with
122 | B.Sort h -> f m (Sort_ h)
124 let f (i, _, b) = f m (GRef_ (i, b)) in
128 | B.Void -> f m (LRef_ (i, None))
129 | B.Abst t -> f m (LRef_ (i, Some t))
130 | B.Abbr t -> whd f c m t
133 | B.Cast (_, t) -> whd f c m t
134 | B.Appl (v, t) -> whd f c {m with s = v :: m.s} t
135 | B.Bind (id, B.Abst w, t) ->
137 | [] -> f m (Bind_ (id, w, t))
139 let f mc = whd f c {c = mc; s = tl} t in
140 B.push f m.c id (B.Abbr (B.Cast (w, v)))
142 | B.Bind (id, b, t) ->
143 let f mc = whd f c {m with c = mc} t in
146 (* Interface functions ******************************************************)
148 let rec ho_whd f c m x =
150 | Sort_ h -> f c (Sort h)
152 let f c = f c (Abst w) in unwind_to_context f c m
153 | LRef_ (_, Some w) -> ho_whd f c m w
154 | GRef_ (_, B.Abst u) -> ho_whd f c m u
155 | GRef_ (_, B.Abbr t) -> ho_whd f c m t
156 | LRef_ (_, None) -> assert false
157 | GRef_ (_, B.Void) -> assert false
162 L.log O.specs level (L.ct_items1 "Now scanning" c t);
163 ho_whd f c empty_machine t
165 let rec are_convertible f c1 m1 t1 c2 m2 t2 =
166 let rec aux m1 r1 m2 r2 = match r1, r2 with
167 | Sort_ h1, Sort_ h2 -> f (h1 = h2)
168 | LRef_ (i1, _), LRef_ (i2, _) ->
169 if i1 = i2 then are_convertible_stacks f c1 m1 c2 m2 else f false
170 | GRef_ (a1, B.Abst _), GRef_ (a2, B.Abst _) ->
171 if a1 = a2 then are_convertible_stacks f c1 m1 c2 m2 else f false
172 | GRef_ (a1, B.Abbr v1), GRef_ (a2, B.Abbr v2) ->
173 if a1 = a2 then are_convertible_stacks f c1 m1 c2 m2 else
174 if a1 < a2 then whd (aux m1 r1) c2 m2 v2 else
175 whd (aux_rev m2 r2) c1 m1 v1
176 | _, GRef_ (_, B.Abbr v2) ->
177 whd (aux m1 r1) c2 m2 v2
178 | GRef_ (_, B.Abbr v1), _ ->
179 whd (aux_rev m2 r2) c1 m1 v1
180 | Bind_ (id1, w1, t1), Bind_ (id2, w2, t2) ->
184 push (are_convertible f c1 m1 t1) c2 m2 id2 w2 t2
186 push f c1 m1 id1 w1 t1
189 are_convertible f c1 m1 w1 c2 m2 w2
191 and aux_rev m2 r2 m1 r1 = aux m1 r1 m2 r2 in
192 let f m1 r1 = whd (aux m1 r1) c2 m2 t2 in
195 and are_convertible_stacks f c1 m1 c2 m2 =
196 let mm1, mm2 = {m1 with s = []}, {m2 with s = []} in
197 let map f v1 v2 = are_convertible f c1 mm1 v1 c2 mm2 v2 in
198 if List.length m1.s <> List.length m2.s then f false else
199 C.forall2 f map m1.s m2.s
201 let are_convertible f c t1 t2 =
202 L.log O.specs level (L.ct_items2 "Now converting" c t1 "and" c t2);
203 are_convertible f c empty_machine t1 c empty_machine t2