| 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)
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 =
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
;;