]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/ocaml/cic_proof_checking/cicReductionMachine.ml
Added universes handling. The PRE_UNIVERSES tag may help ;)
[helm.git] / helm / ocaml / cic_proof_checking / cicReductionMachine.ml
index f53471414b660a53e7e4c04310c1c0b0383ef54d..e0fd252a6b6b8a254c25b60bd9a82f76eed7fd8a 100644 (file)
@@ -353,7 +353,10 @@ prerr_endline ("%%%%%UWVAR " ^ String.concat " ; " (List.map (function (uri,t) -
           CicSubstitution.lift m (RS.from_ens (List.assq uri ens))
          else
           let params =
-           (match CicEnvironment.get_obj uri with
+           let o,_ = 
+             CicEnvironment.get_cooked_obj uri CicUniv.empty_ugraph
+           in
+           (match o with
                C.Constant _ -> raise ReferenceToConstant
              | C.Variable (_,_,_,params) -> params
              | C.CurrentProof _ -> raise ReferenceToCurrentProof
@@ -382,7 +385,10 @@ prerr_endline ("%%%%%UWVAR " ^ String.concat " ; " (List.map (function (uri,t) -
        | C.Appl l -> C.Appl (List.map (unwind_aux m) l)
        | C.Const (uri,exp_named_subst) ->
           let params =
-           (match CicEnvironment.get_obj uri with
+           let o,_ = 
+             CicEnvironment.get_cooked_obj uri CicUniv.empty_ugraph 
+           in
+           (match o with
                C.Constant (_,_,_,params) -> params
              | C.Variable _ -> raise ReferenceToVariable
              | C.CurrentProof (_,_,_,_,params) -> params
@@ -395,7 +401,10 @@ prerr_endline ("%%%%%UWVAR " ^ String.concat " ; " (List.map (function (uri,t) -
             C.Const (uri,exp_named_subst')
        | C.MutInd (uri,i,exp_named_subst) ->
           let params =
-           (match CicEnvironment.get_obj uri with
+           let o,_ = 
+             CicEnvironment.get_cooked_obj uri CicUniv.empty_ugraph 
+           in
+           (match o with
                C.Constant _ -> raise ReferenceToConstant
              | C.Variable _ -> raise ReferenceToVariable
              | C.CurrentProof _ -> raise ReferenceToCurrentProof
@@ -408,7 +417,10 @@ prerr_endline ("%%%%%UWVAR " ^ String.concat " ; " (List.map (function (uri,t) -
             C.MutInd (uri,i,exp_named_subst')
        | C.MutConstruct (uri,i,j,exp_named_subst) ->
           let params =
-           (match CicEnvironment.get_obj uri with
+           let o,_ = 
+             CicEnvironment.get_cooked_obj uri CicUniv.empty_ugraph
+           in
+           (match o with
                C.Constant _ -> raise ReferenceToConstant
              | C.Variable _ -> raise ReferenceToVariable
              | C.CurrentProof _ -> raise ReferenceToCurrentProof
@@ -530,7 +542,10 @@ if List.mem uri params then prerr_endline "---- OK2" ;
          if List.exists (function (uri',_) -> UriManager.eq uri' uri) ens then
           reduce (0, [], [], RS.from_ens (List.assq uri ens), s)
          else
-          (match CicEnvironment.get_obj uri with
+          ( let o,_ = 
+             CicEnvironment.get_cooked_obj uri CicUniv.empty_ugraph
+           in
+            match o with
               C.Constant _ -> raise ReferenceToConstant
             | C.CurrentProof _ -> raise ReferenceToCurrentProof
             | C.InductiveDefinition _ -> raise ReferenceToInductiveDefinition
@@ -585,7 +600,10 @@ if List.mem uri params then prerr_endline "---- OK2" ;
          C.Appl (List.append (List.map (unwind k e ens) l) s)
   *)
      | (k, e, ens, (C.Const (uri,exp_named_subst) as t), s) ->
-        (match CicEnvironment.get_obj uri with
+        (let o,_ = 
+          CicEnvironment.get_cooked_obj uri CicUniv.empty_ugraph 
+        in
+         match o with
             C.Constant (_,Some body,_,_) ->
              let ens' = push_exp_named_subst k e ens exp_named_subst in
               (* constants are closed *)
@@ -640,11 +658,14 @@ if List.mem uri params then prerr_endline "---- OK2" ;
               reduce (k, e, ens, (List.nth pl (j-1)), s)
            | C.Appl (C.MutConstruct (_,_,j,_) :: tl) ->
               let (arity, r) =
-               match CicEnvironment.get_obj mutind with
-                  C.InductiveDefinition (tl,ingredients,r) ->
-                    let (_,_,arity,_) = List.nth tl i in
-                     (arity,r)
-                | _ -> raise WrongUriToInductiveDefinition
+               let o,_ = 
+                 CicEnvironment.get_cooked_obj mutind CicUniv.empty_ugraph
+               in
+                 match o with
+                      C.InductiveDefinition (tl,ingredients,r) ->
+                       let (_,_,arity,_) = List.nth tl i in
+                         (arity,r)
+                    | _ -> raise WrongUriToInductiveDefinition
               in
                let ts =
                 let num_to_eat = r in
@@ -726,10 +747,22 @@ if List.mem uri params then prerr_endline "---- OK2" ;
      | (uri,t)::tl ->
          push_exp_named_subst k e ((uri,RS.to_ens (unwind k e ens t))::ens) tl
    in
-    reduce 
+     reduce 
   ;;
-  
-  let rec whd ?(subst=[]) context t = reduce ~subst context (0, [], [], t, []);;
+  (*
+  let rec whd context t = 
+    try 
+      reduce context (0, [], [], t, [])
+    with Not_found -> 
+      prerr_endline (CicPp.ppterm t) ; 
+      raise Not_found
+  ;;
+  *)
+
+  let rec whd ?(subst=[]) context t = 
+    reduce ~subst context (0, [], [], t, [])
+  ;;
+
   
 (* DEBUGGING ONLY
 let whd context t =
@@ -778,140 +811,210 @@ let whd = R.whd;;
 let (===) x y = (Pervasives.compare x y = 0)
 
 (* t1, t2 must be well-typed *)
-let are_convertible ?(subst=[]) ?(metasenv=[]) =
- let rec aux test_equality_only context t1 t2 =
-  let aux2 test_equality_only t1 t2 =
+let are_convertible ?(subst=[]) ?(metasenv=[])  =
+ let rec aux test_equality_only context t1 t2 ugraph =
+  let aux2 test_equality_only t1 t2 ugraph =
+
    (* this trivial euristic cuts down the total time of about five times ;-) *)
    (* this because most of the time t1 and t2 are "sintactically" the same   *)
    if t1 === t2 then
-    true
+     true,ugraph
    else
     begin
      let module C = Cic in
        match (t1,t2) with
-          (C.Rel n1, C.Rel n2) -> n1 = n2
+          (C.Rel n1, C.Rel n2) -> (n1 = n2),ugraph
         | (C.Var (uri1,exp_named_subst1), C.Var (uri2,exp_named_subst2)) ->
-            U.eq uri1 uri2 &&
+            if U.eq uri1 uri2 then
              (try
                List.fold_right2
-                (fun (uri1,x) (uri2,y) b ->
-                  U.eq uri1 uri2 && aux test_equality_only context x y && b
-                ) exp_named_subst1 exp_named_subst2 true 
+                (fun (uri1,x) (uri2,y) (b,ugraph) ->
+                  let b',ugraph' = aux test_equality_only context x y ugraph in
+                  (U.eq uri1 uri2 && b' && b),ugraph'
+                ) exp_named_subst1 exp_named_subst2 (true,ugraph) 
               with
-               Invalid_argument _ -> false
+               Invalid_argument _ -> false,ugraph
              )
+           else
+             false,ugraph
         | (C.Meta (n1,l1), C.Meta (n2,l2)) ->
-            n1 = n2 &&
-             let l1 = CicUtil.clean_up_local_context subst metasenv n1 l1 in
-             let l2 = CicUtil.clean_up_local_context subst metasenv n2 l2 in
-             List.fold_left2
-              (fun b t1 t2 ->
-                b &&
-                 match t1,t2 with
-                    None,_
-                  | _,None  -> true
-                  | Some t1',Some t2' -> aux test_equality_only context t1' t2'
-              ) true l1 l2
-         (* TASSI: CONSTRAINTS *)
+           if n1 = n2 then
+             let b2, ugraph1 = 
+               let l1 = CicUtil.clean_up_local_context subst metasenv n1 l1 in
+               let l2 = CicUtil.clean_up_local_context subst metasenv n2 l2 in
+                 List.fold_left2
+                   (fun (b,ugraph) t1 t2 ->
+                      if b then 
+                        match t1,t2 with
+                            None,_
+                          | _,None  -> true,ugraph
+                          | Some t1',Some t2' -> 
+                              aux test_equality_only context t1' t2' ugraph
+                      else
+                        false,ugraph
+                   ) (true,ugraph) l1 l2
+             in
+               if b2 then true,ugraph1 else false,ugraph 
+           else
+             false,ugraph
+          (* TASSI: CONSTRAINTS *)
        | (C.Sort (C.Type t1), C.Sort (C.Type t2)) when test_equality_only ->
-           CicUniv.add_eq t2 t1
+           true,(CicUniv.add_eq t2 t1 ugraph)
          (* TASSI: CONSTRAINTS *)
        | (C.Sort (C.Type t1), C.Sort (C.Type t2)) ->
-           CicUniv.add_ge t2 t1
+           true,(CicUniv.add_ge t2 t1 ugraph)
          (* TASSI: CONSTRAINTS *)
-       | (C.Sort s1, C.Sort (C.Type _)) -> not test_equality_only
+       | (C.Sort s1, C.Sort (C.Type _)) -> (not test_equality_only),ugraph
          (* TASSI: CONSTRAINTS *)
-        | (C.Sort s1, C.Sort s2) -> s1 = s2
-       | (C.Prod (name1,s1,t1), C.Prod(_,s2,t2)) ->
-           aux true context s1 s2 &&
-            aux test_equality_only ((Some (name1, (C.Decl s1)))::context) t1 t2
+        | (C.Sort s1, C.Sort s2) -> (s1 = s2),ugraph
+        | (C.Prod (name1,s1,t1), C.Prod(_,s2,t2)) ->
+           let b',ugraph' = aux true context s1 s2 ugraph in
+           if b' then 
+              aux test_equality_only ((Some (name1, (C.Decl s1)))::context) 
+               t1 t2 ugraph'
+           else
+             false,ugraph
         | (C.Lambda (name1,s1,t1), C.Lambda(_,s2,t2)) ->
-           aux test_equality_only context s1 s2 &&
-            aux test_equality_only ((Some (name1, (C.Decl s1)))::context) t1 t2
+           let b',ugraph' = aux test_equality_only context s1 s2 ugraph in
+           if b' then
+            aux test_equality_only ((Some (name1, (C.Decl s1)))::context) 
+              t1 t2 ugraph'
+          else
+            false,ugraph
         | (C.LetIn (name1,s1,t1), C.LetIn(_,s2,t2)) ->
-           aux test_equality_only context s1 s2 &&
+           let b',ugraph' = aux test_equality_only context s1 s2 ugraph in
+          if b' then
             aux test_equality_only
-             ((Some (name1, (C.Def (s1,None))))::context) t1 t2
+             ((Some (name1, (C.Def (s1,None))))::context) t1 t2 ugraph'
+          else
+            false,ugraph
         | (C.Appl l1, C.Appl l2) ->
            (try
              List.fold_right2
-              (fun  x y b -> aux test_equality_only context x y && b) l1 l2 true
+               (fun  x y (b,ugraph) -> 
+                if b then
+                  aux test_equality_only context x y ugraph
+                else
+                  false,ugraph) l1 l2 (true,ugraph)
             with
-             Invalid_argument _ -> false
+             Invalid_argument _ -> false,ugraph
            )
         | (C.Const (uri1,exp_named_subst1), C.Const (uri2,exp_named_subst2)) ->
-            U.eq uri1 uri2 &&
+            let b' = U.eq uri1 uri2 in
+           if b' then
              (try
                List.fold_right2
-                (fun (uri1,x) (uri2,y) b ->
-                  U.eq uri1 uri2 && aux test_equality_only context x y && b
-                ) exp_named_subst1 exp_named_subst2 true 
+                (fun (uri1,x) (uri2,y) (b,ugraph) ->
+                 if b && U.eq uri1 uri2 then
+                   aux test_equality_only context x y ugraph 
+                 else
+                   false,ugraph
+                ) exp_named_subst1 exp_named_subst2 (true,ugraph)
               with
-               Invalid_argument _ -> false
+               Invalid_argument _ -> false,ugraph
              )
+           else
+             false,ugraph
         | (C.MutInd (uri1,i1,exp_named_subst1),
            C.MutInd (uri2,i2,exp_named_subst2)
           ) ->
-            U.eq uri1 uri2 && i1 = i2 &&
+            let b' = U.eq uri1 uri2 && i1 = i2 in
+           if b' then
              (try
                List.fold_right2
-                (fun (uri1,x) (uri2,y) b ->
-                  U.eq uri1 uri2 && aux test_equality_only context x y && b
-                ) exp_named_subst1 exp_named_subst2 true 
+                (fun (uri1,x) (uri2,y) (b,ugraph) ->
+                  if b && U.eq uri1 uri2 then
+                   aux test_equality_only context x y ugraph
+                 else
+                  false,ugraph
+                ) exp_named_subst1 exp_named_subst2 (true,ugraph)
               with
-               Invalid_argument _ -> false
+               Invalid_argument _ -> false,ugraph
              )
+           else 
+             false,ugraph
         | (C.MutConstruct (uri1,i1,j1,exp_named_subst1),
            C.MutConstruct (uri2,i2,j2,exp_named_subst2)
           ) ->
-            U.eq uri1 uri2 && i1 = i2 && j1 = j2 &&
+            let b' = U.eq uri1 uri2 && i1 = i2 && j1 = j2 in
+           if b' then
              (try
                List.fold_right2
-                (fun (uri1,x) (uri2,y) b ->
-                  U.eq uri1 uri2 && aux test_equality_only context x y && b
-                ) exp_named_subst1 exp_named_subst2 true 
+                (fun (uri1,x) (uri2,y) (b,ugraph) ->
+                 if b && U.eq uri1 uri2 then
+                   aux test_equality_only context x y ugraph
+                 else
+                   false,ugraph
+                ) exp_named_subst1 exp_named_subst2 (true,ugraph)
               with
-               Invalid_argument _ -> false
+               Invalid_argument _ -> false,ugraph
              )
+           else
+             false,ugraph
         | (C.MutCase (uri1,i1,outtype1,term1,pl1),
            C.MutCase (uri2,i2,outtype2,term2,pl2)) -> 
-            U.eq uri1 uri2 && i1 = i2 &&
-             aux test_equality_only context outtype1 outtype2 &&
-             aux test_equality_only context term1 term2 &&
-             List.fold_right2
-              (fun x y b -> b && aux test_equality_only context x y)
-              pl1 pl2 true
+            let b' = U.eq uri1 uri2 && i1 = i2 in
+           if b' then
+             let b'',ugraph''=aux test_equality_only context 
+                outtype1 outtype2 ugraph in
+            if b'' then 
+              let b''',ugraph'''= aux test_equality_only context 
+                  term1 term2 ugraph'' in
+              List.fold_right2
+                (fun x y (b,ugraph) -> 
+                  if b then
+                    aux test_equality_only context x y ugraph 
+                  else 
+                    false,ugraph)
+                pl1 pl2 (true,ugraph''')
+            else
+              false,ugraph
+           else
+             false,ugraph
         | (C.Fix (i1,fl1), C.Fix (i2,fl2)) ->
-           let tys =
-            List.map (function (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl1
-           in
-            i1 = i2 &&
+            let tys =
+              List.map (function (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl1
+            in
+            if i1 = i2 then
              List.fold_right2
-              (fun (_,recindex1,ty1,bo1) (_,recindex2,ty2,bo2) b ->
-                b && recindex1 = recindex2 &&
-                 aux test_equality_only context ty1 ty2 &&
-                 aux test_equality_only (tys@context) bo1 bo2)
-              fl1 fl2 true
+              (fun (_,recindex1,ty1,bo1) (_,recindex2,ty2,bo2) (b,ugraph) ->
+                if b && recindex1 = recindex2 then
+                 let b',ugraph' = aux test_equality_only context ty1 ty2 
+                     ugraph in
+                 if b' then
+                   aux test_equality_only (tys@context) bo1 bo2 ugraph'
+                 else
+                   false,ugraph
+               else
+                 false,ugraph)
+            fl1 fl2 (true,ugraph)
+           else
+             false,ugraph
         | (C.CoFix (i1,fl1), C.CoFix (i2,fl2)) ->
            let tys =
             List.map (function (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl1
            in
-            i1 = i2 &&
-             List.fold_right2
-              (fun (_,ty1,bo1) (_,ty2,bo2) b ->
-                b && aux test_equality_only context ty1 ty2 &&
-                 aux test_equality_only (tys@context) bo1 bo2)
-              fl1 fl2 true
+            if i1 = i2 then
+              List.fold_right2
+              (fun (_,ty1,bo1) (_,ty2,bo2) (b,ugraph) ->
+               if b then
+                 let b',ugraph' = aux test_equality_only context ty1 ty2 
+                     ugraph in
+                 if b' then
+                   aux test_equality_only (tys@context) bo1 bo2 ugraph'
+                 else
+                   false,ugraph
+               else
+                 false,ugraph)
+            fl1 fl2 (true,ugraph)
+           else
+             false,ugraph
         | (C.Cast _, _) | (_, C.Cast _)
         | (C.Implicit _, _) | (_, C.Implicit _) ->
             assert false
-        | (_,_) -> false
+        | (_,_) -> false,ugraph
     end
   in
-(*
-   if aux2 test_equality_only t1 t2 then true
-   else
-*)
      begin
      debug t1 [t2] "PREWHD";
      (* 
@@ -925,8 +1028,9 @@ let are_convertible ?(subst=[]) ?(metasenv=[]) =
      let t1' = whd ~subst context t1 in
      let t2' = whd ~subst context t2 in
       debug t1' [t2'] "POSTWHD";
-      aux2 test_equality_only t1' t2'
+      aux2 test_equality_only t1' t2' ugraph
     end
  in
-  aux false
+  aux false (*c t1 t2 ugraph *)
 ;;
+