]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/software/components/grafite_engine/nCicCoercDeclaration.ml
fixed coercion mechanism w.r.t. undo/require
[helm.git] / helm / software / components / grafite_engine / nCicCoercDeclaration.ml
index 141ae369e226ed0f5c2d60de59b5ab23a6babfd5..550cb93c4a10394ffcdd7ecc74146d416de77cfb 100644 (file)
@@ -130,14 +130,61 @@ let only_head = function
   | t -> t
 ;;
 
-let basic_eval_ncoercion (name,t,s,d,p,a) status =
-  let to_s = 
-    NCicCoercion.look_for_coercion status [] [] [] skel_dummy s
+let src_tgt_cpos_arity_of_ty_id_src_tgt status ty id src tgt =
+  let status, src, cpos = 
+    let rec aux cpos ctx = function
+      | NCic.Prod (name,ty,bo) ->
+         if name <> id then aux (cpos+1) ((name,NCic.Decl ty)::ctx) bo
+         else
+           (try 
+            let metasenv,subst,status,src =
+              GrafiteDisambiguate.disambiguate_nterm 
+                None status ctx [] [] ("",0,src) in
+            let src = NCicUntrusted.apply_subst subst [] src in
+            (* CHECK that the declared pattern matches the abstraction *)
+            let _ = NCicUnification.unify status metasenv subst ctx ty src in
+            let src = cleanup_skel () src in
+            status, src, cpos
+           with 
+           | NCicUnification.UnificationFailure _
+           | NCicUnification.Uncertain _
+           | MultiPassDisambiguator.DisambiguationError _ ->
+               raise (GrafiteTypes.Command_error "bad source pattern"))
+      | _ -> assert false
+    in
+      aux 0 [] ty
   in
-  let from_d = 
-    NCicCoercion.look_for_coercion status [] [] [] d skel_dummy
+  let status, tgt, arity = 
+    let metasenv,subst,status,tgt =
+      GrafiteDisambiguate.disambiguate_nterm 
+        None status [] [] [] ("",0,tgt) in
+    let tgt = NCicUntrusted.apply_subst subst [] tgt in
+    (* CHECK che sia unificabile mancante *)
+    let rec count_prod = function
+      | NCic.Prod (_,_,x) -> 1 + count_prod x
+      | _ -> 0
+    in
+    let arity = count_prod tgt in
+    let tgt=
+      if arity > 0 then cleanup_funclass_skel tgt 
+      else cleanup_skel () tgt 
+    in
+     status, tgt, arity
   in
-  let status = NCicCoercion.index_coercion status name t s d a p in
+  status, src, tgt, cpos, arity
+;;
+
+let fresh_uri status prefix suffix = 
+  let mk x = NUri.uri_of_string (status#baseuri ^ "/" ^ prefix ^ x ^ suffix) in
+  let rec diverge u i =
+    if NCicLibrary.aliases_of u = [] then u
+    else diverge (mk ("__" ^ string_of_int i)) (i+1)
+  in
+   diverge (mk "") 0
+;;
+
+
+let close_graph name t s d to_s from_d p a status =
   let c =
     List.find 
      (function (_,_,NCic.Appl (x::_),_,_) -> x = t | _ -> assert false) 
@@ -194,86 +241,77 @@ let basic_eval_ncoercion (name,t,s,d,p,a) status =
            NCicPp.ppterm ~metasenv:[] ~subst:[] ~context:[] src ^ " ===> " ^
            NCicPp.ppterm ~metasenv:[] ~subst:[] ~context:[] tgt ^
            " cpos=" ^ string_of_int pos ^ " arity=" ^ string_of_int arity));
