]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/ocaml/cic_proof_checking/cicEnvironment.ml
Added universes handling. The PRE_UNIVERSES tag may help ;)
[helm.git] / helm / ocaml / cic_proof_checking / cicEnvironment.ml
index 0c5c9c01e9030259fff0591ca2a43260e347a84a..0f01a0a55d2f133ffae17a1eab5bd2a5c5641e8e 100644 (file)
  * http://cs.unibo.it/helm/.
  *)
 
-(******************************************************************************)
-(*                                                                            *)
-(*                               PROJECT HELM                                 *)
-(*                                                                            *)
-(*                Claudio Sacerdoti Coen <sacerdot@cs.unibo.it>               *)
-(*                                 24/01/2000                                 *)
-(*                                                                            *)
-(* This module implements a trival cache system (an hash-table) for cic       *)
-(* objects. Uses the getter (getter.ml) and the parser (cicParser.ml)         *)
-(*                                                                            *)
-(******************************************************************************)
+(*****************************************************************************)
+(*                                                                           *)
+(*                              PROJECT HELM                                 *)
+(*                                                                           *)
+(*               Claudio Sacerdoti Coen <sacerdot@cs.unibo.it>               *)
+(*                                24/01/2000                                 *)
+(*                                                                           *)
+(* This module implements a trival cache system (an hash-table) for cic      *)
+(* objects. Uses the getter (getter.ml) and the parser (cicParser.ml)        *)
+(*                                                                           *)
+(*****************************************************************************)
+
 
 let cleanup_tmp = true;;
 
@@ -42,7 +43,7 @@ let set_trust f = trust := f
 let trust_obj uri = !trust uri
 
 type type_checked_obj =
-   CheckedObj of Cic.obj     (* cooked obj *)
+   CheckedObj of (Cic.obj * CicUniv.universe_graph)    (* cooked obj *)
  | UncheckedObj of Cic.obj   (* uncooked obj to proof-check *)
 ;;
 
@@ -59,25 +60,44 @@ exception Term_not_found of UriManager.uri;;
 module Cache :
   sig
    val find_or_add_unchecked :
-    UriManager.uri -> get_object_to_add:(unit -> Cic.obj) -> Cic.obj
-   val unchecked_to_frozen : UriManager.uri -> unit
+     UriManager.uri -> 
+     get_object_to_add:(unit -> Cic.obj * CicUniv.universe_graph option) -> 
+     Cic.obj * CicUniv.universe_graph
+   val can_be_cooked:
+     UriManager.uri -> bool
+   val unchecked_to_frozen : 
+     UriManager.uri -> unit
    val frozen_to_cooked :
-    uri:UriManager.uri -> unit
-   val find_cooked : key:UriManager.uri -> Cic.obj
-   val add_cooked : key:UriManager.uri -> Cic.obj -> unit
+     uri:UriManager.uri -> unit
+   val hack_univ:
+     UriManager.uri -> CicUniv.universe_graph -> unit
+   val find_cooked : 
+     key:UriManager.uri -> Cic.obj * CicUniv.universe_graph
+   val add_cooked : 
+     key:UriManager.uri -> (Cic.obj * CicUniv.universe_graph) -> unit
+   val not_jet_cooked:
+     UriManager.uri -> Cic.obj * CicUniv.universe_graph
    val remove: UriManager.uri -> unit
 
    val dump_to_channel : ?callback:(string -> unit) -> out_channel -> unit
    val restore_from_channel : ?callback:(string -> unit) -> in_channel -> unit
    val empty : unit -> unit
+   val is_in_frozen: UriManager.uri -> bool
+   val is_in_unchecked: UriManager.uri -> bool
   end 
 =
   struct
+   (*************************************************************************
+     TASSI: invariant
+     The CacheOfCookedObjects will contain only objects with a valid universe
+     graph. valid means that non None (used if there is no universe file
+     in the universe generation phase).
+   **************************************************************************)
    module CacheOfCookedObjects :
     sig
      val mem  : UriManager.uri -> bool
