aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Herbelin2014-08-17 17:16:58 +0200
committerHugo Herbelin2014-08-18 18:56:38 +0200
commitb6c3f54d04ce441ac68ffabfca69c18847707518 (patch)
tree6921f4ecb293e06ecaa0f13ed7deaceeaf194d76
parent287d6f88b78634561fff65d32eeb501f12440df8 (diff)
A reorganization of the "assert" tactics (hopefully uniform naming
scheme, redundancies, possibility of chaining a tactic knowing the name of introduced hypothesis, new proof engine).
-rw-r--r--dev/doc/changes.txt3
-rw-r--r--plugins/cc/cctac.ml8
-rw-r--r--plugins/decl_mode/decl_proof_instr.ml2
-rw-r--r--plugins/funind/functional_principles_proofs.ml2
-rw-r--r--plugins/funind/g_indfun.ml42
-rw-r--r--plugins/funind/recdef.ml4
-rw-r--r--tactics/contradiction.ml36
-rw-r--r--tactics/equality.ml5
-rw-r--r--tactics/inv.ml2
-rw-r--r--tactics/rewrite.ml9
-rw-r--r--tactics/tactics.ml158
-rw-r--r--tactics/tactics.mli62
-rw-r--r--test-suite/success/apply.v7
13 files changed, 159 insertions, 141 deletions
diff --git a/dev/doc/changes.txt b/dev/doc/changes.txt
index 4ea33ddbea..cea4cf1224 100644
--- a/dev/doc/changes.txt
+++ b/dev/doc/changes.txt
@@ -91,6 +91,9 @@
"intros_pattern" and "intros_patterns" is not anymore behaving like
tactic "intros" on the empty list.
+- API of cut tactics changed: cut_intro should be replaced by
+ "enough_tac Anonymous"
+
=========================================
= CHANGES BETWEEN COQ V8.3 AND COQ V8.4 =
=========================================
diff --git a/plugins/cc/cctac.ml b/plugins/cc/cctac.ml
index 3151a7ec75..1383d86033 100644
--- a/plugins/cc/cctac.ml
+++ b/plugins/cc/cctac.ml
@@ -328,7 +328,7 @@ let refute_tac c t1 t2 p =
let neweq= new_app_global _eq [|intype;tt1;tt2|] in
let hid = Tacmach.New.of_old (pf_get_new_id (Id.of_string "Heq")) gl in
let false_t=mkApp (c,[|mkVar hid|]) in
- Tacticals.New.tclTHENS (neweq (assert_tac (Name hid)))
+ Tacticals.New.tclTHENS (neweq (assert_before (Name hid)))
[proof_tac p; simplest_elim false_t]
end
@@ -347,7 +347,7 @@ let convert_to_goal_tac c t1 t2 p =
let x = Tacmach.New.of_old (pf_get_new_id (Id.of_string "X")) gl in
let identity=mkLambda (Name x,sort,mkRel 1) in
let endt=app_global _eq_rect [|sort;tt1;identity;c;tt2;mkVar e|] in
- Tacticals.New.tclTHENS (neweq (assert_tac (Name e)))
+ Tacticals.New.tclTHENS (neweq (assert_before (Name e)))
[proof_tac p; Proofview.V82.tactic (endt refine_exact_check)]
end
@@ -356,7 +356,7 @@ let convert_to_hyp_tac c1 t1 c2 t2 p =
let tt2=constr_of_term t2 in
let h = Tacmach.New.of_old (pf_get_new_id (Id.of_string "H")) gl in
let false_t=mkApp (c2,[|mkVar h|]) in
- Tacticals.New.tclTHENS (assert_tac (Name h) tt2)
+ Tacticals.New.tclTHENS (assert_before (Name h) tt2)
[convert_to_goal_tac c1 t1 t2 p;
simplest_elim false_t]
end
@@ -389,7 +389,7 @@ let discriminate_tac (cstr,u as cstru) p =
[|outtype;trivial;pred;identity;concl;injt|] k) in
let neweq=new_app_global _eq [|intype;t1;t2|] in
Tacticals.New.tclTHEN (Proofview.V82.tclEVARS evm)
- (Tacticals.New.tclTHENS (neweq (assert_tac (Name hid)))
+ (Tacticals.New.tclTHENS (neweq (assert_before (Name hid)))
[proof_tac p; Proofview.V82.tactic (endt refine_exact_check)])
end
diff --git a/plugins/decl_mode/decl_proof_instr.ml b/plugins/decl_mode/decl_proof_instr.ml
index 702d554fc5..5e915228e4 100644
--- a/plugins/decl_mode/decl_proof_instr.ml
+++ b/plugins/decl_mode/decl_proof_instr.ml
@@ -109,7 +109,7 @@ let clean_tmp gls =
clean_all (tmp_ids gls) gls
let assert_postpone id t =
- assert_tac (Name id) t
+ assert_before (Name id) t
(* start a proof *)
diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml
index 7f0db547d3..aba93de479 100644
--- a/plugins/funind/functional_principles_proofs.ml
+++ b/plugins/funind/functional_principles_proofs.ml
@@ -448,7 +448,7 @@ let clean_hyp_with_heq ptes_infos eq_hyps hyp_id env sigma =
in
(* observe_tac "rec hyp " *)
(tclTHENS
- (Proofview.V82.of_tactic (assert_tac (Name rec_pte_id) t_x))
+ (Proofview.V82.of_tactic (assert_before (Name rec_pte_id) t_x))
[
(* observe_tac "prove rec hyp" *) (prove_rec_hyp eq_hyps);
(* observe_tac "prove rec hyp" *)
diff --git a/plugins/funind/g_indfun.ml4 b/plugins/funind/g_indfun.ml4
index 5fa689f000..1d63fe01a9 100644
--- a/plugins/funind/g_indfun.ml4
+++ b/plugins/funind/g_indfun.ml4
@@ -324,7 +324,7 @@ let poseq_unsafe idunsafe cstr gl =
tclTHEN
(Proofview.V82.of_tactic (Tactics.letin_tac None (Name idunsafe) cstr None Locusops.allHypsAndConcl))
(tclTHENFIRST
- (Proofview.V82.of_tactic (Tactics.assert_tac Anonymous (mkEq typ (mkVar idunsafe) cstr)))
+ (Proofview.V82.of_tactic (Tactics.assert_before Anonymous (mkEq typ (mkVar idunsafe) cstr)))
(Proofview.V82.of_tactic Tactics.reflexivity))
gl
diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml
index ff35c98124..8602f0a527 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -1059,7 +1059,7 @@ let termination_proof_header is_mes input_type ids args_id relation
(tclTHENS
(observe_tac
(str "first assert")
- (Proofview.V82.of_tactic (assert_tac
+ (Proofview.V82.of_tactic (assert_before
(Name wf_rec_arg)
(mkApp (delayed_force acc_rel,
[|input_type;relation;mkVar rec_arg_id|])
@@ -1071,7 +1071,7 @@ let termination_proof_header is_mes input_type ids args_id relation
tclTHENS
(observe_tac
(str "second assert")
- (Proofview.V82.of_tactic (assert_tac
+ (Proofview.V82.of_tactic (assert_before
(Name wf_thm)
(mkApp (delayed_force well_founded,[|input_type;relation|]))
))
diff --git a/tactics/contradiction.ml b/tactics/contradiction.ml
index 96e8e60bba..4a43b8038e 100644
--- a/tactics/contradiction.ml
+++ b/tactics/contradiction.ml
@@ -18,24 +18,26 @@ open Misctypes
(* Absurd *)
-let absurd c gls =
- let env = pf_env gls and sigma = project gls in
- let j = Retyping.get_judgment_of env sigma c in
- let sigma, j = Coercion.inh_coerce_to_sort Loc.ghost env sigma j in
- let c = j.Environ.utj_val in
- (tclTHENS
- (tclTHEN (Proofview.V82.of_tactic (elim_type (build_coq_False ()))) (Proofview.V82.of_tactic (cut c)))
- ([(tclTHENS
- (Proofview.V82.of_tactic (cut (mkApp(build_coq_not (),[|c|]))))
- ([(tclTHEN (Proofview.V82.of_tactic intros)
- ((fun gl ->
- let ida = pf_nth_hyp_id gl 1
- and idna = pf_nth_hyp_id gl 2 in
- exact_no_check (mkApp(mkVar idna,[|mkVar ida|])) gl)));
- tclIDTAC]));
- tclIDTAC])) { gls with Evd.sigma; }
+let mk_absurd_proof t =
+ let id = Namegen.default_dependent_ident in
+ mkLambda (Names.Name id,mkApp(build_coq_not (),[|t|]),
+ mkLambda (Names.Name id,t,mkApp (mkRel 2,[|mkRel 1|])))
-let absurd c = Proofview.V82.tactic (absurd c)
+let absurd c =
+ Proofview.Goal.raw_enter begin fun gl ->
+ let env = Proofview.Goal.env gl in
+ let sigma = Proofview.Goal.sigma gl in
+ let j = Retyping.get_judgment_of env sigma c in
+ let sigma, j = Coercion.inh_coerce_to_sort Loc.ghost env sigma j in
+ let t = j.Environ.utj_val in
+ Tacticals.New.tclTHENLIST [
+ Proofview.V82.tclEVARS sigma;
+ elim_type (build_coq_False ());
+ Simple.apply (mk_absurd_proof t)
+ ]
+ end
+
+let absurd c = absurd c
(* Contradiction *)
diff --git a/tactics/equality.ml b/tactics/equality.ml
index 5f8e9f5030..28017f8533 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -907,7 +907,7 @@ let discr_positions env sigma (lbeq,eqn,(t,t1,t2)) eq_clause cpath dirn sort =
let pf = Clenvtac.clenv_value_cast_meta absurd_clause in
Proofview.V82.tclEVARS sigma <*>
Proofview.tclEFFECTS eff <*>
- tclTHENS (cut_intro absurd_term)
+ tclTHENS (assert_after Anonymous absurd_term)
[onLastHypId gen_absurdity; (Proofview.V82.tactic (refine pf))]
let discrEq (lbeq,_,(t,t1,t2) as u) eq_clause =
@@ -1514,7 +1514,8 @@ let cutSubstInHyp_LR eqn id =
if not (dependent (mkRel 1) body) then raise NothingToRewrite;
let refine = Proofview.V82.tactic (fun gl -> Tacmach.refine_no_check (mkVar id) gl) in
let subst = tclTHENFIRST (bareRevSubstInConcl (lbeq,u) body eq) refine in
- Proofview.V82.tclEVARS sigma <*> (cut_replacing id expected_goal subst)
+ Proofview.V82.tclEVARS sigma <*>
+ tclTHENLAST (assert_after_replacing id expected_goal) subst
end
let cutSubstInHyp_RL eqn id =
diff --git a/tactics/inv.ml b/tactics/inv.ml
index 45f416c2cf..089fef4bc9 100644
--- a/tactics/inv.ml
+++ b/tactics/inv.ml
@@ -483,7 +483,7 @@ let raw_inversion inv_kind id status names =
let neqns = List.length realargs in
tclTHEN (Proofview.V82.tclEVARS sigma)
(tclTHENS
- (assert_tac Anonymous cut_concl)
+ (assert_before Anonymous cut_concl)
[case_tac names
(introCaseAssumsThen (rewrite_equations_tac inv_kind id neqns))
(Some elim_predicate) ind (c, t);
diff --git a/tactics/rewrite.ml b/tactics/rewrite.ml
index a8a4b1dcce..29176e2df1 100644
--- a/tactics/rewrite.ml
+++ b/tactics/rewrite.ml
@@ -1426,7 +1426,7 @@ let cl_rewrite_clause_tac ?abs strat clause gl =
let tac =
match clause, p with
| Some id, Some p ->
- Proofview.V82.of_tactic (cut_replacing id newt (Proofview.V82.tactic (Tacmach.refine p)))
+ tclTHENLAST (Proofview.V82.of_tactic (assert_after_replacing id newt)) (Tacmach.refine p)
| Some id, None ->
change_in_hyp None (fun env sigma -> sigma, newt) (id, InHypTypeOnly)
| None, Some p ->
@@ -2061,9 +2061,10 @@ let setoid_symmetry_in id =
let he,c1,c2 = mkApp (equiv, Array.of_list others),c1,c2 in
let new_hyp' = mkApp (he, [| c2 ; c1 |]) in
let new_hyp = it_mkProd_or_LetIn new_hyp' binders in
- tclTHENS (Proofview.V82.of_tactic (Tactics.cut new_hyp))
- [ intro_replacing id;
- Proofview.V82.of_tactic (Tacticals.New.tclTHENLIST [ intros; setoid_symmetry; apply (mkVar id); Tactics.assumption ]) ]
+ Proofview.V82.of_tactic
+ (Tacticals.New.tclTHENLAST
+ (Tactics.assert_after_replacing id new_hyp)
+ (Tacticals.New.tclTHENLIST [ intros; setoid_symmetry; apply (mkVar id); Tactics.assumption ]))
gl)
let _ = Hook.set Tactics.setoid_reflexivity setoid_reflexivity
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index 0b9f722fad..f3a43be0bb 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -6,8 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-let a = 1
-
open Pp
open Errors
open Util
@@ -155,23 +153,43 @@ end
let convert x y = convert_gen Reduction.CONV x y
let convert_leq x y = convert_gen Reduction.CUMUL x y
-let error_clear_dependency env id = function
+let clear_dependency_msg env id = function
+ | Evarutil.OccurHypInSimpleClause None ->
+ pr_id id ++ str " is used in conclusion."
+ | Evarutil.OccurHypInSimpleClause (Some id') ->
+ pr_id id ++ strbrk " is used in hypothesis " ++ pr_id id' ++ str"."
+ | Evarutil.EvarTypingBreak ev ->
+ str "Cannot remove " ++ pr_id id ++
+ strbrk " without breaking the typing of " ++
+ Printer.pr_existential env ev ++ str"."
+
+let error_clear_dependency env id err =
+ errorlabstrm "" (clear_dependency_msg env id err)
+
+let replacing_dependency_msg env id = function
| Evarutil.OccurHypInSimpleClause None ->
- errorlabstrm "" (pr_id id ++ str " is used in conclusion.")
+ str "Cannot change " ++ pr_id id ++ str ", it is used in conclusion."
| Evarutil.OccurHypInSimpleClause (Some id') ->
- errorlabstrm ""
- (pr_id id ++ strbrk " is used in hypothesis " ++ pr_id id' ++ str".")
+ str "Cannot change " ++ pr_id id ++
+ strbrk ", it is used in hypothesis " ++ pr_id id' ++ str"."
| Evarutil.EvarTypingBreak ev ->
- errorlabstrm ""
- (str "Cannot remove " ++ pr_id id ++
- strbrk " without breaking the typing of " ++
- Printer.pr_existential env ev ++ str".")
+ str "Cannot change " ++ pr_id id ++
+ strbrk " without breaking the typing of " ++
+ Printer.pr_existential env ev ++ str"."
+
+let error_replacing_dependency env id err =
+ errorlabstrm "" (replacing_dependency_msg env id err)
let thin l gl =
try thin l gl
with Evarutil.ClearDependencyError (id,err) ->
error_clear_dependency (pf_env gl) id err
+let thin_for_replacing l gl =
+ try Tacmach.thin l gl
+ with Evarutil.ClearDependencyError (id,err) ->
+ error_replacing_dependency (pf_env gl) id err
+
let apply_clear_request clear_flag dft c =
let check_isvar c =
if not (isVar c) then
@@ -223,6 +241,10 @@ type name_flag =
| NamingBasedOn of Id.t * Id.t list
| NamingMustBe of Loc.t * Id.t
+let naming_of_name = function
+ | Anonymous -> NamingAvoid []
+ | Name id -> NamingMustBe (dloc,id)
+
let find_name repl decl naming gl = match naming with
| NamingAvoid idl ->
(* this case must be compatible with [find_intro_names] below. *)
@@ -242,29 +264,41 @@ let find_name repl decl naming gl = match naming with
(* Cut rule *)
(**************************************************************)
-let internal_cut_gen b naming t =
+let assert_before_then_gen b naming t tac =
Proofview.Goal.raw_enter begin fun gl ->
- try
let id = find_name b (Anonymous,None,t) naming gl in
- Proofview.V82.tactic (internal_cut b id t)
- with Evarutil.ClearDependencyError (id,err) ->
- error_clear_dependency (Proofview.Goal.env gl) id err
+ Tacticals.New.tclTHENLAST
+ (Proofview.V82.tactic
+ (fun gl ->
+ try internal_cut b id t gl
+ with Evarutil.ClearDependencyError (id,err) ->
+ error_replacing_dependency (pf_env gl) id err))
+ (tac id)
end
-let internal_cut = internal_cut_gen false
-let internal_cut_replace = internal_cut_gen true
+let assert_before_gen b naming t =
+ assert_before_then_gen b naming t (fun _ -> Proofview.tclUNIT ())
-let internal_cut_rev_gen b naming t =
+let assert_before na = assert_before_gen false (naming_of_name na)
+let assert_before_replacing id = assert_before_gen true (NamingMustBe (dloc,id))
+
+let assert_after_then_gen b naming t tac =
Proofview.Goal.raw_enter begin fun gl ->
- try
let id = find_name b (Anonymous,None,t) naming gl in
- Proofview.V82.tactic (internal_cut_rev b id t)
- with Evarutil.ClearDependencyError (id,err) ->
- error_clear_dependency (Proofview.Goal.env gl) id err
+ Tacticals.New.tclTHENFIRST
+ (Proofview.V82.tactic
+ (fun gl ->
+ try internal_cut_rev b id t gl
+ with Evarutil.ClearDependencyError (id,err) ->
+ error_replacing_dependency (pf_env gl) id err))
+ (tac id)
end
-let internal_cut_rev = internal_cut_rev_gen false
-let internal_cut_rev_replace = internal_cut_rev_gen true
+let assert_after_gen b naming t =
+ assert_after_then_gen b naming t (fun _ -> (Proofview.tclUNIT ()))
+
+let assert_after na = assert_after_gen false (naming_of_name na)
+let assert_after_replacing id = assert_after_gen true (NamingMustBe (dloc,id))
(**************************************************************)
(* Fixpoints and CoFixpoints *)
@@ -605,22 +639,6 @@ let rec get_next_hyp_position id = function
else
get_next_hyp_position id right
-let thin_for_replacing l gl =
- try Tacmach.thin l gl
- with Evarutil.ClearDependencyError (id,err) -> match err with
- | Evarutil.OccurHypInSimpleClause None ->
- errorlabstrm ""
- (str "Cannot change " ++ pr_id id ++ str ", it is used in conclusion.")
- | Evarutil.OccurHypInSimpleClause (Some id') ->
- errorlabstrm ""
- (str "Cannot change " ++ pr_id id ++
- strbrk ", it is used in hypothesis " ++ pr_id id' ++ str".")
- | Evarutil.EvarTypingBreak ev ->
- errorlabstrm ""
- (str "Cannot change " ++ pr_id id ++
- strbrk " without breaking the typing of " ++
- Printer.pr_existential (pf_env gl) ev ++ str".")
-
let intro_replacing id gl =
let next_hyp = get_next_hyp_position id (pf_hyps gl) in
tclTHENLIST
@@ -742,9 +760,9 @@ let map_induction_arg f = function
| clear_flag,ElimOnAnonHyp n as x -> x
| clear_flag,ElimOnIdent id as x -> x
-(**************************)
-(* Cut tactics *)
-(**************************)
+(****************************************)
+(* tactic "cut" (actually modus ponens) *)
+(****************************************)
let cut c =
Proofview.Goal.raw_enter begin fun gl ->
@@ -775,38 +793,6 @@ let cut c =
Tacticals.New.tclZEROMSG (str "Not a proposition or a type.")
end
-let cut_intro t = Tacticals.New.tclTHENFIRST (cut t) intro
-
-(* [assert_replacing id T tac] adds the subgoals of the proof of [T]
- before the current goal
-
- id:T0 id:T0 id:T
- ===== ------> tac(=====) + ====
- G T G
-
- It fails if the hypothesis to replace appears in the goal or in
- another hypothesis.
-*)
-
-let assert_replacing id t tac =
- Tacticals.New.tclTHENFIRST
- (internal_cut_replace (NamingMustBe (dloc,id)) t) tac
-
-(* [cut_replacing id T tac] adds the subgoals of the proof of [T]
- after the current goal
-
- id:T0 id:T id:T0
- ===== ------> ==== + tac(=====)
- G G T
-
- It fails if the hypothesis to replace appears in the goal or in
- another hypothesis.
-*)
-
-let cut_replacing id t tac =
- Tacticals.New.tclTHENLAST
- (internal_cut_rev_replace (NamingMustBe (dloc,id)) t) tac
-
let error_uninstantiated_metas t clenv =
let na = meta_name clenv.evd (List.hd (Metaset.elements (metavars_of t))) in
let id = match na with Name id -> id | _ -> anomaly (Pp.str "unnamed dependent meta")
@@ -853,10 +839,10 @@ let clenv_refine_in ?(sidecond_first=false) with_evars ?(with_classes=true) nami
(Proofview.V82.tclEVARS clenv.evd)
(if sidecond_first then
Tacticals.New.tclTHENFIRST
- (internal_cut_gen with_clear naming new_hyp_typ) exact_tac
+ (assert_before_gen with_clear naming new_hyp_typ) exact_tac
else
Tacticals.New.tclTHENLAST
- (internal_cut_rev_gen with_clear naming new_hyp_typ) exact_tac)
+ (assert_after_gen with_clear naming new_hyp_typ) exact_tac)
(********************************************)
(* Elimination tactics *)
@@ -1178,7 +1164,7 @@ let descend_in_conjunctions tac exit c =
| None -> Tacticals.New.tclFAIL 0 (mt())
| Some (p,pt) ->
Tacticals.New.tclTHENS
- (internal_cut (NamingAvoid []) pt)
+ (assert_before Anonymous pt)
[Proofview.V82.tactic (refine p); (* Might be ill-typed due to forbidden elimination. *)
Tacticals.New.onLastHypId (fun id ->
Tacticals.New.tclTHEN
@@ -1520,7 +1506,7 @@ let specialize (c,lbind) g =
| Var id when Id.List.mem id (pf_ids_of_hyps g) ->
tclTHEN tac
(tclTHENFIRST
- (fun g -> Proofview.V82.of_tactic (internal_cut_replace (NamingMustBe (dloc,id)) (pf_type_of g term)) g)
+ (fun g -> Proofview.V82.of_tactic (assert_before_replacing id (pf_type_of g term)) g)
(exact_no_check term)) g
| _ -> tclTHEN tac
(tclTHENLAST
@@ -1830,7 +1816,7 @@ let intros_patterns = function
| l -> intro_patterns_to MoveLast l
(**************************)
-(* Other cut tactics *)
+(* Forward reasoning *)
(**************************)
let rec prepare_naming loc = function
@@ -1872,14 +1858,8 @@ let do_replace id = function
let assert_as first ipat c =
let naming,tac = prepare_intros IntroAnonymous ipat in
let repl = do_replace (head_ident c) naming in
- Tacticals.New.tclTHENS
- ((if first then internal_cut_gen
- else internal_cut_rev_gen) repl naming c)
- (if first then [Proofview.tclUNIT (); Tacticals.New.onLastHypId tac]
- else [Tacticals.New.onLastHypId tac; Proofview.tclUNIT ()])
-
-let assert_tac na = assert_as true (ipat_of_name na)
-let enough_tac na = assert_as false (ipat_of_name na)
+ if first then assert_before_then_gen repl naming c tac
+ else assert_after_then_gen repl naming c tac
(* apply in as *)
@@ -1990,7 +1970,7 @@ let letin_tac with_eq name c ty occs =
let letin_pat_tac with_eq name c occs =
letin_tac_gen with_eq (AbstractPattern (name,c,occs,false,tactic_infer_flags)) None
-(* Tactics "pose proof" (usetac=None) and "assert" (otherwise) *)
+(* Tactics "pose proof" (usetac=None) and "assert"/"enough" (otherwise) *)
let forward b usetac ipat c =
match usetac with
| None ->
diff --git a/tactics/tactics.mli b/tactics/tactics.mli
index 77e1938c68..19ecc2f89e 100644
--- a/tactics/tactics.mli
+++ b/tactics/tactics.mli
@@ -280,7 +280,7 @@ val induction : evars_flag ->
val general_case_analysis : evars_flag -> clear_flag -> constr with_bindings -> unit Proofview.tactic
val simplest_case : constr -> unit Proofview.tactic
-val simple_destruct : quantified_hypothesis -> unit Proofview.tactic
+val simple_destruct : quantified_hypothesis -> unit Proofview.tactic
val destruct : evars_flag ->
(evar_map * constr with_bindings) induction_arg list ->
constr with_bindings option ->
@@ -300,8 +300,8 @@ val induction_destruct : rec_flag -> evars_flag ->
(** {6 Eliminations giving the type instead of the proof. } *)
-val case_type : constr -> unit Proofview.tactic
-val elim_type : constr -> unit Proofview.tactic
+val case_type : types -> unit Proofview.tactic
+val elim_type : types -> unit Proofview.tactic
(** {6 Introduction tactics. } *)
@@ -341,22 +341,46 @@ val transitivity : constr -> unit Proofview.tactic
val etransitivity : unit Proofview.tactic
val intros_transitivity : constr option -> unit Proofview.tactic
-val cut : constr -> unit Proofview.tactic
-val cut_intro : constr -> unit Proofview.tactic
-val assert_replacing : Id.t -> types -> unit Proofview.tactic -> unit Proofview.tactic
-val cut_replacing : Id.t -> types -> unit Proofview.tactic -> unit Proofview.tactic
-
-val assert_as : bool -> intro_pattern_expr located option -> constr -> unit Proofview.tactic
-val forward : bool -> unit Proofview.tactic option -> intro_pattern_expr located option -> constr -> unit Proofview.tactic
-val letin_tac : (bool * intro_pattern_naming_expr located) option -> Name.t ->
- constr -> types option -> clause -> unit Proofview.tactic
-val letin_pat_tac : (bool * intro_pattern_naming_expr located) option -> Name.t ->
- evar_map * constr -> clause -> unit Proofview.tactic
-val assert_tac : Name.t -> types -> unit Proofview.tactic
-val enough_tac : Name.t -> types -> unit Proofview.tactic
-val assert_by : Name.t -> types -> unit Proofview.tactic -> unit Proofview.tactic
-val enough_by : Name.t -> types -> unit Proofview.tactic -> unit Proofview.tactic
-val pose_proof : Name.t -> constr -> unit Proofview.tactic
+(** {6 Cut tactics. } *)
+
+val assert_before_replacing: Id.t -> types -> unit Proofview.tactic
+val assert_after_replacing : Id.t -> types -> unit Proofview.tactic
+val assert_before : Name.t -> types -> unit Proofview.tactic
+val assert_after : Name.t -> types -> unit Proofview.tactic
+
+val assert_as : (* true = before *) bool ->
+ intro_pattern_expr located option -> constr -> unit Proofview.tactic
+
+(** Implements the tactics assert, enough and pose proof; note that "by"
+ applies on the first goal for both assert and enough *)
+
+val assert_by : Name.t -> types -> unit Proofview.tactic ->
+ unit Proofview.tactic
+val enough_by : Name.t -> types -> unit Proofview.tactic ->
+ unit Proofview.tactic
+val pose_proof : Name.t -> constr ->
+ unit Proofview.tactic
+
+(** Common entry point for user-level "assert", "enough" and "pose proof" *)
+
+val forward : bool -> unit Proofview.tactic option ->
+ intro_pattern_expr located option -> constr -> unit Proofview.tactic
+
+(** Implements the tactic cut, actually a modus ponens rule *)
+
+val cut : types -> unit Proofview.tactic
+
+(** {6 Tactics for adding local definitions. } *)
+
+val letin_tac : (bool * intro_pattern_naming_expr located) option ->
+ Name.t -> constr -> types option -> clause -> unit Proofview.tactic
+
+(** Common entry point for user-level "set", "pose" and "remember" *)
+
+val letin_pat_tac : (bool * intro_pattern_naming_expr located) option ->
+ Name.t -> evar_map * constr -> clause -> unit Proofview.tactic
+
+(** {6 Generalize tactics. } *)
val generalize : constr list -> tactic
val generalize_gen : ((occurrences * constr) * Name.t) list -> tactic
diff --git a/test-suite/success/apply.v b/test-suite/success/apply.v
index 71d8d26f15..57b030fc5d 100644
--- a/test-suite/success/apply.v
+++ b/test-suite/success/apply.v
@@ -439,3 +439,10 @@ eexists.
intros.
apply H in H0.
Abort.
+
+(* Check correct failure of apply in when hypothesis is dependent *)
+
+Goal forall H:0=0, H = H.
+intros.
+Fail apply eq_sym in H.
+Abort.