- (* newmeta is the lowest index of the new metas introduced *)
- let (consthead,newmetas,arguments,_) =
- new_metasenv_for_apply newmeta' proof context termty
- in
- let newmetasenv = metasenv'@newmetas in
- let subst,newmetasenv' =
- CicUnification.fo_unif newmetasenv context consthead ty
- in
- let in_subst_domain i = List.exists (function (j,_) -> i=j) subst in
- let apply_subst = CicMetaSubst.apply_subst subst in
- let old_uninstantiatedmetas,new_uninstantiatedmetas =
- (* subst_in doesn't need the context. Hence the underscore. *)
- let subst_in _ = CicMetaSubst.apply_subst subst in
- classify_metas newmeta in_subst_domain subst_in newmetasenv'
- in
- let bo' =
- apply_subst
- (if List.length newmetas = 0 then
- term'
- else
- Cic.Appl (term'::arguments)
- )
- in
- let newmetasenv'' = new_uninstantiatedmetas@old_uninstantiatedmetas in
- let (newproof, newmetasenv''') =
- let subst_in =
- CicMetaSubst.apply_subst ((metano,(context, bo'))::subst)
- in
- subst_meta_and_metasenv_in_proof
- proof metano subst_in newmetasenv''
- in
- (newproof, List.map (function (i,_,_) -> i) new_uninstantiatedmetas)
+ let subst,newmetasenv',t =
+ try
+ new_metasenv_and_unify_and_t newmeta' metasenv' proof context term' ty
+ termty
+ with CicUnification.UnificationFailure _ ->
+ new_metasenv_and_unify_and_t newmeta' metasenv' proof context term' ty
+ (CicReduction.whd context termty)
+ in
+ let in_subst_domain i = List.exists (function (j,_) -> i=j) subst in
+ let apply_subst = CicMetaSubst.apply_subst subst in
+ let old_uninstantiatedmetas,new_uninstantiatedmetas =
+ (* subst_in doesn't need the context. Hence the underscore. *)
+ let subst_in _ = CicMetaSubst.apply_subst subst in
+ classify_metas newmeta in_subst_domain subst_in newmetasenv'
+ in
+ let bo' = apply_subst t in
+ let newmetasenv'' = new_uninstantiatedmetas@old_uninstantiatedmetas in
+ let subst_in =
+ (* if we just apply the subtitution, the type is irrelevant:
+ we may use Implicit, since it will be dropped *)
+ CicMetaSubst.apply_subst ((metano,(context,bo',Cic.Implicit None))::subst)
+ in
+ let (newproof, newmetasenv''') =
+ subst_meta_and_metasenv_in_proof proof metano subst_in newmetasenv''
+ in
+ (subst_in,
+ (newproof,
+ List.map (function (i,_,_) -> i) new_uninstantiatedmetas))
+
+let apply_tac ~term status = snd (apply_tac_verbose ~term status)
+
+let apply_tac_verbose ~term status =
+ try
+ apply_tac_verbose ~term status
+ (* TODO cacciare anche altre eccezioni? *)
+ with CicUnification.UnificationFailure _ as e ->
+ raise (Fail (Printexc.to_string e))