]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/software/lambda-delta/basic_rg/brgReduction.ml
- new semantic log system
[helm.git] / helm / software / lambda-delta / basic_rg / brgReduction.ml
index aced1a22ec6a7673845d0357ff0fa0c003665bb2..74f6a504887511303cec3fbe1aeb9163ead41bde 100644 (file)
 module U = NUri
 module C = Cps
 module S = Share
+module L = Log
 module B = Brg
 module E = BrgEnvironment
 
-exception LRefNotFound of string Lazy.t
-
-type bind = Void_
-          | Abst_ of B.term
-          | Abbr_ of B.term
-
-type environment = int * bind list
+type environment = int * B.bind list
 
 type stack = B.term list
 
@@ -31,10 +26,12 @@ type context = {
    s: stack
 }
 
+exception LRefNotFound of (context, B.term) L.item list
+
 type whd_result =
    | Sort_ of int
    | LRef_ of int * B.term option
-   | GRef_ of int * B.bind * B.term
+   | GRef_ of int * B.bind
    | Bind_ of B.term * B.term
 
 type ho_whd_result =
@@ -43,6 +40,8 @@ type ho_whd_result =
 
 (* Internal functions *******************************************************)
 
+let error i = raise (LRefNotFound (L.items1 (string_of_int i)))
+
 let empty_e = 0, []
 
 let push_e f b (l, e) =
@@ -50,36 +49,45 @@ let push_e f b (l, e) =
 
 let get_e f c i =
    let (gl, ge), (ll, le) = c.g, c.l in
-   if i >= gl + ll then raise (LRefNotFound (lazy (string_of_int i)));
+   if i >= gl + ll then error i;
    let b =
       if i < gl then List.nth ge (gl - (succ i)) 
       else List.nth le (gl + ll - (succ i))
    in
    f b
 
-let rec lref_map f map t = match t with
-   | B.LRef i             -> f (B.LRef (map i))
-   | B.GRef _             -> f t
-   | B.Sort _             -> f t
-   | B.Cast (w, u)        ->
+let rec lref_map_bind f map b = match b with
+   | B.Abbr v ->
+      let f v' = f (S.sh1 v v' b B.abbr) in
+      lref_map f map v      
+   | B.Abst w ->
+      let f w' = f (S.sh1 w w' b B.abst) in
+      lref_map f map w
+   | B.Void   -> f b
+
+and lref_map f map t = match t with
+   | B.LRef i          -> f (B.LRef (map i))
+   | B.GRef _          -> f t
+   | B.Sort _          -> f t
+   | B.Cast (w, u)     ->
       let f w' u' = f (S.sh2 w w' u u' t B.cast) in
       let f w' = lref_map (f w') map u in 
       lref_map f map w
-   | B.Appl (w, u)        ->
+   | B.Appl (w, u)     ->
       let f w' u' = f (S.sh2 w w' u u' t B.appl) in
       let f w' = lref_map (f w') map u in 
       lref_map f map w
-   | B.Bind (id, b, w, u) ->
-      let f w' u' = f (S.sh2 w w' u u' t (B.bind id b)) in
-      let f w' = lref_map (f w') map u in 
-      lref_map f map w
+   | B.Bind (id, b, u) ->
+      let f b' u' = f (S.sh2 b b' u u' t (B.bind id)) in
+      let f b' = lref_map (f b') map u in 
+      lref_map_bind f map b
 
 (* to share *)
 let lift f c = 
    let (gl, _), (ll, le) = c.g, c.l in
    let map i = if i >= gl then succ i else i in
    let map f = function
-      | Abbr_ t -> let f t' = f (Abbr_ t') in lref_map f map t
+      | B.Abbr t -> let f t' = f (B.Abbr t') in lref_map f map t
       | _       -> assert false
    in
    let f le' = f {c with l = (ll, le')} in
@@ -97,52 +105,52 @@ let xchg f c t =
 let rec whd f c t = match t with
    | B.Sort h                 -> f c (Sort_ h)
    | B.GRef uri               ->
-      let f (i, _, b, t) = f c (GRef_ (i, b, t)) in
+      let f (i, _, b) = f c (GRef_ (i, b)) in
       E.get_obj f uri
-   | B.LRef i                 ->
+   | B.LRef i                ->
       let f = function
-         | Void_   -> f c (LRef_ (i, None))
-        | Abst_ t -> f c (LRef_ (i, Some t))
-        | Abbr_ t -> whd f c t
+         | B.Void   -> f c (LRef_ (i, None))
+        | B.Abst t -> f c (LRef_ (i, Some t))
+        | B.Abbr t -> whd f c t
       in
       get_e f c i
