+
+let existselim t id1 t1 id2 t2 =
+(*BUG: t1 and t2 not used *)
+(*PARSING BUG: t2 is parsed in the current context, but it may
+ have occurrences of id1 in it *)
+ Tactics.elim_intros t
+ ~mk_fresh_name_callback:
+ (let i = ref 0 in
+ fun _ _ _ ~typ ->
+ incr i;
+ if !i = 1 then Cic.Name id1 else Cic.Name id2)
+
+let andelim = existselim;;
+
+let rewritingstep ~dbd lhs rhs just conclude =
+ let aux ((proof,goal) as status) =
+ let (curi,metasenv,proofbo,proofty) = proof in
+ let _,context,_ = CicUtil.lookup_meta goal metasenv in
+ let eq,trans =
+ match LibraryObjects.eq_URI () with
+ None -> raise (ProofEngineTypes.Fail (lazy "You need to register the default equality first. Please use the \"default\" command"))
+ | Some uri ->
+ Cic.MutInd (uri,0,[]), Cic.Const (LibraryObjects.trans_eq_URI ~eq:uri,[])
+ in
+ let ty,_ =
+ CicTypeChecker.type_of_aux' metasenv context rhs CicUniv.empty_ugraph in
+ let just =
+ match just with
+ None ->
+ Tactics.auto ~dbd
+ ~params:["paramodulation","on"; "timeout","3"]
+ | Some just -> Tactics.apply just
+ in
+ match lhs with
+ None ->
+ let plhs,prhs =
+ match
+ fst
+ (CicTypeChecker.type_of_aux' metasenv context (Cic.Rel 1)
+ CicUniv.empty_ugraph)
+ with
+ Cic.Appl [_;_;plhs;prhs] -> plhs,prhs
+ | _ -> assert false in
+ let last_hyp_name =
+ match context with
+ (Some (Cic.Name id,_))::_ -> id
+ | _ -> assert false
+ in
+ (match conclude with
+ None ->
+ ProofEngineTypes.apply_tactic
+ (Tacticals.thens
+ ~start:(Tactics.apply ~term:trans)
+ ~continuations:
+ [ Tactics.apply prhs ;
+ Tactics.apply (Cic.Rel 1) ;
+ just]) status
+ | Some name ->
+ let mk_fresh_name_callback =
+ fun metasenv context _ ~typ ->
+ FreshNamesGenerator.mk_fresh_name ~subst:[]
+ metasenv context name ~typ
+ in
+ ProofEngineTypes.apply_tactic
+ (Tacticals.thens
+ ~start:(Tactics.cut ~mk_fresh_name_callback
+ (Cic.Appl [eq ; ty ; plhs ; rhs]))
+ ~continuations:
+ [ Tactics.clear ~hyps:[last_hyp_name] ;
+ Tacticals.thens
+ ~start:(Tactics.apply ~term:trans)
+ ~continuations:
+ [ Tactics.apply prhs ;
+ Tactics.apply (Cic.Rel 1) ;
+ just]
+ ]) status)
+ | Some lhs ->
+ match conclude with
+ None -> ProofEngineTypes.apply_tactic just status
+ | Some name ->
+ let mk_fresh_name_callback =
+ fun metasenv context _ ~typ ->
+ FreshNamesGenerator.mk_fresh_name ~subst:[]
+ metasenv context name ~typ
+ in
+ ProofEngineTypes.apply_tactic
+ (Tacticals.thens
+ ~start:
+ (Tactics.cut ~mk_fresh_name_callback
+ (Cic.Appl [eq ; ty ; lhs ; rhs]))
+ ~continuations:[ Tacticals.id_tac ; just ]) status
+ in
+ ProofEngineTypes.mk_tactic aux
+;;
+
+let we_proceed_by_induction_on t pat =
+ (*BUG here: pat unused *)
+ Tactics.elim_intros ~depth:0 t
+;;
+
+let case id ~params =
+ (*BUG here: id unused*)
+ (*BUG here: it does not verify that the previous branch is closed *)
+ (*BUG here: the params should be parsed telescopically*)
+ (*BUG here: the tactic_terms should be terms*)
+ let rec aux ~params ((proof,goal) as status) =
+ match params with
+ [] -> proof,[goal]
+ | (id,t)::tl ->
+ match ProofEngineTypes.apply_tactic (assume id t) status with
+ proof,[goal] -> aux tl (proof,goal)
+ | _ -> assert false
+ in
+ ProofEngineTypes.mk_tactic (aux ~params)
+;;
+
+let thesisbecomes t =
+let ty = None in
+ (*BUG here: missing check on t *)
+ match ty with
+ None -> Tacticals.id_tac
+ | Some ty ->
+ Tactics.change ~pattern:(None,[],Some (Cic.Implicit (Some `Hole)))
+ (fun _ metasenv ugraph -> ty,metasenv,ugraph)
+;;
+
+let byinduction t id = suppose t id None;;