- (* aux function to add coercions to funclass *)
- let rec fix_arity metasenv context subst he hetype args_bo_and_ty ugraph =
- (* {{{ body *)
- let pristinemenv = metasenv in
- let metasenv,hetype' =
- mk_prod_of_metas metasenv context subst args_bo_and_ty
- in
- try
- let subst,metasenv,ugraph =
- fo_unif_subst_eat_prods
- subst context metasenv hetype hetype' ugraph
- in
- subst,metasenv,ugraph,hetype',he,args_bo_and_ty
- with RefineFailure s | Uncertain s as exn
- when allow_coercions && !insert_coercions ->
- (* {{{ we search a coercion of the head (saturated) to funclass *)
- let metasenv = pristinemenv in
- debug_print (lazy
- ("Fixing arity of: "^CicMetaSubst.ppterm ~metasenv subst hetype ^
- " since unif failed with: " ^ CicMetaSubst.ppterm ~metasenv subst hetype'
- (* ^ " cause: " ^ Lazy.force s *)));
- let how_many_args_are_needed =
- let rec aux n = function
- | Cic.Prod(_,_,t) -> aux (n+1) t
- | _ -> n
- in
- aux 0 (CicMetaSubst.apply_subst subst hetype)
- in
- let args, remainder =
- HExtlib.split_nth how_many_args_are_needed args_bo_and_ty
- in
- let args = List.map fst args in
- let x =
- if args <> [] then
- match he with
- | Cic.Appl l -> Cic.Appl (l@args)
- | _ -> Cic.Appl (he::args)
- else
- he
- in
- let x,xty,subst,metasenv,ugraph =
- (*CSC: here unsharing is necessary to avoid an unwanted
- relocalization. However, this also shows a great source of
- inefficiency: "x" is refined twice (once now and once in the
- subsequent eat_prods_and_args). Morevoer, how is divergence avoided?
- *)
- type_of_aux subst metasenv context (Unshare.unshare x) ugraph
- in
- let carr_src =
- CoercDb.coerc_carr_of_term (CicMetaSubst.apply_subst subst xty)
- in
- let carr_tgt = CoercDb.Fun 0 in
- match CoercGraph.look_for_coercion' metasenv subst context carr_src carr_tgt with
- | CoercGraph.NoCoercion
- | CoercGraph.NotMetaClosed
- | CoercGraph.NotHandled _ -> raise exn
- | CoercGraph.SomeCoercionToTgt candidates
- | CoercGraph.SomeCoercion candidates ->
- match
- HExtlib.list_findopt
- (fun (metasenv,last,coerc) ->
- let subst,metasenv,ugraph =
- fo_unif_subst subst context metasenv last x ugraph in
- debug_print (lazy ("Tentative " ^ CicMetaSubst.ppterm ~metasenv subst coerc));
- try
- (* we want this to be available in the error handler fo the
- * following (so it has its own try. *)
- let t,tty,subst,metasenv,ugraph =
- type_of_aux subst metasenv context coerc ugraph
- in
- try
- let metasenv, hetype' =
- mk_prod_of_metas metasenv context subst remainder
- in
- debug_print (lazy
- (" unif: " ^ CicMetaSubst.ppterm ~metasenv subst tty ^ " = " ^
- CicMetaSubst.ppterm ~metasenv subst hetype'));
- let subst,metasenv,ugraph =
- fo_unif_subst_eat_prods
- subst context metasenv tty hetype' ugraph
- in
- debug_print (lazy " success!");
- Some (subst,metasenv,ugraph,tty,t,remainder)
- with
- | Uncertain _ | RefineFailure _ ->
- try
- let subst,metasenv,ugraph,hetype',he,args_bo_and_ty =
- fix_arity
- metasenv context subst t tty remainder ugraph
- in
- Some (subst,metasenv,ugraph,hetype',he,args_bo_and_ty)
- with Uncertain _ | RefineFailure _ -> None
- with
- Uncertain _
- | RefineFailure _
- | HExtlib.Localized (_,Uncertain _)
- | HExtlib.Localized (_,RefineFailure _) -> None
- | exn -> assert false) (* ritornare None, e' un localized *)
- candidates
- with
- | Some(subst,metasenv,ugraph,hetype',he,args_bo_and_ty)->
- subst,metasenv,ugraph,hetype',he,args_bo_and_ty
- | None ->
- more_args_than_expected localization_tbl metasenv
- subst he context hetype args_bo_and_ty exn
- (* }}} end coercion to funclass stuff *)
- (* }}} end fix_arity *)
+ (* given he:hety, gives beack all (c he) such that (c e):?->? *)
+ let fix_arity exn metasenv context subst he hetype ugraph =
+ let hetype = CicMetaSubst.apply_subst subst hetype in
+ let src = CoercDb.coerc_carr_of_term hetype in
+ let tgt = CoercDb.Fun 0 in
+ match CoercGraph.look_for_coercion' metasenv subst context src tgt with
+ | CoercGraph.NoCoercion
+ | CoercGraph.NotMetaClosed
+ | CoercGraph.NotHandled _ -> raise exn
+ | CoercGraph.SomeCoercionToTgt candidates
+ | CoercGraph.SomeCoercion candidates ->
+ HExtlib.filter_map
+ (fun (metasenv,last,coerc) ->
+ let pp t =
+ CicMetaSubst.ppterm_in_context ~metasenv subst t context in
+ let subst,metasenv,ugraph =
+ fo_unif_subst subst context metasenv last he ugraph in
+ debug_print (lazy ("New head: "^ pp coerc));
+ try
+ let t,tty,subst,metasenv,ugraph =
+ type_of_aux subst metasenv context coerc ugraph in
+ (*{{{*)debug_print (lazy (" refined: "^ pp t));
+ debug_print (lazy (" has type: "^ pp tty));(*}}}*)
+ Some (t,tty,subst,metasenv,ugraph)
+ with
+ | Uncertain _ | RefineFailure _
+ | HExtlib.Localized (_,Uncertain _)
+ | HExtlib.Localized (_,RefineFailure _) -> None
+ | exn -> assert false)
+ candidates