-   | B.Appl (v, t)            -> whd f {c with s = v :: c.s} t   
-   | B.Bind (_, B.Abbr, v, t) -> 
-      let f l = whd f {c with l = l} t in
-      push_e f (Abbr_ v) c.l
-   | B.Bind (_, B.Abst, w, t) -> 
+   | B.Cast (_, t)           -> whd f c t
+   | B.Appl (v, t)           -> whd f {c with s = v :: c.s} t   
+   | B.Bind (_, B.Abst w, t) -> 
       begin match c.s with
          | []      -> f c (Bind_ (w, t))
         | v :: tl -> 
            let f tl l = whd f {c with l = l; s = tl} t in
-           push_e (f tl) (Abbr_ v) c.l
+           push_e (f tl) (B.Abbr v) c.l
       end
-   | B.Cast (_, t)            -> whd f c t
+   | B.Bind (_, b, t) -> 
+      let f l = whd f {c with l = l} t in
+      push_e f b c.l
 
 let push f c t = 
    assert (c.s = []);
    let f c g = xchg f {c with g = g} t in
-   let f c = push_e (f c) Void_ c.g in
+   let f c = push_e (f c) B.Void c.g in
    lift f c 
 
 (* Interface functions ******************************************************)
 
 let rec are_convertible f c1 t1 c2 t2 =
    let rec aux c1' r1 c2' r2 = match r1, r2 with
-      | Sort_ h1, Sort_ h2                             -> f (h1 = h2)
-      | LRef_ (i1, _), LRef_ (i2, _)                   ->
+      | Sort_ h1, Sort_ h2                           -> f (h1 = h2)
+      | LRef_ (i1, _), LRef_ (i2, _)                 ->
          if i1 = i2 then are_convertible_stacks f c1' c2' else f false
-      | GRef_ (a1, B.Abst, _), GRef_ (a2, B.Abst, _)   ->
+      | GRef_ (a1, B.Abst _), GRef_ (a2, B.Abst _)   ->
          if a1 = a2 then are_convertible_stacks f c1' c2' else f false
-      | GRef_ (a1, B.Abbr, v1), GRef_ (a2, B.Abbr, v2) ->
+      | GRef_ (a1, B.Abbr v1), GRef_ (a2, B.Abbr v2) ->
          if a1 = a2 then are_convertible_stacks f c1' c2' else
         if a1 < a2 then whd (aux c1' r1) c2' v2 else
         whd (aux_rev c2' r2) c1' v1
-      | _, GRef_ (_, B.Abbr, v2)                       ->
+      | _, GRef_ (_, B.Abbr v2)                      ->
          whd (aux c1' r1) c2' v2
-      | GRef_ (_, B.Abbr, v1), _                       ->
+      | GRef_ (_, B.Abbr v1), _                      ->
         whd (aux_rev c2' r2) c1' v1
-      | Bind_ (w1, t1), Bind_ (w2, t2)                 ->
+      | Bind_ (w1, t1), Bind_ (w2, t2)               ->
          let f b = 
            if b then 
               let f c1'' t1' = push (are_convertible f c1'' t1') c2' t2 in
@@ -164,31 +172,30 @@ let are_convertible f c t1 t2 = are_convertible f c t1 c t2
 
 let rec ho_whd f c t =
    let aux c' = function
-      | Sort_ h           -> f c' (Sort h)
-      | Bind_ (w, t)      -> f c' (Abst w)
-      | LRef_ (_, Some w) -> ho_whd f c w
-      | GRef_ (_, _, u)   -> ho_whd f c u
-      | LRef_ (_, None)   -> assert false
+      | Sort_ h             -> f c' (Sort h)
+      | Bind_ (w, t)        -> f c' (Abst w)
+      | LRef_ (_, Some w)   -> ho_whd f c w
+      | GRef_ (_, B.Abst u) -> ho_whd f c u
+      | GRef_ (_, B.Abbr u) -> ho_whd f c u
+      | LRef_ (_, None)     -> assert false
+      | GRef_ (_, B.Void)   -> assert false
    in
    whd aux c t
 
-let push f c b 
+let push f c b = 
    assert (c.l = empty_e && c.s = []);
    let f g = f {c with g = g} in
-   let b = match b with
-      | B.Abbr -> Abbr_ t
-      | B.Abst -> Abst_ t
-   in
    push_e f b c.g
 
 let get f c i =
    let gl, ge = c.g in
-   if i >= gl then raise (LRefNotFound (lazy (string_of_int i)));
-   match List.nth ge (gl - (succ i)) with
-      | Abbr_ v -> f (B.Abbr, v)
-      | Abst_ w -> f (B.Abst, w)
-      | Void_   -> assert false
+   if i >= gl then error i;
+   f (List.nth ge (gl - (succ i)))
 
 let empty_context = {
    g = empty_e; l = empty_e; s = []
 }
+
+let iter f map c =
+   let _, ge = c.g in   
+   C.list_iter f map ge