X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2Fsoftware%2Flambda-delta%2Fbasic_ag%2FbagReduction.ml;fp=helm%2Fsoftware%2Flambda-delta%2Fbasic_ag%2FbagReduction.ml;h=0310e8d2833de378e435ae3ffcf80b998da5dcad;hb=338e3e5c639fbcfeeb347a0121cacc6c0f1fc42a;hp=0000000000000000000000000000000000000000;hpb=c87a73806365feadc23300194a42ab8edb0f8b1b;p=helm.git diff --git a/helm/software/lambda-delta/basic_ag/bagReduction.ml b/helm/software/lambda-delta/basic_ag/bagReduction.ml new file mode 100644 index 000000000..0310e8d28 --- /dev/null +++ b/helm/software/lambda-delta/basic_ag/bagReduction.ml @@ -0,0 +1,154 @@ +(* + ||M|| This file is part of HELM, an Hypertextual, Electronic + ||A|| Library of Mathematics, developed at the Computer Science + ||T|| Department, University of Bologna, Italy. + ||I|| + ||T|| HELM is free software; you can redistribute it and/or + ||A|| modify it under the terms of the GNU General Public License + \ / version 2 or (at your option) any later version. + \ / This software is distributed as is, NO WARRANTY. + V_______________________________________________________________ *) + +module C = Cps +module L = Log +module B = Bag +module O = BagOutput +module E = BagEnvironment +module S = BagSubstitution + +exception LRefNotFound of B.message + +type machine = { + c: B.context; + s: B.term list +} + +type whd_result = + | Sort_ of int + | LRef_ of int * B.term option + | GRef_ of int * B.bind + | Bind_ of int * B.id * B.term * B.term + +type ho_whd_result = + | Sort of int + | Abst of B.term + +(* Internal functions *******************************************************) + +let level = 5 + +let error i = raise (LRefNotFound (L.items1 (string_of_int i))) + +let empty_machine = {c = B.empty_context; s = []} + +let contents f c m = + let f gl ges = B.contents (f gl ges) m.c in + B.contents f c + +let unwind_to_context f c m = B.append f c m.c + +let unwind_to_term f m t = + let map f t (l, id, b) = f (B.Bind (l, id, b, t)) in + let f mc = C.list_fold_left f map t mc in + B.contents f m.c + +let get f c m i = + let f = function + | Some (_, b) -> f b + | None -> error i + in + let f c = B.get f c i in + unwind_to_context f c m + +let push f c m l id w = + assert (m.s = []); + let f w = B.push f c l id (B.Abst w) in + unwind_to_term f m w + +(* to share *) +let rec whd f c m x = match x with + | B.Sort h -> f m (Sort_ h) + | B.GRef uri -> + let f (i, _, b) = f m (GRef_ (i, b)) in + E.get_obj f uri + | B.LRef i -> + let f = function + | B.Void -> f m (LRef_ (i, None)) + | B.Abst t -> f m (LRef_ (i, Some t)) + | B.Abbr t -> whd f c m t + in + get f c m i + | B.Cast (_, t) -> whd f c m t + | B.Appl (v, t) -> whd f c {m with s = v :: m.s} t + | B.Bind (l, id, B.Abst w, t) -> + begin match m.s with + | [] -> f m (Bind_ (l, id, w, t)) + | v :: tl -> + let f mc = whd f c {c = mc; s = tl} t in + B.push f m.c l id (B.Abbr (B.Cast (w, v))) + end + | B.Bind (l, id, b, t) -> + let f mc = whd f c {m with c = mc} t in + B.push f m.c l id b + +(* Interface functions ******************************************************) + +let rec ho_whd f c m x = + let aux m = function + | Sort_ h -> f c (Sort h) + | Bind_ (_, _, w, _) -> + let f c = f c (Abst w) in unwind_to_context f c m + | LRef_ (_, Some w) -> ho_whd f c m w + | GRef_ (_, B.Abst u) -> ho_whd f c m u + | GRef_ (_, B.Abbr t) -> ho_whd f c m t + | LRef_ (_, None) -> assert false + | GRef_ (_, B.Void) -> assert false + in + whd aux c m x + +let ho_whd f c t = + let f c r = L.unbox (); f c r in + L.box (); L.log O.specs level (L.ct_items1 "Now scanning" c t); + ho_whd f c empty_machine t + +let rec are_convertible f c m1 t1 m2 t2 = + let rec aux m1 r1 m2 r2 = match r1, r2 with + | Sort_ h1, Sort_ h2 -> f (h1 = h2) + | LRef_ (i1, _), LRef_ (i2, _) -> + if i1 = i2 then are_convertible_stacks f c m1 m2 else f false + | GRef_ (a1, B.Abst _), GRef_ (a2, B.Abst _) -> + if a1 = a2 then are_convertible_stacks f c m1 m2 else f false + | GRef_ (a1, B.Abbr v1), GRef_ (a2, B.Abbr v2) -> + if a1 = a2 then are_convertible_stacks f c m1 m2 else + if a1 < a2 then whd (aux m1 r1) c m2 v2 else + whd (aux_rev m2 r2) c m1 v1 + | _, GRef_ (_, B.Abbr v2) -> + whd (aux m1 r1) c m2 v2 + | GRef_ (_, B.Abbr v1), _ -> + whd (aux_rev m2 r2) c m1 v1 + | Bind_ (l1, id1, w1, t1), Bind_ (l2, id2, w2, t2) -> + let f b = + if b then + let f c = + S.subst (are_convertible f c m1 t1 m2) l1 l2 t2 + in + push f c m1 l1 id1 w1 + else f false + in + are_convertible f c m1 w1 m2 w2 + | _ -> f false + and aux_rev m2 r2 m1 r1 = aux m1 r1 m2 r2 in + let f m1 r1 = whd (aux m1 r1) c m2 t2 in + whd f c m1 t1 + +and are_convertible_stacks f c m1 m2 = + let mm1, mm2 = {m1 with s = []}, {m2 with s = []} in + let map f v1 v2 = are_convertible f c mm1 v1 mm2 v2 in + if List.length m1.s <> List.length m2.s then f false else + C.forall2 f map m1.s m2.s + +let are_convertible f c t1 t2 = + let f b = L.unbox (); f b in + L.box (); + L.log O.specs level (L.ct_items2 "Now converting" c t1 "and" c t2); + are_convertible f c empty_machine t1 empty_machine t2