-     val find : UriManager.uri -> Cic.obj
-     val add  : UriManager.uri -> Cic.obj -> unit
+     val find : UriManager.uri -> Cic.obj * CicUniv.universe_graph
+     val add  : UriManager.uri -> (Cic.obj * CicUniv.universe_graph) -> unit
      val remove : UriManager.uri -> unit
 
       (** (de)serialization of type checker cache *)
@@ -102,10 +122,9 @@ module Cache :
       with
        Not_found -> false
      ;;
-     let find uri = HT.find hashtable uri
-     ;;
-     let add uri obj =
-      HT.add hashtable uri obj
+     let find uri = HT.find hashtable uri ;;
+     let add uri (obj,ugraph) =
+       HT.add hashtable uri (obj,ugraph)
      ;;
      let remove uri =
        if mem uri then
@@ -127,7 +146,8 @@ module Cache :
              let uri' = recons uri in
              let exp_named_subst' =
               List.map
-               (function (uri,t) ->(recons uri,restore_in_term t)) exp_named_subst
+               (function (uri,t) ->(recons uri,restore_in_term t)) 
+               exp_named_subst
              in
               C.Var (uri',exp_named_subst')
           | C.Meta (i,l) ->
@@ -256,7 +276,12 @@ module Cache :
           callback (UriManager.string_of_uri k);
           HT.add hashtable
             (UriManager.uri_of_string (UriManager.string_of_uri k))
-            (restore_uris v))
+
+(************************************************
+   TASSI: FIXME add channel stuff for universes
+*************************************************)
+
+            ((restore_uris v),CicUniv.empty_ugraph))
         restored
      ;;
 
@@ -265,40 +290,119 @@ module Cache :
    let frozen_list = ref [];;
    let unchecked_list = ref [];;
 
+   let is_in_frozen uri =
+     List.mem_assoc uri !frozen_list
+   ;;
+   
+   let is_in_unchecked uri =
+     List.mem_assoc uri !unchecked_list
+   ;;
+   (*******************************************************************
+     TASSI: invariant
+     we need, in the universe generation phase, to traverse objects
+     that are not jet committed, so we search them in the frozen list.
+     Only uncommitted objects without a universe file (see the assertion) 
+     can be searched with method
+   *******************************************************************)
+   let not_jet_cooked uri =
+     try
+       let o,u = List.assoc uri !frozen_list in
+        match u with
+            None -> o, CicUniv.empty_ugraph
+          | Some _ -> assert false (* only univ_maker ca use this *)
+     with Not_found -> 
+       CacheOfCookedObjects.find uri
+   ;;
    let find_or_add_unchecked uri ~get_object_to_add =
-    try
-     List.assq uri !unchecked_list
-    with
-     Not_found ->
-      if List.mem_assq uri !frozen_list then
-       raise (CircularDependency (UriManager.string_of_uri uri))
-      else
-       if CacheOfCookedObjects.mem uri then
-        raise (AlreadyCooked (UriManager.string_of_uri uri))
-       else
-        (* OK, it is not already frozen nor cooked *)
-        let obj = get_object_to_add () in
-         unchecked_list := (uri,obj)::!unchecked_list ;
-         obj
+     try
+       let o,g = List.assq uri !unchecked_list in
+        match g with
+            None -> o,CicUniv.empty_ugraph
+          | Some g' -> o,g'
+     with
+        Not_found ->
+          if List.mem_assq uri !frozen_list then
+            begin
+              print_endline "\nCircularDependency!\nfrozen list: \n";
+              List.iter (
+                fun (u,(_,o)) ->
+                  let su = UriManager.string_of_uri u in
+                  let univ = if o = None then "NO_UNIV" else "" in
+                  print_endline (su^" "^univ)) 
+                !frozen_list;
+              raise (CircularDependency (UriManager.string_of_uri uri))
+            end
+          else
+            if CacheOfCookedObjects.mem uri then
+               raise (AlreadyCooked (UriManager.string_of_uri uri))
+            else
+               (* OK, it is not already frozen nor cooked *)
+               let obj,ugraph = get_object_to_add () in
+              let ugraph_real = 
+                match ugraph with
+                    None -> CicUniv.empty_ugraph
+                  | Some g -> g
+              in
+                unchecked_list := (uri,(obj,ugraph))::!unchecked_list ;
+                obj,ugraph_real
    ;;
    let unchecked_to_frozen uri =
     try
