+ let curi, metasenv, pbo, pty = proof in
+ let (metano,context,gty) = CicUtil.lookup_meta goal metasenv in
+ match hyps_pat with
+ he::(_::_ as tl) ->
+ PET.apply_tactic
+ (Tacticals.then_
+ (rewrite_tac ~direction
+ ~pattern:(None,[he],None) equality)
+ (rewrite_tac ~direction ~pattern:(None,tl,concl_pat) equality)
+ ) status
+ | [_] as hyps_pat when concl_pat <> None ->
+ PET.apply_tactic
+ (Tacticals.then_
+ (rewrite_tac ~direction
+ ~pattern:(None,hyps_pat,None) equality)
+ (rewrite_tac ~direction ~pattern:(None,[],concl_pat) equality)
+ ) status
+ | _ ->
+ let arg,dir2,tac,concl_pat,gty =
+ match hyps_pat with
+ [] -> None,true,(fun ~term _ -> PT.exact_tac term),concl_pat,gty
+ | [name,pat] ->
+ let rec find_hyp n =
+ function
+ [] -> assert false
+ | Some (Cic.Name s,Cic.Decl ty)::_ when name = s ->
+ Cic.Rel n, CicSubstitution.lift n ty
+ | Some (Cic.Name s,Cic.Def _)::_ -> assert false (*CSC: not implemented yet! But does this make any sense?*)
+ | _::tl -> find_hyp (n+1) tl
+ in
+ let arg,gty = find_hyp 1 context in
+ let last_hyp_name_of_status (proof,goal) =
+ let curi, metasenv, pbo, pty = proof in
+ let metano,context,gty = CicUtil.lookup_meta goal metasenv in
+ match context with
+ (Some (Cic.Name s,_))::_ -> s
+ | _ -> assert false
+ in
+ let dummy = "dummy" in
+ Some arg,false,
+ (fun ~term typ ->
+ Tacticals.seq
+ ~tactics:
+ [ProofEngineStructuralRules.rename name dummy;
+ PT.letin_tac
+ ~mk_fresh_name_callback:(fun _ _ _ ~typ -> Cic.Name name) term;
+ ProofEngineStructuralRules.clearbody name;
+ ReductionTactics.change_tac
+ ~pattern:
+ (None,[name,Cic.Implicit (Some `Hole)], None)
+ (ProofEngineTypes.const_lazy_term typ);
+ ProofEngineStructuralRules.clear dummy
+ ]),
+ Some pat,gty
+ | _::_ -> assert false
+ in
+ let if_right_to_left do_not_change a b =