-         Some (name,bo,src,tgt,arity,pos)
+         let uri = fresh_uri status name ".con" in
+         let obj_kind = NCic.Constant 
+           ([],name,Some bo,ty,(`Generated,`Definition,`Coercion arity)) 
+         in
+         let height = NCicTypeChecker.height_of_obj_kind uri [] obj_kind in
+         let obj = uri,height,[],[],obj_kind in
+         let c = 
+           NCic.Const 
+             (NReference.reference_of_spec uri (NReference.Def height))
+         in
+         Some (obj,name,c,src,tgt,pos,arity)
        with 
        | NCicTypeChecker.TypeCheckerFailure _
        | NCicUnification.UnificationFailure _ 
        | NCicUnification.Uncertain _ -> None
      ) composites
   in
+    composites
+;;
+
+(* idempotent *)
+let basic_index_ncoercion (name,t,s,d,position,arity) status =
+  NCicCoercion.index_coercion status name t s d arity position
+;;
+
+let basic_eval_ncoercion (name,t,s,d,p,a) status =
+  let to_s = 
+    NCicCoercion.look_for_coercion status [] [] [] skel_dummy s
+  in
+  let from_d = 
+    NCicCoercion.look_for_coercion status [] [] [] d skel_dummy
+  in
+  let status = NCicCoercion.index_coercion status name t s d a p in
+  let composites = close_graph name t s d to_s from_d p a status in
   List.fold_left 
-    (fun st (name,t,s,d,a,p) -> NCicCoercion.index_coercion st name t s d a p) 
-    status composites
+    (fun (uris,infos,st) ((uri,_,_,_,_ as obj),name,t,s,d,p,a) -> 
+      let info = name,t,s,d,p,a in
+      let st = NCicLibrary.add_obj st obj in
+      let st = basic_index_ncoercion info st in
+      uri::uris, info::infos, st)
+    ([],[],status) composites
 ;;
 
-let inject_ncoercion =
- let basic_eval_ncoercion (name,t,s,d,p,a) ~refresh_uri_in_universe
-  ~refresh_uri_in_term
- =
+let record_ncoercion =
+ let aux (name,t,s,d,p,a) ~refresh_uri_in_universe ~refresh_uri_in_term =
   let t = refresh_uri_in_term t in
   let s = refresh_uri_in_term s in
   let d = refresh_uri_in_term d in
-   basic_eval_ncoercion (name,t,s,d,p,a)
+   basic_index_ncoercion (name,t,s,d,p,a)
  in
-  NRstatus.Serializer.register "ncoercion" basic_eval_ncoercion
-;;
-
-let src_tgt_cpos_arity_of_ty_id_src_tgt status ty id src tgt =
-  let status, src, cpos = 
-    let rec aux cpos ctx = function
-      | NCic.Prod (name,ty,bo) ->
-         if name <> id then aux (cpos+1) ((name,NCic.Decl ty)::ctx) bo
-         else
-           (try 
-            let metasenv,subst,status,src =
-              GrafiteDisambiguate.disambiguate_nterm 
-                None status ctx [] [] ("",0,src) in
-            let src = NCicUntrusted.apply_subst subst [] src in
-            (* CHECK that the declared pattern matches the abstraction *)
-            let _ = NCicUnification.unify status metasenv subst ctx ty src in
-            let src = cleanup_skel () src in
-            status, src, cpos
-           with 
-           | NCicUnification.UnificationFailure _
-           | NCicUnification.Uncertain _
-           | MultiPassDisambiguator.DisambiguationError _ ->
-               raise (GrafiteTypes.Command_error "bad source pattern"))
-      | _ -> assert false
-    in
-      aux 0 [] ty
-  in
-  let status, tgt, arity = 
-    let metasenv,subst,status,tgt =
-      GrafiteDisambiguate.disambiguate_nterm 
-        None status [] [] [] ("",0,tgt) in
-    let tgt = NCicUntrusted.apply_subst subst [] tgt in
-    (* CHECK che sia unificabile mancante *)
-    let rec count_prod = function
-      | NCic.Prod (_,_,x) -> 1 + count_prod x
-      | _ -> 0
-    in
-    let arity = count_prod tgt in
-    let tgt=
-      if arity > 0 then cleanup_funclass_skel tgt 
-      else cleanup_skel () tgt 
-    in
-     status, tgt, arity
-  in
-  status, src, tgt, cpos, arity
+ let aux_l l ~refresh_uri_in_universe ~refresh_uri_in_term =
+   List.fold_right (aux ~refresh_uri_in_universe ~refresh_uri_in_term) l
+ in
+  NRstatus.Serializer.register "ncoercion" aux_l
 ;;
 
-let basic_eval_and_inject_ncoercion infos status =
- let status = basic_eval_ncoercion infos status in
- let dump = inject_ncoercion infos::status#dump in
-  status#set_dump dump
+let basic_eval_and_record_ncoercion infos status =
+ let uris, cinfos, status = basic_eval_ncoercion infos status in
+ let dump = record_ncoercion (infos::cinfos) :: status#dump in
+  status#set_dump dump, uris
 ;;
 
-let basic_eval_and_inject_ncoercion_from_t_cpos_arity 
+let basic_eval_and_record_ncoercion_from_t_cpos_arity 
       status (name,t,cpos,arity) 
 =
   let ty = NCicTypeChecker.typeof ~subst:[] ~metasenv:[] [] t in
   let src,tgt = src_tgt_of_ty_cpos_arity ty cpos arity in
-  basic_eval_and_inject_ncoercion (name,t,src,tgt,cpos,arity) status
+  let status, uris =
+   basic_eval_and_record_ncoercion (name,t,src,tgt,cpos,arity) status
+  in
+   status,`New uris
 ;;
 
 let eval_ncoercion status name t ty (id,src) tgt = 
@@ -289,9 +327,9 @@ let eval_ncoercion status name t ty (id,src) tgt =
 
  let status, src, tgt, cpos, arity = 
    src_tgt_cpos_arity_of_ty_id_src_tgt status ty id src tgt in
- let status =
-  basic_eval_and_inject_ncoercion (name,t,src,tgt,cpos,arity) status
+ let status, uris =
+  basic_eval_and_record_ncoercion (name,t,src,tgt,cpos,arity) status
  in
-  status,`New []
+  status,`New uris
 ;;