-     let obj = List.assq uri !unchecked_list in
+     let obj,ugraph = List.assq uri !unchecked_list in
       unchecked_list := List.remove_assq uri !unchecked_list ;
-      frozen_list := (uri,obj)::!frozen_list
+      frozen_list := (uri,(obj,ugraph))::!frozen_list
     with
      Not_found -> raise (CouldNotFreeze (UriManager.string_of_uri uri))
    ;;
+   (************************************************************
+     TASSI: invariant
+     only object with a valid universe graph can be committed
+   *************************************************************)
    let frozen_to_cooked ~uri =
     try
-     let obj = List.assq uri !frozen_list in
-      frozen_list := List.remove_assq uri !frozen_list ;
-       CacheOfCookedObjects.add uri obj
+      let obj,ugraph = List.assq uri !frozen_list in
+       match ugraph with
+           None -> 
+             assert false (* only non dummy universes can be committed *)
+         | Some g ->
+             frozen_list := List.remove_assq uri !frozen_list ;
+             CacheOfCookedObjects.add uri (obj,g)
     with
-     Not_found -> raise (CouldNotUnfreeze (UriManager.string_of_uri uri))
+       Not_found -> raise (CouldNotUnfreeze (UriManager.string_of_uri uri))
+   ;;
+   let can_be_cooked uri =
+     try
+       let obj,ugraph = List.assq uri !frozen_list in
+        match ugraph with
+            None -> false
+          | Some _ -> true
+     with
+        Not_found -> false
+   ;;
+   let hack_univ uri real_ugraph =
+     try
+       let o,g = List.assq uri !frozen_list in
+        match g with
+            None -> 
+              frozen_list := List.remove_assoc uri !frozen_list;
+              frozen_list := (uri,(o,Some real_ugraph))::!frozen_list;
+          | Some g -> 
+              prerr_endline (
+                "You are probably hacking an object already hacked or an"^
+                " object that has the universe file but is not"^
+                " jet committed");
+              assert false
+     with
+        Not_found -> 
+          prerr_endline (
+            "You are hacking an object that is not in the"^
+            " frozen_list, this means you are probably generating an"^
+            " universe file for an object that already as an universe file");
+          assert false
    ;;
    let find_cooked ~key:uri = CacheOfCookedObjects.find uri;;
-   let add_cooked ~key:uri obj = CacheOfCookedObjects.add uri obj;;
+   let add_cooked ~key:uri (obj,ugraph) = 
+     CacheOfCookedObjects.add uri (obj,ugraph);;
    let remove uri =
      if (!unchecked_list <> []) || (!frozen_list <> []) then
        failwith "CicEnvironment.remove while type checking"
@@ -307,7 +411,11 @@ module Cache :
    ;;
    let dump_to_channel = CacheOfCookedObjects.dump_to_channel;;
    let restore_from_channel = CacheOfCookedObjects.restore_from_channel;;
-   let empty = CacheOfCookedObjects.empty;;
+   let empty () = 
+     CacheOfCookedObjects.empty ();
+     unchecked_list := [] ;
+     frozen_list := []
+   ;;
   end
 ;;
 
@@ -333,112 +441,173 @@ let find_or_add_unchecked_to_cache uri =
             (* The body does not exist ==> we consider it an axiom *)
             None
      in
+
+       (* 
+          maybe this is not the right place to do this.. but I think
+         obj_of_xml is called only here 
+       *)
+     (* this brakes something : let _ = CicUniv.restart_numbering () in *)
+     let obj = CicParser.obj_of_xml filename bodyfilename in
+     let ugraph,filename_univ = 
+       (*
+       try 
+        let filename_univ = 
+          Http_getter.getxml' (
+            UriManager.uri_of_string (
+              (UriManager.string_of_uri uri) ^ ".univ")) 
+        in
+          (Some (CicUniv.ugraph_of_xml filename_univ),Some filename_univ)
+       with Failure s ->
+         
+        prerr_endline (
+          "WE HAVE NO UNIVERSE FILE FOR " ^ (UriManager.string_of_uri uri));
+        None,None
+        *)
+         (**********************************************
+           TASSI: should fail when universes will be ON
+         ***********************************************)
+         (Some CicUniv.empty_ugraph,None)
+     in
      let cleanup () =
