]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/software/lambda-delta/basic_ag/bagReduction.ml
we started the support for the coercions "alle" and "alli"
[helm.git] / helm / software / lambda-delta / basic_ag / bagReduction.ml
index 0ec3d2c2bc89f349581d6f2f9f5d580e7162aec5..279ca072f1a38b5b9db5fbf96d7b956a562a1810 100644 (file)
@@ -21,6 +21,7 @@ module S = BagSubstitution
 exception LRefNotFound of B.message
 
 type machine = {
+   i: int;
    c: B.context;
    s: B.term list
 }
@@ -33,23 +34,26 @@ type whd_result =
 
 type ho_whd_result =
    | Sort of int
+   | GRef of U.uri * B.term list
    | Abst of B.term
 
 type ac_result = (int * NUri.uri * Bag.term list) list option
 
 (* Internal functions *******************************************************)
 
+let term_of_whdr = function
+   | Sort_ h             -> B.Sort h
+   | LRef_ (i, _)        -> B.LRef i
+   | GRef_ (_, uri, _)   -> B.GRef uri
+   | Bind_ (l, id, w, t) -> B.bind_abst l id w t
+
 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 empty_machine = {i = 0; c = B.empty_context; s = []}
 
-let unwind_to_context f c m = B.append f c m.c
+let inc m = {m with i = succ m.i}
 
 let unwind_to_term f m t =
    let map f t (l, id, b) = f (B.Bind (l, id, b, t)) in
@@ -66,7 +70,7 @@ let get f c m i =
       | None        -> error i
    in
    let f c = B.get f c i in
-   unwind_to_context f c m
+   B.append f c m.c
 
 let push f c m l id w = 
    assert (m.s = []);
@@ -92,7 +96,7 @@ let rec whd f c m x = match x with
       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
+           let f mc = whd f c {m with 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)         -> 
@@ -107,24 +111,34 @@ let insert f i uri vs = function
 
 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
+      | Sort_ h                  -> f (Sort h)
+      | Bind_ (_, _, w, _)       -> 
+         let f w = f (Abst w) in unwind_to_term f m w
+      | LRef_ (_, Some w)        -> ho_whd f c m w
+      | GRef_ (_, uri, B.Abst w) -> 
+         let f = function 
+           | Abst _ as r -> f r 
+           | GRef _ as r -> f r
+           | Sort _      ->
+              let f vs = f (GRef (uri, vs)) in unwind_stack f m
+        in
+        ho_whd f c m w
+      | GRef_ (_, _, B.Abbr v)   -> ho_whd f c m v
+      | 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 level; f c r in
+   let f r = L.unbox level; f r in
    L.box level; L.log O.specs level (L.ct_items1 "Now scanning" c t);
    ho_whd f c empty_machine t
 
 let rec are_convertible f xl c m1 t1 m2 t2 =
-   let rec aux m1 r1 m2 r2 = match r1, r2 with
+   let rec aux m1 r1 m2 r2 =
+   let u, t = term_of_whdr r1, term_of_whdr r2 in
+   L.log O.specs level (L.ct_items2 "Now really converting" c u "and" c t);   
+   match r1, r2 with
       | Sort_ h1, Sort_ h2                                 -> 
          if h1 = h2 then f xl else f None
       | LRef_ (i1, _), LRef_ (i2, _)                       ->
@@ -141,14 +155,18 @@ let rec are_convertible f xl c m1 t1 m2 t2 =
         whd (aux_rev m2 r2) c m1 v1      
       | Bind_ (l1, id1, w1, t1), Bind_ (l2, id2, w2, t2)   ->
          let f xl =
-           let h c = S.subst (are_convertible f xl c m1 t1 m2) l1 l2 t2 in
+           let h c =
+              let m1, m2 = inc m1, inc m2 in
+              S.subst (are_convertible f xl c m1 t1 m2) l1 l2 t2
+           in
             if xl = None then f xl else push h c m1 l1 id1 w1
         in
         are_convertible f xl c m1 w1 m2 w2
 (* we detect the AUT-QE reduction rule for type/prop inclusion *)      
-      | GRef_ (_, uri, B.Abst _), Bind_ (l2, _, _, _)      ->
-         let g vs = insert f l2 uri vs xl in
+      | GRef_ (_, uri, B.Abst _), Bind_ (l1, _, _, _)      ->
+         let g vs = insert f l1 uri vs xl in
         if U.eq uri I.imp then unwind_stack g m1 else 
+        if U.eq uri I.all then unwind_stack g m1 else
         begin L.warn (U.string_of_uri uri); f None end
       | _                                                  -> f None
    and aux_rev m2 r2 m1 r1 = aux m1 r1 m2 r2 in