-       if cleanup_tmp then
-        begin
-         if Sys.file_exists filename then Unix.unlink filename ;
-         match bodyfilename with
-            Some f -> if Sys.file_exists f then Unix.unlink f
-          | None -> ()
-        end ;
-      in
-      CicUniv.directly_to_env_begin ();
-      let obj =
-        try
-          CicParser.obj_of_xml filename bodyfilename
-        with exn ->
-          cleanup ();
-          raise exn
-      in
-      CicUniv.directly_to_env_end ();
-      cleanup ();
-       obj
-   )
+       Unix.unlink filename ;
+       begin
+        match filename_univ with
+            Some f -> Unix.unlink f
+           | None -> ()
+       end;
+       begin
+        match bodyfilename with
+            Some f -> Unix.unlink f
+          | None -> ()
+       end 
+     in
+       cleanup();
+       obj,ugraph)
 ;;
 
 (* set_type_checking_info uri                               *)
 (* must be called once the type-checking of uri is finished *)
 (* The object whose uri is uri is unfreezed                 *)
-let set_type_checking_info uri =
- Cache.frozen_to_cooked uri
+let set_type_checking_info ?(replace_ugraph=None) uri =
+  if Cache.can_be_cooked uri && replace_ugraph <> None then
+    invalid_arg (
+      "?replace_ugraph must be None if you are not committing an "^
+      "object that has an no universe graph associated "^
+      "(can happen only in the fase of universes graphs generation).");
+  if not (Cache.can_be_cooked uri) && replace_ugraph = None then
+    invalid_arg (
+      "?replace_ugraph must be (Some ugraph) when committing an object that "^
+      "has no associated universe graph. If this is in make_univ phase you "^
+      "should drop this exception and let univ_make commit thi object with "^
+      "proper arguments");
+  begin
+    match replace_ugraph with 
+       None -> ()
+      | Some g -> Cache.hack_univ uri g
+  end;
+  Cache.frozen_to_cooked uri
 ;;
 
+
 (* is_type_checked uri                                                *)
 (* CSC: commento falso ed obsoleto *)
 (* returns a CheckedObj if the term has been type-checked             *)
 (* otherwise it freezes the term for type-checking and returns
  it *)
 (* set_type_checking_info must be called to unfreeze the term         *)
-let is_type_checked ?(trust=true) uri =
+let is_type_checked ?(trust=true) uri base_univ =
  try
-  CheckedObj (Cache.find_cooked uri)
+   let o,u = Cache.find_cooked uri in
+     CheckedObj (o,CicUniv.merge_ugraphs u base_univ)
  with
-  Not_found ->
-   let obj = find_or_add_unchecked_to_cache uri in
-    Cache.unchecked_to_frozen uri ;
-    if trust && trust_obj uri then
-     begin
-      CicLogger.log (`Trusting uri) ;
-      set_type_checking_info uri ;
-      CheckedObj (Cache.find_cooked uri)
-     end
-    else
-     UncheckedObj obj
+     Not_found ->
+       let obj,ugraph = find_or_add_unchecked_to_cache uri in
+        Cache.unchecked_to_frozen uri ;
+        if trust && trust_obj uri then
+          begin
+            CicLogger.log (`Trusting uri) ;
+            set_type_checking_info uri  ;
+            let o,u = Cache.find_cooked uri in
+            let u' = CicUniv.merge_ugraphs base_univ ugraph in
+              CheckedObj (o,u')
+          end
+        else
+          begin
+            UncheckedObj obj
+          end
 ;;
 
 (* get_cooked_obj ~trust uri *)
 (* returns the object if it is already type-checked or if it can be *)
 (* trusted (if [trust] = true and the trusting function accepts it) *)
 (* Otherwise it raises Not_found                                    *)
-let get_cooked_obj ?(trust=true) uri =
+let get_cooked_obj ?(trust=true) uri base_univ =
  try
-  Cache.find_cooked uri
+   let o,u = Cache.find_cooked uri in
+     o,(CicUniv.merge_ugraphs base_univ u)
  with Not_found ->
   if trust && trust_obj uri then
    begin
-    match is_type_checked uri with
-       CheckedObj obj -> obj
-     | _ -> assert false
+    match is_type_checked uri base_univ with
+       CheckedObj (obj,ugraph) -> obj,(CicUniv.merge_ugraphs ugraph base_univ)
+      | _ -> assert false
    end
   else
-   begin
-    prerr_endline ("@@@ OOOOOOOPS: get_cooked_obj(" ^ UriManager.string_of_uri uri ^ ") raises Not_found since the object is not type-checked nor trusted.") ;
-    raise Not_found
-   end
+    begin 
+      prerr_endline (
+       "@@@ OOOOOOOPS: get_cooked_obj(" ^ UriManager.string_of_uri uri ^ 
+       ") raises Not_found since the object is not type-checked"^
+       " nor trusted.");
+      raise Not_found 
+    end
 ;;
 
-(* get_obj uri                                                                *)
-(* returns the cic object whose uri is uri. If the term is not just in cache, *)
-(* then it is parsed via CicParser.term_of_xml from the file whose name is    *)
-(* the result of Getter.getxml uri                                            *)
-let get_obj uri =
- try
-  get_cooked_obj uri
- with
-  Not_found ->
-   find_or_add_unchecked_to_cache uri
+(* get_obj uri                                                               *)
+(* returns the cic object whose uri is uri. If the term is not just in cache,*)
+(* then it is parsed via CicParser.term_of_xml from the file whose name is   *)
+(* the result of Getter.getxml uri                                           *)
+let get_obj ?(not_jet_cooked=false) uri base_univ =
+  if not_jet_cooked then
+    let o,u = Cache.not_jet_cooked uri in
+      o,(CicUniv.merge_ugraphs base_univ u)
+  else
+    try
+      get_cooked_obj uri base_univ
+    with
+       Not_found ->
+         let s = ( UriManager.string_of_uri uri) in
+         let o,u = find_or_add_unchecked_to_cache uri in
+           o,(CicUniv.merge_ugraphs base_univ u)
 ;; 
 
 exception OnlyPutOfInductiveDefinitionsIsAllowed
 
-let put_inductive_definition uri obj =
+let put_inductive_definition uri (obj,ugraph) =
  match obj with
-    Cic.InductiveDefinition _ -> Cache.add_cooked uri obj
+    Cic.InductiveDefinition _ -> Cache.add_cooked uri (obj,ugraph)
   | _ -> raise OnlyPutOfInductiveDefinitionsIsAllowed
 ;;
 
 let in_cache uri = 
  try
-  ignore (Cache.find_cooked uri);true
- with Not_found -> false
+   ignore (Cache.find_cooked uri);
+   prerr_endline "TROVATO NELLA CHECKED";true
+ with Not_found -> 
+   if Cache.is_in_frozen uri then
+     (prerr_endline "TROVATO NELLA FROZEN";true)
+   else
+     if Cache.is_in_unchecked uri then
+       (prerr_endline "TROVATO NELLA UNCHECKED";true)
+     else
+       (prerr_endline ("NON TROVATO:" ^ (UriManager.string_of_uri uri) );false)
 ;;
 
-let add_type_checked_term uri obj =
+let add_type_checked_term uri (obj,ugraph) =
   match obj with 
-  Cic.Constant (s,(Some bo),ty,ul) ->
-    Cache.add_cooked ~key:uri obj
-  | _ -> assert false 
-  Cache.add_cooked 
+      Cic.Constant (s,(Some bo),ty,ul) ->
+       Cache.add_cooked ~key:uri (obj,ugraph)
+    | _ -> 
+       assert false 
 ;;
 
 let remove_term = Cache.remove