aboutsummaryrefslogtreecommitdiff
path: root/doc/sphinx/proof-engine
diff options
context:
space:
mode:
Diffstat (limited to 'doc/sphinx/proof-engine')
-rw-r--r--doc/sphinx/proof-engine/detailed-tactic-examples.rst776
-rw-r--r--doc/sphinx/proof-engine/ltac.rst1383
-rw-r--r--doc/sphinx/proof-engine/proof-handling.rst832
-rw-r--r--doc/sphinx/proof-engine/ssreflect-proof-language.rst5508
-rw-r--r--doc/sphinx/proof-engine/tactics.rst4807
-rw-r--r--doc/sphinx/proof-engine/vernacular-commands.rst1282
6 files changed, 14588 insertions, 0 deletions
diff --git a/doc/sphinx/proof-engine/detailed-tactic-examples.rst b/doc/sphinx/proof-engine/detailed-tactic-examples.rst
new file mode 100644
index 0000000000..b629d15b11
--- /dev/null
+++ b/doc/sphinx/proof-engine/detailed-tactic-examples.rst
@@ -0,0 +1,776 @@
+.. _detailedexamplesoftactics:
+
+Detailed examples of tactics
+============================
+
+This chapter presents detailed examples of certain tactics, to
+illustrate their behavior.
+
+.. _dependent-induction:
+
+dependent induction
+-------------------
+
+The tactics ``dependent induction`` and ``dependent destruction`` are another
+solution for inverting inductive predicate instances and potentially
+doing induction at the same time. It is based on the ``BasicElim`` tactic
+of Conor McBride which works by abstracting each argument of an
+inductive instance by a variable and constraining it by equalities
+afterwards. This way, the usual induction and destruct tactics can be
+applied to the abstracted instance and after simplification of the
+equalities we get the expected goals.
+
+The abstracting tactic is called generalize_eqs and it takes as
+argument a hypothesis to generalize. It uses the JMeq datatype
+defined in Coq.Logic.JMeq, hence we need to require it before. For
+example, revisiting the first example of the inversion documentation:
+
+.. coqtop:: in reset
+
+ Require Import Coq.Logic.JMeq.
+
+ Inductive Le : nat -> nat -> Set :=
+ | LeO : forall n:nat, Le 0 n
+ | LeS : forall n m:nat, Le n m -> Le (S n) (S m).
+
+ Parameter P : nat -> nat -> Prop.
+
+ Goal forall n m:nat, Le (S n) m -> P n m.
+
+ intros n m H.
+
+.. coqtop:: all
+
+ generalize_eqs H.
+
+The index ``S n`` gets abstracted by a variable here, but a corresponding
+equality is added under the abstract instance so that no information
+is actually lost. The goal is now almost amenable to do induction or
+case analysis. One should indeed first move ``n`` into the goal to
+strengthen it before doing induction, or ``n`` will be fixed in the
+inductive hypotheses (this does not matter for case analysis). As a
+rule of thumb, all the variables that appear inside constructors in
+the indices of the hypothesis should be generalized. This is exactly
+what the ``generalize_eqs_vars`` variant does:
+
+.. coqtop:: all abort
+
+ generalize_eqs_vars H.
+ induction H.
+
+As the hypothesis itself did not appear in the goal, we did not need
+to use an heterogeneous equality to relate the new hypothesis to the
+old one (which just disappeared here). However, the tactic works just
+as well in this case, e.g.:
+
+.. coqtop:: none
+
+ Require Import Coq.Program.Equality.
+
+.. coqtop:: in
+
+ Parameter Q : forall (n m : nat), Le n m -> Prop.
+ Goal forall n m (p : Le (S n) m), Q (S n) m p.
+
+.. coqtop:: all
+
+ intros n m p.
+ generalize_eqs_vars p.
+
+One drawback of this approach is that in the branches one will have to
+substitute the equalities back into the instance to get the right
+assumptions. Sometimes injection of constructors will also be needed
+to recover the needed equalities. Also, some subgoals should be
+directly solved because of inconsistent contexts arising from the
+constraints on indexes. The nice thing is that we can make a tactic
+based on discriminate, injection and variants of substitution to
+automatically do such simplifications (which may involve the axiom K).
+This is what the ``simplify_dep_elim`` tactic from ``Coq.Program.Equality``
+does. For example, we might simplify the previous goals considerably:
+
+.. coqtop:: all abort
+
+ induction p ; simplify_dep_elim.
+
+The higher-order tactic ``do_depind`` defined in ``Coq.Program.Equality``
+takes a tactic and combines the building blocks we have seen with it:
+generalizing by equalities calling the given tactic with the
+generalized induction hypothesis as argument and cleaning the subgoals
+with respect to equalities. Its most important instantiations
+are ``dependent induction`` and ``dependent destruction`` that do induction or
+simply case analysis on the generalized hypothesis. For example we can
+redo what we’ve done manually with dependent destruction:
+
+.. coqtop:: in
+
+ Lemma ex : forall n m:nat, Le (S n) m -> P n m.
+
+.. coqtop:: in
+
+ intros n m H.
+
+.. coqtop:: all abort
+
+ dependent destruction H.
+
+This gives essentially the same result as inversion. Now if the
+destructed hypothesis actually appeared in the goal, the tactic would
+still be able to invert it, contrary to dependent inversion. Consider
+the following example on vectors:
+
+.. coqtop:: in
+
+ Set Implicit Arguments.
+
+.. coqtop:: in
+
+ Parameter A : Set.
+
+.. coqtop:: in
+
+ Inductive vector : nat -> Type :=
+ | vnil : vector 0
+ | vcons : A -> forall n, vector n -> vector (S n).
+
+.. coqtop:: in
+
+ Goal forall n, forall v : vector (S n),
+ exists v' : vector n, exists a : A, v = vcons a v'.
+
+.. coqtop:: in
+
+ intros n v.
+
+.. coqtop:: all
+
+ dependent destruction v.
+
+In this case, the ``v`` variable can be replaced in the goal by the
+generalized hypothesis only when it has a type of the form ``vector (S n)``,
+that is only in the second case of the destruct. The first one is
+dismissed because ``S n <> 0``.
+
+
+A larger example
+~~~~~~~~~~~~~~~~
+
+Let’s see how the technique works with induction on inductive
+predicates on a real example. We will develop an example application
+to the theory of simply-typed lambda-calculus formalized in a
+dependently-typed style:
+
+.. coqtop:: in reset
+
+ Inductive type : Type :=
+ | base : type
+ | arrow : type -> type -> type.
+
+.. coqtop:: in
+
+ Notation " t --> t' " := (arrow t t') (at level 20, t' at next level).
+
+.. coqtop:: in
+
+ Inductive ctx : Type :=
+ | empty : ctx
+ | snoc : ctx -> type -> ctx.
+
+.. coqtop:: in
+
+ Notation " G , tau " := (snoc G tau) (at level 20, tau at next level).
+
+.. coqtop:: in
+
+ Fixpoint conc (G D : ctx) : ctx :=
+ match D with
+ | empty => G
+ | snoc D' x => snoc (conc G D') x
+ end.
+
+.. coqtop:: in
+
+ Notation " G ; D " := (conc G D) (at level 20).
+
+.. coqtop:: in
+
+ Inductive term : ctx -> type -> Type :=
+ | ax : forall G tau, term (G, tau) tau
+ | weak : forall G tau,
+ term G tau -> forall tau', term (G, tau') tau
+ | abs : forall G tau tau',
+ term (G , tau) tau' -> term G (tau --> tau')
+ | app : forall G tau tau',
+ term G (tau --> tau') -> term G tau -> term G tau'.
+
+We have defined types and contexts which are snoc-lists of types. We
+also have a ``conc`` operation that concatenates two contexts. The ``term``
+datatype represents in fact the possible typing derivations of the
+calculus, which are isomorphic to the well-typed terms, hence the
+name. A term is either an application of:
+
+
++ the axiom rule to type a reference to the first variable in a
+ context
++ the weakening rule to type an object in a larger context
++ the abstraction or lambda rule to type a function
++ the application to type an application of a function to an argument
+
+
+Once we have this datatype we want to do proofs on it, like weakening:
+
+.. coqtop:: in abort
+
+ Lemma weakening : forall G D tau, term (G ; D) tau ->
+ forall tau', term (G , tau' ; D) tau.
+
+The problem here is that we can’t just use induction on the typing
+derivation because it will forget about the ``G ; D`` constraint appearing
+in the instance. A solution would be to rewrite the goal as:
+
+.. coqtop:: in abort
+
+ Lemma weakening' : forall G' tau, term G' tau ->
+ forall G D, (G ; D) = G' ->
+ forall tau', term (G, tau' ; D) tau.
+
+With this proper separation of the index from the instance and the
+right induction loading (putting ``G`` and ``D`` after the inducted-on
+hypothesis), the proof will go through, but it is a very tedious
+process. One is also forced to make a wrapper lemma to get back the
+more natural statement. The ``dependent induction`` tactic alleviates this
+trouble by doing all of this plumbing of generalizing and substituting
+back automatically. Indeed we can simply write:
+
+.. coqtop:: in
+
+ Require Import Coq.Program.Tactics.
+ Require Import Coq.Program.Equality.
+
+.. coqtop:: in
+
+ Lemma weakening : forall G D tau, term (G ; D) tau ->
+ forall tau', term (G , tau' ; D) tau.
+
+.. coqtop:: in
+
+ Proof with simpl in * ; simpl_depind ; auto.
+
+.. coqtop:: in
+
+ intros G D tau H. dependent induction H generalizing G D ; intros.
+
+This call to dependent induction has an additional arguments which is
+a list of variables appearing in the instance that should be
+generalized in the goal, so that they can vary in the induction
+hypotheses. By default, all variables appearing inside constructors
+(except in a parameter position) of the instantiated hypothesis will
+be generalized automatically but one can always give the list
+explicitly.
+
+.. coqtop:: all
+
+ Show.
+
+The ``simpl_depind`` tactic includes an automatic tactic that tries to
+simplify equalities appearing at the beginning of induction
+hypotheses, generally using trivial applications of ``reflexivity``. In
+cases where the equality is not between constructor forms though, one
+must help the automation by giving some arguments, using the
+``specialize`` tactic for example.
+
+.. coqtop:: in
+
+ destruct D... apply weak; apply ax. apply ax.
+
+.. coqtop:: in
+
+ destruct D...
+
+.. coqtop:: all
+
+ Show.
+
+.. coqtop:: all
+
+ specialize (IHterm G0 empty eq_refl).
+
+Once the induction hypothesis has been narrowed to the right equality,
+it can be used directly.
+
+.. coqtop:: all
+
+ apply weak, IHterm.
+
+Now concluding this subgoal is easy.
+
+.. coqtop:: in
+
+ constructor; apply IHterm; reflexivity.
+
+.. seealso::
+ The :tacn:`induction`, :tacn:`case`, and :tacn:`inversion` tactics.
+
+
+autorewrite
+-----------
+
+Here are two examples of ``autorewrite`` use. The first one ( *Ackermann
+function*) shows actually a quite basic use where there is no
+conditional rewriting. The second one ( *Mac Carthy function*)
+involves conditional rewritings and shows how to deal with them using
+the optional tactic of the ``Hint Rewrite`` command.
+
+
+.. example:: Ackermann function
+
+ .. coqtop:: in reset
+
+ Require Import Arith.
+
+ .. coqtop:: in
+
+ Parameter Ack : nat -> nat -> nat.
+
+ .. coqtop:: in
+
+ Axiom Ack0 : forall m:nat, Ack 0 m = S m.
+ Axiom Ack1 : forall n:nat, Ack (S n) 0 = Ack n 1.
+ Axiom Ack2 : forall n m:nat, Ack (S n) (S m) = Ack n (Ack (S n) m).
+
+ .. coqtop:: in
+
+ Hint Rewrite Ack0 Ack1 Ack2 : base0.
+
+ .. coqtop:: all
+
+ Lemma ResAck0 : Ack 3 2 = 29.
+
+ .. coqtop:: all
+
+ autorewrite with base0 using try reflexivity.
+
+.. example:: MacCarthy function
+
+ .. coqtop:: in reset
+
+ Require Import Omega.
+
+ .. coqtop:: in
+
+ Parameter g : nat -> nat -> nat.
+
+ .. coqtop:: in
+
+ Axiom g0 : forall m:nat, g 0 m = m.
+ Axiom g1 : forall n m:nat, (n > 0) -> (m > 100) -> g n m = g (pred n) (m - 10).
+ Axiom g2 : forall n m:nat, (n > 0) -> (m <= 100) -> g n m = g (S n) (m + 11).
+
+ .. coqtop:: in
+
+ Hint Rewrite g0 g1 g2 using omega : base1.
+
+ .. coqtop:: in
+
+ Lemma Resg0 : g 1 110 = 100.
+
+ .. coqtop:: out
+
+ Show.
+
+ .. coqtop:: all
+
+ autorewrite with base1 using reflexivity || simpl.
+
+ .. coqtop:: none
+
+ Qed.
+
+ .. coqtop:: all
+
+ Lemma Resg1 : g 1 95 = 91.
+
+ .. coqtop:: all
+
+ autorewrite with base1 using reflexivity || simpl.
+
+ .. coqtop:: none
+
+ Qed.
+
+Using the tactic language
+-------------------------
+
+
+About the cardinality of the set of natural numbers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The first example which shows how to use pattern matching over the
+proof context is a proof of the fact that natural numbers have more
+than two elements. This can be done as follows:
+
+.. coqtop:: in reset
+
+ Lemma card_nat :
+ ~ exists x : nat, exists y : nat, forall z:nat, x = z \/ y = z.
+ Proof.
+
+.. coqtop:: in
+
+ red; intros (x, (y, Hy)).
+
+.. coqtop:: in
+
+ elim (Hy 0); elim (Hy 1); elim (Hy 2); intros;
+
+ match goal with
+ | _ : ?a = ?b, _ : ?a = ?c |- _ =>
+ cut (b = c); [ discriminate | transitivity a; auto ]
+ end.
+
+.. coqtop:: in
+
+ Qed.
+
+We can notice that all the (very similar) cases coming from the three
+eliminations (with three distinct natural numbers) are successfully
+solved by a match goal structure and, in particular, with only one
+pattern (use of non-linear matching).
+
+
+Permutations of lists
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A more complex example is the problem of permutations of
+lists. The aim is to show that a list is a permutation of
+another list.
+
+.. coqtop:: in reset
+
+ Section Sort.
+
+.. coqtop:: in
+
+ Variable A : Set.
+
+.. coqtop:: in
+
+ Inductive perm : list A -> list A -> Prop :=
+ | perm_refl : forall l, perm l l
+ | perm_cons : forall a l0 l1, perm l0 l1 -> perm (a :: l0) (a :: l1)
+ | perm_append : forall a l, perm (a :: l) (l ++ a :: nil)
+ | perm_trans : forall l0 l1 l2, perm l0 l1 -> perm l1 l2 -> perm l0 l2.
+
+.. coqtop:: in
+
+ End Sort.
+
+First, we define the permutation predicate as shown above.
+
+.. coqtop:: none
+
+ Require Import List.
+
+
+.. coqtop:: in
+
+ Ltac perm_aux n :=
+ match goal with
+ | |- (perm _ ?l ?l) => apply perm_refl
+ | |- (perm _ (?a :: ?l1) (?a :: ?l2)) =>
+ let newn := eval compute in (length l1) in
+ (apply perm_cons; perm_aux newn)
+ | |- (perm ?A (?a :: ?l1) ?l2) =>
+ match eval compute in n with
+ | 1 => fail
+ | _ =>
+ let l1' := constr:(l1 ++ a :: nil) in
+ (apply (perm_trans A (a :: l1) l1' l2);
+ [ apply perm_append | compute; perm_aux (pred n) ])
+ end
+ end.
+
+Next we define an auxiliary tactic ``perm_aux`` which takes an argument
+used to control the recursion depth. This tactic behaves as follows. If
+the lists are identical (i.e. convertible), it concludes. Otherwise, if
+the lists have identical heads, it proceeds to look at their tails.
+Finally, if the lists have different heads, it rotates the first list by
+putting its head at the end if the new head hasn't been the head previously. To check this, we keep track of the
+number of performed rotations using the argument ``n``. We do this by
+decrementing ``n`` each time we perform a rotation. It works because
+for a list of length ``n`` we can make exactly ``n - 1`` rotations
+to generate at most ``n`` distinct lists. Notice that we use the natural
+numbers of Coq for the rotation counter. From :ref:`ltac-syntax` we know
+that it is possible to use the usual natural numbers, but they are only
+used as arguments for primitive tactics and they cannot be handled, so,
+in particular, we cannot make computations with them. Thus the natural
+choice is to use Coq data structures so that Coq makes the computations
+(reductions) by ``eval compute in`` and we can get the terms back by match.
+
+.. coqtop:: in
+
+ Ltac solve_perm :=
+ match goal with
+ | |- (perm _ ?l1 ?l2) =>
+ match eval compute in (length l1 = length l2) with
+ | (?n = ?n) => perm_aux n
+ end
+ end.
+
+The main tactic is ``solve_perm``. It computes the lengths of the two lists
+and uses them as arguments to call ``perm_aux`` if the lengths are equal (if they
+aren't, the lists cannot be permutations of each other). Using this tactic we
+can now prove lemmas as follows:
+
+.. coqtop:: in
+
+ Lemma solve_perm_ex1 :
+ perm nat (1 :: 2 :: 3 :: nil) (3 :: 2 :: 1 :: nil).
+ Proof. solve_perm. Qed.
+
+.. coqtop:: in
+
+ Lemma solve_perm_ex2 :
+ perm nat
+ (0 :: 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: 9 :: nil)
+ (0 :: 2 :: 4 :: 6 :: 8 :: 9 :: 7 :: 5 :: 3 :: 1 :: nil).
+ Proof. solve_perm. Qed.
+
+Deciding intuitionistic propositional logic
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Pattern matching on goals allows a powerful backtracking when returning tactic
+values. An interesting application is the problem of deciding intuitionistic
+propositional logic. Considering the contraction-free sequent calculi LJT* of
+Roy Dyckhoff :cite:`Dyc92`, it is quite natural to code such a tactic using the
+tactic language as shown below.
+
+.. coqtop:: in reset
+
+ Ltac basic :=
+ match goal with
+ | |- True => trivial
+ | _ : False |- _ => contradiction
+ | _ : ?A |- ?A => assumption
+ end.
+
+.. coqtop:: in
+
+ Ltac simplify :=
+ repeat (intros;
+ match goal with
+ | H : ~ _ |- _ => red in H
+ | H : _ /\ _ |- _ =>
+ elim H; do 2 intro; clear H
+ | H : _ \/ _ |- _ =>
+ elim H; intro; clear H
+ | H : ?A /\ ?B -> ?C |- _ =>
+ cut (A -> B -> C);
+ [ intro | intros; apply H; split; assumption ]
+ | H: ?A \/ ?B -> ?C |- _ =>
+ cut (B -> C);
+ [ cut (A -> C);
+ [ intros; clear H
+ | intro; apply H; left; assumption ]
+ | intro; apply H; right; assumption ]
+ | H0 : ?A -> ?B, H1 : ?A |- _ =>
+ cut B; [ intro; clear H0 | apply H0; assumption ]
+ | |- _ /\ _ => split
+ | |- ~ _ => red
+ end).
+
+.. coqtop:: in
+
+ Ltac my_tauto :=
+ simplify; basic ||
+ match goal with
+ | H : (?A -> ?B) -> ?C |- _ =>
+ cut (B -> C);
+ [ intro; cut (A -> B);
+ [ intro; cut C;
+ [ intro; clear H | apply H; assumption ]
+ | clear H ]
+ | intro; apply H; intro; assumption ]; my_tauto
+ | H : ~ ?A -> ?B |- _ =>
+ cut (False -> B);
+ [ intro; cut (A -> False);
+ [ intro; cut B;
+ [ intro; clear H | apply H; assumption ]
+ | clear H ]
+ | intro; apply H; red; intro; assumption ]; my_tauto
+ | |- _ \/ _ => (left; my_tauto) || (right; my_tauto)
+ end.
+
+The tactic ``basic`` tries to reason using simple rules involving truth, falsity
+and available assumptions. The tactic ``simplify`` applies all the reversible
+rules of Dyckhoff’s system. Finally, the tactic ``my_tauto`` (the main
+tactic to be called) simplifies with ``simplify``, tries to conclude with
+``basic`` and tries several paths using the backtracking rules (one of the
+four Dyckhoff’s rules for the left implication to get rid of the contraction
+and the right ``or``).
+
+Having defined ``my_tauto``, we can prove tautologies like these:
+
+.. coqtop:: in
+
+ Lemma my_tauto_ex1 :
+ forall A B : Prop, A /\ B -> A \/ B.
+ Proof. my_tauto. Qed.
+
+.. coqtop:: in
+
+ Lemma my_tauto_ex2 :
+ forall A B : Prop, (~ ~ B -> B) -> (A -> B) -> ~ ~ A -> B.
+ Proof. my_tauto. Qed.
+
+
+Deciding type isomorphisms
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A more tricky problem is to decide equalities between types modulo
+isomorphisms. Here, we choose to use the isomorphisms of the simply
+typed λ-calculus with Cartesian product and unit type (see, for
+example, :cite:`RC95`). The axioms of this λ-calculus are given below.
+
+.. coqtop:: in reset
+
+ Open Scope type_scope.
+
+.. coqtop:: in
+
+ Section Iso_axioms.
+
+.. coqtop:: in
+
+ Variables A B C : Set.
+
+.. coqtop:: in
+
+ Axiom Com : A * B = B * A.
+
+ Axiom Ass : A * (B * C) = A * B * C.
+
+ Axiom Cur : (A * B -> C) = (A -> B -> C).
+
+ Axiom Dis : (A -> B * C) = (A -> B) * (A -> C).
+
+ Axiom P_unit : A * unit = A.
+
+ Axiom AR_unit : (A -> unit) = unit.
+
+ Axiom AL_unit : (unit -> A) = A.
+
+.. coqtop:: in
+
+ Lemma Cons : B = C -> A * B = A * C.
+
+ Proof.
+
+ intro Heq; rewrite Heq; reflexivity.
+
+ Qed.
+
+.. coqtop:: in
+
+ End Iso_axioms.
+
+.. coqtop:: in
+
+ Ltac simplify_type ty :=
+ match ty with
+ | ?A * ?B * ?C =>
+ rewrite <- (Ass A B C); try simplify_type_eq
+ | ?A * ?B -> ?C =>
+ rewrite (Cur A B C); try simplify_type_eq
+ | ?A -> ?B * ?C =>
+ rewrite (Dis A B C); try simplify_type_eq
+ | ?A * unit =>
+ rewrite (P_unit A); try simplify_type_eq
+ | unit * ?B =>
+ rewrite (Com unit B); try simplify_type_eq
+ | ?A -> unit =>
+ rewrite (AR_unit A); try simplify_type_eq
+ | unit -> ?B =>
+ rewrite (AL_unit B); try simplify_type_eq
+ | ?A * ?B =>
+ (simplify_type A; try simplify_type_eq) ||
+ (simplify_type B; try simplify_type_eq)
+ | ?A -> ?B =>
+ (simplify_type A; try simplify_type_eq) ||
+ (simplify_type B; try simplify_type_eq)
+ end
+ with simplify_type_eq :=
+ match goal with
+ | |- ?A = ?B => try simplify_type A; try simplify_type B
+ end.
+
+.. coqtop:: in
+
+ Ltac len trm :=
+ match trm with
+ | _ * ?B => let succ := len B in constr:(S succ)
+ | _ => constr:(1)
+ end.
+
+.. coqtop:: in
+
+ Ltac assoc := repeat rewrite <- Ass.
+
+.. coqtop:: in
+
+ Ltac solve_type_eq n :=
+ match goal with
+ | |- ?A = ?A => reflexivity
+ | |- ?A * ?B = ?A * ?C =>
+ apply Cons; let newn := len B in solve_type_eq newn
+ | |- ?A * ?B = ?C =>
+ match eval compute in n with
+ | 1 => fail
+ | _ =>
+ pattern (A * B) at 1; rewrite Com; assoc; solve_type_eq (pred n)
+ end
+ end.
+
+.. coqtop:: in
+
+ Ltac compare_structure :=
+ match goal with
+ | |- ?A = ?B =>
+ let l1 := len A
+ with l2 := len B in
+ match eval compute in (l1 = l2) with
+ | ?n = ?n => solve_type_eq n
+ end
+ end.
+
+.. coqtop:: in
+
+ Ltac solve_iso := simplify_type_eq; compare_structure.
+
+The tactic to judge equalities modulo this axiomatization is shown above.
+The algorithm is quite simple. First types are simplified using axioms that
+can be oriented (this is done by ``simplify_type`` and ``simplify_type_eq``).
+The normal forms are sequences of Cartesian products without Cartesian product
+in the left component. These normal forms are then compared modulo permutation
+of the components by the tactic ``compare_structure``. If they have the same
+lengths, the tactic ``solve_type_eq`` attempts to prove that the types are equal.
+The main tactic that puts all these components together is called ``solve_iso``.
+
+Here are examples of what can be solved by ``solve_iso``.
+
+.. coqtop:: in
+
+ Lemma solve_iso_ex1 :
+ forall A B : Set, A * unit * B = B * (unit * A).
+ Proof.
+ intros; solve_iso.
+ Qed.
+
+.. coqtop:: in
+
+ Lemma solve_iso_ex2 :
+ forall A B C : Set,
+ (A * unit -> B * (C * unit)) =
+ (A * unit -> (C -> unit) * C) * (unit -> A -> B).
+ Proof.
+ intros; solve_iso.
+ Qed.
diff --git a/doc/sphinx/proof-engine/ltac.rst b/doc/sphinx/proof-engine/ltac.rst
new file mode 100644
index 0000000000..0322b43694
--- /dev/null
+++ b/doc/sphinx/proof-engine/ltac.rst
@@ -0,0 +1,1383 @@
+.. _ltac:
+
+The tactic language
+===================
+
+This chapter gives a compact documentation of |Ltac|, the tactic language
+available in |Coq|. We start by giving the syntax, and next, we present the
+informal semantics. If you want to know more regarding this language and
+especially about its foundations, you can refer to :cite:`Del00`. Chapter
+:ref:`detailedexamplesoftactics` is devoted to giving small but nontrivial
+use examples of this language.
+
+.. _ltac-syntax:
+
+Syntax
+------
+
+The syntax of the tactic language is given below. See Chapter
+:ref:`gallinaspecificationlanguage` for a description of the BNF metasyntax used
+in these grammar rules. Various already defined entries will be used in this
+chapter: entries :token:`natural`, :token:`integer`, :token:`ident`,
+:token:`qualid`, :token:`term`, :token:`cpattern` and :token:`atomic_tactic`
+represent respectively the natural and integer numbers, the authorized
+identificators and qualified names, Coq terms and patterns and all the atomic
+tactics described in Chapter :ref:`tactics`. The syntax of :token:`cpattern` is
+the same as that of terms, but it is extended with pattern matching
+metavariables. In :token:`cpattern`, a pattern matching metavariable is
+represented with the syntax :g:`?id` where :g:`id` is an :token:`ident`. The
+notation :g:`_` can also be used to denote metavariable whose instance is
+irrelevant. In the notation :g:`?id`, the identifier allows us to keep
+instantiations and to make constraints whereas :g:`_` shows that we are not
+interested in what will be matched. On the right hand side of pattern matching
+clauses, the named metavariables are used without the question mark prefix. There
+is also a special notation for second-order pattern matching problems: in an
+applicative pattern of the form :g:`@?id id1 … idn`, the variable id matches any
+complex expression with (possible) dependencies in the variables :g:`id1 … idn`
+and returns a functional term of the form :g:`fun id1 … idn => term`.
+
+The main entry of the grammar is :n:`@expr`. This language is used in proof
+mode but it can also be used in toplevel definitions as shown below.
+
+.. note::
+
+ - The infix tacticals  ``… || …`` ,  ``… + …`` , and  ``… ; …``  are associative.
+
+ .. example::
+
+ If you want that :n:`@tactic__2; @tactic__3` be fully run on the first
+ subgoal generated by :n:`@tactic__1`, before running on the other
+ subgoals, then you should not write
+ :n:`@tactic__1; (@tactic__2; @tactic__3)` but rather
+ :n:`@tactic__1; [> @tactic__2; @tactic__3 .. ]`.
+
+ - In :token:`tacarg`, there is an overlap between :token:`qualid` as a
+ direct tactic argument and :token:`qualid` as a particular case of
+ :token:`term`. The resolution is done by first looking for a reference
+ of the tactic language and if it fails, for a reference to a term.
+ To force the resolution as a reference of the tactic language, use the
+ form :n:`ltac:(@qualid)`. To force the resolution as a reference to a
+ term, use the syntax :n:`(@qualid)`.
+
+ - As shown by the figure, tactical  ``… || …``  binds more than the prefix
+ tacticals :tacn:`try`, :tacn:`repeat`, :tacn:`do` and :tacn:`abstract`
+ which themselves bind more than the postfix tactical  ``… ;[ … ]`` 
+ which binds at the same level as  ``… ; …`` .
+
+ .. example::
+
+ :n:`try repeat @tactic__1 || @tactic__2; @tactic__3; [ {+| @tactic } ]; @tactic__4`
+
+ is understood as:
+
+ :n:`((try (repeat (@tactic__1 || @tactic__2)); @tactic__3); [ {+| @tactic } ]); @tactic__4`
+
+.. productionlist:: coq
+ expr : `expr` ; `expr`
+ : [> `expr` | ... | `expr` ]
+ : `expr` ; [ `expr` | ... | `expr` ]
+ : `tacexpr3`
+ tacexpr3 : do (`natural` | `ident`) `tacexpr3`
+ : progress `tacexpr3`
+ : repeat `tacexpr3`
+ : try `tacexpr3`
+ : once `tacexpr3`
+ : exactly_once `tacexpr3`
+ : timeout (`natural` | `ident`) `tacexpr3`
+ : time [`string`] `tacexpr3`
+ : only `selector`: `tacexpr3`
+ : `tacexpr2`
+ tacexpr2 : `tacexpr1` || `tacexpr3`
+ : `tacexpr1` + `tacexpr3`
+ : tryif `tacexpr1` then `tacexpr1` else `tacexpr1`
+ : `tacexpr1`
+ tacexpr1 : fun `name` ... `name` => `atom`
+ : let [rec] `let_clause` with ... with `let_clause` in `atom`
+ : match goal with `context_rule` | ... | `context_rule` end
+ : match reverse goal with `context_rule` | ... | `context_rule` end
+ : match `expr` with `match_rule` | ... | `match_rule` end
+ : lazymatch goal with `context_rule` | ... | `context_rule` end
+ : lazymatch reverse goal with `context_rule` | ... | `context_rule` end
+ : lazymatch `expr` with `match_rule` | ... | `match_rule` end
+ : multimatch goal with `context_rule` | ... | `context_rule` end
+ : multimatch reverse goal with `context_rule` | ... | `context_rule` end
+ : multimatch `expr` with `match_rule` | ... | `match_rule` end
+ : abstract `atom`
+ : abstract `atom` using `ident`
+ : first [ `expr` | ... | `expr` ]
+ : solve [ `expr` | ... | `expr` ]
+ : idtac [ `message_token` ... `message_token`]
+ : fail [`natural`] [`message_token` ... `message_token`]
+ : fresh [ `component` … `component` ]
+ : context `ident` [`term`]
+ : eval `redexpr` in `term`
+ : type of `term`
+ : constr : `term`
+ : uconstr : `term`
+ : type_term `term`
+ : numgoals
+ : guard `test`
+ : assert_fails `tacexpr3`
+ : assert_succeeds `tacexpr3`
+ : `atomic_tactic`
+ : `qualid` `tacarg` ... `tacarg`
+ : `atom`
+ atom : `qualid`
+ : ()
+ : `integer`
+ : ( `expr` )
+ component : `string` | `qualid`
+ message_token : `string` | `ident` | `integer`
+ tacarg : `qualid`
+ : ()
+ : ltac : `atom`
+ : `term`
+ let_clause : `ident` [`name` ... `name`] := `expr`
+ context_rule : `context_hyp`, ..., `context_hyp` |- `cpattern` => `expr`
+ : `cpattern` => `expr`
+ : |- `cpattern` => `expr`
+ : _ => `expr`
+ context_hyp : `name` : `cpattern`
+ : `name` := `cpattern` [: `cpattern`]
+ match_rule : `cpattern` => `expr`
+ : context [`ident`] [ `cpattern` ] => `expr`
+ : _ => `expr`
+ test : `integer` = `integer`
+ : `integer` (< | <= | > | >=) `integer`
+ selector : [`ident`]
+ : `integer`
+ : (`integer` | `integer` - `integer`), ..., (`integer` | `integer` - `integer`)
+ toplevel_selector : `selector`
+ : all
+ : par
+ : !
+
+.. productionlist:: coq
+ top : [Local] Ltac `ltac_def` with ... with `ltac_def`
+ ltac_def : `ident` [`ident` ... `ident`] := `expr`
+ : `qualid` [`ident` ... `ident`] ::= `expr`
+
+.. _ltac-semantics:
+
+Semantics
+---------
+
+Tactic expressions can only be applied in the context of a proof. The
+evaluation yields either a term, an integer or a tactic. Intermediate
+results can be terms or integers but the final result must be a tactic
+which is then applied to the focused goals.
+
+There is a special case for ``match goal`` expressions of which the clauses
+evaluate to tactics. Such expressions can only be used as end result of
+a tactic expression (never as argument of a non-recursive local
+definition or of an application).
+
+The rest of this section explains the semantics of every construction of
+|Ltac|.
+
+Sequence
+~~~~~~~~
+
+A sequence is an expression of the following form:
+
+.. tacn:: @expr__1 ; @expr__2
+ :name: ltac-seq
+
+ The expression :n:`@expr__1` is evaluated to :n:`v__1`, which must be
+ a tactic value. The tactic :n:`v__1` is applied to the current goal,
+ possibly producing more goals. Then :n:`@expr__2` is evaluated to
+ produce :n:`v__2`, which must be a tactic value. The tactic
+ :n:`v__2` is applied to all the goals produced by the prior
+ application. Sequence is associative.
+
+Local application of tactics
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Different tactics can be applied to the different goals using the
+following form:
+
+.. tacn:: [> {*| @expr }]
+ :name: [> ... | ... | ... ] (dispatch)
+
+ The expressions :n:`@expr__i` are evaluated to :n:`v__i`, for
+ i = 1, ..., n and all have to be tactics. The :n:`v__i` is applied to the
+ i-th goal, for i = 1, ..., n. It fails if the number of focused goals is not
+ exactly n.
+
+ .. note::
+
+ If no tactic is given for the i-th goal, it behaves as if the tactic idtac
+ were given. For instance, ``[> | auto]`` is a shortcut for ``[> idtac | auto
+ ]``.
+
+ .. tacv:: [> {*| @expr__i} | @expr .. | {*| @expr__j}]
+
+ In this variant, :n:`@expr` is used for each goal coming after those
+ covered by the list of :n:`@expr__i` but before those covered by the
+ list of :n:`@expr__j`.
+
+ .. tacv:: [> {*| @expr} | .. | {*| @expr}]
+
+ In this variant, idtac is used for the goals not covered by the two lists of
+ :n:`@expr`.
+
+ .. tacv:: [> @expr .. ]
+
+ In this variant, the tactic :n:`@expr` is applied independently to each of
+ the goals, rather than globally. In particular, if there are no goals, the
+ tactic is not run at all. A tactic which expects multiple goals, such as
+ ``swap``, would act as if a single goal is focused.
+
+ .. tacv:: @expr__0 ; [{*| @expr__i}]
+
+ This variant of local tactic application is paired with a sequence. In this
+ variant, there must be as many :n:`@expr__i` as goals generated
+ by the application of :n:`@expr__0` to each of the individual goals
+ independently. All the above variants work in this form too.
+ Formally, :n:`@expr ; [ ... ]` is equivalent to :n:`[> @expr ; [> ... ] .. ]`.
+
+.. _goal-selectors:
+
+Goal selectors
+~~~~~~~~~~~~~~
+
+We can restrict the application of a tactic to a subset of the currently
+focused goals with:
+
+.. tacn:: @toplevel_selector : @expr
+ :name: ... : ... (goal selector)
+
+ We can also use selectors as a tactical, which allows to use them nested
+ in a tactic expression, by using the keyword ``only``:
+
+ .. tacv:: only @selector : @expr
+ :name: only ... : ...
+
+ When selecting several goals, the tactic :token:`expr` is applied globally to all
+ selected goals.
+
+ .. tacv:: [@ident] : @expr
+
+ In this variant, :token:`expr` is applied locally to a goal previously named
+ by the user (see :ref:`existential-variables`).
+
+ .. tacv:: @num : @expr
+
+ In this variant, :token:`expr` is applied locally to the :token:`num`-th goal.
+
+ .. tacv:: {+, @num-@num} : @expr
+
+ In this variant, :n:`@expr` is applied globally to the subset of goals
+ described by the given ranges. You can write a single ``n`` as a shortcut
+ for ``n-n`` when specifying multiple ranges.
+
+ .. tacv:: all: @expr
+ :name: all: ...
+
+ In this variant, :token:`expr` is applied to all focused goals. ``all:`` can only
+ be used at the toplevel of a tactic expression.
+
+ .. tacv:: !: @expr
+
+ In this variant, if exactly one goal is focused, :token:`expr` is
+ applied to it. Otherwise the tactic fails. ``!:`` can only be
+ used at the toplevel of a tactic expression.
+
+ .. tacv:: par: @expr
+ :name: par: ...
+
+ In this variant, :n:`@expr` is applied to all focused goals in parallel.
+ The number of workers can be controlled via the command line option
+ ``-async-proofs-tac-j`` taking as argument the desired number of workers.
+ Limitations: ``par:`` only works on goals containing no existential
+ variables and :n:`@expr` must either solve the goal completely or do
+ nothing (i.e. it cannot make some progress). ``par:`` can only be used at
+ the toplevel of a tactic expression.
+
+ .. exn:: No such goal.
+ :name: No such goal. (Goal selector)
+ :undocumented:
+
+ .. TODO change error message index entry
+
+For loop
+~~~~~~~~
+
+There is a for loop that repeats a tactic :token:`num` times:
+
+.. tacn:: do @num @expr
+ :name: do
+
+ :n:`@expr` is evaluated to ``v`` which must be a tactic value. This tactic
+ value ``v`` is applied :token:`num` times. Supposing :token:`num` > 1, after the
+ first application of ``v``, ``v`` is applied, at least once, to the generated
+ subgoals and so on. It fails if the application of ``v`` fails before the num
+ applications have been completed.
+
+Repeat loop
+~~~~~~~~~~~
+
+We have a repeat loop with:
+
+.. tacn:: repeat @expr
+ :name: repeat
+
+ :n:`@expr` is evaluated to ``v``. If ``v`` denotes a tactic, this tactic is
+ applied to each focused goal independently. If the application succeeds, the
+ tactic is applied recursively to all the generated subgoals until it eventually
+ fails. The recursion stops in a subgoal when the tactic has failed *to make
+ progress*. The tactic :n:`repeat @expr` itself never fails.
+
+Error catching
+~~~~~~~~~~~~~~
+
+We can catch the tactic errors with:
+
+.. tacn:: try @expr
+ :name: try
+
+ :n:`@expr` is evaluated to ``v`` which must be a tactic value. The tactic
+ value ``v`` is applied to each focused goal independently. If the application of
+ ``v`` fails in a goal, it catches the error and leaves the goal unchanged. If the
+ level of the exception is positive, then the exception is re-raised with its
+ level decremented.
+
+Detecting progress
+~~~~~~~~~~~~~~~~~~
+
+We can check if a tactic made progress with:
+
+.. tacn:: progress expr
+ :name: progress
+
+ :n:`@expr` is evaluated to v which must be a tactic value. The tactic value ``v``
+ is applied to each focued subgoal independently. If the application of ``v``
+ to one of the focused subgoal produced subgoals equal to the initial
+ goals (up to syntactical equality), then an error of level 0 is raised.
+
+ .. exn:: Failed to progress.
+ :undocumented:
+
+Backtracking branching
+~~~~~~~~~~~~~~~~~~~~~~
+
+We can branch with the following structure:
+
+.. tacn:: @expr__1 + @expr__2
+ :name: + (backtracking branching)
+
+ :n:`@expr__1` and :n:`@expr__2` are evaluated respectively to :n:`v__1` and
+ :n:`v__2` which must be tactic values. The tactic value :n:`v__1` is applied to
+ each focused goal independently and if it fails or a later tactic fails, then
+ the proof backtracks to the current goal and :n:`v__2` is applied.
+
+ Tactics can be seen as having several successes. When a tactic fails it
+ asks for more successes of the prior tactics.
+ :n:`@expr__1 + @expr__2` has all the successes of :n:`v__1` followed by all the
+ successes of :n:`v__2`. Algebraically,
+ :n:`(@expr__1 + @expr__2); @expr__3 = (@expr__1; @expr__3) + (@expr__2; @expr__3)`.
+
+ Branching is left-associative.
+
+First tactic to work
+~~~~~~~~~~~~~~~~~~~~
+
+Backtracking branching may be too expensive. In this case we may
+restrict to a local, left biased, branching and consider the first
+tactic to work (i.e. which does not fail) among a panel of tactics:
+
+.. tacn:: first [{*| @expr}]
+ :name: first
+
+ The :n:`@expr__i` are evaluated to :n:`v__i` and :n:`v__i` must be
+ tactic values for i = 1, ..., n. Supposing n > 1,
+ :n:`first [@expr__1 | ... | @expr__n]` applies :n:`v__1` in each
+ focused goal independently and stops if it succeeds; otherwise it
+ tries to apply :n:`v__2` and so on. It fails when there is no
+ applicable tactic. In other words,
+ :n:`first [@expr__1 | ... | @expr__n]` behaves, in each goal, as the first
+ :n:`v__i` to have *at least* one success.
+
+ .. exn:: No applicable tactic.
+ :undocumented:
+
+ .. tacv:: first @expr
+
+ This is an |Ltac| alias that gives a primitive access to the first
+ tactical as an |Ltac| definition without going through a parsing rule. It
+ expects to be given a list of tactics through a ``Tactic Notation``,
+ allowing to write notations of the following form:
+
+ .. example::
+
+ .. coqtop:: in
+
+ Tactic Notation "foo" tactic_list(tacs) := first tacs.
+
+Left-biased branching
+~~~~~~~~~~~~~~~~~~~~~
+
+Yet another way of branching without backtracking is the following
+structure:
+
+.. tacn:: @expr__1 || @expr__2
+ :name: || (left-biased branching)
+
+ :n:`@expr__1` and :n:`@expr__2` are evaluated respectively to :n:`v__1` and
+ :n:`v__2` which must be tactic values. The tactic value :n:`v__1` is
+ applied in each subgoal independently and if it fails *to progress* then
+ :n:`v__2` is applied. :n:`@expr__1 || @expr__2` is
+ equivalent to :n:`first [ progress @expr__1 | @expr__2 ]` (except that
+ if it fails, it fails like :n:`v__2`). Branching is left-associative.
+
+Generalized biased branching
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The tactic
+
+.. tacn:: tryif @expr__1 then @expr__2 else @expr__3
+ :name: tryif
+
+ is a generalization of the biased-branching tactics above. The
+ expression :n:`@expr__1` is evaluated to :n:`v__1`, which is then
+ applied to each subgoal independently. For each goal where :n:`v__1`
+ succeeds at least once, :n:`@expr__2` is evaluated to :n:`v__2` which
+ is then applied collectively to the generated subgoals. The :n:`v__2`
+ tactic can trigger backtracking points in :n:`v__1`: where :n:`v__1`
+ succeeds at least once,
+ :n:`tryif @expr__1 then @expr__2 else @expr__3` is equivalent to
+ :n:`v__1; v__2`. In each of the goals where :n:`v__1` does not succeed at least
+ once, :n:`@expr__3` is evaluated in :n:`v__3` which is is then applied to the
+ goal.
+
+Soft cut
+~~~~~~~~
+
+Another way of restricting backtracking is to restrict a tactic to a
+single success *a posteriori*:
+
+.. tacn:: once @expr
+ :name: once
+
+ :n:`@expr` is evaluated to ``v`` which must be a tactic value. The tactic value
+ ``v`` is applied but only its first success is used. If ``v`` fails,
+ :n:`once @expr` fails like ``v``. If ``v`` has at least one success,
+ :n:`once @expr` succeeds once, but cannot produce more successes.
+
+Checking the successes
+~~~~~~~~~~~~~~~~~~~~~~
+
+Coq provides an experimental way to check that a tactic has *exactly
+one* success:
+
+.. tacn:: exactly_once @expr
+ :name: exactly_once
+
+ :n:`@expr` is evaluated to ``v`` which must be a tactic value. The tactic value
+ ``v`` is applied if it has at most one success. If ``v`` fails,
+ :n:`exactly_once @expr` fails like ``v``. If ``v`` has a exactly one success,
+ :n:`exactly_once @expr` succeeds like ``v``. If ``v`` has two or more
+ successes, exactly_once expr fails.
+
+ .. warning::
+
+ The experimental status of this tactic pertains to the fact if ``v``
+ performs side effects, they may occur in an unpredictable way. Indeed,
+ normally ``v`` would only be executed up to the first success until
+ backtracking is needed, however exactly_once needs to look ahead to see
+ whether a second success exists, and may run further effects
+ immediately.
+
+ .. exn:: This tactic has more than one success.
+ :undocumented:
+
+Checking the failure
+~~~~~~~~~~~~~~~~~~~~
+
+Coq provides a derived tactic to check that a tactic *fails*:
+
+.. tacn:: assert_fails @expr
+ :name: assert_fails
+
+ This behaves like :n:`tryif @expr then fail 0 tac "succeeds" else idtac`.
+
+Checking the success
+~~~~~~~~~~~~~~~~~~~~
+
+Coq provides a derived tactic to check that a tactic has *at least one*
+success:
+
+.. tacn:: assert_succeeds @expr
+ :name: assert_succeeds
+
+ This behaves like
+ :n:`tryif (assert_fails tac) then fail 0 tac "fails" else idtac`.
+
+Solving
+~~~~~~~
+
+We may consider the first to solve (i.e. which generates no subgoal)
+among a panel of tactics:
+
+.. tacn:: solve [{*| @expr}]
+ :name: solve
+
+ The :n:`@expr__i` are evaluated to :n:`v__i` and :n:`v__i` must be
+ tactic values, for i = 1, ..., n. Supposing n > 1,
+ :n:`solve [@expr__1 | ... | @expr__n]` applies :n:`v__1` to
+ each goal independently and stops if it succeeds; otherwise it tries to
+ apply :n:`v__2` and so on. It fails if there is no solving tactic.
+
+ .. exn:: Cannot solve the goal.
+ :undocumented:
+
+ .. tacv:: solve @expr
+
+ This is an |Ltac| alias that gives a primitive access to the :n:`solve:`
+ tactical. See the :n:`first` tactical for more information.
+
+Identity
+~~~~~~~~
+
+The constant :n:`idtac` is the identity tactic: it leaves any goal unchanged but
+it appears in the proof script.
+
+.. tacn:: idtac {* message_token}
+ :name: idtac
+
+ This prints the given tokens. Strings and integers are printed
+ literally. If a (term) variable is given, its contents are printed.
+
+Failing
+~~~~~~~
+
+.. tacn:: fail
+ :name: fail
+
+ This is the always-failing tactic: it does not solve any
+ goal. It is useful for defining other tacticals since it can be caught by
+ :tacn:`try`, :tacn:`repeat`, :tacn:`match goal`, or the branching tacticals.
+
+ .. tacv:: fail @num
+
+ The number is the failure level. If no level is specified, it defaults to 0.
+ The level is used by :tacn:`try`, :tacn:`repeat`, :tacn:`match goal` and the branching
+ tacticals. If 0, it makes :tacn:`match goal` consider the next clause
+ (backtracking). If nonzero, the current :tacn:`match goal` block, :tacn:`try`,
+ :tacn:`repeat`, or branching command is aborted and the level is decremented. In
+ the case of :n:`+`, a nonzero level skips the first backtrack point, even if
+ the call to :n:`fail @num` is not enclosed in a :n:`+` command,
+ respecting the algebraic identity.
+
+ .. tacv:: fail {* message_token}
+
+ The given tokens are used for printing the failure message.
+
+ .. tacv:: fail @num {* message_token}
+
+ This is a combination of the previous variants.
+
+ .. tacv:: gfail
+ :name: gfail
+
+ This variant fails even when used after :n:`;` and there are no goals left.
+ Similarly, ``gfail`` fails even when used after ``all:`` and there are no
+ goals left. See the example for clarification.
+
+ .. tacv:: gfail {* message_token}
+ gfail @num {* message_token}
+
+ These variants fail with an error message or an error level even if
+ there are no goals left. Be careful however if Coq terms have to be
+ printed as part of the failure: term construction always forces the
+ tactic into the goals, meaning that if there are no goals when it is
+ evaluated, a tactic call like :n:`let x := H in fail 0 x` will succeed.
+
+ .. exn:: Tactic Failure message (level @num).
+ :undocumented:
+
+ .. exn:: No such goal.
+ :name: No such goal. (fail)
+ :undocumented:
+
+ .. example::
+
+ .. coqtop:: all fail
+
+ Goal True.
+ Proof. fail. Abort.
+
+ Goal True.
+ Proof. trivial; fail. Qed.
+
+ Goal True.
+ Proof. trivial. fail. Abort.
+
+ Goal True.
+ Proof. trivial. all: fail. Qed.
+
+ Goal True.
+ Proof. gfail. Abort.
+
+ Goal True.
+ Proof. trivial; gfail. Abort.
+
+ Goal True.
+ Proof. trivial. gfail. Abort.
+
+ Goal True.
+ Proof. trivial. all: gfail. Abort.
+
+Timeout
+~~~~~~~
+
+We can force a tactic to stop if it has not finished after a certain
+amount of time:
+
+.. tacn:: timeout @num @expr
+ :name: timeout
+
+ :n:`@expr` is evaluated to ``v`` which must be a tactic value. The tactic value
+ ``v`` is applied normally, except that it is interrupted after :n:`@num` seconds
+ if it is still running. In this case the outcome is a failure.
+
+ .. warning::
+
+ For the moment, timeout is based on elapsed time in seconds,
+ which is very machine-dependent: a script that works on a quick machine
+ may fail on a slow one. The converse is even possible if you combine a
+ timeout with some other tacticals. This tactical is hence proposed only
+ for convenience during debugging or other development phases, we strongly
+ advise you to not leave any timeout in final scripts. Note also that
+ this tactical isn’t available on the native Windows port of Coq.
+
+Timing a tactic
+~~~~~~~~~~~~~~~
+
+A tactic execution can be timed:
+
+.. tacn:: time @string @expr
+ :name: time
+
+ evaluates :n:`@expr` and displays the running time of the tactic expression, whether it
+ fails or succeeds. In case of several successes, the time for each successive
+ run is displayed. Time is in seconds and is machine-dependent. The :n:`@string`
+ argument is optional. When provided, it is used to identify this particular
+ occurrence of time.
+
+Timing a tactic that evaluates to a term
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Tactic expressions that produce terms can be timed with the experimental
+tactic
+
+.. tacn:: time_constr expr
+ :name: time_constr
+
+ which evaluates :n:`@expr ()` and displays the time the tactic expression
+ evaluated, assuming successful evaluation. Time is in seconds and is
+ machine-dependent.
+
+ This tactic currently does not support nesting, and will report times
+ based on the innermost execution. This is due to the fact that it is
+ implemented using the following internal tactics:
+
+ .. tacn:: restart_timer @string
+ :name: restart_timer
+
+ Reset a timer
+
+ .. tacn:: finish_timing {? (@string)} @string
+ :name: finish_timing
+
+ Display an optionally named timer. The parenthesized string argument
+ is also optional, and determines the label associated with the timer
+ for printing.
+
+ By copying the definition of :tacn:`time_constr` from the standard library,
+ users can achive support for a fixed pattern of nesting by passing
+ different :token:`string` parameters to :tacn:`restart_timer` and
+ :tacn:`finish_timing` at each level of nesting.
+
+ .. example::
+
+ .. coqtop:: all abort
+
+ Ltac time_constr1 tac :=
+ let eval_early := match goal with _ => restart_timer "(depth 1)" end in
+ let ret := tac () in
+ let eval_early := match goal with _ => finish_timing ( "Tactic evaluation" ) "(depth 1)" end in
+ ret.
+
+ Goal True.
+ let v := time_constr
+ ltac:(fun _ =>
+ let x := time_constr1 ltac:(fun _ => constr:(10 * 10)) in
+ let y := time_constr1 ltac:(fun _ => eval compute in x) in
+ y) in
+ pose v.
+
+Local definitions
+~~~~~~~~~~~~~~~~~
+
+Local definitions can be done as follows:
+
+.. tacn:: let @ident__1 := @expr__1 {* with @ident__i := @expr__i} in @expr
+ :name: let ... := ...
+
+ each :n:`@expr__i` is evaluated to :n:`v__i`, then, :n:`@expr` is evaluated
+ by substituting :n:`v__i` to each occurrence of :n:`@ident__i`, for
+ i = 1, ..., n. There are no dependencies between the :n:`@expr__i` and the
+ :n:`@ident__i`.
+
+ Local definitions can be made recursive by using :n:`let rec` instead of :n:`let`.
+ In this latter case, the definitions are evaluated lazily so that the rec
+ keyword can be used also in non-recursive cases so as to avoid the eager
+ evaluation of local definitions.
+
+ .. but rec changes the binding!!
+
+Application
+~~~~~~~~~~~
+
+An application is an expression of the following form:
+
+.. tacn:: @qualid {+ @tacarg}
+
+ The reference :n:`@qualid` must be bound to some defined tactic definition
+ expecting at least as many arguments as the provided :n:`tacarg`. The
+ expressions :n:`@expr__i` are evaluated to :n:`v__i`, for i = 1, ..., n.
+
+ .. what expressions ??
+
+Function construction
+~~~~~~~~~~~~~~~~~~~~~
+
+A parameterized tactic can be built anonymously (without resorting to
+local definitions) with:
+
+.. tacn:: fun {+ @ident} => @expr
+
+ Indeed, local definitions of functions are a syntactic sugar for binding
+ a :n:`fun` tactic to an identifier.
+
+Pattern matching on terms
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We can carry out pattern matching on terms with:
+
+.. tacn:: match @expr with {+| @cpattern__i => @expr__i} end
+
+ The expression :n:`@expr` is evaluated and should yield a term which is
+ matched against :n:`cpattern__1`. The matching is non-linear: if a
+ metavariable occurs more than once, it should match the same expression
+ every time. It is first-order except on the variables of the form :n:`@?id`
+ that occur in head position of an application. For these variables, the
+ matching is second-order and returns a functional term.
+
+ Alternatively, when a metavariable of the form :n:`?id` occurs under binders,
+ say :n:`x__1, …, x__n` and the expression matches, the
+ metavariable is instantiated by a term which can then be used in any
+ context which also binds the variables :n:`x__1, …, x__n` with
+ same types. This provides with a primitive form of matching under
+ context which does not require manipulating a functional term.
+
+ If the matching with :n:`@cpattern__1` succeeds, then :n:`@expr__1` is
+ evaluated into some value by substituting the pattern matching
+ instantiations to the metavariables. If :n:`@expr__1` evaluates to a
+ tactic and the match expression is in position to be applied to a goal
+ (e.g. it is not bound to a variable by a :n:`let in`), then this tactic is
+ applied. If the tactic succeeds, the list of resulting subgoals is the
+ result of the match expression. If :n:`@expr__1` does not evaluate to a
+ tactic or if the match expression is not in position to be applied to a
+ goal, then the result of the evaluation of :n:`@expr__1` is the result
+ of the match expression.
+
+ If the matching with :n:`@cpattern__1` fails, or if it succeeds but the
+ evaluation of :n:`@expr__1` fails, or if the evaluation of
+ :n:`@expr__1` succeeds but returns a tactic in execution position whose
+ execution fails, then :n:`cpattern__2` is used and so on. The pattern
+ :n:`_` matches any term and shadows all remaining patterns if any. If all
+ clauses fail (in particular, there is no pattern :n:`_`) then a
+ no-matching-clause error is raised.
+
+ Failures in subsequent tactics do not cause backtracking to select new
+ branches or inside the right-hand side of the selected branch even if it
+ has backtracking points.
+
+ .. exn:: No matching clauses for match.
+
+ No pattern can be used and, in particular, there is no :n:`_` pattern.
+
+ .. exn:: Argument of match does not evaluate to a term.
+
+ This happens when :n:`@expr` does not denote a term.
+
+ .. tacv:: multimatch @expr with {+| @cpattern__i => @expr__i} end
+
+ Using multimatch instead of match will allow subsequent tactics to
+ backtrack into a right-hand side tactic which has backtracking points
+ left and trigger the selection of a new matching branch when all the
+ backtracking points of the right-hand side have been consumed.
+
+ The syntax :n:`match …` is, in fact, a shorthand for :n:`once multimatch …`.
+
+ .. tacv:: lazymatch @expr with {+| @cpattern__i => @expr__i} end
+
+ Using lazymatch instead of match will perform the same pattern
+ matching procedure but will commit to the first matching branch
+ rather than trying a new matching if the right-hand side fails. If
+ the right-hand side of the selected branch is a tactic with
+ backtracking points, then subsequent failures cause this tactic to
+ backtrack.
+
+ .. tacv:: context @ident [@cpattern]
+
+ This special form of patterns matches any term with a subterm matching
+ cpattern. If there is a match, the optional :n:`@ident` is assigned the "matched
+ context", i.e. the initial term where the matched subterm is replaced by a
+ hole. The example below will show how to use such term contexts.
+
+ If the evaluation of the right-hand-side of a valid match fails, the next
+ matching subterm is tried. If no further subterm matches, the next clause
+ is tried. Matching subterms are considered top-bottom and from left to
+ right (with respect to the raw printing obtained by setting option
+ :flag:`Printing All`).
+
+ .. example::
+
+ .. coqtop:: all abort
+
+ Ltac f x :=
+ match x with
+ context f [S ?X] =>
+ idtac X; (* To display the evaluation order *)
+ assert (p := eq_refl 1 : X=1); (* To filter the case X=1 *)
+ let x:= context f[O] in assert (x=O) (* To observe the context *)
+ end.
+ Goal True.
+ f (3+4).
+
+.. _ltac-match-goal:
+
+Pattern matching on goals
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We can perform pattern matching on goals using the following expression:
+
+.. we should provide the full grammar here
+
+.. tacn:: match goal with {+| {+ hyp} |- @cpattern => @expr } | _ => @expr end
+ :name: match goal
+
+ If each hypothesis pattern :n:`hyp`\ :sub:`1,i`, with i = 1, ..., m\ :sub:`1` is
+ matched (non-linear first-order unification) by a hypothesis of the
+ goal and if :n:`cpattern_1` is matched by the conclusion of the goal,
+ then :n:`@expr__1` is evaluated to :n:`v__1` by substituting the
+ pattern matching to the metavariables and the real hypothesis names
+ bound to the possible hypothesis names occurring in the hypothesis
+ patterns. If :n:`v__1` is a tactic value, then it is applied to the
+ goal. If this application fails, then another combination of hypotheses
+ is tried with the same proof context pattern. If there is no other
+ combination of hypotheses then the second proof context pattern is tried
+ and so on. If the next to last proof context pattern fails then
+ the last :n:`@expr` is evaluated to :n:`v` and :n:`v` is
+ applied. Note also that matching against subterms (using the :n:`context
+ @ident [ @cpattern ]`) is available and is also subject to yielding several
+ matchings.
+
+ Failures in subsequent tactics do not cause backtracking to select new
+ branches or combinations of hypotheses, or inside the right-hand side of
+ the selected branch even if it has backtracking points.
+
+ .. exn:: No matching clauses for match goal.
+
+ No clause succeeds, i.e. all matching patterns, if any, fail at the
+ application of the right-hand-side.
+
+ .. note::
+
+ It is important to know that each hypothesis of the goal can be matched
+ by at most one hypothesis pattern. The order of matching is the
+ following: hypothesis patterns are examined from right to left
+ (i.e. hyp\ :sub:`i,m`\ :sub:`i`` before hyp\ :sub:`i,1`). For each
+ hypothesis pattern, the goal hypotheses are matched in order (newest
+ first), but it possible to reverse this order (oldest first)
+ with the :n:`match reverse goal with` variant.
+
+ .. tacv:: multimatch goal with {+| {+ hyp} |- @cpattern => @expr } | _ => @expr end
+
+ Using :n:`multimatch` instead of :n:`match` will allow subsequent tactics
+ to backtrack into a right-hand side tactic which has backtracking points
+ left and trigger the selection of a new matching branch or combination of
+ hypotheses when all the backtracking points of the right-hand side have
+ been consumed.
+
+ The syntax :n:`match [reverse] goal …` is, in fact, a shorthand for
+ :n:`once multimatch [reverse] goal …`.
+
+ .. tacv:: lazymatch goal with {+| {+ hyp} |- @cpattern => @expr } | _ => @expr end
+
+ Using lazymatch instead of match will perform the same pattern matching
+ procedure but will commit to the first matching branch with the first
+ matching combination of hypotheses rather than trying a new matching if
+ the right-hand side fails. If the right-hand side of the selected branch
+ is a tactic with backtracking points, then subsequent failures cause
+ this tactic to backtrack.
+
+Filling a term context
+~~~~~~~~~~~~~~~~~~~~~~
+
+The following expression is not a tactic in the sense that it does not
+produce subgoals but generates a term to be used in tactic expressions:
+
+.. tacn:: context @ident [@expr]
+
+ :n:`@ident` must denote a context variable bound by a context pattern of a
+ match expression. This expression evaluates replaces the hole of the
+ value of :n:`@ident` by the value of :n:`@expr`.
+
+ .. exn:: Not a context variable.
+ :undocumented:
+
+ .. exn:: Unbound context identifier @ident.
+ :undocumented:
+
+Generating fresh hypothesis names
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Tactics sometimes have to generate new names for hypothesis. Letting the
+system decide a name with the intro tactic is not so good since it is
+very awkward to retrieve the name the system gave. The following
+expression returns an identifier:
+
+.. tacn:: fresh {* component}
+
+ It evaluates to an identifier unbound in the goal. This fresh identifier
+ is obtained by concatenating the value of the :n:`@component`\ s (each of them
+ is, either a :n:`@qualid` which has to refer to a (unqualified) name, or
+ directly a name denoted by a :n:`@string`).
+
+ If the resulting name is already used, it is padded with a number so that it
+ becomes fresh. If no component is given, the name is a fresh derivative of
+ the name ``H``.
+
+Computing in a constr
+~~~~~~~~~~~~~~~~~~~~~
+
+Evaluation of a term can be performed with:
+
+.. tacn:: eval @redexpr in @term
+
+ where :n:`@redexpr` is a reduction tactic among :tacn:`red`, :tacn:`hnf`,
+ :tacn:`compute`, :tacn:`simpl`, :tacn:`cbv`, :tacn:`lazy`, :tacn:`unfold`,
+ :tacn:`fold`, :tacn:`pattern`.
+
+Recovering the type of a term
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. tacn:: type of @term
+
+ This tactic returns the type of :token:`term`.
+
+Manipulating untyped terms
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. tacn:: uconstr : @term
+
+ The terms built in |Ltac| are well-typed by default. It may not be
+ appropriate for building large terms using a recursive |Ltac| function: the
+ term has to be entirely type checked at each step, resulting in potentially
+ very slow behavior. It is possible to build untyped terms using |Ltac| with
+ the :n:`uconstr : @term` syntax.
+
+.. tacn:: type_term @term
+
+ An untyped term, in |Ltac|, can contain references to hypotheses or to
+ |Ltac| variables containing typed or untyped terms. An untyped term can be
+ type checked using the function type_term whose argument is parsed as an
+ untyped term and returns a well-typed term which can be used in tactics.
+
+Untyped terms built using :n:`uconstr :` can also be used as arguments to the
+:tacn:`refine` tactic. In that case the untyped term is type
+checked against the conclusion of the goal, and the holes which are not solved
+by the typing procedure are turned into new subgoals.
+
+Counting the goals
+~~~~~~~~~~~~~~~~~~
+
+.. tacn:: numgoals
+
+ The number of goals under focus can be recovered using the :n:`numgoals`
+ function. Combined with the guard command below, it can be used to
+ branch over the number of goals produced by previous tactics.
+
+ .. example::
+
+ .. coqtop:: in
+
+ Ltac pr_numgoals := let n := numgoals in idtac "There are" n "goals".
+
+ Goal True /\ True /\ True.
+ split;[|split].
+
+ .. coqtop:: all abort
+
+ all:pr_numgoals.
+
+Testing boolean expressions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. tacn:: guard @test
+ :name: guard
+
+ The :tacn:`guard` tactic tests a boolean expression, and fails if the expression
+ evaluates to false. If the expression evaluates to true, it succeeds
+ without affecting the proof.
+
+ The accepted tests are simple integer comparisons.
+
+ .. example::
+
+ .. coqtop:: in
+
+ Goal True /\ True /\ True.
+ split;[|split].
+
+ .. coqtop:: all
+
+ all:let n:= numgoals in guard n<4.
+ Fail all:let n:= numgoals in guard n=2.
+
+ .. exn:: Condition not satisfied.
+ :undocumented:
+
+Proving a subgoal as a separate lemma
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. tacn:: abstract @expr
+ :name: abstract
+
+ From the outside, :n:`abstract @expr` is the same as :n:`solve @expr`.
+ Internally it saves an auxiliary lemma called ``ident_subproofn`` where
+ ``ident`` is the name of the current goal and ``n`` is chosen so that this is
+ a fresh name. Such an auxiliary lemma is inlined in the final proof term.
+
+ This tactical is useful with tactics such as :tacn:`omega` or
+ :tacn:`discriminate` that generate huge proof terms. With that tool the user
+ can avoid the explosion at time of the Save command without having to cut
+ manually the proof in smaller lemmas.
+
+ It may be useful to generate lemmas minimal w.r.t. the assumptions they
+ depend on. This can be obtained thanks to the option below.
+
+ .. warning::
+
+ The abstract tactic, while very useful, still has some known
+ limitations, see https://github.com/coq/coq/issues/9146 for more
+ details. Thus we recommend using it caution in some
+ "non-standard" contexts. In particular, ``abstract`` won't
+ properly work when used inside quotations ``ltac:(...)``, or
+ if used as part of typeclass resolution, it may produce wrong
+ terms when in universe polymorphic mode.
+
+ .. tacv:: abstract @expr using @ident
+
+ Give explicitly the name of the auxiliary lemma.
+
+ .. warning::
+
+ Use this feature at your own risk; explicitly named and reused subterms
+ don’t play well with asynchronous proofs.
+
+ .. tacv:: transparent_abstract @expr
+ :name: transparent_abstract
+
+ Save the subproof in a transparent lemma rather than an opaque one.
+
+ .. warning::
+
+ Use this feature at your own risk; building computationally relevant
+ terms with tactics is fragile.
+
+ .. tacv:: transparent_abstract @expr using @ident
+
+ Give explicitly the name of the auxiliary transparent lemma.
+
+ .. warning::
+
+ Use this feature at your own risk; building computationally relevant terms
+ with tactics is fragile, and explicitly named and reused subterms
+ don’t play well with asynchronous proofs.
+
+ .. exn:: Proof is not complete.
+ :name: Proof is not complete. (abstract)
+ :undocumented:
+
+Tactic toplevel definitions
+---------------------------
+
+Defining |Ltac| functions
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Basically, |Ltac| toplevel definitions are made as follows:
+
+.. cmd:: Ltac @ident {* @ident} := @expr
+
+ This defines a new |Ltac| function that can be used in any tactic
+ script or new |Ltac| toplevel definition.
+
+ .. note::
+
+ The preceding definition can equivalently be written:
+
+ :n:`Ltac @ident := fun {+ @ident} => @expr`
+
+ Recursive and mutual recursive function definitions are also possible
+ with the syntax:
+
+ .. cmdv:: Ltac @ident {* @ident} {* with @ident {* @ident}} := @expr
+
+ It is also possible to *redefine* an existing user-defined tactic using the syntax:
+
+ .. cmdv:: Ltac @qualid {* @ident} ::= @expr
+
+ A previous definition of qualid must exist in the environment. The new
+ definition will always be used instead of the old one and it goes across
+ module boundaries.
+
+ If preceded by the keyword Local the tactic definition will not be
+ exported outside the current module.
+
+Printing |Ltac| tactics
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. cmd:: Print Ltac @qualid
+
+ Defined |Ltac| functions can be displayed using this command.
+
+.. cmd:: Print Ltac Signatures
+
+ This command displays a list of all user-defined tactics, with their arguments.
+
+Debugging |Ltac| tactics
+------------------------
+
+Backtraces
+~~~~~~~~~~
+
+.. flag:: Ltac Backtrace
+
+ Setting this flag displays a backtrace on Ltac failures that can be useful
+ to find out what went wrong. It is disabled by default for performance
+ reasons.
+
+Info trace
+~~~~~~~~~~
+
+.. cmd:: Info @num @expr
+ :name: Info
+
+ This command can be used to print the trace of the path eventually taken by an
+ |Ltac| script. That is, the list of executed tactics, discarding
+ all the branches which have failed. To that end the :cmd:`Info` command can be
+ used with the following syntax.
+
+
+ The number :n:`@num` is the unfolding level of tactics in the trace. At level
+ 0, the trace contains a sequence of tactics in the actual script, at level 1,
+ the trace will be the concatenation of the traces of these tactics, etc…
+
+ .. example::
+
+ .. coqtop:: in reset
+
+ Ltac t x := exists x; reflexivity.
+ Goal exists n, n=0.
+
+ .. coqtop:: all
+
+ Info 0 t 1||t 0.
+
+ .. coqtop:: in
+
+ Undo.
+
+ .. coqtop:: all
+
+ Info 1 t 1||t 0.
+
+ The trace produced by :cmd:`Info` tries its best to be a reparsable
+ |Ltac| script, but this goal is not achievable in all generality.
+ So some of the output traces will contain oddities.
+
+ As an additional help for debugging, the trace produced by :cmd:`Info` contains
+ (in comments) the messages produced by the :tacn:`idtac` tactical at the right
+ position in the script. In particular, the calls to idtac in branches which failed are
+ not printed.
+
+ .. opt:: Info Level @num
+ :name: Info Level
+
+ This option is an alternative to the :cmd:`Info` command.
+
+ This will automatically print the same trace as :n:`Info @num` at each
+ tactic call. The unfolding level can be overridden by a call to the
+ :cmd:`Info` command.
+
+Interactive debugger
+~~~~~~~~~~~~~~~~~~~~
+
+.. flag:: Ltac Debug
+
+ This option governs the step-by-step debugger that comes with the |Ltac| interpreter.
+
+When the debugger is activated, it stops at every step of the evaluation of
+the current |Ltac| expression and prints information on what it is doing.
+The debugger stops, prompting for a command which can be one of the
+following:
+
++-----------------+-----------------------------------------------+
+| simple newline: | go to the next step |
++-----------------+-----------------------------------------------+
+| h: | get help |
++-----------------+-----------------------------------------------+
+| x: | exit current evaluation |
++-----------------+-----------------------------------------------+
+| s: | continue current evaluation without stopping |
++-----------------+-----------------------------------------------+
+| r n: | advance n steps further |
++-----------------+-----------------------------------------------+
+| r string: | advance up to the next call to “idtac string” |
++-----------------+-----------------------------------------------+
+
+.. exn:: Debug mode not available in the IDE
+ :undocumented:
+
+A non-interactive mode for the debugger is available via the option:
+
+.. flag:: Ltac Batch Debug
+
+ This option has the effect of presenting a newline at every prompt, when
+ the debugger is on. The debug log thus created, which does not require
+ user input to generate when this option is set, can then be run through
+ external tools such as diff.
+
+Profiling |Ltac| tactics
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+It is possible to measure the time spent in invocations of primitive
+tactics as well as tactics defined in |Ltac| and their inner
+invocations. The primary use is the development of complex tactics,
+which can sometimes be so slow as to impede interactive usage. The
+reasons for the performence degradation can be intricate, like a slowly
+performing |Ltac| match or a sub-tactic whose performance only
+degrades in certain situations. The profiler generates a call tree and
+indicates the time spent in a tactic depending on its calling context. Thus
+it allows to locate the part of a tactic definition that contains the
+performance issue.
+
+.. flag:: Ltac Profiling
+
+ This option enables and disables the profiler.
+
+.. cmd:: Show Ltac Profile
+
+ Prints the profile
+
+ .. cmdv:: Show Ltac Profile @string
+
+ Prints a profile for all tactics that start with :n:`@string`. Append a period
+ (.) to the string if you only want exactly that name.
+
+.. cmd:: Reset Ltac Profile
+
+ Resets the profile, that is, deletes all accumulated information.
+
+ .. warning::
+
+ Backtracking across a :cmd:`Reset Ltac Profile` will not restore the information.
+
+.. coqtop:: reset in
+
+ Require Import Coq.omega.Omega.
+
+ Ltac mytauto := tauto.
+ Ltac tac := intros; repeat split; omega || mytauto.
+
+ Notation max x y := (x + (y - x)) (only parsing).
+
+ Goal forall x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z,
+ max x (max y z) = max (max x y) z /\ max x (max y z) = max (max x y) z
+ /\
+ (A /\ B /\ C /\ D /\ E /\ F /\ G /\ H /\ I /\ J /\ K /\ L /\ M /\
+ N /\ O /\ P /\ Q /\ R /\ S /\ T /\ U /\ V /\ W /\ X /\ Y /\ Z
+ ->
+ Z /\ Y /\ X /\ W /\ V /\ U /\ T /\ S /\ R /\ Q /\ P /\ O /\ N /\
+ M /\ L /\ K /\ J /\ I /\ H /\ G /\ F /\ E /\ D /\ C /\ B /\ A).
+ Proof.
+
+.. coqtop:: all
+
+ Set Ltac Profiling.
+ tac.
+ Show Ltac Profile.
+ Show Ltac Profile "omega".
+
+.. coqtop:: in
+
+ Abort.
+ Unset Ltac Profiling.
+
+.. tacn:: start ltac profiling
+ :name: start ltac profiling
+
+ This tactic behaves like :tacn:`idtac` but enables the profiler.
+
+.. tacn:: stop ltac profiling
+ :name: stop ltac profiling
+
+ Similarly to :tacn:`start ltac profiling`, this tactic behaves like
+ :tacn:`idtac`. Together, they allow you to exclude parts of a proof script
+ from profiling.
+
+.. tacn:: reset ltac profile
+ :name: reset ltac profile
+
+ This tactic behaves like the corresponding vernacular command
+ and allow displaying and resetting the profile from tactic scripts for
+ benchmarking purposes.
+
+.. tacn:: show ltac profile
+ :name: show ltac profile
+
+ This tactic behaves like the corresponding vernacular command
+ and allow displaying and resetting the profile from tactic scripts for
+ benchmarking purposes.
+
+.. tacn:: show ltac profile @string
+ :name: show ltac profile
+
+ This tactic behaves like the corresponding vernacular command
+ and allow displaying and resetting the profile from tactic scripts for
+ benchmarking purposes.
+
+You can also pass the ``-profile-ltac`` command line option to ``coqc``, which
+turns the :flag:`Ltac Profiling` option on at the beginning of each document,
+and performs a :cmd:`Show Ltac Profile` at the end.
+
+.. warning::
+
+ Note that the profiler currently does not handle backtracking into
+ multi-success tactics, and issues a warning to this effect in many cases
+ when such backtracking occurs.
+
+Run-time optimization tactic
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. tacn:: optimize_heap
+ :name: optimize_heap
+
+ This tactic behaves like :n:`idtac`, except that running it compacts the
+ heap in the OCaml run-time system. It is analogous to the Vernacular
+ command :cmd:`Optimize Heap`.
diff --git a/doc/sphinx/proof-engine/proof-handling.rst b/doc/sphinx/proof-engine/proof-handling.rst
new file mode 100644
index 0000000000..16b158c397
--- /dev/null
+++ b/doc/sphinx/proof-engine/proof-handling.rst
@@ -0,0 +1,832 @@
+.. _proofhandling:
+
+-------------------
+ Proof handling
+-------------------
+
+In |Coq|’s proof editing mode all top-level commands documented in
+Chapter :ref:`vernacularcommands` remain available and the user has access to specialized
+commands dealing with proof development pragmas documented in this
+section. They can also use some other specialized commands called
+*tactics*. They are the very tools allowing the user to deal with
+logical reasoning. They are documented in Chapter :ref:`tactics`.
+
+Coq user interfaces usually have a way of marking whether the user has
+switched to proof editing mode. For instance, in coqtop the prompt ``Coq <``   is changed into
+:n:`@ident <`   where :token:`ident` is the declared name of the theorem currently edited.
+
+At each stage of a proof development, one has a list of goals to
+prove. Initially, the list consists only in the theorem itself. After
+having applied some tactics, the list of goals contains the subgoals
+generated by the tactics.
+
+To each subgoal is associated a number of hypotheses called the *local context*
+of the goal. Initially, the local context contains the local variables and
+hypotheses of the current section (see Section :ref:`gallina-assumptions`) and
+the local variables and hypotheses of the theorem statement. It is enriched by
+the use of certain tactics (see e.g. :tacn:`intro`).
+
+When a proof is completed, the message ``Proof completed`` is displayed.
+One can then register this proof as a defined constant in the
+environment. Because there exists a correspondence between proofs and
+terms of λ-calculus, known as the *Curry-Howard isomorphism*
+:cite:`How80,Bar81,Gir89,H89`, |Coq| stores proofs as terms of |Cic|. Those
+terms are called *proof terms*.
+
+
+.. exn:: No focused proof.
+
+ Coq raises this error message when one attempts to use a proof editing command
+ out of the proof editing mode.
+
+.. _proof-editing-mode:
+
+Switching on/off the proof editing mode
+-------------------------------------------
+
+The proof editing mode is entered by asserting a statement, which typically is
+the assertion of a theorem using an assertion command like :cmd:`Theorem`. The
+list of assertion commands is given in :ref:`Assertions`. The command
+:cmd:`Goal` can also be used.
+
+.. cmd:: Goal @form
+
+ This is intended for quick assertion of statements, without knowing in
+ advance which name to give to the assertion, typically for quick
+ testing of the provability of a statement. If the proof of the
+ statement is eventually completed and validated, the statement is then
+ bound to the name ``Unnamed_thm`` (or a variant of this name not already
+ used for another statement).
+
+.. cmd:: Qed
+
+ This command is available in interactive editing proof mode when the
+ proof is completed. Then :cmd:`Qed` extracts a proof term from the proof
+ script, switches back to Coq top-level and attaches the extracted
+ proof term to the declared name of the original goal. This name is
+ added to the environment as an opaque constant.
+
+ .. exn:: Attempt to save an incomplete proof.
+ :undocumented:
+
+ .. note::
+
+ Sometimes an error occurs when building the proof term, because
+ tactics do not enforce completely the term construction
+ constraints.
+
+ The user should also be aware of the fact that since the
+ proof term is completely rechecked at this point, one may have to wait
+ a while when the proof is large. In some exceptional cases one may
+ even incur a memory overflow.
+
+ .. cmdv:: Defined
+ :name: Defined
+
+ Same as :cmd:`Qed` but the proof is then declared transparent, which means
+ that its content can be explicitly used for type checking and that it can be
+ unfolded in conversion tactics (see :ref:`performingcomputations`,
+ :cmd:`Opaque`, :cmd:`Transparent`).
+
+ .. cmdv:: Save @ident
+ :name: Save
+
+ Forces the name of the original goal to be :token:`ident`. This
+ command (and the following ones) can only be used if the original goal
+ has been opened using the :cmd:`Goal` command.
+
+.. cmd:: Admitted
+
+ This command is available in interactive editing mode to give up
+ the current proof and declare the initial goal as an axiom.
+
+.. cmd:: Abort
+
+ This command cancels the current proof development, switching back to
+ the previous proof development, or to the |Coq| toplevel if no other
+ proof was edited.
+
+ .. exn:: No focused proof (No proof-editing in progress).
+ :undocumented:
+
+ .. cmdv:: Abort @ident
+
+ Aborts the editing of the proof named :token:`ident` (in case you have
+ nested proofs).
+
+ .. seealso:: :flag:`Nested Proofs Allowed`
+
+ .. cmdv:: Abort All
+
+ Aborts all current goals.
+
+.. cmd:: Proof @term
+ :name: Proof `term`
+
+ This command applies in proof editing mode. It is equivalent to
+ :n:`exact @term. Qed.`
+ That is, you have to give the full proof in one gulp, as a
+ proof term (see Section :ref:`applyingtheorems`).
+
+.. cmd:: Proof
+
+ Is a no-op which is useful to delimit the sequence of tactic commands
+ which start a proof, after a :cmd:`Theorem` command. It is a good practice to
+ use :cmd:`Proof` as an opening parenthesis, closed in the script with a
+ closing :cmd:`Qed`.
+
+ .. seealso:: :cmd:`Proof with`
+
+.. cmd:: Proof using {+ @ident }
+
+ This command applies in proof editing mode. It declares the set of
+ section variables (see :ref:`gallina-assumptions`) used by the proof.
+ At :cmd:`Qed` time, the
+ system will assert that the set of section variables actually used in
+ the proof is a subset of the declared one.
+
+ The set of declared variables is closed under type dependency. For
+ example, if ``T`` is a variable and ``a`` is a variable of type
+ ``T``, then the commands ``Proof using a`` and ``Proof using T a``
+ are equivalent.
+
+ .. cmdv:: Proof using {+ @ident } with @tactic
+
+ Combines in a single line :cmd:`Proof with` and :cmd:`Proof using`.
+
+ .. seealso:: :ref:`tactics-implicit-automation`
+
+ .. cmdv:: Proof using All
+
+ Use all section variables.
+
+ .. cmdv:: Proof using {? Type }
+
+ Use only section variables occurring in the statement.
+
+ .. cmdv:: Proof using Type*
+
+ The ``*`` operator computes the forward transitive closure. E.g. if the
+ variable ``H`` has type ``p < 5`` then ``H`` is in ``p*`` since ``p`` occurs in the type
+ of ``H``. ``Type*`` is the forward transitive closure of the entire set of
+ section variables occurring in the statement.
+
+ .. cmdv:: Proof using -({+ @ident })
+
+ Use all section variables except the list of :token:`ident`.
+
+ .. cmdv:: Proof using @collection1 + @collection2
+
+ Use section variables from the union of both collections.
+ See :ref:`nameaset` to know how to form a named collection.
+
+ .. cmdv:: Proof using @collection1 - @collection2
+
+ Use section variables which are in the first collection but not in the
+ second one.
+
+ .. cmdv:: Proof using @collection - ({+ @ident })
+
+ Use section variables which are in the first collection but not in the
+ list of :token:`ident`.
+
+ .. cmdv:: Proof using @collection *
+
+ Use section variables in the forward transitive closure of the collection.
+ The ``*`` operator binds stronger than ``+`` and ``-``.
+
+
+Proof using options
+```````````````````
+
+The following options modify the behavior of ``Proof using``.
+
+
+.. opt:: Default Proof Using "@expression"
+ :name: Default Proof Using
+
+ Use :n:`@expression` as the default ``Proof using`` value. E.g. ``Set Default
+ Proof Using "a b"`` will complete all ``Proof`` commands not followed by a
+ ``using`` part with ``using a b``.
+
+
+.. flag:: Suggest Proof Using
+
+ When :cmd:`Qed` is performed, suggest a ``using`` annotation if the user did not
+ provide one.
+
+.. _`nameaset`:
+
+Name a set of section hypotheses for ``Proof using``
+````````````````````````````````````````````````````
+
+.. cmd:: Collection @ident := @expression
+
+ This can be used to name a set of section
+ hypotheses, with the purpose of making ``Proof using`` annotations more
+ compact.
+
+ .. example::
+
+ Define the collection named ``Some`` containing ``x``, ``y`` and ``z``::
+
+ Collection Some := x y z.
+
+ Define the collection named ``Fewer`` containing only ``x`` and ``y``::
+
+ Collection Fewer := Some - z
+
+ Define the collection named ``Many`` containing the set union or set
+ difference of ``Fewer`` and ``Some``::
+
+ Collection Many := Fewer + Some
+ Collection Many := Fewer - Some
+
+ Define the collection named ``Many`` containing the set difference of
+ ``Fewer`` and the unnamed collection ``x y``::
+
+ Collection Many := Fewer - (x y)
+
+
+
+.. cmd:: Existential @num := @term
+
+ This command instantiates an existential variable. :token:`num` is an index in
+ the list of uninstantiated existential variables displayed by :cmd:`Show Existentials`.
+
+ This command is intended to be used to instantiate existential
+ variables when the proof is completed but some uninstantiated
+ existential variables remain. To instantiate existential variables
+ during proof edition, you should use the tactic :tacn:`instantiate`.
+
+.. cmd:: Grab Existential Variables
+
+ This command can be run when a proof has no more goal to be solved but
+ has remaining uninstantiated existential variables. It takes every
+ uninstantiated existential variable and turns it into a goal.
+
+
+Navigation in the proof tree
+--------------------------------
+
+.. cmd:: Undo
+
+ This command cancels the effect of the last command. Thus, it
+ backtracks one step.
+
+.. cmdv:: Undo @num
+
+ Repeats Undo :token:`num` times.
+
+.. cmdv:: Restart
+ :name: Restart
+
+ This command restores the proof editing process to the original goal.
+
+ .. exn:: No focused proof to restart.
+ :undocumented:
+
+.. cmd:: Focus
+
+ This focuses the attention on the first subgoal to prove and the
+ printing of the other subgoals is suspended until the focused subgoal
+ is solved or unfocused. This is useful when there are many current
+ subgoals which clutter your screen.
+
+ .. deprecated:: 8.8
+
+ Prefer the use of bullets or focusing brackets (see below).
+
+.. cmdv:: Focus @num
+
+ This focuses the attention on the :token:`num` th subgoal to prove.
+
+ .. deprecated:: 8.8
+
+ Prefer the use of focusing brackets with a goal selector (see below).
+
+.. cmd:: Unfocus
+
+ This command restores to focus the goal that were suspended by the
+ last :cmd:`Focus` command.
+
+ .. deprecated:: 8.8
+
+.. cmd:: Unfocused
+
+ Succeeds if the proof is fully unfocused, fails if there are some
+ goals out of focus.
+
+.. _curly-braces:
+
+.. index:: {
+ }
+
+.. cmd:: %{ %| %}
+
+ The command ``{`` (without a terminating period) focuses on the first
+ goal, much like :cmd:`Focus` does, however, the subproof can only be
+ unfocused when it has been fully solved ( *i.e.* when there is no
+ focused goal left). Unfocusing is then handled by ``}`` (again, without a
+ terminating period). See also an example in the next section.
+
+ Note that when a focused goal is proved a message is displayed
+ together with a suggestion about the right bullet or ``}`` to unfocus it
+ or focus the next one.
+
+ .. cmdv:: @num: %{
+
+ This focuses on the :token:`num`\-th subgoal to prove.
+
+ .. cmdv:: [@ident]: %{
+
+ This focuses on the named goal :token:`ident`.
+
+ .. note::
+
+ Goals are just existential variables and existential variables do not
+ get a name by default. You can give a name to a goal by using :n:`refine ?[@ident]`.
+ You may also wrap this in an Ltac-definition like:
+
+ .. coqtop:: in
+
+ Ltac name_goal name := refine ?[name].
+
+ .. seealso:: :ref:`existential-variables`
+
+ .. example::
+
+ This first example uses the Ltac definition above, and the named goals
+ only serve for documentation.
+
+ .. coqtop:: all
+
+ Goal forall n, n + 0 = n.
+ Proof.
+ induction n; [ name_goal base | name_goal step ].
+ [base]: {
+
+ .. coqtop:: all
+
+ reflexivity.
+
+ .. coqtop:: in
+
+ }
+
+ .. coqtop:: all
+
+ [step]: {
+
+ .. coqtop:: all
+
+ simpl.
+ f_equal.
+ assumption.
+ }
+ Qed.
+
+ This can also be a way of focusing on a shelved goal, for instance:
+
+ .. coqtop:: all
+
+ Goal exists n : nat, n = n.
+ eexists ?[x].
+ reflexivity.
+ [x]: exact 0.
+ Qed.
+
+ .. exn:: This proof is focused, but cannot be unfocused this way.
+
+ You are trying to use ``}`` but the current subproof has not been fully solved.
+
+ .. exn:: No such goal (@num).
+ :undocumented:
+
+ .. exn:: No such goal (@ident).
+ :undocumented:
+
+ .. exn:: Brackets do not support multi-goal selectors.
+
+ Brackets are used to focus on a single goal given either by its position
+ or by its name if it has one.
+
+ .. seealso:: The error messages about bullets below.
+
+.. _bullets:
+
+Bullets
+```````
+
+Alternatively to ``{`` and ``}``, proofs can be structured with bullets. The
+use of a bullet ``b`` for the first time focuses on the first goal ``g``, the
+same bullet cannot be used again until the proof of ``g`` is completed,
+then it is mandatory to focus the next goal with ``b``. The consequence is
+that ``g`` and all goals present when ``g`` was focused are focused with the
+same bullet ``b``. See the example below.
+
+Different bullets can be used to nest levels. The scope of bullet does
+not go beyond enclosing ``{`` and ``}``, so bullets can be reused as further
+nesting levels provided they are delimited by these. Bullets are made of
+repeated ``-``, ``+`` or ``*`` symbols:
+
+.. prodn:: bullet ::= {+ - } %| {+ + } %| {+ * }
+
+Note again that when a focused goal is proved a message is displayed
+together with a suggestion about the right bullet or ``}`` to unfocus it
+or focus the next one.
+
+.. note::
+
+ In Proof General (``Emacs`` interface to |Coq|), you must use
+ bullets with the priority ordering shown above to have a correct
+ indentation. For example ``-`` must be the outer bullet and ``**`` the inner
+ one in the example below.
+
+The following example script illustrates all these features:
+
+.. example::
+
+ .. coqtop:: all
+
+ Goal (((True /\ True) /\ True) /\ True) /\ True.
+ Proof.
+ split.
+ - split.
+ + split.
+ ** { split.
+ - trivial.
+ - trivial.
+ }
+ ** trivial.
+ + trivial.
+ - assert True.
+ { trivial. }
+ assumption.
+ Qed.
+
+.. exn:: Wrong bullet @bullet__1: Current bullet @bullet__2 is not finished.
+
+ Before using bullet :n:`@bullet__1` again, you should first finish proving
+ the current focused goal.
+ Note that :n:`@bullet__1` and :n:`@bullet__2` may be the same.
+
+.. exn:: Wrong bullet @bullet__1: Bullet @bullet__2 is mandatory here.
+
+ You must put :n:`@bullet__2` to focus on the next goal. No other bullet is
+ allowed here.
+
+.. exn:: No such goal. Focus next goal with bullet @bullet.
+
+ You tried to apply a tactic but no goals were under focus.
+ Using :n:`@bullet` is mandatory here.
+
+.. FIXME: the :noindex: below works around a Sphinx issue.
+ (https://github.com/sphinx-doc/sphinx/issues/4979)
+ It should be removed once that issue is fixed.
+
+.. exn:: No such goal. Try unfocusing with %}.
+ :noindex:
+
+ You just finished a goal focused by ``{``, you must unfocus it with ``}``.
+
+Set Bullet Behavior
+```````````````````
+.. opt:: Bullet Behavior %( "None" %| "Strict Subproofs" %)
+ :name: Bullet Behavior
+
+ This option controls the bullet behavior and can take two possible values:
+
+ - "None": this makes bullets inactive.
+ - "Strict Subproofs": this makes bullets active (this is the default behavior).
+
+.. _requestinginformation:
+
+Requesting information
+----------------------
+
+
+.. cmd:: Show
+
+ This command displays the current goals.
+
+ .. exn:: No focused proof.
+ :undocumented:
+
+ .. cmdv:: Show @num
+
+ Displays only the :token:`num`\-th subgoal.
+
+ .. exn:: No such goal.
+ :undocumented:
+
+ .. cmdv:: Show @ident
+
+ Displays the named goal :token:`ident`. This is useful in
+ particular to display a shelved goal but only works if the
+ corresponding existential variable has been named by the user
+ (see :ref:`existential-variables`) as in the following example.
+
+ .. example::
+
+ .. coqtop:: all abort
+
+ Goal exists n, n = 0.
+ eexists ?[n].
+ Show n.
+
+ .. cmdv:: Show Script
+ :name: Show Script
+
+ Displays the whole list of tactics applied from the
+ beginning of the current proof. This tactics script may contain some
+ holes (subgoals not yet proved). They are printed under the form
+
+ ``<Your Tactic Text here>``.
+
+ .. deprecated:: 8.10
+
+ Please use a text editor.
+
+ .. cmdv:: Show Proof
+ :name: Show Proof
+
+ It displays the proof term generated by the tactics
+ that have been applied. If the proof is not completed, this term
+ contain holes, which correspond to the sub-terms which are still to be
+ constructed. These holes appear as a question mark indexed by an
+ integer, and applied to the list of variables in the context, since it
+ may depend on them. The types obtained by abstracting away the context
+ from the type of each placeholder are also printed.
+
+ .. cmdv:: Show Conjectures
+ :name: Show Conjectures
+
+ It prints the list of the names of all the
+ theorems that are currently being proved. As it is possible to start
+ proving a previous lemma during the proof of a theorem, this list may
+ contain several names.
+
+ .. cmdv:: Show Intro
+ :name: Show Intro
+
+ If the current goal begins by at least one product,
+ this command prints the name of the first product, as it would be
+ generated by an anonymous :tacn:`intro`. The aim of this command is to ease
+ the writing of more robust scripts. For example, with an appropriate
+ Proof General macro, it is possible to transform any anonymous :tacn:`intro`
+ into a qualified one such as ``intro y13``. In the case of a non-product
+ goal, it prints nothing.
+
+ .. cmdv:: Show Intros
+ :name: Show Intros
+
+ This command is similar to the previous one, it
+ simulates the naming process of an :tacn:`intros`.
+
+ .. cmdv:: Show Existentials
+ :name: Show Existentials
+
+ It displays the set of all uninstantiated
+ existential variables in the current proof tree, along with the type
+ and the context of each variable.
+
+ .. cmdv:: Show Match @ident
+
+ This variant displays a template of the Gallina
+ ``match`` construct with a branch for each constructor of the type
+ :token:`ident`
+
+ .. example::
+
+ .. coqtop:: all
+
+ Show Match nat.
+
+ .. exn:: Unknown inductive type.
+ :undocumented:
+
+ .. cmdv:: Show Universes
+ :name: Show Universes
+
+ It displays the set of all universe constraints and
+ its normalized form at the current stage of the proof, useful for
+ debugging universe inconsistencies.
+
+
+.. cmd:: Guarded
+
+ Some tactics (e.g. :tacn:`refine`) allow to build proofs using
+ fixpoint or co-fixpoint constructions. Due to the incremental nature
+ of interactive proof construction, the check of the termination (or
+ guardedness) of the recursive calls in the fixpoint or cofixpoint
+ constructions is postponed to the time of the completion of the proof.
+
+ The command :cmd:`Guarded` allows checking if the guard condition for
+ fixpoint and cofixpoint is violated at some time of the construction
+ of the proof without having to wait the completion of the proof.
+
+.. _showing_diffs:
+
+Showing differences between proof steps
+---------------------------------------
+
+
+Coq can automatically highlight the differences between successive proof steps and between
+values in some error messages.
+For example, the following screenshots of CoqIDE and coqtop show the application
+of the same :tacn:`intros` tactic. The tactic creates two new hypotheses, highlighted in green.
+The conclusion is entirely in pale green because although it’s changed, no tokens were added
+to it. The second screenshot uses the "removed" option, so it shows the conclusion a
+second time with the old text, with deletions marked in red. Also, since the hypotheses are
+new, no line of old text is shown for them.
+
+.. comment screenshot produced with:
+ Inductive ev : nat -> Prop :=
+ | ev_0 : ev 0
+ | ev_SS : forall n : nat, ev n -> ev (S (S n)).
+
+ Fixpoint double (n:nat) :=
+ match n with
+ | O => O
+ | S n' => S (S (double n'))
+ end.
+
+ Goal forall n, ev n -> exists k, n = double k.
+ intros n E.
+
+..
+
+ .. image:: ../_static/diffs-coqide-on.png
+ :alt: |CoqIDE| with Set Diffs on
+
+..
+
+ .. image:: ../_static/diffs-coqide-removed.png
+ :alt: |CoqIDE| with Set Diffs removed
+
+..
+
+ .. image:: ../_static/diffs-coqtop-on3.png
+ :alt: coqtop with Set Diffs on
+
+This image shows an error message with diff highlighting in CoqIDE:
+
+..
+
+ .. image:: ../_static/diffs-error-message.png
+ :alt: |CoqIDE| error message with diffs
+
+How to enable diffs
+```````````````````
+
+.. opt:: Diffs %( "on" %| "off" %| "removed" %)
+ :name: Diffs
+
+ The “on” setting highlights added tokens in green, while the “removed” setting
+ additionally reprints items with removed tokens in red. Unchanged tokens in
+ modified items are shown with pale green or red. Diffs in error messages
+ use red and green for the compared values; they appear regardless of the setting.
+ (Colors are user-configurable.)
+
+For coqtop, showing diffs can be enabled when starting coqtop with the
+``-diffs on|off|removed`` command-line option or by setting the :opt:`Diffs` option
+within Coq. You will need to provide the ``-color on|auto`` command-line option when
+you start coqtop in either case.
+
+Colors for coqtop can be configured by setting the ``COQ_COLORS`` environment
+variable. See section :ref:`customization-by-environment-variables`. Diffs
+use the tags ``diff.added``, ``diff.added.bg``, ``diff.removed`` and ``diff.removed.bg``.
+
+In CoqIDE, diffs should be enabled from the ``View`` menu. Don’t use the ``Set Diffs``
+command in CoqIDE. You can change the background colors shown for diffs from the
+``Edit | Preferences | Tags`` panel by changing the settings for the ``diff.added``,
+``diff.added.bg``, ``diff.removed`` and ``diff.removed.bg`` tags. This panel also
+lets you control other attributes of the highlights, such as the foreground
+color, bold, italic, underline and strikeout.
+
+Note: As of this writing (August 2018), Proof General will need minor changes
+to be able to show diffs correctly. We hope it will support this feature soon.
+See https://github.com/ProofGeneral/PG/issues/381 for the current status.
+
+How diffs are calculated
+````````````````````````
+
+Diffs are calculated as follows:
+
+1. Select the old proof state to compare to, which is the proof state before
+ the last tactic that changed the proof. Changes that only affect the view
+ of the proof, such as ``all: swap 1 2``, are ignored.
+
+2. For each goal in the new proof state, determine what old goal to compare
+ it to—the one it is derived from or is the same as. Match the hypotheses by
+ name (order is ignored), handling compacted items specially.
+
+3. For each hypothesis and conclusion (the “items”) in each goal, pass
+ them as strings to the lexer to break them into tokens. Then apply the
+ Myers diff algorithm :cite:`Myers` on the tokens and add appropriate highlighting.
+
+Notes:
+
+* Aside from the highlights, output for the "on" option should be identical
+ to the undiffed output.
+* Goals completed in the last proof step will not be shown even with the
+ "removed" setting.
+
+.. comment The following screenshots show diffs working with multiple goals and with compacted
+ hypotheses. In the first one, notice that the goal ``P 1`` is not highlighted at
+ all after the split because it has not changed.
+
+ .. todo: Use this script and remove the screenshots when COQ_COLORS
+ works for coqtop in sphinx
+ .. coqtop:: none
+
+ Set Diffs "on".
+ Parameter P : nat -> Prop.
+ Goal P 1 /\ P 2 /\ P 3.
+
+ .. coqtop:: out
+
+ split.
+
+ .. coqtop:: all abort
+
+ 2: split.
+
+ ..
+
+ .. coqtop:: none
+
+ Set Diffs "on".
+ Goal forall n m : nat, n + m = m + n.
+ Set Diffs "on".
+
+ .. coqtop:: out
+
+ intros n.
+
+ .. coqtop:: all abort
+
+ intros m.
+
+This screen shot shows the result of applying a :tacn:`split` tactic that replaces one goal
+with 2 goals. Notice that the goal ``P 1`` is not highlighted at all after
+the split because it has not changed.
+
+..
+
+ .. image:: ../_static/diffs-coqide-multigoal.png
+ :alt: coqide with Set Diffs on with multiple goals
+
+This is how diffs may appear after applying a :tacn:`intro` tactic that results
+in compacted hypotheses:
+
+..
+
+ .. image:: ../_static/diffs-coqide-compacted.png
+ :alt: coqide with Set Diffs on with compacted hyptotheses
+
+Controlling the effect of proof editing commands
+------------------------------------------------
+
+
+.. opt:: Hyps Limit @num
+ :name: Hyps Limit
+
+ This option controls the maximum number of hypotheses displayed in goals
+ after the application of a tactic. All the hypotheses remain usable
+ in the proof development.
+ When unset, it goes back to the default mode which is to print all
+ available hypotheses.
+
+
+.. flag:: Nested Proofs Allowed
+
+ When turned on (it is off by default), this option enables support for nested
+ proofs: a new assertion command can be inserted before the current proof is
+ finished, in which case Coq will temporarily switch to the proof of this
+ *nested lemma*. When the proof of the nested lemma is finished (with :cmd:`Qed`
+ or :cmd:`Defined`), its statement will be made available (as if it had been
+ proved before starting the previous proof) and Coq will switch back to the
+ proof of the previous assertion.
+
+
+Controlling memory usage
+------------------------
+
+When experiencing high memory usage the following commands can be used
+to force |Coq| to optimize some of its internal data structures.
+
+
+.. cmd:: Optimize Proof
+
+ This command forces |Coq| to shrink the data structure used to represent
+ the ongoing proof.
+
+
+.. cmd:: Optimize Heap
+
+ This command forces the |OCaml| runtime to perform a heap compaction.
+ This is in general an expensive operation.
+ See: `OCaml Gc <http://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html#VALcompact>`_
+ There is also an analogous tactic :tacn:`optimize_heap`.
diff --git a/doc/sphinx/proof-engine/ssreflect-proof-language.rst b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
new file mode 100644
index 0000000000..b240cef40c
--- /dev/null
+++ b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
@@ -0,0 +1,5508 @@
+.. _thessreflectprooflanguage:
+
+------------------------------
+ The |SSR| proof language
+------------------------------
+
+:Authors: Georges Gonthier, Assia Mahboubi, Enrico Tassi
+
+
+Introduction
+------------
+
+This chapter describes a set of tactics known as |SSR| originally
+designed to provide support for the so-called *small scale reflection*
+proof methodology. Despite the original purpose this set of tactic is
+of general interest and is available in |Coq| starting from version 8.7.
+
+|SSR| was developed independently of the tactics described in
+Chapter :ref:`tactics`. Indeed the scope of the tactics part of |SSR| largely
+overlaps with the standard set of tactics. Eventually the overlap will
+be reduced in future releases of |Coq|.
+
+Proofs written in |SSR| typically look quite different from the
+ones written using only tactics as per Chapter :ref:`tactics`. We try to
+summarise here the most “visible” ones in order to help the reader
+already accustomed to the tactics described in Chapter :ref:`tactics` to read
+this chapter.
+
+The first difference between the tactics described in this chapter and the
+tactics described in Chapter :ref:`tactics` is the way hypotheses are managed
+(we call this *bookkeeping*). In Chapter :ref:`tactics` the most common
+approach is to avoid moving explicitly hypotheses back and forth between the
+context and the conclusion of the goal. On the contrary in |SSR| all
+bookkeeping is performed on the conclusion of the goal, using for that
+purpose a couple of syntactic constructions behaving similar to tacticals
+(and often named as such in this chapter). The ``:`` tactical moves hypotheses
+from the context to the conclusion, while ``=>`` moves hypotheses from the
+conclusion to the context, and ``in`` moves back and forth a hypothesis from the
+context to the conclusion for the time of applying an action to it.
+
+While naming hypotheses is commonly done by means of an ``as`` clause in the
+basic model of Chapter :ref:`tactics`, it is here to ``=>`` that this task is
+devoted. Tactics frequently leave new assumptions in the conclusion, and are
+often followed by ``=>`` to explicitly name them. While generalizing the
+goal is normally not explicitly needed in Chapter :ref:`tactics`, it is an
+explicit operation performed by ``:``.
+
+.. seealso:: :ref:`bookkeeping_ssr`
+
+Beside the difference of bookkeeping model, this chapter includes
+specific tactics which have no explicit counterpart in Chapter :ref:`tactics`
+such as tactics to mix forward steps and generalizations as
+:tacn:`generally have` or :tacn:`without loss`.
+
+|SSR| adopts the point of view that rewriting, definition
+expansion and partial evaluation participate all to a same concept of
+rewriting a goal in a larger sense. As such, all these functionalities
+are provided by the :tacn:`rewrite <rewrite (ssreflect)>` tactic.
+
+|SSR| includes a little language of patterns to select subterms in
+tactics or tacticals where it matters. Its most notable application is
+in the :tacn:`rewrite <rewrite (ssreflect)>` tactic, where patterns are
+used to specify where the rewriting step has to take place.
+
+Finally, |SSR| supports so-called reflection steps, typically
+allowing to switch back and forth between the computational view and
+logical view of a concept.
+
+To conclude it is worth mentioning that |SSR| tactics can be mixed
+with non |SSR| tactics in the same proof, or in the same Ltac
+expression. The few exceptions to this statement are described in
+section :ref:`compatibility_issues_ssr`.
+
+
+Acknowledgments
+~~~~~~~~~~~~~~~
+
+The authors would like to thank Frédéric Blanqui, François Pottier and
+Laurence Rideau for their comments and suggestions.
+
+
+Usage
+-----
+
+
+Getting started
+~~~~~~~~~~~~~~~
+
+To be available, the tactics presented in this manual need the
+following minimal set of libraries to be loaded: ``ssreflect.v``,
+``ssrfun.v`` and ``ssrbool.v``.
+Moreover, these tactics come with a methodology
+specific to the authors of |SSR| and which requires a few options
+to be set in a different way than in their default way. All in all,
+this corresponds to working in the following context:
+
+.. coqtop:: in
+
+ From Coq Require Import ssreflect ssrfun ssrbool.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+.. seealso::
+ :flag:`Implicit Arguments`, :flag:`Strict Implicit`,
+ :flag:`Printing Implicit Defensive`
+
+.. _compatibility_issues_ssr:
+
+
+Compatibility issues
+~~~~~~~~~~~~~~~~~~~~
+
+Requiring the above modules creates an environment which is mostly
+compatible with the rest of |Coq|, up to a few discrepancies:
+
+
++ New keywords (``is``) might clash with variable, constant, tactic or
+ tactical names, or with quasi-keywords in tactic or vernacular
+ notations.
++ New tactic(al)s names (:tacn:`last`, :tacn:`done`, :tacn:`have`, :tacn:`suffices`,
+ :tacn:`suff`, :tacn:`without loss`, :tacn:`wlog`, :tacn:`congr`, :tacn:`unlock`)
+ might clash with user tactic names.
++ Identifiers with both leading and trailing ``_``, such as ``_x_``, are
+ reserved by |SSR| and cannot appear in scripts.
++ The extensions to the :tacn:`rewrite` tactic are partly incompatible with those
+ available in current versions of |Coq|; in particular: ``rewrite .. in
+ (type of k)`` or ``rewrite .. in *`` or any other variant of :tacn:`rewrite`
+ will not work, and the |SSR| syntax and semantics for occurrence selection
+ and rule chaining is different. Use an explicit rewrite direction
+ (``rewrite <- …`` or ``rewrite -> …``) to access the |Coq| rewrite tactic.
++ New symbols (``//``, ``/=``, ``//=``) might clash with adjacent
+ existing symbols.
+ This can be avoided by inserting white spaces.
++ New constant and theorem names might clash with the user theory.
+ This can be avoided by not importing all of |SSR|:
+
+ .. coqtop:: in
+
+ From Coq Require ssreflect.
+ Import ssreflect.SsrSyntax.
+
+ Note that the full
+ syntax of |SSR|’s rewrite and reserved identifiers are enabled
+ only if the ssreflect module has been required and if ``SsrSyntax`` has
+ been imported. Thus a file that requires (without importing) ``ssreflect``
+ and imports ``SsrSyntax``, can be required and imported without
+ automatically enabling |SSR|’s extended rewrite syntax and
+ reserved identifiers.
++ Some user notations (in particular, defining an infix ``;``) might
+ interfere with the "open term", parenthesis free, syntax of tactics
+ such as have, set and pose.
++ The generalization of if statements to non-Boolean conditions is turned off
+ by |SSR|, because it is mostly subsumed by Coercion to ``bool`` of the
+ ``sumXXX`` types (declared in ``ssrfun.v``) and the
+ :n:`if @term is @pattern then @term else @term` construct
+ (see :ref:`pattern_conditional_ssr`). To use the
+ generalized form, turn off the |SSR| Boolean ``if`` notation using the command:
+ ``Close Scope boolean_if_scope``.
++ The following flags can be unset to make |SSR| more compatible with
+ parts of Coq:
+
+.. flag:: SsrRewrite
+
+ Controls whether the incompatible rewrite syntax is enabled (the default).
+ Disabling the flag makes the syntax compatible with other parts of Coq.
+
+.. flag:: SsrIdents
+
+ Controls whether tactics can refer to |SSR|-generated variables that are
+ in the form _xxx_. Scripts with explicit references to such variables
+ are fragile; they are prone to failure if the proof is later modified or
+ if the details of variable name generation change in future releases of Coq.
+
+ The default is on, which gives an error message when the user tries to
+ create such identifiers. Disabling the flag generates a warning instead,
+ increasing compatibility with other parts of Coq.
+
+|Gallina| extensions
+--------------------
+
+Small-scale reflection makes an extensive use of the programming
+subset of |Gallina|, |Coq|’s logical specification language. This subset
+is quite suited to the description of functions on representations,
+because it closely follows the well-established design of the ML
+programming language. The |SSR| extension provides three additions
+to |Gallina|, for pattern assignment, pattern testing, and polymorphism;
+these mitigate minor but annoying discrepancies between |Gallina| and
+ML.
+
+
+Pattern assignment
+~~~~~~~~~~~~~~~~~~
+
+The |SSR| extension provides the following construct for
+irrefutable pattern matching, that is, destructuring assignment:
+
+.. prodn::
+ term += let: @pattern := @term in @term
+
+Note the colon ``:`` after the ``let`` keyword, which avoids any ambiguity
+with a function definition or |Coq|’s basic destructuring let. The let:
+construct differs from the latter in that
+
+
++ The pattern can be nested (deep pattern matching), in particular,
+ this allows expression of the form:
+
+.. coqdoc::
+
+ let: exist (x, y) p_xy := Hp in … .
+
++ The destructured constructor is explicitly given in the pattern, and
+ is used for type inference.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Definition f u := let: (m, n) := u in m + n.
+ Check f.
+
+ Using :g:`let:` Coq infers a type for :g:`f`,
+ whereas with a usual ``let`` the same term requires an extra type
+ annotation in order to type check.
+
+ .. coqtop:: reset all
+
+ Fail Definition f u := let (m, n) := u in m + n.
+
+
+The ``let:`` construct is just (more legible) notation for the primitive
+|Gallina| expression :n:`match @term with @pattern => @term end`.
+
+The |SSR| destructuring assignment supports all the dependent
+match annotations; the full syntax is
+
+.. prodn::
+ term += let: @pattern {? as @ident} {? in @pattern} := @term {? return @term} in @term
+
+where the second :token:`pattern` and the second :token:`term` are *types*.
+
+When the ``as`` and ``return`` keywords are both present, then :token:`ident` is bound
+in both the second :token:`pattern` and the second :token:`term`; variables
+in the optional type :token:`pattern` are bound only in the second term, and
+other variables in the first :token:`pattern` are bound only in the third
+:token:`term`, however.
+
+
+.. _pattern_conditional_ssr:
+
+Pattern conditional
+~~~~~~~~~~~~~~~~~~~
+
+The following construct can be used for a refutable pattern matching,
+that is, pattern testing:
+
+.. prodn::
+ term += if @term is @pattern then @term else @term
+
+Although this construct is not strictly ML (it does exist in variants
+such as the pattern calculus or the ρ-calculus), it turns out to be
+very convenient for writing functions on representations, because most
+such functions manipulate simple data types such as Peano integers,
+options, lists, or binary trees, and the pattern conditional above is
+almost always the right construct for analyzing such simple types. For
+example, the null and all list function(al)s can be defined as follows:
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Variable d: Set.
+ Fixpoint null (s : list d) :=
+ if s is nil then true else false.
+ Variable a : d -> bool.
+ Fixpoint all (s : list d) : bool :=
+ if s is cons x s' then a x && all s' else true.
+
+The pattern conditional also provides a notation for destructuring
+assignment with a refutable pattern, adapted to the pure functional
+setting of |Gallina|, which lacks a ``Match_Failure`` exception.
+
+Like ``let:`` above, the ``if…is`` construct is just (more legible) notation
+for the primitive |Gallina| expression
+:n:`match @term with @pattern => @term | _ => @term end`.
+
+Similarly, it will always be displayed as the expansion of this form
+in terms of primitive match expressions (where the default expression
+may be replicated).
+
+Explicit pattern testing also largely subsumes the generalization of
+the ``if`` construct to all binary data types; compare
+:n:`if @term is inl _ then @term else @term` and
+:n:`if @term then @term else @term`.
+
+The latter appears to be marginally shorter, but it is quite
+ambiguous, and indeed often requires an explicit annotation
+``(term : {_} + {_})`` to type check, which evens the character count.
+
+Therefore, |SSR| restricts by default the condition of a plain if
+construct to the standard ``bool`` type; this avoids spurious type
+annotations.
+
+.. example::
+
+ .. coqtop:: all
+
+ Definition orb b1 b2 := if b1 then true else b2.
+
+As pointed out in section :ref:`compatibility_issues_ssr`,
+this restriction can be removed with
+the command:
+
+``Close Scope boolean_if_scope.``
+
+Like ``let:`` above, the ``if-is-then-else``
+construct supports
+the dependent match annotations:
+
+.. prodn::
+ term += if @term is @pattern as @ident in @pattern return @term then @term else @term
+
+As in ``let:`` the variable :token:`ident` (and those in the type pattern)
+are bound in the second :token:`term`; :token:`ident` is also bound in the
+third :token:`term` (but not in the fourth :token:`term`), while the
+variables in the first :token:`pattern` are bound only in the third
+:token:`term`.
+
+Another variant allows to treat the ``else`` case first:
+
+.. prodn::
+ term += if @term isn't @pattern then @term else @term
+
+Note that :token:`pattern` eventually binds variables in the third
+:token:`term` and not in the second :token:`term`.
+
+.. _parametric_polymorphism_ssr:
+
+Parametric polymorphism
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Unlike ML, polymorphism in core |Gallina| is explicit: the type
+parameters of polymorphic functions must be declared explicitly, and
+supplied at each point of use. However, |Coq| provides two features to
+suppress redundant parameters:
+
+
++ Sections are used to provide (possibly implicit) parameters for a
+ set of definitions.
++ Implicit arguments declarations are used to tell |Coq| to use type
+ inference to deduce some parameters from the context at each point of
+ call.
+
+
+The combination of these features provides a fairly good emulation of
+ML-style polymorphism, but unfortunately this emulation breaks down
+for higher-order programming. Implicit arguments are indeed not
+inferred at all points of use, but only at points of call, leading to
+expressions such as
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+ Variable T : Type.
+ Variable null : forall T : Type, T -> bool.
+ Variable all : (T -> bool) -> list T -> bool.
+
+ .. coqtop:: all
+
+ Definition all_null (s : list T) := all (@null T) s.
+
+Unfortunately, such higher-order expressions are quite frequent in
+representation functions, especially those which use |Coq|'s
+``Structures`` to emulate Haskell typeclasses.
+
+Therefore, |SSR| provides a variant of |Coq|’s implicit argument
+declaration, which causes |Coq| to fill in some implicit parameters at
+each point of use, e.g., the above definition can be written:
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+ Variable T : Type.
+ Variable null : forall T : Type, T -> bool.
+ Variable all : (T -> bool) -> list T -> bool.
+
+
+ .. coqtop:: all
+
+ Prenex Implicits null.
+ Definition all_null (s : list T) := all null s.
+
+Better yet, it can be omitted entirely, since :g:`all_null s` isn’t much of
+an improvement over :g:`all null s`.
+
+The syntax of the new declaration is
+
+.. cmd:: Prenex Implicits {+ @ident__i}
+
+ This command checks that each :n:`@ident__i` is the name of a functional
+ constant, whose implicit arguments are prenex, i.e., the first
+ :math:`n_i > 0` arguments of :n:`@ident__i` are implicit; then it assigns
+ ``Maximal Implicit`` status to these arguments.
+
+ As these prenex implicit arguments are ubiquitous and have often large
+ display strings, it is strongly recommended to change the default
+ display settings of |Coq| so that they are not printed (except after
+ a ``Set Printing All`` command). All |SSR| library files thus start
+ with the incantation
+
+ .. coqdoc::
+
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+
+Anonymous arguments
+~~~~~~~~~~~~~~~~~~~
+
+When in a definition, the type of a certain argument is mandatory, but
+not its name, one usually uses “arrow” abstractions for prenex
+arguments, or the ``(_ : term)`` syntax for inner arguments. In |SSR|,
+the latter can be replaced by the open syntax ``of term`` or
+(equivalently) ``& term``, which are both syntactically equivalent to a
+``(_ : term)`` expression. This feature almost behaves as the
+following extension of the binder syntax:
+
+.. prodn::
+ binder += & @term | of @term
+
+Caveat: ``& T`` and ``of T`` abbreviations have to appear at the end
+of a binder list. For instance, the usual two-constructor polymorphic
+type list, i.e. the one of the standard ``List`` library, can be
+defined by the following declaration:
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Inductive list (A : Type) : Type := nil | cons of A & list A.
+
+
+Wildcards
+~~~~~~~~~
+
+The terms passed as arguments to |SSR| tactics can contain
+*holes*, materialized by wildcards ``_``. Since |SSR| allows a more
+powerful form of type inference for these arguments, it enhances the
+possibilities of using such wildcards. These holes are in particular
+used as a convenient shorthand for abstractions, especially in local
+definitions or type expressions.
+
+Wildcards may be interpreted as abstractions (see for example sections
+:ref:`definitions_ssr` and ref:`structure_ssr`), or their content can be
+inferred from the whole context of the goal (see for example section
+:ref:`abbreviations_ssr`).
+
+
+.. _definitions_ssr:
+
+Definitions
+~~~~~~~~~~~
+
+.. tacn:: pose
+ :name: pose (ssreflect)
+
+ This tactic allows to add a defined constant to a proof context.
+ |SSR| generalizes this tactic in several ways. In particular, the
+ |SSR| pose tactic supports *open syntax*: the body of the
+ definition does not need surrounding parentheses. For instance:
+
+.. coqdoc::
+
+ pose t := x + y.
+
+is a valid tactic expression.
+
+The pose tactic is also improved for the local definition of higher
+order terms. Local definitions of functions can use the same syntax as
+global ones.
+For example, the tactic :tacn:`pose <pose (ssreflect)>` supoprts parameters:
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test : True.
+ pose f x y := x + y.
+
+The |SSR| pose tactic also supports (co)fixpoints, by providing
+the local counterpart of the ``Fixpoint f := …`` and ``CoFixpoint f := …``
+constructs. For instance, the following tactic:
+
+.. coqdoc::
+
+ pose fix f (x y : nat) {struct x} : nat :=
+ if x is S p then S (f p y) else 0.
+
+defines a local fixpoint ``f``, which mimics the standard plus operation
+on natural numbers.
+
+Similarly, local cofixpoints can be defined by a tactic of the form:
+
+.. coqdoc::
+
+ pose cofix f (arg : T) := … .
+
+The possibility to include wildcards in the body of the definitions
+offers a smooth way of defining local abstractions. The type of
+“holes” is guessed by type inference, and the holes are abstracted.
+For instance the tactic:
+
+.. coqdoc::
+
+ pose f := _ + 1.
+
+is shorthand for:
+
+.. coqdoc::
+
+ pose f n := n + 1.
+
+When the local definition of a function involves both arguments and
+holes, hole abstractions appear first. For instance, the tactic:
+
+.. coqdoc::
+
+ pose f x := x + _.
+
+is shorthand for:
+
+.. coqdoc::
+
+ pose f n x := x + n.
+
+The interaction of the pose tactic with the interpretation of implicit
+arguments results in a powerful and concise syntax for local
+definitions involving dependent types. For instance, the tactic:
+
+.. coqdoc::
+
+ pose f x y := (x, y).
+
+adds to the context the local definition:
+
+.. coqdoc::
+
+ pose f (Tx Ty : Type) (x : Tx) (y : Ty) := (x, y).
+
+The generalization of wildcards makes the use of the pose tactic
+resemble ML-like definitions of polymorphic functions.
+
+
+.. _abbreviations_ssr:
+
+
+Abbreviations
+~~~~~~~~~~~~~
+
+.. tacn:: set @ident {? : @term } := {? @occ_switch } @term
+ :name: set (ssreflect)
+
+ The |SSR| ``set`` tactic performs abbreviations: it introduces a
+ defined constant for a subterm appearing in the goal and/or in the
+ context.
+
+ |SSR| extends the :tacn:`set` tactic by supplying:
+
+ + an open syntax, similarly to the :tacn:`pose (ssreflect)` tactic;
+ + a more aggressive matching algorithm;
+ + an improved interpretation of wildcards, taking advantage of the
+ matching algorithm;
+ + an improved occurrence selection mechanism allowing to abstract only
+ selected occurrences of a term.
+
+.. prodn::
+ occ_switch ::= { {? + %| - } {* @num } }
+
+where:
+
++ :token:`ident` is a fresh identifier chosen by the user.
++ term 1 is an optional type annotation. The type annotation term 1
+ can be given in open syntax (no surrounding parentheses). If no
+ :token:`occ_switch` (described hereafter) is present,
+ it is also the case for the second :token:`term`.
+ On the other hand, in presence of :token:`occ_switch`, parentheses
+ surrounding the second :token:`term` are mandatory.
++ In the occurrence switch :token:`occ_switch`, if the first element of the
+ list is a natural, this element should be a number, and not an Ltac
+ variable. The empty list ``{}`` is not interpreted as a valid occurrence
+ switch, it is rather used as a flag to signal the intent of the user to
+ clear the name following it (see :ref:`ssr_rewrite_occ_switch` and
+ :ref:`introduction_ssr`)
+
+The tactic:
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Axiom f : nat -> nat.
+
+ .. coqtop:: all
+
+ Lemma test x : f x + f x = f x.
+ set t := f _.
+
+ .. coqtop:: all restart
+
+ set t := {2}(f _).
+
+
+The type annotation may contain wildcards, which will be filled
+with the appropriate value by the matching process.
+
+The tactic first tries to find a subterm of the goal matching
+the second :token:`term`
+(and its type), and stops at the first subterm it finds. Then
+the occurrences of this subterm selected by the optional :token:`occ_switch`
+are replaced by :token:`ident` and a definition :n:`@ident := @term`
+is added to the
+context. If no :token:`occ_switch` is present, then all the occurrences are
+abstracted.
+
+
+Matching
+````````
+
+The matching algorithm compares a pattern :token:`term` with a subterm of the
+goal by comparing their heads and then pairwise unifying their
+arguments (modulo conversion). Head symbols match under the following
+conditions:
+
+
++ If the head of :token:`term` is a constant, then it should be syntactically
+ equal to the head symbol of the subterm.
++ If this head is a projection of a canonical structure, then
+ canonical structure equations are used for the matching.
++ If the head of term is *not* a constant, the subterm should have the
+ same structure (λ abstraction,let…in structure …).
++ If the head of :token:`term` is a hole, the subterm should have at least as
+ many arguments as :token:`term`.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test (x y z : nat) : x + y = z.
+ set t := _ x.
+
++ In the special case where ``term`` is of the form
+ ``(let f := t0 in f) t1 … tn`` , then the pattern ``term`` is treated
+ as ``(_ t1 … tn)``. For each
+ subterm in the goal having the form ``(A u1 … um)`` with m ≥ n, the
+ matching algorithm successively tries to find the largest partial
+ application ``(A u1 … uj)`` convertible to the head ``t0`` of ``term``.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test : (let f x y z := x + y + z in f 1) 2 3 = 6.
+ set t := (let g y z := S y + z in g) 2.
+
+ The notation ``unkeyed`` defined in ``ssreflect.v`` is a shorthand for
+ the degenerate term ``let x := … in x``.
+
+Moreover:
+
++ Multiple holes in ``term`` are treated as independent placeholders.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test x y z : x + y = z.
+ set t := _ + _.
+
++ The type of the subterm matched should fit the type (possibly casted
+ by some type annotations) of the pattern ``term``.
++ The replacement of the subterm found by the instantiated pattern
+ should not capture variables. In the example above ``x`` is bound
+ and should not be captured.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test : forall x : nat, x + 1 = 0.
+ Fail set t := _ + 1.
+
++ Typeclass inference should fill in any residual hole, but matching
+ should never assign a value to a global existential variable.
+
+
+.. _occurrence_selection_ssr:
+
+Occurrence selection
+````````````````````
+
+|SSR| provides a generic syntax for the selection of occurrences
+by their position indexes. These *occurrence switches* are shared by
+all |SSR| tactics which require control on subterm selection like
+rewriting, generalization, …
+
+An *occurrence switch* can be:
+
++ A list natural numbers ``{+ n1 … nm}``
+ of occurrences affected by the tactic.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Axiom f : nat -> nat.
+
+ .. coqtop:: all
+
+ Lemma test : f 2 + f 8 = f 2 + f 2.
+ set x := {+1 3}(f 2).
+
+ Notice that some occurrences of a given term may be
+ hidden to the user, for example because of a notation. The vernacular
+ ``Set Printing All`` command displays all these hidden occurrences and
+ should be used to find the correct coding of the occurrences to be
+ selected [#1]_.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Notation "a < b":= (le (S a) b).
+ Lemma test x y : x < y -> S x < S y.
+ set t := S x.
+
++ A list of natural numbers between ``{n1 … nm}``.
+ This is equivalent to the previous ``{+ n1 … nm}`` but the list
+ should start with a number, and not with an Ltac variable.
++ A list ``{- n1 … nm}`` of occurrences *not* to be affected by the
+ tactic.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Axiom f : nat -> nat.
+
+ .. coqtop:: all
+
+ Lemma test : f 2 + f 8 = f 2 + f 2.
+ set x := {-2}(f 2).
+
+
+ Note that, in this goal, it behaves like ``set x := {1 3}(f 2).``
++ In particular, the switch ``{+}`` selects *all* the occurrences. This
+ switch is useful to turn off the default behavior of a tactic which
+ automatically clears some assumptions (see section :ref:`discharge_ssr` for
+ instance).
++ The switch ``{-}`` imposes that *no* occurrences of the term should be
+ affected by the tactic. The tactic: ``set x := {-}(f 2).`` leaves the goal
+ unchanged and adds the definition ``x := f 2`` to the context. This kind
+ of tactic may be used to take advantage of the power of the matching
+ algorithm in a local definition, instead of copying large terms by
+ hand.
+
+It is important to remember that matching *preceeds* occurrence
+selection.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test x y z : x + y = x + y + z.
+ set a := {2}(_ + _).
+
+Hence, in the following goal, the same tactic fails since there is
+only one occurrence of the selected term.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test x y z : (x + y) + (z + z) = z + z.
+ Fail set a := {2}(_ + _).
+
+
+.. _basic_localization_ssr:
+
+Basic localization
+~~~~~~~~~~~~~~~~~~
+
+It is possible to define an abbreviation for a term appearing in the
+context of a goal thanks to the ``in`` tactical.
+
+.. tacv:: set @ident := @term in {+ @ident}
+
+ This variant of :tacn:`set (ssreflect)` introduces a defined constant
+ called :token:`ident` in the context, and folds it in
+ the context entries mentioned on the right hand side of ``in``.
+ The body of :token:`ident` is the first subterm matching these context
+ entries (taken in the given order).
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+
+ .. coqtop:: all
+
+ Lemma test x t (Hx : x = 3) : x + t = 4.
+ set z := 3 in Hx.
+
+.. tacv:: set @ident := @term in {+ @ident} *
+
+ This variant matches :token:`term` and then folds :token:`ident` similarly
+ in all the given context entries but also folds :token:`ident` in the goal.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+
+ .. coqtop:: all
+
+ Lemma test x t (Hx : x = 3) : x + t = 4.
+ set z := 3 in Hx * .
+
+ Indeed, remember that 4 is just a notation for (S 3).
+
+The use of the ``in`` tactical is not limited to the localization of
+abbreviations: for a complete description of the in tactical, see
+section :ref:`bookkeeping_ssr` and :ref:`localization_ssr`.
+
+
+.. _basic_tactics_ssr:
+
+Basic tactics
+-------------
+
+A sizable fraction of proof scripts consists of steps that do not
+"prove" anything new, but instead perform menial bookkeeping tasks
+such as selecting the names of constants and assumptions or splitting
+conjuncts. Although they are logically trivial, bookkeeping steps are
+extremely important because they define the structure of the data-flow
+of a proof script. This is especially true for reflection-based
+proofs, which often involve large numbers of constants and
+assumptions. Good bookkeeping consists in always explicitly declaring
+(i.e., naming) all new constants and assumptions in the script, and
+systematically pruning irrelevant constants and assumptions in the
+context. This is essential in the context of an interactive
+development environment (IDE), because it facilitates navigating the
+proof, allowing to instantly "jump back" to the point at which a
+questionable assumption was added, and to find relevant assumptions by
+browsing the pruned context. While novice or casual |Coq| users may find
+the automatic name selection feature convenient, the usage of such a
+feature severely undermines the readability and maintainability of
+proof scripts, much like automatic variable declaration in programming
+languages. The |SSR| tactics are therefore designed to support
+precise bookkeeping and to eliminate name generation heuristics. The
+bookkeeping features of |SSR| are implemented as tacticals (or
+pseudo-tacticals), shared across most |SSR| tactics, and thus form
+the foundation of the |SSR| proof language.
+
+
+.. _bookkeeping_ssr:
+
+Bookkeeping
+~~~~~~~~~~~
+
+During the course of a proof |Coq| always present the user with a
+*sequent* whose general form is::
+
+ ci : Ti
+ …
+ dj := ej : Tj
+ …
+ Fk : Pk
+ …
+ =================
+ forall (xl : Tl ) …,
+ let ym := bm in … in
+ Pn -> … -> C
+
+The *goal* to be proved appears below the double line; above the line
+is the *context* of the sequent, a set of declarations of *constants*
+``ci`` , *defined constants* d i , and *facts* ``Fk`` that can be used to
+prove the goal (usually, ``Ti`` , ``Tj : Type`` and ``Pk : Prop``).
+The various
+kinds of declarations can come in any order. The top part of the
+context consists of declarations produced by the Section
+commands ``Variable``, ``Let``, and ``Hypothesis``.
+This *section context* is never
+affected by the |SSR| tactics: they only operate on the lower part
+— the *proof context*. As in the figure above, the goal often
+decomposes into a series of (universally) quantified *variables*
+``(xl : Tl)``, local *definitions*
+``let ym := bm in``, and *assumptions*
+``P n ->``,
+and a *conclusion* ``C`` (as in the context, variables, definitions, and
+assumptions can appear in any order). The conclusion is what actually
+needs to be proved — the rest of the goal can be seen as a part of the
+proof context that happens to be “below the line”.
+
+However, although they are logically equivalent, there are fundamental
+differences between constants and facts on the one hand, and variables
+and assumptions on the others. Constants and facts are *unordered*,
+but *named* explicitly in the proof text; variables and assumptions
+are *ordered*, but *unnamed*: the display names of variables may
+change at any time because of α-conversion.
+
+Similarly, basic deductive steps such as apply can only operate on the
+goal because the |Gallina| terms that control their action (e.g., the
+type of the lemma used by ``apply``) only provide unnamed bound variables.
+[#2]_ Since the proof script can only refer directly to the context, it
+must constantly shift declarations from the goal to the context and
+conversely in between deductive steps.
+
+In |SSR| these moves are performed by two *tacticals* ``=>`` and
+``:``, so that the bookkeeping required by a deductive step can be
+directly associated to that step, and that tactics in an |SSR|
+script correspond to actual logical steps in the proof rather than
+merely shuffle facts. Still, some isolated bookkeeping is unavoidable,
+such as naming variables and assumptions at the beginning of a
+proof. |SSR| provides a specific ``move`` tactic for this purpose.
+
+Now ``move`` does essentially nothing: it is mostly a placeholder for
+``=>`` and ``:``. The ``=>`` tactical moves variables, local definitions,
+and assumptions to the context, while the ``:`` tactical moves facts and
+constants to the goal.
+
+.. example::
+
+ For example, the proof of [#3]_
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma subnK : forall m n, n <= m -> m - n + n = m.
+
+ might start with
+
+ .. coqtop:: all
+
+ move=> m n le_n_m.
+
+ where move does nothing, but ``=> m n le_m_n`` changes
+ the variables and assumption of the goal in the constants
+ ``m n : nat`` and the fact ``le_n_m : n <= m``, thus exposing the
+ conclusion ``m - n + n = m``.
+
+ The ``:`` tactical is the converse of ``=>``, indeed it removes facts and
+ constants from the context by turning them into variables and
+ assumptions.
+
+ .. coqtop:: all
+
+ move: m le_n_m.
+
+ turns back ``m`` and ``le_m_n`` into a variable and an assumption,
+ removing them from the proof context, and changing the goal to
+ ``forall m, n <= m -> m - n + n = m``
+ which can be proved by induction on ``n`` using ``elim: n``.
+
+Because they are tacticals, ``:`` and ``=>`` can be combined, as in
+
+.. coqdoc::
+
+ move: m le_n_m => p le_n_p.
+
+simultaneously renames ``m`` and ``le_m_n`` into ``p`` and ``le_n_p``,
+respectively, by first turning them into unnamed variables, then
+turning these variables back into constants and facts.
+
+Furthermore, |SSR| redefines the basic |Coq| tactics ``case``, ``elim``,
+and ``apply`` so that they can take better advantage of
+``:`` and ``=>``. In there
+|SSR| variants, these tactic operate on the first variable or
+constant of the goal and they do not use or change the proof context.
+The ``:`` tactical is used to operate on an element in the context.
+
+.. example::
+
+ For instance the proof of ``subnK`` could continue with ``elim: n``.
+ Instead of ``elim n`` (note, no colon), this has the advantage of
+ removing n from the context. Better yet, this ``elim`` can be combined
+ with previous move and with the branching version of the ``=>`` tactical
+ (described in :ref:`introduction_ssr`),
+ to encapsulate the inductive step in a single
+ command:
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma subnK : forall m n, n <= m -> m - n + n = m.
+ move=> m n le_n_m.
+ elim: n m le_n_m => [|n IHn] m => [_ | lt_n_m].
+
+ which breaks down the proof into two subgoals, the second one
+ having in its context
+ ``lt_n_m : S n <= m`` and
+ ``IHn : forall m, n <= m -> m - n + n = m``.
+
+The ``:`` and ``=>`` tacticals can be explained very simply if one views
+the goal as a stack of variables and assumptions piled on a conclusion:
+
++ ``tactic : a b c`` pushes the context constants ``a``, ``b``, ``c`` as goal
+ variables *before* performing tactic.
++ ``tactic => a b c`` pops the top three goal variables as context
+ constants ``a``, ``b``, ``c``, *after* tactic has been performed.
+
+These pushes and pops do not need to balance out as in the examples
+above, so ``move: m le_n_m => p``
+would rename ``m`` into ``p``, but leave an extra assumption ``n <= p``
+in the goal.
+
+Basic tactics like apply and elim can also be used without the ’:’
+tactical: for example we can directly start a proof of ``subnK`` by
+induction on the top variable ``m`` with
+
+.. coqdoc::
+
+ elim=> [|m IHm] n le_n.
+
+The general form of the localization tactical in is also best
+explained in terms of the goal stack::
+
+ tactic in a H1 H2 *.
+
+is basically equivalent to
+
+.. coqdoc::
+
+ move: a H1 H2; tactic => a H1 H2.
+
+
+with two differences: the in tactical will preserve the body of a ifa
+is a defined constant, and if the ``*`` is omitted it will use a
+temporary abbreviation to hide the statement of the goal from
+``tactic``.
+
+The general form of the in tactical can be used directly with the
+``move``, ``case`` and ``elim`` tactics, so that one can write
+
+.. coqdoc::
+
+ elim: n => [|n IHn] in m le_n_m *.
+
+instead of
+
+.. coqdoc::
+
+ elim: n m le_n_m => [|n IHn] m le_n_m.
+
+This is quite useful for inductive proofs that involve many facts.
+
+See section :ref:`localization_ssr` for
+the general syntax and presentation of the in
+tactical.
+
+
+.. _the_defective_tactics_ssr:
+
+The defective tactics
+~~~~~~~~~~~~~~~~~~~~~
+
+In this section we briefly present the three basic tactics performing
+context manipulations and the main backward chaining tool.
+
+
+The move tactic.
+````````````````
+
+.. tacn:: move
+ :name: move
+
+ This tactic, in its defective form, behaves like the :tacn:`hnf` tactic.
+
+ .. example::
+
+ .. coqtop:: reset all
+
+ Require Import ssreflect.
+ Goal not False.
+ move.
+
+ More precisely, the :tacn:`move` tactic inspects the goal and does nothing
+ (:tacn:`idtac`) if an introduction step is possible, i.e. if the goal is a
+ product or a ``let … in``, and performs :tacn:`hnf` otherwise.
+
+ Of course this tactic is most often used in combination with the bookkeeping
+ tacticals (see section :ref:`introduction_ssr` and :ref:`discharge_ssr`).
+ These combinations mostly subsume the :tacn:`intros`, :tacn:`generalize`,
+ :tacn:`revert`, :tacn:`rename`, :tacn:`clear` and :tacn:`pattern` tactics.
+
+
+The case tactic
+```````````````
+
+.. tacn:: case
+ :name: case (ssreflect)
+
+ This tactic performs *primitive case analysis* on (co)inductive
+ types; specifically, it destructs the top variable or assumption of
+ the goal, exposing its constructor(s) and its arguments, as well as
+ setting the value of its type family indices if it belongs to a type
+ family (see section :ref:`type_families_ssr`).
+
+ The |SSR| case tactic has a special behavior on equalities. If the
+ top assumption of the goal is an equality, the case tactic “destructs”
+ it as a set of equalities between the constructor arguments of its
+ left and right hand sides, as per the tactic injection. For example,
+ ``case`` changes the goal::
+
+ (x, y) = (1, 2) -> G.
+
+ into::
+
+ x = 1 -> y = 2 -> G.
+
+ Note also that the case of |SSR| performs :g:`False` elimination, even
+ if no branch is generated by this case operation. Hence the tactic
+ :tacn:`case` on a goal of the form :g:`False -> G` will succeed and
+ prove the goal.
+
+
+The elim tactic
+```````````````
+
+.. tacn:: elim
+ :name: elim (ssreflect)
+
+ This tactic performs inductive elimination on inductive types. In its
+ defective form, the tactic performs inductive elimination on a goal whose
+ top assumption has an inductive type.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test m : forall n : nat, m <= n.
+ elim.
+
+
+.. _apply_ssr:
+
+The apply tactic
+````````````````
+
+.. tacn:: apply {? @term }
+ :name: apply (ssreflect)
+
+ This is the main backward chaining tactic of the proof system.
+ It takes as argument any :token:`term` and applies it to the goal.
+ Assumptions in the type of :token:`term` that don’t directly match the goal
+ may generate one or more subgoals.
+
+ In its defective form, this tactic is a synonym for::
+
+ intro top; first [refine top | refine (top _) | refine (top _ _) | …]; clear top.
+
+ where :g:`top` is a fresh name, and the sequence of :tacn:`refine` tactics
+ tries to catch the appropriate number of wildcards to be inserted. Note that
+ this use of the :tacn:`refine` tactic implies that the tactic tries to match
+ the goal up to expansion of constants and evaluation of subterms.
+
+:tacn:`apply (ssreflect)` has a special behavior on goals containing
+existential metavariables of sort :g:`Prop`.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Axiom lt_trans : forall a b c, a < b -> b < c -> a < c.
+
+ .. coqtop:: all
+
+ Lemma test : forall y, 1 < y -> y < 2 -> exists x : { n | n < 3 }, 0 < proj1_sig x.
+ move=> y y_gt1 y_lt2; apply: (ex_intro _ (exist _ y _)).
+ by apply: lt_trans y_lt2 _.
+ by move=> y_lt3; apply: lt_trans y_gt1.
+
+ Note that the last ``_`` of the tactic
+ ``apply: (ex_intro _ (exist _ y _))``
+ represents a proof that ``y < 3``. Instead of generating the goal::
+
+ 0 < proj1_sig (exist (fun n : nat => n < 3) y ?Goal).
+
+ the system tries to prove ``y < 3`` calling the trivial tactic.
+ If it succeeds, let’s say because the context contains
+ ``H : y < 3``, then the
+ system generates the following goal::
+
+ 0 < proj1_sig (exist (fun n => n < 3) y H).
+
+ Otherwise the missing proof is considered to be irrelevant, and is
+ thus discharged generating the two goals shown above.
+
+ Last, the user can replace the trivial tactic by defining an Ltac
+ expression named ``ssrautoprop``.
+
+
+.. _discharge_ssr:
+
+Discharge
+~~~~~~~~~
+
+The general syntax of the discharging tactical ``:`` is:
+
+.. tacn:: @tactic {? @ident } : {+ @d_item } {? @clear_switch }
+ :name: ... : ... (ssreflect)
+ :undocumented:
+
+.. prodn::
+ d_item ::= {? @occ_switch %| @clear_switch } @term
+.. prodn::
+ clear_switch ::= { {+ @ident } }
+
+with the following requirements:
+
++ :token:`tactic` must be one of the four basic tactics described in :ref:`the_defective_tactics_ssr`,
+ i.e., ``move``, ``case``, ``elim`` or ``apply``, the ``exact``
+ tactic (section :ref:`terminators_ssr`),
+ the ``congr`` tactic (section :ref:`congruence_ssr`),
+ or the application of the *view*
+ tactical ‘/’ (section :ref:`interpreting_assumptions_ssr`) to one of move, case, or elim.
++ The optional :token:`ident` specifies *equation generation* (section :ref:`generation_of_equations_ssr`),
+ and is only allowed if tactic is ``move``, ``case`` or ``elim``, or the
+ application of the view tactical ‘/’ (section :ref:`interpreting_assumptions_ssr`) to ``case`` or ``elim``.
++ An :token:`occ_switch` selects occurrences of :token:`term`, as in :ref:`abbreviations_ssr`; :token:`occ_switch`
+ is not allowed if :token:`tactic` is ``apply`` or ``exact``.
++ A clear item :token:`clear_switch` specifies facts and constants to be
+ deleted from the proof context (as per the clear tactic).
+
+
+The ``:`` tactical first *discharges* all the :token:`d_item`, right to left,
+and then performs tactic, i.e., for each :token:`d_item`, starting with the last one :
+
+
+#. The |SSR| matching algorithm described in section :ref:`abbreviations_ssr` is
+ used to find occurrences of term in the goal, after filling any holes
+ ‘_’ in term; however if tactic is apply or exact a different matching
+ algorithm, described below, is used [#4]_.
+#. These occurrences are replaced by a new variable; in particular, if
+ term is a fact, this adds an assumption to the goal.
+#. If term is *exactly* the name of a constant or fact in the proof
+ context, it is deleted from the context, unless there is an
+ :token:`occ_switch`.
+
+
+Finally, tactic is performed just after the first :token:`d_item`
+has been generalized
+— that is, between steps 2 and 3. The names listed in
+the final :token:`clear_switch` (if it is present) are cleared first, before
+:token:`d_item` n is discharged.
+
+Switches affect the discharging of a :token:`d_item` as follows:
+
+
++ An :token:`occ_switch` restricts generalization (step 2) to a specific subset
+ of the occurrences of term, as per section :ref:`abbreviations_ssr`, and prevents clearing (step
+ 3).
++ All the names specified by a :token:`clear_switch` are deleted from the
+ context in step 3, possibly in addition to term.
+
+
+For example, the tactic:
+
+.. coqdoc::
+
+ move: n {2}n (refl_equal n).
+
++ first generalizes ``(refl_equal n : n = n)``;
++ then generalizes the second occurrence of ``n``.
++ finally generalizes all the other occurrences of ``n``, and clears ``n``
+ from the proof context (assuming n is a proof constant).
+
+Therefore this tactic changes any goal ``G`` into
+
+.. coqdoc::
+
+ forall n n0 : nat, n = n0 -> G.
+
+where the name ``n0`` is picked by the |Coq| display function, and assuming
+``n`` appeared only in ``G``.
+
+Finally, note that a discharge operation generalizes defined constants
+as variables, and not as local definitions. To override this behavior,
+prefix the name of the local definition with a ``@``, like in ``move: @n``.
+
+This is in contrast with the behavior of the in tactical (see
+section :ref:`localization_ssr`), which preserves local
+definitions by default.
+
+
+Clear rules
+```````````
+
+The clear step will fail if term is a proof constant that appears in
+other facts; in that case either the facts should be cleared
+explicitly with a :token:`clear_switch`, or the clear step should be disabled.
+The latter can be done by adding an :token:`occ_switch` or simply by putting
+parentheses around term: both
+``move: (n).``
+and
+``move: {+}n.``
+generalize ``n`` without clearing ``n`` from the proof context.
+
+The clear step will also fail if the :token:`clear_switch` contains a :token:`ident` that
+is not in the *proof* context. Note that |SSR| never clears a
+section constant.
+
+If tactic is ``move`` or ``case`` and an equation :token:`ident` is given, then clear
+(step 3) for :token:`d_item` is suppressed (see section :ref:`generation_of_equations_ssr`).
+
+Intro patterns (see section :ref:`introduction_ssr`)
+and the ``rewrite`` tactic (see section :ref:`rewriting_ssr`)
+let one place a :token:`clear_switch` in the middle of other items
+(namely identifiers, views and rewrite rules). This can trigger the
+addition of proof context items to the ones being explicitly
+cleared, and in turn this can result in clear errors (e.g. if the
+context item automatically added occurs in the goal). The
+relevant sections describe ways to avoid the unintended clear of
+context items.
+
+
+Matching for apply and exact
+````````````````````````````
+
+The matching algorithm for :token:`d_item` of the |SSR|
+``apply`` and ``exact``
+tactics exploits the type of the first :token:`d_item` to interpret
+wildcards in the
+other :token:`d_item` and to determine which occurrences of these should be
+generalized. Therefore, occur switches are not needed for apply and
+exact.
+
+Indeed, the |SSR| tactic ``apply: H x`` is equivalent to
+``refine (@H _ … _ x); clear H x``
+with an appropriate number of wildcards between ``H`` and ``x``.
+
+Note that this means that matching for ``apply`` and ``exact`` has much more
+context to interpret wildcards; in particular it can accommodate the
+``_`` :token:`d_item`, which would always be rejected after ``move:``.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Axiom f : nat -> nat.
+ Axiom g : nat -> nat.
+
+ .. coqtop:: all
+
+ Lemma test (Hfg : forall x, f x = g x) a b : f a = g b.
+ apply: trans_equal (Hfg _) _.
+
+This tactic is equivalent (see section
+:ref:`bookkeeping_ssr`) to:
+``refine (trans_equal (Hfg _) _).``
+and this is a common idiom for applying transitivity on the left hand
+side of an equation.
+
+
+.. _abstract_ssr:
+
+The abstract tactic
+```````````````````
+
+.. tacn:: abstract: {+ d_item}
+ :name: abstract (ssreflect)
+
+ This tactic assigns an abstract constant previously introduced with the
+ :n:`[: @ident ]` intro pattern (see section :ref:`introduction_ssr`).
+
+In a goal like the following::
+
+ m : nat
+ abs : <hidden>
+ n : nat
+ =============
+ m < 5 + n
+
+The tactic ``abstract: abs n`` first generalizes the goal with respect ton
+(that is not visible to the abstract constant abs) and then assigns
+abs. The resulting goal is::
+
+ m : nat
+ n : nat
+ =============
+ m < 5 + n
+
+Once this subgoal is closed, all other goals having abs in their
+context see the type assigned to ``abs``. In this case::
+
+ m : nat
+ abs : forall n, m < 5 + n
+ =============
+ …
+
+For a more detailed example the reader should refer to
+section :ref:`structure_ssr`.
+
+
+.. _introduction_ssr:
+
+Introduction in the context
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The application of a tactic to a given goal can generate (quantified)
+variables, assumptions, or definitions, which the user may want to
+*introduce* as new facts, constants or defined constants,
+respectively. If the tactic splits the goal into several subgoals,
+each of them may require the introduction of different constants and
+facts. Furthermore it is very common to immediately decompose or
+rewrite with an assumption instead of adding it to the context, as the
+goal can often be simplified and even proved after this.
+
+All these operations are performed by the introduction tactical ``=>``,
+whose general syntax is
+
+.. tacn:: @tactic => {+ @i_item }
+ :name: =>
+ :undocumented:
+
+.. prodn::
+ i_item ::= @i_pattern %| @s_item %| @clear_switch %| @i_view %| @i_block
+
+.. prodn::
+ s_item ::= /= %| // %| //=
+
+.. prodn::
+ i_view ::= {? %{%} } /@term %| /ltac:( @tactic )
+
+.. prodn::
+ i_pattern ::= @ident %| > %| _ %| ? %| * %| + %| {? @occ_switch } -> %| {? @occ_switch }<- %| [ {?| @i_item } ] %| - %| [: {+ @ident } ]
+
+.. prodn::
+ i_block ::= [^ @ident ] %| [^~ @ident ] %| [^~ @num ]
+
+The ``=>`` tactical first executes :token:`tactic`, then the :token:`i_item`\s,
+left to right. An :token:`s_item` specifies a
+simplification operation; a :token:`clear_switch`
+specifies context pruning as in :ref:`discharge_ssr`.
+The :token:`i_pattern`\s can be seen as a variant of *intro patterns*
+(see :tacn:`intros`:) each performs an introduction operation, i.e., pops some
+variables or assumptions from the goal.
+
+Simplification items
+`````````````````````
+
+An :token:`s_item` can simplify the set of subgoals or the subgoals themselves:
+
++ ``//`` removes all the “trivial” subgoals that can be resolved by the
+ |SSR| tactic :tacn:`done` described in :ref:`terminators_ssr`, i.e.,
+ it executes ``try done``.
++ ``/=`` simplifies the goal by performing partial evaluation, as per the
+ tactic :tacn:`simpl` [#5]_.
++ ``//=`` combines both kinds of simplification; it is equivalent to
+ ``/= //``, i.e., ``simpl; try done``.
+
+
+When an :token:`s_item` immediately precedes a :token:`clear_switch`, then the
+:token:`clear_switch` is executed
+*after* the :token:`s_item`, e.g., ``{IHn}//`` will solve some subgoals,
+possibly using the fact ``IHn``, and will erase ``IHn`` from the context
+of the remaining subgoals.
+
+Views
+`````
+
+The first entry in the :token:`i_view` grammar rule, :n:`/@term`,
+represents a view (see section :ref:`views_and_reflection_ssr`).
+It interprets the top of the stack with the view :token:`term`.
+It is equivalent to :n:`move/@term`.
+
+A :token:`clear_switch` that immediately precedes an :token:`i_view`
+is complemented with the name of the view if an only if the :token:`i_view`
+is a simple proof context entry [#10]_.
+E.g. ``{}/v`` is equivalent to ``/v{v}``.
+This behavior can be avoided by separating the :token:`clear_switch`
+from the :token:`i_view` with the ``-`` intro pattern or by putting
+parentheses around the view.
+
+A :token:`clear_switch` that immediately precedes an :token:`i_view`
+is executed after the view application.
+
+
+If the next :token:`i_item` is a view, then the view is
+applied to the assumption in top position once all the
+previous :token:`i_item` have been performed.
+
+The second entry in the :token:`i_view` grammar rule,
+``/ltac:(`` :token:`tactic` ``)``, executes :token:`tactic`.
+Notations can be used to name tactics, for example::
+
+ Notation myop := (ltac:(some ltac code)) : ssripat_scope.
+
+lets one write just ``/myop`` in the intro pattern. Note the scope
+annotation: views are interpreted opening the ``ssripat`` scope.
+
+Intro patterns
+``````````````
+
+|SSR| supports the following :token:`i_pattern`\s:
+
+:token:`ident`
+ pops the top variable, assumption, or local definition into
+ a new constant, fact, or defined constant :token:`ident`, respectively.
+ Note that defined constants cannot be introduced when δ-expansion is
+ required to expose the top variable or assumption.
+ A :token:`clear_switch` (even an empty one) immediately preceding an
+ :token:`ident` is complemented with that :token:`ident` if and only if
+ the identifier is a simple proof context entry [#10]_.
+ As a consequence by prefixing the
+ :token:`ident` with ``{}`` one can *replace* a context entry.
+ This behavior can be avoided by separating the :token:`clear_switch`
+ from the :token:`ident` with the ``-`` intro pattern.
+``>``
+ pops every variable occurring in the rest of the stack.
+ Type class instances are popped even if they don't occur
+ in the rest of the stack.
+ The tactic ``move=> >`` is equivalent to
+ ``move=> ? ?`` on a goal such as::
+
+ forall x y, x < y -> G
+
+ A typical use if ``move=>> H`` to name ``H`` the first assumption,
+ in the example above ``x < y``.
+``?``
+ pops the top variable into an anonymous constant or fact, whose name
+ is picked by the tactic interpreter. |SSR| only generates names that cannot
+ appear later in the user script [#6]_.
+``_``
+ pops the top variable into an anonymous constant that will be deleted
+ from the proof context of all the subgoals produced by the ``=>`` tactical.
+ They should thus never be displayed, except in an error message if the
+ constant is still actually used in the goal or context after the last
+ :token:`i_item` has been executed (:token:`s_item` can erase goals or
+ terms where the constant appears).
+``*``
+ pops all the remaining apparent variables/assumptions as anonymous
+ constants/facts. Unlike ``?`` and ``move`` the ``*``
+ :token:`i_item` does not
+ expand definitions in the goal to expose quantifiers, so it may be useful
+ to repeat a ``move=> *`` tactic, e.g., on the goal::
+
+ forall a b : bool, a <> b
+
+ a first ``move=> *`` adds only ``_a_ : bool`` and ``_b_ : bool``
+ to the context; it takes a second ``move=> *`` to add ``_Hyp_ : _a_ = _b_``.
+``+``
+ temporarily introduces the top variable. It is discharged at the end
+ of the intro pattern. For example ``move=> + y`` on a goal::
+
+ forall x y, P
+
+ is equivalent to ``move=> _x_ y; move: _x_`` that results in the goal::
+
+ forall x, P
+
+:n:`{? occ_switch } ->`
+ (resp. :token:`occ_switch` ``<-``)
+ pops the top assumption (which should be a rewritable proposition) into an
+ anonymous fact, rewrites (resp. rewrites right to left) the goal with this
+ fact (using the |SSR| ``rewrite`` tactic described in section
+ :ref:`rewriting_ssr`, and honoring the optional occurrence selector), and
+ finally deletes the anonymous fact from the context.
+``[`` :token:`i_item` * ``| … |`` :token:`i_item` * ``]``
+ when it is the
+ very *first* :token:`i_pattern` after tactic ``=>`` tactical *and* tactic
+ is not a move, is a *branching*:token:`i_pattern`. It executes the sequence
+ :token:`i_item`:math:`_i` on the i-th subgoal produced by tactic. The
+ execution of tactic should thus generate exactly m subgoals, unless the
+ ``[…]`` :token:`i_pattern` comes after an initial ``//`` or ``//=``
+ :token:`s_item` that closes some of the goals produced by ``tactic``, in
+ which case exactly m subgoals should remain after thes- item, or we have
+ the trivial branching :token:`i_pattern` [], which always does nothing,
+ regardless of the number of remaining subgoals.
+``[`` :token:`i_item` * ``| … |`` :token:`i_item` * ``]``
+ when it is *not*
+ the first :token:`i_pattern` or when tactic is a ``move``, is a
+ *destructing* :token:`i_pattern`. It starts by destructing the top
+ variable, using the |SSR| ``case`` tactic described in
+ :ref:`the_defective_tactics_ssr`. It then behaves as the corresponding
+ branching :token:`i_pattern`, executing the
+ sequence :n:`@i_item__i` in the i-th subgoal generated by the
+ case analysis; unless we have the trivial destructing :token:`i_pattern`
+ ``[]``, the latter should generate exactly m subgoals, i.e., the top
+ variable should have an inductive type with exactly m constructors [#7]_.
+ While it is good style to use the :token:`i_item` i * to pop the variables
+ and assumptions corresponding to each constructor, this is not enforced by
+ |SSR|.
+``-``
+ does nothing, but counts as an intro pattern. It can also be used to
+ force the interpretation of ``[`` :token:`i_item` * ``| … |``
+ :token:`i_item` * ``]`` as a case analysis like in ``move=> -[H1 H2]``. It
+ can also be used to indicate explicitly the link between a view and a name
+ like in ``move=> /eqP-H1``. Last, it can serve as a separator between
+ views. Section :ref:`views_and_reflection_ssr` [#9]_ explains in which
+ respect the tactic ``move=> /v1/v2`` differs from the tactic ``move=>
+ /v1-/v2``.
+``[:`` :token:`ident` ``…]``
+ introduces in the context an abstract constant
+ for each :token:`ident`. Its type has to be fixed later on by using the
+ ``abstract`` tactic. Before then the type displayed is ``<hidden>``.
+
+
+Note that |SSR| does not support the syntax ``(ipat, …, ipat)`` for
+destructing intro-patterns.
+
+Clear switch
+````````````
+
+Clears are deferred until the end of the intro pattern.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect ssrbool.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test x y : Nat.leb 0 x = true -> (Nat.leb 0 x) && (Nat.leb y 2) = true.
+ move=> {x} ->.
+
+If the cleared names are reused in the same intro pattern, a renaming
+is performed behind the scenes.
+
+Facts mentioned in a clear switch must be valid names in the proof
+context (excluding the section context).
+
+Branching and destructuring
+```````````````````````````
+
+The rules for interpreting branching and destructing :token:`i_pattern` are
+motivated by the fact that it would be pointless to have a branching
+pattern if tactic is a ``move``, and in most of the remaining cases
+tactic is ``case`` or ``elim``, which implies destruction.
+The rules above imply that:
+
++ ``move=> [a b].``
++ ``case=> [a b].``
++ ``case=> a b.``
+
+are all equivalent, so which one to use is a matter of style; ``move`` should
+be used for casual decomposition, such as splitting a pair, and ``case``
+should be used for actual decompositions, in particular for type families
+(see :ref:`type_families_ssr`) and proof by contradiction.
+
+The trivial branching :token:`i_pattern` can be used to force the branching
+interpretation, e.g.:
+
++ ``case=> [] [a b] c.``
++ ``move=> [[a b] c].``
++ ``case; case=> a b c.``
+
+are all equivalent.
+
+Block introduction
+``````````````````
+
+|SSR| supports the following :token:`i_block`\s:
+
+:n:`[^ @ident ]`
+ *block destructing* :token:`i_pattern`. It performs a case analysis
+ on the top variable and introduces, in one go, all the variables coming
+ from the case analysis. The names of these variables are obtained by
+ taking the names used in the inductive type declaration and prefixing them
+ with :token:`ident`. If the intro pattern immediately follows a call
+ to ``elim`` with a custom eliminator (see :ref:`custom_elim_ssr`) then
+ the names are taken from the ones used in the type of the eliminator.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Record r := { a : nat; b := (a, 3); _ : bool; }.
+
+ Lemma test : r -> True.
+ Proof. move => [^ x ].
+
+:n:`[^~ @ident ]`
+ *block destructing* using :token:`ident` as a suffix.
+:n:`[^~ @num ]`
+ *block destructing* using :token:`num` as a suffix.
+
+ Only a :token:`s_item` is allowed between the elimination tactic and
+ the block destructing.
+
+.. _generation_of_equations_ssr:
+
+Generation of equations
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The generation of named equations option stores the definition of a
+new constant as an equation. The tactic:
+
+.. coqdoc::
+
+ move En: (size l) => n.
+
+where ``l`` is a list, replaces ``size l`` by ``n`` in the goal and
+adds the fact ``En : size l = n`` to the context.
+This is quite different from:
+
+.. coqdoc::
+
+ pose n := (size l).
+
+which generates a definition ``n := (size l)``. It is not possible to
+generalize or rewrite such a definition; on the other hand, it is
+automatically expanded during computation, whereas expanding the
+equation ``En`` requires explicit rewriting.
+
+The use of this equation name generation option with a ``case`` or an
+``elim`` tactic changes the status of the first :token:`i_item`, in order to
+deal with the possible parameters of the constants introduced.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test (a b :nat) : a <> b.
+ case E : a => [|n].
+
+If the user does not provide a branching :token:`i_item` as first
+:token:`i_item`, or if the :token:`i_item` does not provide enough names for
+the arguments of a constructor, then the constants generated are introduced
+under fresh |SSR| names.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test (a b :nat) : a <> b.
+ case E : a => H.
+ Show 2.
+
+Combining the generation of named equations mechanism with thecase
+tactic strengthens the power of a case analysis. On the other hand,
+when combined with the elim tactic, this feature is mostly useful for
+debug purposes, to trace the values of decomposed parameters and
+pinpoint failing branches.
+
+
+.. _type_families_ssr:
+
+Type families
+~~~~~~~~~~~~~
+
+When the top assumption of a goal has an inductive type, two specific
+operations are possible: the case analysis performed by the :tacn:`case`
+tactic, and the application of an induction principle, performed by
+the :tacn:`elim` tactic. When this top assumption has an inductive type, which
+is moreover an instance of a type family, |Coq| may need help from the
+user to specify which occurrences of the parameters of the type should
+be substituted.
+
+.. tacv:: case: {+ @d_item } / {+ @d_item }
+ elim: {+ @d_item } / {+ @d_item }
+
+ A specific ``/`` switch indicates the type family parameters of the type
+ of a :token:`d_item` immediately following this ``/`` switch.
+ The :token:`d_item` on the right side of the ``/`` switch are discharged as
+ described in section :ref:`discharge_ssr`. The case analysis or elimination
+ will be done on the type of the top assumption after these discharge
+ operations.
+
+ Every :token:`d_item` preceding the ``/`` is interpreted as arguments of this
+ type, which should be an instance of an inductive type family. These terms
+ are not actually generalized, but rather selected for substitution.
+ Occurrence switches can be used to restrict the substitution. If a term is
+ left completely implicit (e.g. writing just ``_``), then a pattern is
+ inferred looking at the type of the top assumption. This allows for the
+ compact syntax:
+
+ .. coqdoc::
+
+ case: {2}_ / eqP.
+
+ where ``_`` is interpreted as ``(_ == _)`` since
+ ``eqP T a b : reflect (a = b) (a == b)`` and reflect is a type family with
+ one index.
+
+ Moreover if the :token:`d_item` list is too short, it is padded with an
+ initial sequence of ``_`` of the right length.
+
+ .. example::
+
+ Here is a small example on lists. We define first a function which
+ adds an element at the end of a given list.
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Require Import List.
+ Section LastCases.
+ Variable A : Type.
+ Implicit Type l : list A.
+ Fixpoint add_last a l : list A :=
+ match l with
+ | nil => a :: nil
+ | hd :: tl => hd :: (add_last a tl) end.
+
+ Then we define an inductive predicate for case analysis on lists
+ according to their last element:
+
+ .. coqtop:: all
+
+ Inductive last_spec : list A -> Type :=
+ | LastSeq0 : last_spec nil
+ | LastAdd s x : last_spec (add_last x s).
+
+ Theorem lastP : forall l : list A, last_spec l.
+ Admitted.
+
+ We are now ready to use ``lastP`` in conjunction with ``case``.
+
+ .. coqtop:: all
+
+ Lemma test l : (length l) * 2 = length (l ++ l).
+ case: (lastP l).
+
+ Applied to the same goal, the tactc ``case: l / (lastP l)``
+ generates the same subgoals but ``l`` has been cleared from both contexts:
+
+ .. coqtop:: all restart
+
+ case: l / (lastP l).
+
+ Again applied to the same goal:
+
+ .. coqtop:: all restart abort
+
+ case: {1 3}l / (lastP l).
+
+ Note that selected occurrences on the left of the ``/``
+ switch have been substituted with l instead of being affected by
+ the case analysis.
+
+ The equation name generation feature combined with a type family ``/``
+ switch generates an equation for the *first* dependent :token:`d_item`
+ specified by the user. Again starting with the above goal, the
+ command:
+
+ .. example::
+
+ .. coqtop:: all
+
+ Lemma test l : (length l) * 2 = length (l ++ l).
+ case E: {1 3}l / (lastP l) => [|s x].
+ Show 2.
+
+
+ There must be at least one :token:`d_item` to the left of the ``/`` switch; this
+ prevents any confusion with the view feature. However, the :token:`d_item`
+ to the right of the ``/`` are optional, and if they are omitted the first
+ assumption provides the instance of the type family.
+
+ The equation always refers to the first :token:`d_item` in the actual tactic
+ call, before any padding with initial ``_``. Thus, if an inductive type
+ has two family parameters, it is possible to have|SSR| generate an
+ equation for the second one by omitting the pattern for the first;
+ note however that this will fail if the type of the second parameter
+ depends on the value of the first parameter.
+
+
+Control flow
+------------
+
+
+.. _indentation_ssr:
+
+Indentation and bullets
+~~~~~~~~~~~~~~~~~~~~~~~
+
+A linear development of |Coq| scripts gives little information on the
+structure of the proof. In addition, replaying a proof after some
+changes in the statement to be proved will usually not display
+information to distinguish between the various branches of case
+analysis for instance.
+
+To help the user in this organization of the proof script at development
+time, |SSR| provides some bullets to highlight the structure of branching
+proofs. The available bullets are ``-``, ``+`` and ``*``. Combined with
+tabulation, this lets us highlight four nested levels of branching; the most
+we have ever needed is three. Indeed, the use of “simpl and closing”
+switches, of terminators (see above section :ref:`terminators_ssr`) and
+selectors (see section :ref:`selectors_ssr`) is powerful enough to avoid most
+of the time more than two levels of indentation.
+
+Here is a fragment of such a structured script::
+
+ case E1: (abezoutn _ _) => [[| k1] [| k2]].
+ - rewrite !muln0 !gexpn0 mulg1 => H1.
+ move/eqP: (sym_equal F0); rewrite -H1 orderg1 eqn_mul1.
+ by case/andP; move/eqP.
+ - rewrite muln0 gexpn0 mulg1 => H1.
+ have F1: t %| t * S k2.+1 - 1.
+ apply: (@dvdn_trans (orderg x)); first by rewrite F0; exact: dvdn_mull.
+ rewrite orderg_dvd; apply/eqP; apply: (mulgI x).
+ rewrite -{1}(gexpn1 x) mulg1 gexpn_add leq_add_sub //.
+ by move: P1; case t.
+ rewrite dvdn_subr in F1; last by exact: dvdn_mulr.
+ + rewrite H1 F0 -{2}(muln1 (p ^ l)); congr (_ * _).
+ by apply/eqP; rewrite -dvdn1.
+ + by move: P1; case: (t) => [| [| s1]].
+ - rewrite muln0 gexpn0 mul1g => H1.
+ ...
+
+
+.. _terminators_ssr:
+
+Terminators
+~~~~~~~~~~~
+
+To further structure scripts, |SSR| supplies *terminating*
+tacticals to explicitly close off tactics. When replaying scripts, we
+then have the nice property that an error immediately occurs when a
+closed tactic fails to prove its subgoal.
+
+It is hence recommended practice that the proof of any subgoal should
+end with a tactic which *fails if it does not solve the current goal*,
+like :tacn:`discriminate`, :tacn:`contradiction` or :tacn:`assumption`.
+
+In fact, |SSR| provides a generic tactical which turns any tactic
+into a closing one (similar to :tacn:`now`). Its general syntax is:
+
+.. tacn:: by @tactic
+ :name: by
+ :undocumented:
+
+The Ltac expression :n:`by [@tactic | @tactic | …]` is equivalent to
+:n:`do [done | by @tactic | by @tactic | …]`, which corresponds to the
+standard Ltac expression :n:`first [done | @tactic; done | @tactic; done | …]`.
+
+In the script provided as example in section :ref:`indentation_ssr`, the
+paragraph corresponding to each sub-case ends with a tactic line prefixed
+with a ``by``, like in:
+
+.. coqdoc::
+
+ by apply/eqP; rewrite -dvdn1.
+
+.. tacn:: done
+ :name: done
+
+ The :tacn:`by` tactical is implemented using the user-defined, and extensible
+ :tacn:`done` tactic. This :tacn:`done` tactic tries to solve the current goal by some
+ trivial means and fails if it doesn’t succeed. Indeed, the tactic
+ expression :n:`by @tactic` is equivalent to :n:`@tactic; done`.
+
+ Conversely, the tactic ``by [ ]`` is equivalent to :tacn:`done`.
+
+ The default implementation of the done tactic, in the ``ssreflect.v``
+ file, is:
+
+ .. coqdoc::
+
+ Ltac done :=
+ trivial; hnf; intros; solve
+ [ do ![solve [trivial | apply: sym_equal; trivial]
+ | discriminate | contradiction | split]
+ | case not_locked_false_eq_true; assumption
+ | match goal with H : ~ _ |- _ => solve [case H; trivial] end ].
+
+ The lemma :g:`not_locked_false_eq_true` is needed to discriminate
+ *locked* boolean predicates (see section :ref:`locking_ssr`). The iterator
+ tactical do is presented in section :ref:`iteration_ssr`. This tactic can be
+ customized by the user, for instance to include an :tacn:`auto` tactic.
+
+A natural and common way of closing a goal is to apply a lemma which
+is the exact one needed for the goal to be solved. The defective form
+of the tactic:
+
+.. coqdoc::
+
+ exact.
+
+is equivalent to:
+
+.. coqdoc::
+
+ do [done | by move=> top; apply top].
+
+where ``top`` is a fresh name assigned to the top assumption of the goal.
+This applied form is supported by the ``:`` discharge tactical, and the
+tactic:
+
+.. coqdoc::
+
+ exact: MyLemma.
+
+is equivalent to:
+
+.. coqdoc::
+
+ by apply: MyLemma.
+
+(see section :ref:`discharge_ssr` for the documentation of the apply: combination).
+
+.. warning::
+
+ The list of tactics (possibly chained by semicolons) that
+ follows the ``by`` keyword is considered to be a parenthesized block applied to
+ the current goal. Hence for example if the tactic:
+
+ .. coqdoc::
+
+ by rewrite my_lemma1.
+
+ succeeds, then the tactic:
+
+ .. coqdoc::
+
+ by rewrite my_lemma1; apply my_lemma2.
+
+ usually fails since it is equivalent to:
+
+ .. coqdoc::
+
+ by (rewrite my_lemma1; apply my_lemma2).
+
+
+.. _selectors_ssr:
+
+Selectors
+~~~~~~~~~
+
+.. tacn:: last
+ first
+ :name: last; first (ssreflect)
+
+ When composing tactics, the two tacticals ``first`` and ``last`` let the user
+ restrict the application of a tactic to only one of the subgoals
+ generated by the previous tactic. This covers the frequent cases where
+ a tactic generates two subgoals one of which can be easily disposed
+ of.
+
+ This is another powerful way of linearization of scripts, since it
+ happens very often that a trivial subgoal can be solved in a less than
+ one line tactic. For instance, :n:`@tactic ; last by @tactic`
+ tries to solve the last subgoal generated by the first
+ tactic using the given second tactic, and fails if it does not succeed.
+ Its analogue :n:`@tactic ; first by @tactic`
+ tries to solve the first subgoal generated by the first tactic using the
+ second given tactic, and fails if it does not succeed.
+
+|SSR| also offers an extension of this facility, by supplying
+tactics to *permute* the subgoals generated by a tactic.
+
+.. tacv:: last first
+ first last
+ :name: last first; first last
+
+ These two equivalent tactics invert the order of the subgoals in focus.
+
+ .. tacv:: last @num first
+
+ If :token:`num`\'s value is :math:`k`,
+ this tactic rotates the :math:`n` subgoals :math:`G_1` , …, :math:`G_n`
+ in focus. The first subgoal becomes :math:`G_{n + 1 − k}` and the
+ circular order of subgoals remains unchanged.
+
+ .. tacn:: first @num last
+
+ If :token:`num`\'s value is :math:`k`,
+ this tactic rotates the :math:`n` subgoals :math:`G_1` , …, :math:`G_n`
+ in focus. The first subgoal becomes :math:`G_k` and the circular order
+ of subgoals remains unchanged.
+
+Finally, the tactics ``last`` and ``first`` combine with the branching syntax
+of Ltac: if the tactic generates n subgoals on a given goal,
+then the tactic
+
+.. coqdoc::
+
+ tactic ; last k [ tactic1 |…| tacticm ] || tacticn.
+
+where natural denotes the integer k as above, applies tactic1 to the n
+−k + 1-th goal, … tacticm to the n −k + 2 − m-th goal and tactic n
+to the others.
+
+.. example::
+
+ Here is a small example on lists. We define first a function which
+ adds an element at the end of a given list.
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Inductive test : nat -> Prop :=
+ | C1 n of n = 1 : test n
+ | C2 n of n = 2 : test n
+ | C3 n of n = 3 : test n
+ | C4 n of n = 4 : test n.
+
+ Lemma example n (t : test n) : True.
+ case: t; last 2 [move=> k| move=> l]; idtac.
+
+
+.. _iteration_ssr:
+
+Iteration
+~~~~~~~~~
+
+.. tacn:: do {? @num } ( @tactic | [ {+| @tactic } ] )
+ :name: do (ssreflect)
+
+ This tactical offers an accurate control on the repetition of tactics.
+ :token:`mult` is a *multiplier*.
+
+ Brackets can only be omitted if a single tactic is given *and* a
+ multiplier is present.
+
+A tactic of the form:
+
+.. coqdoc::
+
+ do [ tactic 1 | … | tactic n ].
+
+is equivalent to the standard Ltac expression:
+
+.. coqdoc::
+
+ first [ tactic 1 | … | tactic n ].
+
+The optional multiplier :token:`mult` specifies how many times the action of
+tactic should be repeated on the current subgoal.
+
+There are four kinds of multipliers:
+
+.. prodn::
+ mult ::= @num ! %| ! %| @num ? %| ?
+
+Their meaning is:
+
++ ``n!`` the step tactic is repeated exactly n times (where n is a
+ positive integer argument).
++ ``!`` the step tactic is repeated as many times as possible, and done
+ at least once.
++ ``?`` the step tactic is repeated as many times as possible,
+ optionally.
++ ``n?`` the step tactic is repeated up to n times, optionally.
+
+
+For instance, the tactic:
+
+.. coqdoc::
+
+ tactic; do 1? rewrite mult_comm.
+
+rewrites at most one time the lemma ``mult_comm`` in all the subgoals
+generated by tactic , whereas the tactic:
+
+.. coqdoc::
+
+ tactic; do 2! rewrite mult_comm.
+
+rewrites exactly two times the lemma ``mult_comm`` in all the subgoals
+generated by tactic, and fails if this rewrite is not possible in some
+subgoal.
+
+Note that the combination of multipliers and rewrite is so often used
+that multipliers are in fact integrated to the syntax of the
+|SSR| rewrite tactic, see section :ref:`rewriting_ssr`.
+
+
+.. _localization_ssr:
+
+Localization
+~~~~~~~~~~~~
+
+In sections :ref:`basic_localization_ssr` and :ref:`bookkeeping_ssr`, we have
+already presented the *localization* tactical in, whose general syntax is:
+
+.. tacn:: @tactic in {+ @ident} {? * }
+ :name: in
+ :undocumented:
+
+where :token:`ident` is a name in the
+context. On the left side of ``in``,
+:token:`tactic` can be ``move``, ``case``, ``elim``, ``rewrite``, ``set``,
+or any tactic formed with the general iteration tactical ``do`` (see section
+:ref:`iteration_ssr`).
+
+The operation described by tactic is performed in the facts listed after
+``in`` and in the goal if a ``*`` ends the list of names.
+
+The ``in`` tactical successively:
+
++ generalizes the selected hypotheses, possibly “protecting” the goal
+ if ``*`` is not present,
++ performs :token:`tactic`, on the obtained goal,
++ reintroduces the generalized facts, under the same names.
+
+This defective form of the ``do`` tactical is useful to avoid clashes
+between standard Ltac in and the |SSR| tactical in.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Ltac mytac H := rewrite H.
+
+ Lemma test x y (H1 : x = y) (H2 : y = 3) : x + y = 6.
+ do [mytac H2] in H1 *.
+
+ the last tactic rewrites the hypothesis ``H2 : y = 3`` both in
+ ``H1 : x = y`` and in the goal ``x + y = 6``.
+
+By default ``in`` keeps the body of local definitions. To erase the body
+of a local definition during the generalization phase, the name of the
+local definition must be written between parentheses, like in
+``rewrite H in H1 (def_n) H2.``
+
+.. tacv:: @tactic in {+ @clear_switch | {? @ } @ident | ( @ident ) | ( {? @ } @ident := @c_pattern ) } {? * }
+
+ This is the most general form of the ``in`` tactical.
+ In its simplest form the last option lets one rename hypotheses that
+ can’t be cleared (like section variables). For example, ``(y := x)``
+ generalizes over ``x`` and reintroduces the generalized variable under the
+ name ``y`` (and does not clear ``x``).
+ For a more precise description of this form of localization refer
+ to :ref:`advanced_generalization_ssr`.
+
+
+.. _structure_ssr:
+
+Structure
+~~~~~~~~~
+
+Forward reasoning structures the script by explicitly specifying some
+assumptions to be added to the proof context. It is closely associated
+with the declarative style of proof, since an extensive use of these
+highlighted statements make the script closer to a (very detailed)
+textbook proof.
+
+Forward chaining tactics allow to state an intermediate lemma and start a
+piece of script dedicated to the proof of this statement. The use of closing
+tactics (see section :ref:`terminators_ssr`) and of indentation makes
+syntactically explicit the portion of the script building the proof of the
+intermediate statement.
+
+
+The have tactic.
+````````````````
+
+.. tacn:: have : @term
+ :name: have
+
+ This is the main |SSR| forward reasoning tactic. It can
+ be used in two modes: one starts a new (sub)proof for an intermediate
+ result in the main proof, and the other provides explicitly a proof
+ term for this intermediate step.
+
+ This tactic supports open syntax for :token:`term`. Applied to a goal ``G``, it
+ generates a first subgoal requiring a proof of :token:`term` in the context of
+ ``G``. The second generated subgoal is of the form :n:`term -> G`, where term
+ becomes the new top assumption, instead of being introduced with a
+ fresh name. At the proof-term level, the have tactic creates a β
+ redex, and introduces the lemma under a fresh name, automatically
+ chosen.
+
+Like in the case of the :n:`pose (ssreflect)` tactic (see section :ref:`definitions_ssr`), the types of
+the holes are abstracted in term.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test : True.
+ have: _ * 0 = 0.
+
+ The invokation of ``have`` is equivalent to:
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Lemma test : True.
+
+ .. coqtop:: all
+
+ have: forall n : nat, n * 0 = 0.
+
+The have tactic also enjoys the same abstraction mechanism as the ``pose``
+tactic for the non-inferred implicit arguments. For instance, the
+tactic:
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Lemma test : True.
+
+ .. coqtop:: all
+
+ have: forall x y, (x, y) = (x, y + 0).
+
+ opens a new subgoal where the type of ``x`` is quantified.
+
+The behavior of the defective have tactic makes it possible to
+generalize it in the following general construction:
+
+.. tacn:: have {* @i_item } {? @i_pattern } {? @s_item | {+ @ssr_binder } } {? : @term } {? := @term | by @tactic }
+ :undocumented:
+
+Open syntax is supported for both :token:`term`. For the description
+of :token:`i_item` and :token:`s_item` see section
+:ref:`introduction_ssr`. The first mode of the
+have tactic, which opens a sub-proof for an intermediate result, uses
+tactics of the form:
+
+.. tacv:: have @clear_switch @i_item : @term by @tactic
+ :undocumented:
+
+which behave like:
+
+.. coqdoc::
+
+ have: term ; first by tactic.
+ move=> clear_switch i_item.
+
+Note that the :token:`clear_switch` *precedes* the:token:`i_item`, which
+allows to reuse
+a name of the context, possibly used by the proof of the assumption,
+to introduce the new assumption itself.
+
+The ``by`` feature is especially convenient when the proof script of the
+statement is very short, basically when it fits in one line like in:
+
+.. coqdoc::
+
+ have H23 : 3 + 2 = 2 + 3 by rewrite addnC.
+
+The possibility of using :token:`i_item` supplies a very concise syntax for
+the further use of the intermediate step. For instance,
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test a : 3 * a - 1 = a.
+ have -> : forall x, x * a = a.
+
+ Note how the second goal was rewritten using the stated equality.
+ Also note that in this last subgoal, the intermediate result does not
+ appear in the context.
+
+Thanks to the deferred execution of clears, the following idiom is
+also supported (assuming x occurs in the goal only):
+
+.. coqdoc::
+
+ have {x} -> : x = y.
+
+Another frequent use of the intro patterns combined with ``have`` is the
+destruction of existential assumptions like in the tactic:
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test : True.
+ have [x Px]: exists x : nat, x > 0; last first.
+
+An alternative use of the ``have`` tactic is to provide the explicit proof
+term for the intermediate lemma, using tactics of the form:
+
+.. tacv:: have {? @ident } := term
+
+ This tactic creates a new assumption of type the type of :token:`term`.
+ If the
+ optional :token:`ident` is present, this assumption is introduced under the
+ name :token:`ident`. Note that the body of the constant is lost for the user.
+
+ Again, non inferred implicit arguments and explicit holes are
+ abstracted.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test : True.
+ have H := forall x, (x, x) = (x, x).
+
+ adds to the context ``H : Type -> Prop.`` This is a schematic example but
+ the feature is specially useful when the proof term to give involves
+ for instance a lemma with some hidden implicit arguments.
+
+After the :token:`i_pattern`, a list of binders is allowed.
+
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ From Coq Require Import Omega.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test : True.
+ have H x (y : nat) : 2 * x + y = x + x + y by omega.
+
+A proof term provided after ``:=`` can mention these bound variables
+(that are automatically introduced with the given names).
+Since the :token:`i_pattern` can be omitted, to avoid ambiguity,
+bound variables can be surrounded
+with parentheses even if no type is specified:
+
+.. coqtop:: all restart
+
+ have (x) : 2 * x = x + x by omega.
+
+The :token:`i_item` and :token:`s_item` can be used to interpret the asserted
+hypothesis with views (see section :ref:`views_and_reflection_ssr`) or simplify the resulting
+goals.
+
+The ``have`` tactic also supports a ``suff`` modifier which allows for
+asserting that a given statement implies the current goal without
+copying the goal itself.
+
+.. example::
+
+ .. coqtop:: all restart abort
+
+ have suff H : 2 + 2 = 3; last first.
+
+ Note that H is introduced in the second goal.
+
+The ``suff`` modifier is not
+compatible with the presence of a list of binders.
+
+.. _generating_let_ssr:
+
+Generating let in context entries with have
+```````````````````````````````````````````
+
+Since |SSR| 1.5 the ``have`` tactic supports a “transparent” modifier
+to generate let in context entries: the ``@`` symbol in front of the
+context entry name.
+
+.. example::
+
+ .. coqtop:: none
+
+ Set Printing Depth 15.
+
+ .. coqtop:: all abort
+
+ Inductive Ord n := Sub x of x < n.
+ Notation "'I_ n" := (Ord n) (at level 8, n at level 2, format "''I_' n").
+ Arguments Sub {_} _ _.
+
+ Lemma test n m (H : m + 1 < n) : True.
+ have @i : 'I_n by apply: (Sub m); omega.
+
+Note that the sub-term produced by ``omega`` is in general huge and
+uninteresting, and hence one may want to hide it.
+For this purpose the ``[: name ]`` intro pattern and the tactic
+``abstract`` (see :ref:`abstract_ssr`) are provided.
+
+.. example::
+
+ .. coqtop:: all abort
+
+ Lemma test n m (H : m + 1 < n) : True.
+ have [:pm] @i : 'I_n by apply: (Sub m); abstract: pm; omega.
+
+ The type of ``pm`` can be cleaned up by its annotation ``(*1*)`` by just
+ simplifying it. The annotations are there for technical reasons only.
+
+When intro patterns for abstract constants are used in conjunction
+with have and an explicit term, they must be used as follows:
+
+.. example::
+
+ .. coqtop:: all abort
+
+ Lemma test n m (H : m + 1 < n) : True.
+ have [:pm] @i : 'I_n := Sub m pm.
+ by omega.
+
+In this case the abstract constant ``pm`` is assigned by using it in
+the term that follows ``:=`` and its corresponding goal is left to be
+solved. Goals corresponding to intro patterns for abstract constants
+are opened in the order in which the abstract constants are declared
+(not in the “order” in which they are used in the term).
+
+Note that abstract constants do respect scopes. Hence, if a variable
+is declared after their introduction, it has to be properly
+generalized (i.e. explicitly passed to the abstract constant when one
+makes use of it).
+
+.. example::
+
+ .. coqtop:: all abort
+
+ Lemma test n m (H : m + 1 < n) : True.
+ have [:pm] @i k : 'I_(n+k) by apply: (Sub m); abstract: pm k; omega.
+
+Last, notice that the use of intro patterns for abstract constants is
+orthogonal to the transparent flag ``@`` for have.
+
+
+The have tactic and typeclass resolution
+```````````````````````````````````````````
+
+Since |SSR| 1.5 the ``have`` tactic behaves as follows with respect to
+typeclass inference.
+
+ .. coqtop:: none
+
+ Axiom ty : Type.
+ Axiom t : ty.
+
+ Goal True.
+
+ .. coqtop:: all
+
+ have foo : ty.
+
+ Full inference for ``ty``. The first subgoal demands a
+ proof of such instantiated statement.
+
+ .. A strange bug prevents using the coqtop directive here
+
+ .. coqdoc::
+
+ have foo : ty := .
+
+ No inference for ``ty``. Unresolved instances are
+ quantified in ``ty``. The first subgoal demands a proof of such quantified
+ statement. Note that no proof term follows ``:=``, hence two subgoals are
+ generated.
+
+ .. coqtop:: all restart
+
+ have foo : ty := t.
+
+ No inference for ``ty`` and ``t``.
+
+ .. coqtop:: all restart abort
+
+ have foo := t.
+
+ No inference for ``t``. Unresolved instances are
+ quantified in the (inferred) type of ``t`` and abstracted in ``t``.
+
+.. flag:: SsrHave NoTCResolution
+
+ This option restores the behavior of |SSR| 1.4 and below (never resolve typeclasses).
+
+Variants: the suff and wlog tactics
+```````````````````````````````````
+
+As it is often the case in mathematical textbooks, forward reasoning
+may be used in slightly different variants. One of these variants is
+to show that the intermediate step L easily implies the initial goal
+G. By easily we mean here that the proof of L ⇒ G is shorter than the
+one of L itself. This kind of reasoning step usually starts with: “It
+suffices to show that …”.
+
+This is such a frequent way of reasoning that |SSR| has a variant
+of the ``have`` tactic called ``suffices`` (whose abridged name is ``suff``).
+The
+``have`` and ``suff`` tactics are equivalent and have the same syntax but:
+
+
++ the order of the generated subgoals is inversed
++ but the optional clear item is still performed in the *second*
+ branch. This means that the tactic:
+
+ .. coqdoc::
+
+ suff {H} H : forall x : nat, x >= 0.
+
+ fails if the context of the current goal indeed contains an
+ assumption named ``H``.
+
+
+The rationale of this clearing policy is to make possible “trivial”
+refinements of an assumption, without changing its name in the main
+branch of the reasoning.
+
+The ``have`` modifier can follow the ``suff`` tactic.
+
+.. example::
+
+ .. coqtop:: none
+
+ Axioms G P : Prop.
+
+ .. coqtop:: all abort
+
+ Lemma test : G.
+ suff have H : P.
+
+ Note that, in contrast with ``have suff``, the name H has been introduced
+ in the first goal.
+
+Another useful construct is reduction, showing that a particular case
+is in fact general enough to prove a general property. This kind of
+reasoning step usually starts with: “Without loss of generality, we
+can suppose that …”. Formally, this corresponds to the proof of a goal
+``G`` by introducing a cut ``wlog_statement -> G``. Hence the user shall
+provide a proof for both ``(wlog_statement -> G) -> G`` and
+``wlog_statement -> G``. However, such cuts are usually rather
+painful to perform by
+hand, because the statement ``wlog_statement`` is tedious to write by hand,
+and sometimes even to read.
+
+|SSR| implements this kind of reasoning step through the :tacn:`without loss`
+tactic, whose short name is :tacn:`wlog`. It offers support to describe
+the shape of the cut statements, by providing the simplifying
+hypothesis and by pointing at the elements of the initial goals which
+should be generalized. The general syntax of without loss is:
+
+.. tacn:: wlog {? suff } {? @clear_switch } {? @i_item } : {* @ident } / @term
+ without loss {? suff } {? @clear_switch } {? @i_item } : {* @ident } / @term
+ :name: wlog; without loss
+ :undocumented:
+
+where each :token:`ident` is a constant in the context
+of the goal. Open syntax is supported for :token:`term`.
+
+In its defective form:
+
+.. tacv:: wlog: / @term
+ without loss: / @term
+ :undocumented:
+
+on a goal G, it creates two subgoals: a first one to prove the
+formula (term -> G) -> G and a second one to prove the formula
+term -> G.
+
+If the optional list of :token:`ident` is present
+on the left side of ``/``, these constants are generalized in the
+premise (term -> G) of the first subgoal. By default bodies of local
+definitions are erased. This behavior can be inhibited by prefixing the
+name of the local definition with the ``@`` character.
+
+In the second subgoal, the tactic:
+
+.. coqdoc::
+
+ move=> clear_switch i_item.
+
+is performed if at least one of these optional switches is present in
+the :tacn:`wlog` tactic.
+
+The :tacn:`wlog` tactic is specially useful when a symmetry argument
+simplifies a proof. Here is an example showing the beginning of the
+proof that quotient and reminder of natural number euclidean division
+are unique.
+
+.. example::
+
+ .. coqtop:: all
+
+ Lemma quo_rem_unicity d q1 q2 r1 r2 :
+ q1*d + r1 = q2*d + r2 -> r1 < d -> r2 < d -> (q1, r1) = (q2, r2).
+ wlog: q1 q2 r1 r2 / q1 <= q2.
+ by case (le_gt_dec q1 q2)=> H; last symmetry; eauto with arith.
+
+The ``wlog suff`` variant is simpler, since it cuts ``wlog_statement`` instead
+of ``wlog_statement -> G``. It thus opens the goals
+``wlog_statement -> G``
+and ``wlog_statement``.
+
+In its simplest form the ``generally have : …`` tactic is equivalent to
+``wlog suff : …`` followed by last first. When the ``have`` tactic is used
+with the ``generally`` (or ``gen``) modifier it accepts an extra identifier
+followed by a comma before the usual intro pattern. The identifier
+will name the new hypothesis in its more general form, while the intro
+pattern will be used to process its instance.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect ssrfun ssrbool.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ Axiom P : nat -> Prop.
+ Axioms eqn leqn : nat -> nat -> bool.
+ Declare Scope this_scope.
+ Notation "a != b" := (eqn a b) (at level 70) : this_scope.
+ Notation "a <= b" := (leqn a b) (at level 70) : this_scope.
+ Open Scope this_scope.
+
+ .. coqtop:: all
+
+ Lemma simple n (ngt0 : 0 < n ) : P n.
+ gen have ltnV, /andP[nge0 neq0] : n ngt0 / (0 <= n) && (n != 0); last first.
+
+
+.. _advanced_generalization_ssr:
+
+Advanced generalization
++++++++++++++++++++++++
+
+The complete syntax for the items on the left hand side of the ``/``
+separator is the following one:
+
+.. tacv:: wlog … : {? @clear_switch | {? @ } @ident | ( {? @ } @ident := @c_pattern) } / @term
+ :undocumented:
+
+Clear operations are intertwined with generalization operations. This
+helps in particular avoiding dependency issues while generalizing some
+facts.
+
+If an :token:`ident` is prefixed with the ``@`` mark, then a let-in redex is
+created, which keeps track if its body (if any). The syntax
+``( ident := c_pattern)`` allows to generalize an arbitrary term using a
+given name. Note that its simplest form ``(x := y)`` is just a renaming of
+``y`` into ``x``. In particular, this can be useful in order to simulate the
+generalization of a section variable, otherwise not allowed. Indeed
+renaming does not require the original variable to be cleared.
+
+The syntax ``(@x := y)`` generates a let-in abstraction but with the
+following caveat: ``x`` will not bind ``y``, but its body, whenever ``y`` can be
+unfolded. This covers the case of both local and global definitions, as
+illustrated in the following example.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Section Test.
+ Variable x : nat.
+ Definition addx z := z + x.
+ Lemma test : x <= addx x.
+ wlog H : (y := x) (@twoy := addx x) / twoy = 2 * y.
+
+ To avoid unfolding the term captured by the pattern add x one can use
+ the pattern ``id (addx x)``, that would produce the following first
+ subgoal
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect Omega.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ Section Test.
+ Variable x : nat.
+ Definition addx z := z + x.
+ Lemma test : x <= addx x.
+
+ .. coqtop:: all
+
+ wlog H : (y := x) (@twoy := id (addx x)) / twoy = 2 * y.
+
+
+.. _rewriting_ssr:
+
+Rewriting
+---------
+
+The generalized use of reflection implies that most of the
+intermediate results handled are properties of effectively computable
+functions. The most efficient mean of establishing such results are
+computation and simplification of expressions involving such
+functions, i.e., rewriting. |SSR| therefore includes an
+extended ``rewrite`` tactic, that unifies and combines most of the
+rewriting functionalities.
+
+
+An extended rewrite tactic
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The main features of the rewrite tactic are:
+
++ It can perform an entire series of such operations in any subset of
+ the goal and/or context;
++ It allows to perform rewriting, simplifications, folding/unfolding
+ of definitions, closing of goals;
++ Several rewriting operations can be chained in a single tactic;
++ Control over the occurrence at which rewriting is to be performed is
+ significantly enhanced.
+
+The general form of an |SSR| rewrite tactic is:
+
+.. tacn:: rewrite {+ @rstep }
+ :name: rewrite (ssreflect)
+ :undocumented:
+
+The combination of a rewrite tactic with the ``in`` tactical (see section
+:ref:`localization_ssr`) performs rewriting in both the context and the goal.
+
+A rewrite step :token:`rstep` has the general form:
+
+.. prodn::
+ rstep ::= {? @r_prefix } @r_item
+
+.. prodn::
+ r_prefix ::= {? - } {? @mult } {? @occ_switch %| @clear_switch } {? [ @r_pattern ] }
+
+.. prodn::
+ r_pattern ::= @term %| in {? @ident in } @term %| %( @term in %| @term as %) @ident in @term
+
+.. prodn::
+ r_item ::= {? / } @term %| @s_item
+
+An :token:`r_prefix` contains annotations to qualify where and how the rewrite
+operation should be performed:
+
++ The optional initial ``-`` indicates the direction of the rewriting of
+ :token:`r_item`:
+ if present the direction is right-to-left and it is left-to-right otherwise.
++ The multiplier :token:`mult` (see section :ref:`iteration_ssr`)
+ specifies if and how the
+ rewrite operation should be repeated.
++ A rewrite operation matches the occurrences of a *rewrite pattern*,
+ and replaces these occurrences by another term, according to the
+ given :token:`r_item`. The optional *redex switch* ``[r_pattern]``,
+ which should
+ always be surrounded by brackets, gives explicitly this rewrite
+ pattern. In its simplest form, it is a regular term. If no explicit
+ redex switch is present the rewrite pattern to be matched is inferred
+ from the :token:`r_item`.
++ This optional term, or the :token:`r_item`, may be preceded by an
+ :token:`occ_switch` (see section :ref:`selectors_ssr`) or a
+ :token:`clear_switch` (see section :ref:`discharge_ssr`),
+ these two possibilities being exclusive.
+
+ An occurrence switch selects
+ the occurrences of the rewrite pattern which should be affected by the
+ rewrite operation.
+
+ A clear switch, even an empty one, is performed *after* the
+ :token:`r_item` is actually processed and is complemented with the name of
+ the rewrite rule if an only if it is a simple proof context entry [#10]_.
+ As a consequence one can
+ write ``rewrite {}H`` to rewrite with ``H`` and dispose ``H`` immediately
+ afterwards.
+ This behavior can be avoided by putting parentheses around the rewrite rule.
+
+An :token:`r_item` can be:
+
+
++ A *simplification* :token:`r_item`,
+ represented by a :token:`s_item` (see section
+ :ref:`introduction_ssr`). Simplification operations are intertwined with the possible
+ other rewrite operations specified by the list of :token:`r_item`.
++ A *folding/unfolding* :token:`r_item`. The tactic:
+ ``rewrite /term`` unfolds the
+ head constant of term in every occurrence of the first matching of
+ term in the goal. In particular, if ``my_def`` is a (local or global)
+ defined constant, the tactic: ``rewrite /my_def.`` is analogous to:
+ ``unfold my_def``.
+ Conversely: ``rewrite -/my_def.`` is equivalent to: ``fold my_def``.
+ When an unfold :token:`r_item` is combined with a
+ redex pattern, a conversion
+ operation is performed. A tactic of the form:
+ ``rewrite -[term1]/term2.``
+ is equivalent to: ``change term1 with term2.`` If ``term2`` is a
+ single constant and ``term1`` head symbol is not ``term2``, then the head
+ symbol of ``term1`` is repeatedly unfolded until ``term2`` appears.
++ A :token:`term`, which can be:
+ + A term whose type has the form:
+ ``forall (x1 : A1 )…(xn : An ), eq term1 term2`` where
+ ``eq`` is the Leibniz equality or a registered setoid
+ equality.
+ + A list of terms ``(t1 ,…,tn)``, each ``ti`` having a type above.
+ The tactic: ``rewrite r_prefix (t1 ,…,tn ).``
+ is equivalent to: ``do [rewrite r_prefix t1 | … | rewrite r_prefix tn ].``
+ + An anonymous rewrite lemma ``(_ : term)``, where term has a type as above. tactic: ``rewrite (_ : term)`` is in fact synonym of: ``cutrewrite (term).``.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all abort
+
+ Definition double x := x + x.
+ Definition ddouble x := double (double x).
+ Lemma test x : ddouble x = 4 * x.
+ rewrite [ddouble _]/double.
+
+ .. warning::
+
+ The |SSR| terms containing holes are *not* typed as
+ abstractions in this context. Hence the following script fails.
+
+ .. coqtop:: all
+
+ Definition f := fun x y => x + y.
+ Lemma test x y : x + y = f y x.
+
+ .. coqtop:: all fail
+
+ rewrite -[f y]/(y + _).
+
+ but the following script succeeds
+
+ .. coqtop:: all
+
+ rewrite -[f y x]/(y + _).
+
+
+.. flag:: SsrOldRewriteGoalsOrder
+
+ Controls the order in which generated subgoals (side conditions)
+ are added to the
+ proof context. The flag is off by default, which puts subgoals generated
+ by conditional rules first, followed by the main goal. When it is on,
+ the main goal appears first. If your proofs are organized to complete
+ proving the main goal before side conditions, turning the flag on will save you
+ from having to add :tacn:`last first` tactics that would be needed
+ to keep the main goal as the currently focused goal.
+
+Remarks and examples
+~~~~~~~~~~~~~~~~~~~~
+
+Rewrite redex selection
+```````````````````````
+
+The general strategy of |SSR| is to grasp as many redexes as
+possible and to let the user select the ones to be rewritten thanks to
+the improved syntax for the control of rewriting.
+
+This may be a source of incompatibilities between the two rewrite
+tactics.
+
+In a rewrite tactic of the form:
+
+.. coqdoc::
+
+ rewrite occ_switch [term1]term2.
+
+``term1`` is the explicit rewrite redex and ``term2`` is the rewrite rule.
+This execution of this tactic unfolds as follows:
+
+
++ First ``term1`` and ``term2`` are βι normalized. Then ``term2``
+ is put in head
+ normal form if the Leibniz equality constructor ``eq`` is not the head
+ symbol. This may involve ζ reductions.
++ Then, the matching algorithm (see section :ref:`abbreviations_ssr`)
+ determines the
+ first subterm of the goal matching the rewrite pattern. The rewrite
+ pattern is given by ``term1``, if an explicit redex pattern switch is
+ provided, or by the type of ``term2`` otherwise. However, matching skips
+ over matches that would lead to trivial rewrites. All the occurrences
+ of this subterm in the goal are candidates for rewriting.
++ Then only the occurrences coded by :token:`occ_switch` (see again section
+ :ref:`abbreviations_ssr`) are finally selected for rewriting.
++ The left hand side of ``term2`` is unified with the subterm found by
+ the matching algorithm, and if this succeeds, all the selected
+ occurrences in the goal are replaced by the right hand side of ``term2``.
++ Finally the goal is βι normalized.
+
+
+In the case ``term2`` is a list of terms, the first top-down (in the
+goal) left-to-right (in the list) matching rule gets selected.
+
+
+Chained rewrite steps
+`````````````````````
+
+The possibility to chain rewrite operations in a single tactic makes
+scripts more compact and gathers in a single command line a bunch of
+surgical operations which would be described by a one sentence in a
+pen and paper proof.
+
+Performing rewrite and simplification operations in a single tactic
+enhances significantly the concision of scripts. For instance the
+tactic:
+
+.. coqdoc::
+
+ rewrite /my_def {2}[f _]/= my_eq //=.
+
+
+unfolds ``my_def`` in the goal, simplifies the second occurrence of the
+first subterm matching pattern ``[f _]``, rewrites ``my_eq``, simplifies the
+goals and closes trivial goals.
+
+Here are some concrete examples of chained rewrite operations, in the
+proof of basic results on natural numbers arithmetic.
+
+.. example::
+
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Axiom addn0 : forall m, m + 0 = m.
+ Axiom addnS : forall m n, m + S n = S (m + n).
+ Axiom addSnnS : forall m n, S m + n = m + S n.
+
+ Lemma addnCA m n p : m + (n + p) = n + (m + p).
+ by elim: m p => [ | m Hrec] p; rewrite ?addSnnS -?addnS.
+ Qed.
+
+ Lemma addnC n m : m + n = n + m.
+ by rewrite -{1}[n]addn0 addnCA addn0.
+ Qed.
+
+Note the use of the ``?`` switch for parallel rewrite operations in the
+proof of ``addnCA``.
+
+
+Explicit redex switches are matched first
+`````````````````````````````````````````
+
+If an :token:`r_prefix` involves a *redex switch*, the first step is to find a
+subterm matching this redex pattern, independently from the left hand
+side of the equality the user wants to rewrite.
+
+
+.. example::
+
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test (H : forall t u, t + u = u + t) x y : x + y = y + x.
+ rewrite [y + _]H.
+
+Note that if this first pattern matching is not compatible with the
+:token:`r_item`, the rewrite fails, even if the goal contains a
+correct redex matching both the redex switch and the left hand side of
+the equality.
+
+.. example::
+
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test (H : forall t u, t + u * 0 = t) x y : x + y * 4 + 2 * 0 = x + 2 * 0.
+ Fail rewrite [x + _]H.
+
+ Indeed the left hand side of ``H`` does not match
+ the redex identified by the pattern ``x + y * 4``.
+
+.. _ssr_rewrite_occ_switch:
+
+Occurrence switches and redex switches
+``````````````````````````````````````
+
+.. example::
+
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test x y : x + y + 0 = x + y + y + 0 + 0 + (x + y + 0).
+ rewrite {2}[_ + y + 0](_: forall z, z + 0 = z).
+
+The second subgoal is generated by the use of an anonymous lemma in
+the rewrite tactic. The effect of the tactic on the initial goal is to
+rewrite this lemma at the second occurrence of the first matching
+``x + y + 0`` of the explicit rewrite redex ``_ + y + 0``.
+
+Occurrence selection and repetition
+```````````````````````````````````
+
+Occurrence selection has priority over repetition switches. This means
+the repetition of a rewrite tactic specified by a multiplier will
+perform matching each time an elementary rewrite operation is
+performed. Repeated rewrite tactics apply to every subgoal generated
+by the previous tactic, including the previous instances of the
+repetition.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Lemma test x y (z : nat) : x + 1 = x + y + 1.
+ rewrite 2!(_ : _ + 1 = z).
+
+This last tactic generates *three* subgoals because
+the second rewrite operation specified with the ``2!`` multiplier
+applies to the two subgoals generated by the first rewrite.
+
+
+Multi-rule rewriting
+````````````````````
+
+The rewrite tactic can be provided a *tuple* of rewrite rules, or more
+generally a tree of such rules, since this tuple can feature arbitrary
+inner parentheses. We call *multirule* such a generalized rewrite
+rule. This feature is of special interest when it is combined with
+multiplier switches, which makes the rewrite tactic iterate the
+rewrite operations prescribed by the rules on the current goal.
+
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ Section Test.
+
+ .. coqtop:: all abort
+
+ Variables (a b c : nat).
+ Hypothesis eqab : a = b.
+ Hypothesis eqac : a = c.
+
+ Lemma test : a = a.
+ rewrite (eqab, eqac).
+
+ Indeed rule ``eqab`` is the first to apply among the ones
+ gathered in the tuple passed to the rewrite tactic. This multirule
+ ``(eqab, eqac)`` is actually a |Coq| term and we can name it with a
+ definition:
+
+ .. coqtop:: all
+
+ Definition multi1 := (eqab, eqac).
+
+ In this case, the tactic ``rewrite multi1`` is a synonym for
+ ``rewrite (eqab, eqac)``.
+
+More precisely, a multirule rewrites the first subterm to which one of
+the rules applies in a left-to-right traversal of the goal, with the
+first rule from the multirule tree in left-to-right order. Matching is
+performed according to the algorithm described in
+Section :ref:`abbreviations_ssr`, but
+literal matches have priority.
+
+.. example::
+
+ .. coqtop:: all abort
+
+ Definition d := a.
+ Hypotheses eqd0 : d = 0.
+ Definition multi2 := (eqab, eqd0).
+
+ Lemma test : d = b.
+ rewrite multi2.
+
+ Indeed rule ``eqd0`` applies without unfolding the
+ definition of ``d``.
+
+For repeated rewrites the selection process is
+repeated anew.
+
+.. example::
+
+ .. coqtop:: all abort
+
+ Hypothesis eq_adda_b : forall x, x + a = b.
+ Hypothesis eq_adda_c : forall x, x + a = c.
+ Hypothesis eqb0 : b = 0.
+ Definition multi3 := (eq_adda_b, eq_adda_c, eqb0).
+
+ Lemma test : 1 + a = 12 + a.
+ rewrite 2!multi3.
+
+ It uses ``eq_adda_b`` then ``eqb0`` on the left-hand
+ side only. Without the bound ``2`` one would obtain ``0 = 0``.
+
+The grouping of rules inside a multirule does not affect the selection
+strategy but can make it easier to include one rule set in another or
+to (universally) quantify over the parameters of a subset of rules (as
+there is special code that will omit unnecessary quantifiers for rules
+that can be syntactically extracted). It is also possible to reverse
+the direction of a rule subset, using a special dedicated syntax: the
+tactic rewrite ``(=~ multi1)`` is equivalent to ``rewrite multi1_rev``.
+
+.. example::
+
+ .. coqtop:: all
+
+ Hypothesis eqba : b = a.
+ Hypothesis eqca : c = a.
+ Definition multi1_rev := (eqba, eqca).
+
+except that the constants ``eqba``, ``eqab``, ``mult1_rev``
+have not been created.
+
+Rewriting with multirules is useful to implement simplification or
+transformation procedures, to be applied on terms of small to medium
+size. For instance the library `ssrnat` (Mathematical Components library)
+provides two implementations
+for arithmetic operations on natural numbers: an elementary one and a
+tail recursive version, less inefficient but also less convenient for
+reasoning purposes. The library also provides one lemma per such
+operation, stating that both versions return the same values when
+applied to the same arguments:
+
+.. coqdoc::
+
+ Lemma addE : add =2 addn.
+ Lemma doubleE : double =1 doublen.
+ Lemma add_mulE n m s : add_mul n m s = addn (muln n m) s.
+ Lemma mulE : mul =2 muln.
+ Lemma mul_expE m n p : mul_exp m n p = muln (expn m n) p.
+ Lemma expE : exp =2 expn.
+ Lemma oddE : odd =1 oddn.
+
+The operation on the left hand side of each lemma is the efficient
+version, and the corresponding naive implementation is on the right
+hand side. In order to reason conveniently on expressions involving
+the efficient operations, we gather all these rules in the definition
+``trecE``:
+
+.. coqdoc::
+
+ Definition trecE := (addE, (doubleE, oddE), (mulE, add_mulE, (expE, mul_expE))).
+
+The tactic: ``rewrite !trecE.``
+restores the naive versions of each operation in a goal involving the
+efficient ones, e.g. for the purpose of a correctness proof.
+
+
+Wildcards vs abstractions
+`````````````````````````
+
+The rewrite tactic supports :token:`r_items` containing holes. For example, in
+the tactic ``rewrite (_ : _ * 0 = 0).``
+the term ``_ * 0 = 0`` is interpreted as ``forall n : nat, n * 0 = 0.``
+Anyway this tactic is *not* equivalent to
+``rewrite (_ : forall x, x * 0 = 0).``.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ Section Test.
+
+ .. coqtop:: all
+
+ Lemma test y z : y * 0 + y * (z * 0) = 0.
+ rewrite (_ : _ * 0 = 0).
+
+ while the other tactic results in
+
+ .. coqtop:: all restart abort
+
+ rewrite (_ : forall x, x * 0 = 0).
+
+ The first tactic requires you to prove the instance of the (missing)
+ lemma that was used, while the latter requires you prove the quantified
+ form.
+
+When |SSR| rewrite fails on standard |Coq| licit rewrite
+````````````````````````````````````````````````````````
+
+In a few cases, the |SSR| rewrite tactic fails rewriting some
+redexes which standard |Coq| successfully rewrites. There are two main
+cases:
+
+
++ |SSR| never accepts to rewrite indeterminate patterns like:
+
+ .. coqdoc::
+
+ Lemma foo (x : unit) : x = tt.
+
+ |SSR| will however accept the
+ ηζ expansion of this rule:
+
+ .. coqdoc::
+
+ Lemma fubar (x : unit) : (let u := x in u) = tt.
+
++ The standard rewrite tactic provided by |Coq| uses a different algorithm
+ to find instances of the rewrite rule.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ Section Test.
+
+ .. coqtop:: all
+
+ Variable g : nat -> nat.
+ Definition f := g.
+ Axiom H : forall x, g x = 0.
+
+ Lemma test : f 3 + f 3 = f 6.
+ (* we call the standard rewrite tactic here *)
+ rewrite -> H.
+
+ This rewriting is not possible in |SSR| because
+ there is no occurrence of the head symbol ``f`` of the rewrite rule in the
+ goal.
+
+ .. coqtop:: all restart fail
+
+ rewrite H.
+
+ Rewriting with ``H`` first requires unfolding the occurrences of
+ ``f``
+ where the substitution is to be performed (here there is a single such
+ occurrence), using tactic ``rewrite /f`` (for a global replacement of
+ f by g) or ``rewrite pattern/f``, for a finer selection.
+
+ .. coqtop:: all restart
+
+ rewrite /f H.
+
+ alternatively one can override the pattern inferred from ``H``
+
+ .. coqtop:: all restart
+
+ rewrite [f _]H.
+
+
+Existential metavariables and rewriting
+```````````````````````````````````````
+
+The rewrite tactic will not instantiate existing existential
+metavariables when matching a redex pattern.
+
+If a rewrite rule generates a goal with new existential metavariables
+in the ``Prop`` sort, these will be generalized as for ``apply``
+(see :ref:`apply_ssr`) and
+corresponding new goals will be generated.
+
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect ssrfun ssrbool.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Set Warnings "-notation-overridden".
+
+ .. coqtop:: all abort
+
+ Axiom leq : nat -> nat -> bool.
+ Notation "m <= n" := (leq m n) : nat_scope.
+ Notation "m < n" := (S m <= n) : nat_scope.
+ Inductive Ord n := Sub x of x < n.
+ Notation "'I_ n" := (Ord n) (at level 8, n at level 2, format "''I_' n").
+ Arguments Sub {_} _ _.
+ Definition val n (i : 'I_n) := let: Sub a _ := i in a.
+ Definition insub n x :=
+ if @idP (x < n) is ReflectT _ Px then Some (Sub x Px) else None.
+ Axiom insubT : forall n x Px, insub n x = Some (Sub x Px).
+
+ Lemma test (x : 'I_2) y : Some x = insub 2 y.
+ rewrite insubT.
+
+ Since the argument corresponding to Px is not supplied by the user, the
+ resulting goal should be ``Some x = Some (Sub y ?Goal).``
+ Instead, |SSR| ``rewrite`` tactic hides the existential variable.
+
+ As in :ref:`apply_ssr`, the ``ssrautoprop`` tactic is used to try to
+ solve the existential variable.
+
+ .. coqtop:: all
+
+ Lemma test (x : 'I_2) y (H : y < 2) : Some x = insub 2 y.
+ rewrite insubT.
+
+
+As a temporary limitation, this behavior is available only if the
+rewriting rule is stated using Leibniz equality (as opposed to setoid
+relations). It will be extended to other rewriting relations in the
+future.
+
+
+.. _locking_ssr:
+
+Locking, unlocking
+~~~~~~~~~~~~~~~~~~
+
+As program proofs tend to generate large goals, it is important to be
+able to control the partial evaluation performed by the simplification
+operations that are performed by the tactics. These evaluations can
+for example come from a ``/=`` simplification switch, or from rewrite
+steps which may expand large terms while performing conversion. We
+definitely want to avoid repeating large subterms of the goal in the
+proof script. We do this by “clamping down” selected function symbols
+in the goal, which prevents them from being considered in
+simplification or rewriting steps. This clamping is accomplished by
+using the occurrence switches (see section:ref:`abbreviations_ssr`)
+together with “term tagging” operations.
+
+|SSR| provides two levels of tagging.
+
+The first one uses auxiliary definitions to introduce a provably equal
+copy of any term t. However this copy is (on purpose) *not
+convertible* to t in the |Coq| system [#8]_. The job is done by the
+following construction:
+
+.. coqdoc::
+
+ Lemma master_key : unit. Proof. exact tt. Qed.
+ Definition locked A := let: tt := master_key in fun x : A => x.
+ Lemma lock : forall A x, x = locked x :> A.
+
+Note that the definition of *master_key* is explicitly opaque. The
+equation ``t = locked t`` given by the ``lock`` lemma can be used for
+selective rewriting, blocking on the fly the reduction in the term ``t``.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect ssrfun ssrbool.
+ From Coq Require Import List.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Variable A : Type.
+ Fixpoint has (p : A -> bool) (l : list A) : bool :=
+ if l is cons x l then p x || (has p l) else false.
+
+ Lemma test p x y l (H : p x = true) : has p ( x :: y :: l) = true.
+ rewrite {2}[cons]lock /= -lock.
+
+It is sometimes desirable to globally prevent a definition from being
+expanded by simplification; this is done by adding locked in the
+definition.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Definition lid := locked (fun x : nat => x).
+
+ Lemma test : lid 3 = 3.
+ rewrite /=.
+ unlock lid.
+
+.. tacn:: unlock {? @occ_switch } @ident
+ :name: unlock
+
+ This tactic unfolds such definitions while removing “locks”, i.e. it
+ replaces the occurrence(s) of :token:`ident` coded by the
+ :token:`occ_switch` with the corresponding body.
+
+We found that it was usually preferable to prevent the expansion of
+some functions by the partial evaluation switch ``/=``, unless this
+allowed the evaluation of a condition. This is possible thanks to another
+mechanism of term tagging, resting on the following *Notation*:
+
+.. coqdoc::
+
+ Notation "'nosimpl' t" := (let: tt := tt in t).
+
+The term ``(nosimpl t)`` simplifies to ``t`` *except* in a definition.
+More precisely, given:
+
+.. coqdoc::
+
+ Definition foo := (nosimpl bar).
+
+the term ``foo`` (or ``(foo t’)``) will *not* be expanded by the *simpl*
+tactic unless it is in a forcing context (e.g., in ``match foo t’ with …
+end``, ``foo t’`` will be reduced if this allows ``match`` to be reduced).
+Note that ``nosimpl bar`` is simply notation for a term that reduces to
+``bar``; hence ``unfold foo`` will replace ``foo`` by ``bar``, and
+``fold foo`` will replace ``bar`` by ``foo``.
+
+.. warning::
+
+ The ``nosimpl`` trick only works if no reduction is apparent in
+ ``t``; in particular, the declaration:
+
+ .. coqdoc::
+
+ Definition foo x := nosimpl (bar x).
+
+ will usually not work. Anyway, the common practice is to tag only the
+ function, and to use the following definition, which blocks the
+ reduction as expected:
+
+ .. coqdoc::
+
+ Definition foo x := nosimpl bar x.
+
+A standard example making this technique shine is the case of
+arithmetic operations. We define for instance:
+
+.. coqdoc::
+
+ Definition addn := nosimpl plus.
+
+The operation ``addn`` behaves exactly like ``plus``, except that
+``(addn (S n) m)`` will not simplify spontaneously to
+``(S (addn n m))`` (the two terms, however, are convertible).
+In addition, the unfolding step: ``rewrite /addn``
+will replace ``addn`` directly with ``plus``, so the ``nosimpl`` form is
+essentially invisible.
+
+
+.. _congruence_ssr:
+
+Congruence
+~~~~~~~~~~
+
+Because of the way matching interferes with parameters of type families,
+the tactic:
+
+.. coqdoc::
+
+ apply: my_congr_property.
+
+will generally fail to perform congruence simplification, even on
+rather simple cases. We therefore provide a more robust alternative in
+which the function is supplied:
+
+.. tacn:: congr {? @num } @term
+ :name: congr
+
+ This tactic:
+ + checks that the goal is a Leibniz equality;
+ + matches both sides of this equality with “term applied to some arguments”, inferring the right number of arguments from the goal and the type of term. This may expand some definitions or fixpoints;
+ + generates the subgoals corresponding to pairwise equalities of the arguments present in the goal.
+
+ The goal can be a non dependent product ``P -> Q``. In that case, the
+ system asserts the equation ``P = Q``, uses it to solve the goal, and
+ calls the ``congr`` tactic on the remaining goal ``P = Q``. This can be useful
+ for instance to perform a transitivity step, like in the following
+ situation.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Lemma test (x y z : nat) (H : x = y) : x = z.
+ congr (_ = _) : H.
+ Abort.
+
+ Lemma test (x y z : nat) : x = y -> x = z.
+ congr (_ = _).
+
+ The optional :token:`num` forces the number of arguments for which the
+ tactic should generate equality proof obligations.
+
+ This tactic supports equalities between applications with dependent
+ arguments. Yet dependent arguments should have exactly the same
+ parameters on both sides, and these parameters should appear as first
+ arguments.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Definition f n :=
+ if n is 0 then plus else mult.
+ Definition g (n m : nat) := plus.
+
+ Lemma test x y : f 0 x y = g 1 1 x y.
+ congr plus.
+
+ This script shows that the ``congr`` tactic matches ``plus``
+ with ``f 0`` on the left hand side and ``g 1 1`` on the right hand
+ side, and solves the goal.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Lemma test n m (Hnm : m <= n) : S m + (S n - S m) = S n.
+ congr S; rewrite -/plus.
+
+ The tactic ``rewrite -/plus`` folds back the expansion of plus
+ which was necessary for matching both sides of the equality with
+ an application of ``S``.
+
+ Like most |SSR| arguments, :token:`term` can contain wildcards.
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Lemma test x y : x + (y * (y + x - x)) = x * 1 + (y + 0) * y.
+ congr ( _ + (_ * _)).
+
+.. _contextual_patterns_ssr:
+
+Contextual patterns
+-------------------
+
+The simple form of patterns used so far, terms possibly containing
+wild cards, often require an additional :token:`occ_switch` to be specified.
+While this may work pretty fine for small goals, the use of
+polymorphic functions and dependent types may lead to an invisible
+duplication of function arguments. These copies usually end up in
+types hidden by the implicit arguments machinery or by user-defined
+notations. In these situations computing the right occurrence numbers
+is very tedious because they must be counted on the goal as printed
+after setting the :flag:`Printing All` flag. Moreover the resulting script is
+not really informative for the reader, since it refers to occurrence
+numbers he cannot easily see.
+
+Contextual patterns mitigate these issues allowing to specify
+occurrences according to the context they occur in.
+
+
+Syntax
+~~~~~~
+
+The following table summarizes the full syntax of :token:`c_pattern` and the
+corresponding subterm(s) identified by the pattern. In the third
+column we use s.m.r. for “the subterms matching the redex” specified
+in the second column.
+
+.. list-table::
+ :header-rows: 1
+
+ * - :token:`c_pattern`
+ - redex
+ - subterms affected
+
+ * - ``term``
+ - ``term``
+ - all occurrences of ``term``
+
+ * - ``ident in term``
+ - subterm of ``term`` selected by ``ident``
+ - all the subterms identified by ``ident`` in all the
+ occurrences of ``term``
+
+ * - ``term1 in ident in term2``
+ - ``term1`` in all s.m.r.
+ - in all the subterms identified by
+ ``ident`` in all the occurrences of ``term2``
+ * - ``term1 as ident in term2``
+ - ``term 1``
+ - in all the subterms identified by ``ident`
+ in all the occurrences of ``term2[term 1 /ident]``
+
+The rewrite tactic supports two more patterns obtained prefixing the
+first two with in. The intended meaning is that the pattern identifies
+all subterms of the specified context. The ``rewrite`` tactic will infer a
+pattern for the redex looking at the rule used for rewriting.
+
+.. list-table::
+ :header-rows: 1
+
+ * - :token:`r_pattern`
+ - redex
+ - subterms affected
+
+ * - ``in term``
+ - inferred from rule
+ - in all s.m.r. in all occurrences of ``term``
+
+ * - ``in ident in term``
+ - inferred from rule
+ - in all s.m.r. in all the subterms identified by ``ident``
+ in all the occurrences of ``term``
+
+The first :token:`c_pattern` is the simplest form matching any context but
+selecting a specific redex and has been described in the previous
+sections. We have seen so far that the possibility of selecting a
+redex using a term with holes is already a powerful means of redex
+selection. Similarly, any terms provided by the user in the more
+complex forms of :token:`c_patterns`
+presented in the tables above can contain
+holes.
+
+For a quick glance at what can be expressed with the last
+:token:`r_pattern`
+consider the goal ``a = b`` and the tactic
+
+.. coqdoc::
+
+ rewrite [in X in _ = X]rule.
+
+It rewrites all occurrences of the left hand side of ``rule``
+inside ``b`` only (``a``, and the hidden type of the equality, are ignored). Note that the
+variant ``rewrite [X in _ = X]rule`` would have rewritten ``b``
+exactly (i.e., it would only work if ``b`` and the left hand side
+of rule can be unified).
+
+
+Matching contextual patterns
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The :token:`c_pattern` and :token:`r_pattern` involving terms
+with holes are matched
+against the goal in order to find a closed instantiation. This
+matching proceeds as follows:
+
+.. list-table::
+ :header-rows: 1
+
+ * - :token:`c_pattern`
+ - instantiation order and place for ``term_i`` and redex
+
+ * - ``term``
+ - ``term`` is matched against the goal, redex is unified with
+ the instantiation of ``term``
+
+ * - ``ident in term``
+ - ``term`` is matched against the goal, redex is unified with the
+ subterm of the instantiation of ``term`` identified by
+ ``ident``
+
+ * - ``term1 in ident in term2``
+ - ``term2`` is matched against the goal, ``term1``
+ is matched against the subterm of the instantiation of
+ ``term1`` identified by ``ident``, redex is unified with
+ the instantiation of ``term1``
+
+ * - ``term1 as ident in term2``
+ - ``term2[term1/ident]`` is matched against
+ the goal, redex is unified with the instantiation of ``term1``
+
+In the following patterns, the redex is intended to be inferred from
+the rewrite rule.
+
+.. list-table::
+ :header-rows: 1
+
+ * - :token:`r_pattern`
+ - instantiation order and place for ``term_i`` and redex
+
+ * - ``in ident in term``
+ - ``term`` is matched against the goal, the redex is matched against
+ the subterm of the instantiation of ``term`` identified by
+ ``ident``
+
+ * - ``in term``
+ - ``term`` is matched against the goal, redex is matched against the
+ instantiation of ``term``
+
+
+Examples
+~~~~~~~~
+
+
+Contextual pattern in set and the : tactical
+````````````````````````````````````````````
+
+As already mentioned in section :ref:`abbreviations_ssr` the ``set``
+tactic takes as an
+argument a term in open syntax. This term is interpreted as the
+simplest form of :token:`c_pattern`. To avoid confusion in the grammar, open
+syntax is supported only for the simplest form of patterns, while
+parentheses are required around more complex patterns.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Lemma test a b : a + b + 1 = b + (a + 1).
+ set t := (X in _ = X).
+ rewrite {}/t.
+ set t := (a + _ in X in _ = X).
+
+
+Since the user may define an infix notation for ``in`` the result of the former
+tactic may be ambiguous. The disambiguation rule implemented is to prefer
+patterns over simple terms, but to interpret a pattern with double
+parentheses as a simple term. For example, the following tactic would
+capture any occurrence of the term ``a in A``.
+
+.. coqdoc::
+
+ set t := ((a in A)).
+
+Contextual patterns can also be used as arguments of the ``:`` tactical.
+For example:
+
+.. coqdoc::
+
+ elim: n (n in _ = n) (refl_equal n).
+
+
+Contextual patterns in rewrite
+``````````````````````````````
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Notation "n .+1" := (Datatypes.S n) (at level 2, left associativity,
+ format "n .+1") : nat_scope.
+
+ Axiom addSn : forall m n, m.+1 + n = (m + n).+1.
+ Axiom addn0 : forall m, m + 0 = m.
+ Axiom addnC : forall m n, m + n = n + m.
+
+ Lemma test x y z f : (x.+1 + y) + f (x.+1 + y) (z + (x + y).+1) = 0.
+ rewrite [in f _ _]addSn.
+
+ Note: the simplification rule ``addSn`` is applied only under the ``f``
+ symbol.
+ Then we simplify also the first addition and expand 0 into 0+0.
+
+ .. coqtop:: all
+
+ rewrite addSn -[X in _ = X]addn0.
+
+ Note that the right hand side of ``addn0`` is undetermined, but the
+ rewrite pattern specifies the redex explicitly. The right hand side
+ of ``addn0`` is unified with the term identified by ``X``, here ``0``.
+
+
+ The following pattern does not specify a redex, since it identifies an
+ entire region, hence the rewrite rule has to be instantiated
+ explicitly. Thus the tactic:
+
+ .. coqtop:: all
+
+ rewrite -{2}[in X in _ = X](addn0 0).
+
+ The following tactic is quite tricky:
+
+ .. coqtop:: all
+
+ rewrite [_.+1 in X in f _ X](addnC x.+1).
+
+ The explicit redex ``_.+1`` is important since its head constant ``S``
+ differs from the head constant inferred from
+ ``(addnC x.+1)`` (that is ``+``).
+ Moreover, the pattern ``f _ X`` is important to rule out
+ the first occurrence of ``(x + y).+1``.
+ Last, only the subterms of ``f _ X``
+ identified by ``X`` are rewritten, thus the first argument of
+ ``f`` is skipped too.
+ Also note the pattern ``_.+1`` is interpreted in the context
+ identified by ``X``, thus it gets instantiated to
+ ``(y + x).+1`` and not ``(x + y).+1``.
+
+ The last rewrite pattern allows to specify exactly the shape of the
+ term identified by X, that is thus unified with the left hand side of
+ the rewrite rule.
+
+ .. coqtop:: all
+
+ rewrite [x.+1 + y as X in f X _]addnC.
+
+
+Patterns for recurrent contexts
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The user can define shortcuts for recurrent contexts corresponding to
+the ``ident in term`` part. The notation scope identified with
+``%pattern``
+provides a special notation ``(X in t)`` the user must adopt
+in order to define
+context shortcuts.
+
+The following example is taken from ``ssreflect.v`` where the
+``LHS`` and ``RHS`` shortcuts are defined.
+
+.. coqdoc::
+
+ Notation RHS := (X in _ = X)%pattern.
+ Notation LHS := (X in X = _)%pattern.
+
+Shortcuts defined this way can be freely used in place of the trailing
+``ident in term`` part of any contextual pattern. Some examples follow:
+
+.. coqdoc::
+
+ set rhs := RHS.
+ rewrite [in RHS]rule.
+ case: (a + _ in RHS).
+
+
+.. _views_and_reflection_ssr:
+
+Views and reflection
+--------------------
+
+The bookkeeping facilities presented in section :ref:`basic_tactics_ssr` are
+crafted to ease simultaneous introductions and generalizations of facts and
+operations of casing, naming etc. It also a common practice to make a stack
+operation immediately followed by an *interpretation* of the fact
+being pushed, that is, to apply a lemma to this fact before passing it
+to a tactic for decomposition, application and so on.
+
+|SSR| provides a convenient, unified syntax to combine these
+interpretation operations with the proof stack operations. This *view
+mechanism* relies on the combination of the ``/`` view switch with
+bookkeeping tactics and tacticals.
+
+.. _custom_elim_ssr:
+
+Interpreting eliminations
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The view syntax combined with the ``elim`` tactic specifies an elimination
+scheme to be used instead of the default, generated, one. Hence the
+|SSR| tactic:
+
+.. coqdoc::
+
+ elim/V.
+
+is a synonym for:
+
+.. coqdoc::
+
+ intro top; elim top using V; clear top.
+
+where top is a fresh name and V any second-order lemma.
+
+Since an elimination view supports the two bookkeeping tacticals of
+discharge and introduction (see section :ref:`basic_tactics_ssr`),
+the |SSR| tactic:
+
+.. coqdoc::
+
+ elim/V: x => y.
+
+is a synonym for:
+
+.. coqdoc::
+
+ elim x using V; clear x; intro y.
+
+where ``x`` is a variable in the context, ``y`` a fresh name and ``V``
+any second order lemma; |SSR| relaxes the syntactic restrictions of the |Coq|
+``elim``. The first pattern following ``:`` can be a ``_`` wildcard if the
+conclusion of the view ``V`` specifies a pattern for its last argument
+(e.g., if ``V`` is a functional induction lemma generated by the
+``Function`` command).
+
+The elimination view mechanism is compatible with the equation name
+generation (see section :ref:`generation_of_equations_ssr`).
+
+
+.. example::
+
+ The following script illustrates a toy example of this feature. Let us
+ define a function adding an element at the end of a list:
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect List.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Variable d : Type.
+ Fixpoint add_last (s : list d) (z : d) {struct s} : list d :=
+ if s is cons x s' then cons x (add_last s' z) else z :: nil.
+
+ One can define an alternative, reversed, induction principle on
+ inductively defined lists, by proving the following lemma:
+
+ .. coqtop:: all
+
+ Axiom last_ind_list : forall P : list d -> Prop,
+ P nil -> (forall s (x : d), P s -> P (add_last s x)) ->
+ forall s : list d, P s.
+
+ Then the combination of elimination views with equation names result
+ in a concise syntax for reasoning inductively using the user-defined
+ elimination scheme.
+
+ .. coqtop:: all
+
+ Lemma test (x : d) (l : list d): l = l.
+ elim/last_ind_list E : l=> [| u v]; last first.
+
+
+User-provided eliminators (potentially generated with |Coq|’s ``Function``
+command) can be combined with the type family switches described
+in section :ref:`type_families_ssr`.
+Consider an eliminator ``foo_ind`` of type:
+
+.. coqdoc::
+
+ foo_ind : forall …, forall x : T, P p1 … pm.
+
+and consider the tactic:
+
+.. coqdoc::
+
+ elim/foo_ind: e1 … / en.
+
+The ``elim/`` tactic distinguishes two cases:
+
+:truncated eliminator: when ``x`` does not occur in ``P p1 … pm`` and the
+ type of ``en`` unifies with ``T`` and ``en`` is not ``_``.
+ In that case, ``en`` is
+ passed to the eliminator as the last argument (``x`` in ``foo_ind``) and
+ ``en−1 … e1`` are used as patterns to select in the goal the occurrences that
+ will be bound by the predicate ``P``, thus it must be possible to unify
+ the sub-term of the goal matched by ``en−1`` with ``pm`` , the one matched
+ by ``en−2`` with ``pm−1`` and so on.
+:regular eliminator: in all the other cases. Here it must be possible
+ to unify the term matched by ``en`` with ``pm`` , the one matched by
+ ``en−1``
+ with ``pm−1`` and so on. Note that standard eliminators have the shape
+ ``…forall x, P … x``, thus ``en`` is the pattern identifying the
+ eliminated term, as expected.
+
+
+As explained in section :ref:`type_families_ssr`, the initial prefix of
+``ei`` can be omitted.
+
+Here is an example of a regular, but nontrivial, eliminator.
+
+.. example::
+
+ Here is a toy example illustrating this feature.
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect FunInd.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Function plus (m n : nat) {struct n} : nat :=
+ if n is S p then S (plus m p) else m.
+
+ About plus_ind.
+
+ Lemma test x y z : plus (plus x y) z = plus x (plus y z).
+
+ The following tactics are all valid and perform the same elimination
+ on this goal.
+
+ .. coqdoc::
+
+ elim/plus_ind: z / (plus _ z).
+ elim/plus_ind: {z}(plus _ z).
+ elim/plus_ind: {z}_.
+ elim/plus_ind: z / _.
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect FunInd.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ Function plus (m n : nat) {struct n} : nat :=
+ if n is S p then S (plus m p) else m.
+
+ About plus_ind.
+
+ Lemma test x y z : plus (plus x y) z = plus x (plus y z).
+
+ .. coqtop:: all
+
+ elim/plus_ind: z / _.
+
+ The two latter examples feature a wildcard pattern: in this case,
+ the resulting pattern is inferred from the type of the eliminator.
+ In both these examples, it is ``(plus _ _)``, which matches the subterm
+ ``plus (plus x y) z`` thus instantiating the last ``_`` with ``z``.
+ Note that the tactic:
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect FunInd.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ Function plus (m n : nat) {struct n} : nat :=
+ if n is S p then S (plus m p) else m.
+
+ About plus_ind.
+
+ Lemma test x y z : plus (plus x y) z = plus x (plus y z).
+
+ .. coqtop:: all
+
+ Fail elim/plus_ind: y / _.
+
+ triggers an error: in the conclusion
+ of the ``plus_ind`` eliminator, the first argument of the predicate
+ ``P`` should be the same as the second argument of ``plus``, in the
+ second argument of ``P``, but ``y`` and ``z`` do no unify.
+
+Here is an example of a truncated eliminator:
+
+.. example::
+
+ Consider the goal:
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect FunInd.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqdoc::
+
+ Lemma test p n (n_gt0 : 0 < n) (pr_p : prime p) :
+ p %| \prod_(i <- prime_decomp n | i \in prime_decomp n) i.1 ^ i.2 ->
+ exists2 x : nat * nat, x \in prime_decomp n & p = x.1.
+ Proof.
+ elim/big_prop: _ => [| u v IHu IHv | [q e] /=].
+
+
+ where the type of the ``big_prop`` eliminator is
+
+ .. coqdoc::
+
+ big_prop: forall (R : Type) (Pb : R -> Type)
+ (idx : R) (op1 : R -> R -> R), Pb idx ->
+ (forall x y : R, Pb x -> Pb y -> Pb (op1 x y)) ->
+ forall (I : Type) (r : seq I) (P : pred I) (F : I -> R),
+ (forall i : I, P i -> Pb (F i)) ->
+ Pb (\big[op1/idx]_(i <- r | P i) F i).
+
+ Since the pattern for the argument of Pb is not specified, the
+ inferred one is used instead: ``big[_/_]_(i <- _ | _ i) _ i``,
+ and after the introductions, the following goals are generated:
+
+ .. coqdoc::
+
+ subgoal 1 is:
+ p %| 1 -> exists2 x : nat * nat, x \in prime_decomp n & p = x.1
+ subgoal 2 is:
+ p %| u * v -> exists2 x : nat * nat, x \in prime_decomp n & p = x.1
+ subgoal 3 is:
+ (q, e) \in prime_decomp n -> p %| q ^ e ->
+ exists2 x : nat * nat, x \in prime_decomp n & p = x.1.
+
+ Note that the pattern matching algorithm instantiated all the
+ variables occurring in the pattern.
+
+
+.. _interpreting_assumptions_ssr:
+
+Interpreting assumptions
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Interpreting an assumption in the context of a proof consists in
+applying to it a lemma before generalizing, and/or decomposing this
+assumption. For instance, with the extensive use of boolean reflection
+(see section :ref:`views_and_reflection_ssr`.4), it is quite frequent
+to need to decompose the logical interpretation of (the boolean
+expression of) a fact, rather than the fact itself. This can be
+achieved by a combination of ``move : _ => _`` switches, like in the
+following example, where ``||`` is a notation for the boolean
+disjunction.
+
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Variables P Q : bool -> Prop.
+ Hypothesis P2Q : forall a b, P (a || b) -> Q a.
+
+ Lemma test a : P (a || a) -> True.
+ move=> HPa; move: {HPa}(P2Q HPa) => HQa.
+
+ which transforms the hypothesis ``HPa : P a`` which has been introduced
+ from the initial statement into ``HQa : Q a``.
+ This operation is so common that the tactic shell has specific
+ syntax for it. The following scripts:
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ Variables P Q : bool -> Prop.
+ Hypothesis P2Q : forall a b, P (a || b) -> Q a.
+
+ Lemma test a : P (a || a) -> True.
+
+ .. coqtop:: all
+
+ move=> HPa; move/P2Q: HPa => HQa.
+
+ or more directly:
+
+ .. coqtop:: all restart
+
+ move/P2Q=> HQa.
+
+ are equivalent to the former one. The former script shows how to
+ interpret a fact (already in the context), thanks to the discharge
+ tactical (see section :ref:`discharge_ssr`) and the latter, how to interpret the top
+ assumption of a goal. Note that the number of wildcards to be inserted
+ to find the correct application of the view lemma to the hypothesis
+ has been automatically inferred.
+
+The view mechanism is compatible with the ``case`` tactic and with the
+equation name generation mechanism (see section :ref:`generation_of_equations_ssr`):
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Variables P Q: bool -> Prop.
+ Hypothesis Q2P : forall a b, Q (a || b) -> P a \/ P b.
+
+ Lemma test a b : Q (a || b) -> True.
+ case/Q2P=> [HPa | HPb].
+
+ This view tactic performs:
+
+ .. coqdoc::
+
+ move=> HQ; case: {HQ}(Q2P HQ) => [HPa | HPb].
+
+The term on the right of the ``/`` view switch is called a *view lemma*.
+Any |SSR| term coercing to a product type can be used as a view
+lemma.
+
+The examples we have given so far explicitly provide the direction of
+the translation to be performed. In fact, view lemmas need not to be
+oriented. The view mechanism is able to detect which application is
+relevant for the current goal.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Variables P Q: bool -> Prop.
+ Hypothesis PQequiv : forall a b, P (a || b) <-> Q a.
+
+ Lemma test a b : P (a || b) -> True.
+ move/PQequiv=> HQab.
+
+ has the same behavior as the first example above.
+
+ The view mechanism can insert automatically a *view hint* to transform
+ the double implication into the expected simple implication. The last
+ script is in fact equivalent to:
+
+ .. coqdoc::
+
+ Lemma test a b : P (a || b) -> True.
+ move/(iffLR (PQequiv _ _)).
+
+ where:
+
+ .. coqdoc::
+
+ Lemma iffLR P Q : (P <-> Q) -> P -> Q.
+
+
+Specializing assumptions
+````````````````````````
+
+The special case when the *head symbol* of the view lemma is a
+wildcard is used to interpret an assumption by *specializing* it. The
+view mechanism hence offers the possibility to apply a higher-order
+assumption to some given arguments.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Lemma test z : (forall x y, x + y = z -> z = x) -> z = 0.
+ move/(_ 0 z).
+
+
+Interpreting goals
+~~~~~~~~~~~~~~~~~~
+
+In a similar way, it is also often convenient to
+changing a goal by turning it into an equivalent proposition. The view
+mechanism of |SSR| has a special syntax ``apply/`` for combining in a
+single tactic simultaneous goal interpretation operations and
+bookkeeping steps.
+
+
+.. example::
+
+ The following example use the ``~~`` prenex notation for boolean negation:
+
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect ssrbool.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Variables P Q: bool -> Prop.
+ Hypothesis PQequiv : forall a b, P (a || b) <-> Q a.
+
+ Lemma test a : P ((~~ a) || a).
+ apply/PQequiv.
+
+ thus in this case, the tactic ``apply/PQequiv`` is equivalent to
+ ``apply: (iffRL (PQequiv _ _))``, where ``iffRL`` is tha analogue of
+ ``iffRL`` for the converse implication.
+
+Any |SSR| term whose type coerces to a double implication can be
+used as a view for goal interpretation.
+
+Note that the goal interpretation view mechanism supports both ``apply``
+and ``exact`` tactics. As expected, a goal interpretation view command
+exact/term should solve the current goal or it will fail.
+
+.. warning::
+
+ Goal interpretation view tactics are *not* compatible with
+ the bookkeeping tactical ``=>`` since this would be redundant with the
+ ``apply: term => _`` construction.
+
+
+Boolean reflection
+~~~~~~~~~~~~~~~~~~
+
+In the Calculus of Inductive Constructions, there is an obvious
+distinction between logical propositions and boolean values. On the
+one hand, logical propositions are objects of *sort* ``Prop`` which is
+the carrier of intuitionistic reasoning. Logical connectives in
+``Prop`` are *types*, which give precise information on the structure
+of their proofs; this information is automatically exploited by |Coq|
+tactics. For example, |Coq| knows that a proof of ``A \/ B`` is
+either a proof of ``A`` or a proof of ``B``. The tactics ``left`` and
+``right`` change the goal ``A \/ B`` to ``A`` and ``B``, respectively;
+dually, the tactic ``case`` reduces the goal ``A \/ B => G`` to two
+subgoals ``A => G`` and ``B => G``.
+
+On the other hand, bool is an inductive *datatype* with two
+constructors true and false. Logical connectives on bool are
+*computable functions*, defined by their truth tables, using case
+analysis:
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Definition orb (b1 b2 : bool) := if b1 then true else b2.
+
+Properties of such connectives are also established using case
+analysis
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect ssrbool.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Lemma test b : b || ~~ b = true.
+ by case: b.
+
+ Once ``b`` is replaced by ``true`` in the first goal and by ``false`` in the
+ second one, the goals reduce by computations to the trivial ``true = true``.
+
+Thus, ``Prop`` and ``bool`` are truly complementary: the former supports
+robust natural deduction, the latter allows brute-force
+evaluation. |SSR| supplies a generic mechanism to have the best of
+the two worlds and move freely from a propositional version of a
+decidable predicate to its boolean version.
+
+First, booleans are injected into propositions using the coercion
+mechanism:
+
+.. coqdoc::
+
+ Coercion is_true (b : bool) := b = true.
+
+This allows any boolean formula ``b`` to be used in a context where |Coq|
+would expect a proposition, e.g., after ``Lemma … : ``. It is then
+interpreted as ``(is_true b)``, i.e., the proposition ``b = true``. Coercions
+are elided by the pretty-printer, so they are essentially transparent
+to the user.
+
+The reflect predicate
+~~~~~~~~~~~~~~~~~~~~~
+
+To get all the benefits of the boolean reflection, it is in fact
+convenient to introduce the following inductive predicate ``reflect`` to
+relate propositions and booleans:
+
+.. coqdoc::
+
+ Inductive reflect (P: Prop): bool -> Type :=
+ | Reflect_true : P -> reflect P true
+ | Reflect_false : ~P -> reflect P false.
+
+The statement ``(reflect P b)`` asserts that ``(is_true b)`` and ``P`` are
+logically equivalent propositions.
+
+For instance, the following lemma:
+
+.. coqdoc::
+
+ Lemma andP: forall b1 b2, reflect (b1 /\ b2) (b1 && b2).
+
+relates the boolean conjunction to the logical one ``/\``. Note that in
+``andP``, ``b1`` and ``b2`` are two boolean variables and the
+proposition ``b1 /\ b2`` hides two coercions. The conjunction of
+``b1`` and ``b2`` can then be viewed as ``b1 /\ b2`` or as ``b1 && b2``.
+
+Expressing logical equivalences through this family of inductive types
+makes possible to take benefit from *rewritable equations* associated
+to the case analysis of |Coq|’s inductive types.
+
+Since the equivalence predicate is defined in |Coq| as:
+
+.. coqdoc::
+
+ Definition iff (A B:Prop) := (A -> B) /\ (B -> A).
+
+where ``/\`` is a notation for ``and``:
+
+.. coqdoc::
+
+ Inductive and (A B:Prop) : Prop := conj : A -> B -> and A B.
+
+This make case analysis very different according to the way an
+equivalence property has been defined.
+
+.. coqdoc::
+
+ Lemma andE (b1 b2 : bool) : (b1 /\ b2) <-> (b1 && b2).
+
+Let us compare the respective behaviors of ``andE`` and ``andP``.
+
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect ssrbool.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+ Axiom andE : forall (b1 b2 : bool), (b1 /\ b2) <-> (b1 && b2).
+
+ .. coqtop:: all
+
+ Lemma test (b1 b2 : bool) : if (b1 && b2) then b1 else ~~(b1||b2).
+
+ .. coqtop:: all
+
+ case: (@andE b1 b2).
+
+ .. coqtop:: none
+
+ Restart.
+
+ .. coqtop:: all
+
+ case: (@andP b1 b2).
+
+Expressing reflection relation through the ``reflect`` predicate is hence
+a very convenient way to deal with classical reasoning, by case
+analysis. Using the ``reflect`` predicate allows moreover to program rich
+specifications inside its two constructors, which will be
+automatically taken into account during destruction. This
+formalisation style gives far more efficient specifications than
+quantified (double) implications.
+
+A naming convention in |SSR| is to postfix the name of view lemmas
+with ``P``. For example, ``orP`` relates ``||`` and ``\/``,
+``negP`` relates ``~~`` and ``~``.
+
+The view mechanism is compatible with reflect predicates.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect ssrbool.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all abort
+
+ Lemma test (a b : bool) (Ha : a) (Hb : b) : a /\ b.
+ apply/andP.
+
+ Conversely
+
+ .. coqtop:: all
+
+ Lemma test (a b : bool) : a /\ b -> a.
+ move/andP.
+
+The same tactics can also be used to perform the converse operation,
+changing a boolean conjunction into a logical one. The view mechanism
+guesses the direction of the transformation to be used i.e., the
+constructor of the reflect predicate which should be chosen.
+
+
+General mechanism for interpreting goals and assumptions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Specializing assumptions
+````````````````````````
+
+The |SSR| tactic:
+
+.. coqdoc::
+
+ move/(_ term1 … termn).
+
+is equivalent to the tactic:
+
+.. coqdoc::
+
+ intro top; generalize (top term1 … termn); clear top.
+
+where ``top`` is a fresh name for introducing the top assumption of the
+current goal.
+
+
+Interpreting assumptions
+````````````````````````
+
+The general form of an assumption view tactic is:
+
+.. tacv:: [move | case] / @term
+ :undocumented:
+
+The term , called the *view lemma* can be:
+
+
++ a (term coercible to a) function;
++ a (possibly quantified) implication;
++ a (possibly quantified) double implication;
++ a (possibly quantified) instance of the reflect predicate (see
+ section :ref:`views_and_reflection_ssr`).
+
+
+Let ``top`` be the top assumption in the goal.
+
+There are three steps in the behavior of an assumption view tactic:
+
++ It first introduces ``top``.
++ If the type of :token:`term` is neither a double implication nor an
+ instance of the reflect predicate, then the tactic automatically
+ generalises a term of the form: ``term term1 … termn`` where the
+ terms ``term1 … termn`` instantiate the possible quantified variables of
+ ``term`` , in order for ``(term term1 … termn top)`` to be well typed.
++ If the type of ``term`` is an equivalence, or an instance of the
+ reflect predicate, it generalises a term of the form:
+ ``(termvh (term term1 … termn ))`` where the term ``termvh``
+ inserted is called an
+ *assumption interpretation view hint*.
++ It finally clears top.
+
+
+For a ``case/term`` tactic, the generalisation step is replaced by a
+case analysis step.
+
+*View hints* are declared by the user (see section:ref:`views_and_reflection_ssr`.8) and are
+stored in the Hint View database. The proof engine automatically
+detects from the shape of the top assumption ``top`` and of the view lemma
+``term`` provided to the tactic the appropriate view hint in the
+database to be inserted.
+
+If ``term`` is a double implication, then the view hint will be one of
+the defined view hints for implication. These hints are by default the
+ones present in the file ``ssreflect.v``:
+
+.. coqdoc::
+
+ Lemma iffLR : forall P Q, (P <-> Q) -> P -> Q.
+
+which transforms a double implication into the left-to-right one, or:
+
+.. coqdoc::
+
+ Lemma iffRL : forall P Q, (P <-> Q) -> Q -> P.
+
+which produces the converse implication. In both cases, the two
+first Prop arguments are implicit.
+
+If ``term`` is an instance of the ``reflect`` predicate, then ``A`` will be one
+of the defined view hints for the ``reflect`` predicate, which are by
+default the ones present in the file ``ssrbool.v``. These hints are not
+only used for choosing the appropriate direction of the translation,
+but they also allow complex transformation, involving negations.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect ssrbool.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Check introN.
+
+ .. coqtop:: all
+
+ Lemma test (a b : bool) (Ha : a) (Hb : b) : ~~ (a && b).
+ apply/andP.
+
+ In fact this last script does not
+ exactly use the hint ``introN``, but the more general hint:
+
+ .. coqtop:: all
+
+ Check introNTF.
+
+ The lemma ``introN`` is an instantiation of ``introNF`` using ``c := true``.
+
+Note that views, being part of :token:`i_pattern`, can be used to interpret
+assertions too. For example the following script asserts ``a && b`` but
+actually uses its propositional interpretation.
+
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect ssrbool.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Lemma test (a b : bool) (pab : b && a) : b.
+ have /andP [pa ->] : (a && b) by rewrite andbC.
+
+Interpreting goals
+
+A goal interpretation view tactic of the form:
+
+.. tacv:: apply/@term
+ :undocumented:
+
+applied to a goal ``top`` is interpreted in the following way:
+
++ If the type of ``term`` is not an instance of the ``reflect`` predicate,
+ nor an equivalence, then the term ``term`` is applied to the current
+ goal ``top``, possibly inserting implicit arguments.
++ If the type of ``term`` is an instance of the reflect predicate or an
+ equivalence, then a *goal interpretation view hint* can possibly be
+ inserted, which corresponds to the application of a term
+ ``(termvh (term _ … _))`` to the current goal, possibly inserting implicit arguments.
+
+
+Like assumption interpretation view hints, goal interpretation ones
+are user-defined lemmas stored (see section :ref:`views_and_reflection_ssr`) in the ``Hint View``
+database bridging the possible gap between the type of ``term`` and the
+type of the goal.
+
+
+Interpreting equivalences
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Equivalent boolean propositions are simply *equal* boolean terms. A
+special construction helps the user to prove boolean equalities by
+considering them as logical double implications (between their coerced
+versions), while performing at the same time logical operations on
+both sides.
+
+The syntax of double views is:
+
+.. tacv:: apply/@term/@term
+ :undocumented:
+
+The first term is the view lemma applied to the left hand side of the
+equality, while the second term is the one applied to the right hand side.
+
+In this context, the identity view can be used when no view has to be applied:
+
+.. coqdoc::
+
+ Lemma idP : reflect b1 b1.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect ssrbool.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Lemma test (b1 b2 b3 : bool) : ~~ (b1 || b2) = b3.
+ apply/idP/idP.
+
+ The same goal can be decomposed in several ways, and the user may
+ choose the most convenient interpretation.
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect ssrbool.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+
+ .. coqtop:: all
+
+ Lemma test (b1 b2 b3 : bool) : ~~ (b1 || b2) = b3.
+ apply/norP/idP.
+
+
+.. _declaring_new_hints_ssr:
+
+Declaring new Hint Views
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. cmd:: Hint View for move / @ident {? | @num }
+ Hint View for apply / @ident {? | @num }
+
+ This command can be used to extend the database of hints for the view
+ mechanism.
+
+ As library ``ssrbool.v`` already declares a
+ corpus of hints, this feature is probably useful only for users who
+ define their own logical connectives.
+
+ The :token:`ident` is the name of the lemma to be
+ declared as a hint. If ``move`` is used as
+ tactic, the hint is declared for assumption interpretation tactics,
+ ``apply`` declares hints for goal interpretations. Goal interpretation
+ view hints are declared for both simple views and left hand side
+ views. The optional natural number is the number of implicit
+ arguments to be considered for the declared hint view lemma.
+
+ .. cmdv:: Hint View for apply//@ident {? | @num }
+
+ This variant with a double slash ``//``, declares hint views for right
+ hand sides of double views.
+
+ See the files ``ssreflect.v`` and ``ssrbool.v`` for examples.
+
+
+Multiple views
+~~~~~~~~~~~~~~
+
+The hypotheses and the goal can be interpreted by applying multiple views
+in sequence. Both move and apply can be followed by an arbitrary
+number of ``/term``. The main difference between the following two
+tactics
+
+.. coqdoc::
+
+ apply/v1/v2/v3.
+ apply/v1; apply/v2; apply/v3.
+
+is that the former applies all the views to the principal goal.
+Applying a view with hypotheses generates new goals, and the second
+line would apply the view ``v2`` to all the goals generated by ``apply/v1``.
+
+Note that the NO-OP intro pattern ``-`` can be used to separate two views,
+making the two following examples equivalent:
+
+.. coqdoc::
+
+ move=> /v1; move=> /v2.
+ move=> /v1 - /v2.
+
+The tactic ``move`` can be used together with the ``in`` tactical to
+pass a given hypothesis to a lemma.
+
+
+.. example::
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect ssrbool.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+ Section Test.
+ Variables P Q R : Prop.
+
+ .. coqtop:: all
+
+ Variable P2Q : P -> Q.
+ Variable Q2R : Q -> R.
+
+ Lemma test (p : P) : True.
+ move/P2Q/Q2R in p.
+
+If the list of views is of length two, ``Hint Views`` for interpreting
+equivalences are indeed taken into account, otherwise only single
+``Hint Views`` are used.
+
+
+|SSR| searching tool
+--------------------
+
+.. cmd:: Search {? @pattern } {* {? - } %( @string %| @pattern %) {? % @ident} } {? in {+ {? - } @qualid } }
+ :name: Search (ssreflect)
+
+ This is the |SSR| extension of the Search command. :token:`qualid` is the
+ name of an open module. This command returns the list of lemmas:
+
+ + whose *conclusion* contains a subterm matching the optional first
+ pattern. A - reverses the test, producing the list of lemmas whose
+ conclusion does not contain any subterm matching the pattern;
+ + whose name contains the given string. A ``-`` prefix reverses the test,
+ producing the list of lemmas whose name does not contain the string. A
+ string that contains symbols or is followed by a scope key, is
+ interpreted as the constant whose notation involves that string (e.g.,
+ :g:`+` for :g:`addn`), if this is unambiguous; otherwise the diagnostic
+ includes the output of the :cmd:`Locate` vernacular command.
+ + whose statement, including assumptions and types, contains a subterm
+ matching the next patterns. If a pattern is prefixed by ``-``, the test is
+ reversed;
+ + contained in the given list of modules, except the ones in the
+ modules prefixed by a ``-``.
+
+.. note::
+
+ + As for regular terms, patterns can feature scope indications. For
+ instance, the command: ``Search _ (_ + _)%N.`` lists all the lemmas whose
+ statement (conclusion or hypotheses) involves an application of the
+ binary operation denoted by the infix ``+`` symbol in the ``N`` scope (which is
+ |SSR| scope for natural numbers).
+ + Patterns with holes should be surrounded by parentheses.
+ + Search always volunteers the expansion of the notation, avoiding the
+ need to execute Locate independently. Moreover, a string fragment
+ looks for any notation that contains fragment as a substring. If the
+ ``ssrbool.v`` library is imported, the command: ``Search "~~".`` answers :
+
+ .. coqtop:: reset none
+
+ From Coq Require Import ssreflect ssrbool.
+ Set Implicit Arguments.
+ Unset Strict Implicit.
+ Unset Printing Implicit Defensive.
+
+ .. coqtop:: all
+
+ Search "~~".
+
+ + A diagnostic is issued if there are different matching notations; it
+ is an error if all matches are partial.
+ + Similarly, a diagnostic warns about multiple interpretations, and
+ signals an error if there is no default one.
+ + The command ``Search in M.`` is a way of obtaining the complete
+ signature of the module ``M``.
+ + Strings and pattern indications can be interleaved, but the first
+ indication has a special status if it is a pattern, and only filters
+ the conclusion of lemmas:
+
+ + The command : ``Search (_ =1 _) "bij".`` lists all the lemmas whose
+ conclusion features a ``=1`` and whose name contains the string ``bij``.
+ + The command : ``Search "bij" (_ =1 _).`` lists all the lemmas whose
+ statement, including hypotheses, features a ``=1`` and whose name
+ contains the string ``bij``.
+
+Synopsis and Index
+------------------
+
+Parameters
+~~~~~~~~~~
+
+|SSR| tactics
+
+.. prodn::
+ d_tactic ::= elim %| case %| congr %| apply %| exact %| move
+
+Notation scope
+
+.. prodn:: key ::= @ident
+
+Module name
+
+.. prodn:: modname ::= @qualid
+
+Natural number
+
+.. prodn:: natural ::= @num %| @ident
+
+where :token:`ident` is an Ltac variable denoting a standard |Coq| numeral
+(should not be the name of a tactic which can be followed by a
+bracket ``[``, like ``do``, ``have``,…)
+
+Items and switches
+~~~~~~~~~~~~~~~~~~
+
+.. prodn:: ssr_binder ::= @ident %| ( @ident {? : @term } )
+
+binder see :ref:`abbreviations_ssr`.
+
+.. prodn:: clear_switch ::= { {+ @ident } }
+
+clear switch see :ref:`discharge_ssr`
+
+.. prodn:: c_pattern ::= {? @term in %| @term as } @ident in @term
+
+context pattern see :ref:`contextual_patterns_ssr`
+
+.. prodn:: d_item ::= {? @occ_switch %| @clear_switch } {? @term %| ( @c_pattern ) }
+
+discharge item see :ref:`discharge_ssr`
+
+.. prodn:: gen_item ::= {? @ } @ident %| ( @ident ) %| ( {? @ } @ident := @c_pattern )
+
+generalization item see :ref:`structure_ssr`
+
+.. prodn:: i_pattern ::= @ident %| > %| _ %| ? %| * %| + %| {? @occ_switch } -> %| {? @occ_switch } <- %| [ {?| @i_item } ] %| - %| [: {+ @ident } ]
+
+intro pattern :ref:`introduction_ssr`
+
+.. prodn:: i_item ::= @clear_switch %| @s_item %| @i_pattern %| @i_view %| @i_block
+
+view :ref:`introduction_ssr`
+
+.. prodn::
+ i_view ::= {? %{%} } /@term %| /ltac:( @tactic )
+
+intro block :ref:`introduction_ssr`
+
+.. prodn::
+ i_block ::= [^ @ident ] %| [^~ @ident ] %| [^~ @num ]
+
+intro item see :ref:`introduction_ssr`
+
+.. prodn:: int_mult ::= {? @num } @mult_mark
+
+multiplier see :ref:`iteration_ssr`
+
+.. prodn:: occ_switch ::= { {? + %| - } {* @num } }
+
+occur. switch see :ref:`occurrence_selection_ssr`
+
+.. prodn:: mult ::= {? @num } @mult_mark
+
+multiplier see :ref:`iteration_ssr`
+
+.. prodn:: mult_mark ::= ? %| !
+
+multiplier mark see :ref:`iteration_ssr`
+
+.. prodn:: r_item ::= {? / } @term %| @s_item
+
+rewrite item see :ref:`rewriting_ssr`
+
+.. prodn:: r_prefix ::= {? - } {? @int_mult } {? @occ_switch %| @clear_switch } {? [ @r_pattern ] }
+
+rewrite prefix see :ref:`rewriting_ssr`
+
+.. prodn:: r_pattern ::= @term %| @c_pattern %| in {? @ident in } @term
+
+rewrite pattern see :ref:`rewriting_ssr`
+
+.. prodn:: r_step ::= {? @r_prefix } @r_item
+
+rewrite step see :ref:`rewriting_ssr`
+
+.. prodn:: s_item ::= /= %| // %| //=
+
+simplify switch see :ref:`introduction_ssr`
+
+Tactics
+~~~~~~~
+
+*Note*: ``without loss`` and ``suffices`` are synonyms for ``wlog`` and ``suff``
+respectively.
+
+.. tacn:: move
+
+ :tacn:`idtac` or :tacn:`hnf` (see :ref:`bookkeeping_ssr`)
+
+.. tacn:: apply
+ exact
+
+ application (see :ref:`the_defective_tactics_ssr`)
+
+.. tacn:: abstract
+
+ see :ref:`abstract_ssr` and :ref:`generating_let_ssr`
+
+.. tacn:: elim
+
+ induction (see :ref:`the_defective_tactics_ssr`)
+
+.. tacn:: case
+
+ case analysis (see :ref:`the_defective_tactics_ssr`)
+
+.. tacn:: rewrite {+ @r_step }
+
+ rewrite (see :ref:`rewriting_ssr`)
+
+.. tacn:: have {* @i_item } {? @i_pattern } {? @s_item %| {+ @ssr_binder } } {? : @term } := @term
+ have {* @i_item } {? @i_pattern } {? @s_item %| {+ @ssr_binder } } : @term {? by @tactic }
+ have suff {? @clear_switch } {? @i_pattern } {? : @term } := @term
+ have suff {? @clear_switch } {? @i_pattern } : @term {? by @tactic }
+ gen have {? @ident , } {? @i_pattern } : {+ @gen_item } / @term {? by @tactic }
+ generally have {? @ident , } {? @i_pattern } : {+ @gen_item } / @term {? by @tactic }
+ :name: _; _; _; _; _; generally have
+
+ forward chaining (see :ref:`structure_ssr`)
+
+.. tacn:: wlog {? suff } {? @i_item } : {* @gen_item %| @clear_switch } / @term
+
+ specializing (see :ref:`structure_ssr`)
+
+.. tacn:: suff {* @i_item } {? @i_pattern } {+ @ssr_binder } : @term {? by @tactic }
+ suffices {* @i_item } {? @i_pattern } {+ @ssr_binder } : @term {? by @tactic }
+ suff {? have } {? @clear_switch } {? @i_pattern } : @term {? by @tactic }
+ suffices {? have } {? @clear_switch } {? @i_pattern } : @term {? by @tactic }
+ :name: suff; suffices; _; _
+
+ backchaining (see :ref:`structure_ssr`)
+
+.. tacn:: pose @ident := @term
+
+ local definition (see :ref:`definitions_ssr`)
+
+.. tacv:: pose @ident {+ @ssr_binder } := @term
+
+ local function definition
+
+.. tacv:: pose fix @fix_body
+
+ local fix definition
+
+.. tacv:: pose cofix @fix_body
+
+ local cofix definition
+
+.. tacn:: set @ident {? : @term } := {? @occ_switch } %( @term %| ( @c_pattern) %)
+
+ abbreviation (see :ref:`abbreviations_ssr`)
+
+.. tacn:: unlock {* {? @r_prefix } @ident }
+
+ unlock (see :ref:`locking_ssr`)
+
+.. tacn:: congr {? @num } @term
+
+ congruence (see :ref:`congruence_ssr`)
+
+
+Tacticals
+~~~~~~~~~
+
+.. prodn:: tactic += @d_tactic {? @ident } : {+ @d_item } {? @clear_switch }
+
+discharge :ref:`discharge_ssr`
+
+.. prodn:: tactic += @tactic => {+ @i_item }
+
+introduction see :ref:`introduction_ssr`
+
+.. prodn:: tactic += @tactic in {+ @gen_item %| @clear_switch } {? * }
+
+localization see :ref:`localization_ssr`
+
+.. prodn:: tactic += do {? @mult } %( @tactic %| [ {+| @tactic } ] %)
+
+iteration see :ref:`iteration_ssr`
+
+.. prodn:: tactic += @tactic ; %( first %| last %) {? @num } %( @tactic %| [ {+| @tactic } ] %)
+
+selector see :ref:`selectors_ssr`
+
+.. prodn:: tactic += @tactic ; %( first %| last %) {? @num }
+
+rotation see :ref:`selectors_ssr`
+
+.. prodn:: tactic += by %( @tactic %| [ {*| @tactic } ] %)
+
+closing see :ref:`terminators_ssr`
+
+Commands
+~~~~~~~~
+
+.. cmd:: Hint View for %( move %| apply %) / @ident {? | @num }
+
+ view hint declaration (see :ref:`declaring_new_hints_ssr`)
+
+.. cmd:: Hint View for apply // @ident {? @num }
+
+ right hand side double , view hint declaration (see :ref:`declaring_new_hints_ssr`)
+
+.. cmd:: Prenex Implicits {+ @ident }
+
+ prenex implicits declaration (see :ref:`parametric_polymorphism_ssr`)
+
+Settings
+~~~~~~~~
+
+.. flag:: Debug Ssreflect
+
+ *Developer only.* Print debug information on reflect.
+
+.. flag:: Debug SsrMatching
+
+ *Developer only.* Print debug information on SSR matching.
+
+.. rubric:: Footnotes
+
+.. [#1] Unfortunately, even after a call to the Set Printing All command,
+ some occurrences are still not displayed to the user, essentially the
+ ones possibly hidden in the predicate of a dependent match structure.
+.. [#2] Thus scripts that depend on bound variable names, e.g., via intros
+ or with, are inherently fragile.
+.. [#3] The name ``subnK`` reads as “right cancellation rule for nat
+ subtraction”.
+.. [#4] Also, a slightly different variant may be used for the first :token:`d_item`
+ of case and elim; see section :ref:`type_families_ssr`.
+.. [#5] Except /= does not expand the local definitions created by the
+ |SSR| in tactical.
+.. [#6] |SSR| reserves all identifiers of the form “_x_”, which is
+ used for such generated names.
+.. [#7] More precisely, it should have a quantified inductive type with a
+ assumptions and m − a constructors.
+.. [#8] This is an implementation feature: there is no such obstruction
+ in the metatheory
+.. [#9] The current state of the proof shall be displayed by the Show
+ Proof command of |Coq| proof mode.
+.. [#10] A simple proof context entry is a naked identifier (i.e. not between
+ parentheses) designating a context entry that is not a section variable.
diff --git a/doc/sphinx/proof-engine/tactics.rst b/doc/sphinx/proof-engine/tactics.rst
new file mode 100644
index 0000000000..afb0239be4
--- /dev/null
+++ b/doc/sphinx/proof-engine/tactics.rst
@@ -0,0 +1,4807 @@
+.. _tactics:
+
+Tactics
+========
+
+A deduction rule is a link between some (unique) formula, that we call
+the *conclusion* and (several) formulas that we call the *premises*. A
+deduction rule can be read in two ways. The first one says: “if I know
+this and this then I can deduce this”. For instance, if I have a proof
+of A and a proof of B then I have a proof of A ∧ B. This is forward
+reasoning from premises to conclusion. The other way says: “to prove
+this I have to prove this and this”. For instance, to prove A ∧ B, I
+have to prove A and I have to prove B. This is backward reasoning from
+conclusion to premises. We say that the conclusion is the *goal* to
+prove and premises are the *subgoals*. The tactics implement *backward
+reasoning*. When applied to a goal, a tactic replaces this goal with
+the subgoals it generates. We say that a tactic reduces a goal to its
+subgoal(s).
+
+Each (sub)goal is denoted with a number. The current goal is numbered
+1. By default, a tactic is applied to the current goal, but one can
+address a particular goal in the list by writing n:tactic which means
+“apply tactic tactic to goal number n”. We can show the list of
+subgoals by typing Show (see Section :ref:`requestinginformation`).
+
+Since not every rule applies to a given statement, not every tactic can
+be used to reduce a given goal. In other words, before applying a tactic
+to a given goal, the system checks that some *preconditions* are
+satisfied. If it is not the case, the tactic raises an error message.
+
+Tactics are built from atomic tactics and tactic expressions (which
+extends the folklore notion of tactical) to combine those atomic
+tactics. This chapter is devoted to atomic tactics. The tactic
+language will be described in Chapter :ref:`ltac`.
+
+Common elements of tactics
+--------------------------
+
+.. _invocation-of-tactics:
+
+Invocation of tactics
+~~~~~~~~~~~~~~~~~~~~~
+
+A tactic is applied as an ordinary command. It may be preceded by a
+goal selector (see Section :ref:`ltac-semantics`). If no selector is
+specified, the default selector is used.
+
+.. _tactic_invocation_grammar:
+
+ .. productionlist:: sentence
+ tactic_invocation : `toplevel_selector` : `tactic`.
+ : `tactic`.
+
+.. opt:: Default Goal Selector "@toplevel_selector"
+ :name: Default Goal Selector
+
+ This option controls the default selector, used when no selector is
+ specified when applying a tactic. The initial value is 1, hence the
+ tactics are, by default, applied to the first goal.
+
+ Using value ``all`` will make it so that tactics are, by default,
+ applied to every goal simultaneously. Then, to apply a tactic tac
+ to the first goal only, you can write ``1:tac``.
+
+ Using value ``!`` enforces that all tactics are used either on a
+ single focused goal or with a local selector (’’strict focusing
+ mode’’).
+
+ Although more selectors are available, only ``all``, ``!`` or a
+ single natural number are valid default goal selectors.
+
+.. _bindingslist:
+
+Bindings list
+~~~~~~~~~~~~~~~~~~~
+
+Tactics that take a term as an argument may also support a bindings list
+to instantiate some parameters of the term by name or position.
+The general form of a term with a bindings list is
+:n:`@term with @bindings_list` where :token:`bindings_list` can take two different forms:
+
+.. _bindings_list_grammar:
+
+ .. productionlist:: bindings_list
+ ref : `ident`
+ : `num`
+ bindings_list : (`ref` := `term`) ... (`ref` := `term`)
+ : `term` ... `term`
+
++ In a bindings list of the form :n:`{+ (@ref:= @term)}`, :n:`@ref` is either an
+ :n:`@ident` or a :n:`@num`. The references are determined according to the type of
+ :n:`@term`. If :n:`@ref` is an identifier, this identifier has to be bound in the
+ type of :n:`@term` and the binding provides the tactic with an instance for the
+ parameter of this name. If :n:`@ref` is a number ``n``, it refers to
+ the ``n``-th non dependent premise of the :n:`@term`, as determined by the type
+ of :n:`@term`.
+
+ .. exn:: No such binder.
+ :undocumented:
+
++ A bindings list can also be a simple list of terms :n:`{* @term}`.
+ In that case the references to which these terms correspond are
+ determined by the tactic. In case of :tacn:`induction`, :tacn:`destruct`, :tacn:`elim`
+ and :tacn:`case`, the terms have to
+ provide instances for all the dependent products in the type of term while in
+ the case of :tacn:`apply`, or of :tacn:`constructor` and its variants, only instances
+ for the dependent products that are not bound in the conclusion of the type
+ are required.
+
+ .. exn:: Not the right number of missing arguments.
+ :undocumented:
+
+.. _intropatterns:
+
+Intro patterns
+~~~~~~~~~~~~~~
+
+Intro patterns let you specify the name to assign to variables and hypotheses
+introduced by tactics. They also let you split an introduced hypothesis into
+multiple hypotheses or subgoals. Common tactics that accept intro patterns
+include :tacn:`assert`, :tacn:`intros` and :tacn:`destruct`.
+
+.. productionlist:: coq
+ intropattern_list : `intropattern` ... `intropattern`
+ : `empty`
+ empty :
+ intropattern : *
+ : **
+ : `simple_intropattern`
+ simple_intropattern : `simple_intropattern_closed` [ % `term` ... % `term` ]
+ simple_intropattern_closed : `naming_intropattern`
+ : _
+ : `or_and_intropattern`
+ : `equality_intropattern`
+ naming_intropattern : `ident`
+ : ?
+ : ?`ident`
+ or_and_intropattern : [ `intropattern_list` | ... | `intropattern_list` ]
+ : ( `simple_intropattern` , ... , `simple_intropattern` )
+ : ( `simple_intropattern` & ... & `simple_intropattern` )
+ equality_intropattern : ->
+ : <-
+ : [= `intropattern_list` ]
+ or_and_intropattern_loc : `or_and_intropattern`
+ : `ident`
+
+Note that the intro pattern syntax varies between tactics.
+Most tactics use :n:`@simple_intropattern` in the grammar.
+:tacn:`destruct`, :tacn:`edestruct`, :tacn:`induction`,
+:tacn:`einduction`, :tacn:`case`, :tacn:`ecase` and the various
+:tacn:`inversion` tactics use :n:`@or_and_intropattern_loc`, while
+:tacn:`intros` and :tacn:`eintros` use :n:`@intropattern_list`.
+The :n:`eqn:` construct in various tactics uses :n:`@naming_intropattern`.
+
+**Naming patterns**
+
+Use these elementary patterns to specify a name:
+
+* :n:`@ident` - use the specified name
+* :n:`?` - let Coq choose a name
+* :n:`?@ident` - generate a name that begins with :n:`@ident`
+* :n:`_` - discard the matched part (unless it is required for another
+ hypothesis)
+* if a disjunction pattern omits a name, such as :g:`[|H2]`, Coq will choose a name
+
+**Splitting patterns**
+
+The most common splitting patterns are:
+
+* split a hypothesis in the form :n:`A /\ B` into two
+ hypotheses :g:`H1: A` and :g:`H2: B` using the pattern :g:`(H1 & H2)` or
+ :g:`(H1, H2)` or :g:`[H1 H2]`.
+ :ref:`Example <intropattern_conj_ex>`. This also works on :n:`A <-> B`, which
+ is just a notation representing :n:`(A -> B) /\ (B -> A)`.
+* split a hypothesis in the form :g:`A \/ B` into two
+ subgoals using the pattern :g:`[H1|H2]`. The first subgoal will have the hypothesis
+ :g:`H1: A` and the second subgoal will have the hypothesis :g:`H2: B`.
+ :ref:`Example <intropattern_disj_ex>`
+* split a hypothesis in either of the forms :g:`A /\ B` or :g:`A \/ B` using the pattern :g:`[]`.
+
+Patterns can be nested: :n:`[[Ha|Hb] H]` can be used to split :n:`(A \/ B) /\ C`.
+
+Note that there is no equivalent to intro patterns for goals. For a goal :g:`A /\ B`,
+use the :tacn:`split` tactic to replace the current goal with subgoals :g:`A` and :g:`B`.
+For a goal :g:`A \/ B`, use :tacn:`left` to replace the current goal with :g:`A`, or
+:tacn:`right` to replace the current goal with :g:`B`.
+
+* :n:`( {+, @simple_intropattern}` ) - matches
+ a product over an inductive type with a
+ :ref:`single constructor <intropattern_cons_note>`.
+ If the number of patterns
+ equals the number of constructor arguments, then it applies the patterns only to
+ the arguments, and
+ :n:`( {+, @simple_intropattern} )` is equivalent to :n:`[{+ @simple_intropattern}]`.
+ If the number of patterns equals the number of constructor arguments plus the number
+ of :n:`let-ins`, the patterns are applied to the arguments and :n:`let-in` variables.
+
+* :n:`( {+& @simple_intropattern} )` - matches a right-hand nested term that consists
+ of one or more nested binary inductive types such as :g:`a1 OP1 a2 OP2 ...`
+ (where the :g:`OPn` are right-associative).
+ (If the :g:`OPn` are left-associative, additional parentheses will be needed to make the
+ term right-hand nested, such as :g:`a1 OP1 (a2 OP2 ...)`.)
+ The splitting pattern can have more than 2 names, for example :g:`(H1 & H2 & H3)`
+ matches :g:`A /\ B /\ C`.
+ The inductive types must have a
+ :ref:`single constructor with two parameters <intropattern_cons_note>`.
+ :ref:`Example <intropattern_ampersand_ex>`
+
+* :n:`[ {+| @intropattern_list} ]` - splits an inductive type that has
+ :ref:`multiple constructors <intropattern_cons_note>`
+ such as :n:`A \/ B`
+ into multiple subgoals. The number of :token:`intropattern_list` must be the same as the number of
+ constructors for the matched part.
+* :n:`[ {+ @intropattern} ]` - splits an inductive type that has a
+ :ref:`single constructor with multiple parameters <intropattern_cons_note>`
+ such as :n:`A /\ B` into multiple hypotheses. Use :n:`[H1 [H2 H3]]` to match :g:`A /\ B /\ C`.
+* :n:`[]` - splits an inductive type: If the inductive
+ type has multiple constructors, such as :n:`A \/ B`,
+ create one subgoal for each constructor. If the inductive type has a single constructor with
+ multiple parameters, such as :n:`A /\ B`, split it into multiple hypotheses.
+
+**Equality patterns**
+
+These patterns can be used when the hypothesis is an equality:
+
+* :n:`->` - replaces the right-hand side of the hypothesis with the left-hand
+ side of the hypothesis in the conclusion of the goal; the hypothesis is
+ cleared; if the left-hand side of the hypothesis is a variable, it is
+ substituted everywhere in the context and the variable is removed.
+ :ref:`Example <intropattern_rarrow_ex>`
+* :n:`<-` - similar to :n:`->`, but replaces the left-hand side of the hypothesis
+ with the right-hand side of the hypothesis.
+* :n:`[= {*, @intropattern} ]` - If the product is over an equality type,
+ applies either :tacn:`injection` or :tacn:`discriminate`.
+ If :tacn:`injection` is applicable, the intropattern
+ is used on the hypotheses generated by :tacn:`injection`. If the
+ number of patterns is smaller than the number of hypotheses generated, the
+ pattern :n:`?` is used to complete the list.
+ :ref:`Example <intropattern_inj_discr_ex>`
+
+**Other patterns**
+
+* :n:`*` - introduces one or more quantified variables from the result
+ until there are no more quantified variables.
+ :ref:`Example <intropattern_star_ex>`
+
+* :n:`**` - introduces one or more quantified variables or hypotheses from the result until there are
+ no more quantified variables or implications (:g:`->`). :g:`intros **` is equivalent
+ to :g:`intros`.
+ :ref:`Example <intropattern_2stars_ex>`
+
+* :n:`@simple_intropattern_closed {* % @term}` - first applies each of the terms
+ with the :tacn:`apply ... in` tactic on the hypothesis to be introduced, then it uses
+ :n:`@simple_intropattern_closed`.
+ :ref:`Example <intropattern_injection_ex>`
+
+.. flag:: Bracketing Last Introduction Pattern
+
+ For :n:`intros @intropattern_list`, controls how to handle a
+ conjunctive pattern that doesn't give enough simple patterns to match
+ all the arguments in the constructor. If set (the default), |Coq| generates
+ additional names to match the number of arguments.
+ Unsetting the option will put the additional hypotheses in the goal instead, behavior that is more
+ similar to |SSR|'s intro patterns.
+
+ .. deprecated:: 8.10
+
+.. _intropattern_cons_note:
+
+.. note::
+
+ :n:`A \/ B` and :n:`A /\ B` use infix notation to refer to the inductive
+ types :n:`or` and :n:`and`.
+ :n:`or` has multiple constructors (:n:`or_introl` and :n:`or_intror`),
+ while :n:`and` has a single constructor (:n:`conj`) with multiple parameters
+ (:n:`A` and :n:`B`).
+ These are defined in theories/Init/Logic.v. The "where" clauses define the
+ infix notation for "or" and "and".
+
+ .. coqdoc::
+
+ Inductive or (A B:Prop) : Prop :=
+ | or_introl : A -> A \/ B
+ | or_intror : B -> A \/ B
+ where "A \/ B" := (or A B) : type_scope.
+
+ Inductive and (A B:Prop) : Prop :=
+ conj : A -> B -> A /\ B
+ where "A /\ B" := (and A B) : type_scope.
+
+.. note::
+
+ :n:`intros {+ p}` is not always equivalent to :n:`intros p; ... ; intros p`
+ if some of the :n:`p` are :g:`_`. In the first form, all erasures are done
+ at once, while they're done sequentially for each tactic in the second form.
+ If the second matched term depends on the first matched term and the pattern
+ for both is :g:`_` (i.e., both will be erased), the first :n:`intros` in the second
+ form will fail because the second matched term still has the dependency on the first.
+
+Examples:
+
+.. _intropattern_conj_ex:
+
+ .. example:: intro pattern for /\\
+
+ .. coqtop:: reset none
+
+ Goal forall (A: Prop) (B: Prop), (A /\ B) -> True.
+
+ .. coqtop:: out
+
+ intros.
+
+ .. coqtop:: all
+
+ destruct H as (HA & HB).
+
+.. _intropattern_disj_ex:
+
+ .. example:: intro pattern for \\/
+
+ .. coqtop:: reset none
+
+ Goal forall (A: Prop) (B: Prop), (A \/ B) -> True.
+
+ .. coqtop:: out
+
+ intros.
+
+ .. coqtop:: all
+
+ destruct H as [HA|HB]. all: swap 1 2.
+
+.. _intropattern_rarrow_ex:
+
+ .. example:: -> intro pattern
+
+ .. coqtop:: reset none
+
+ Goal forall (x:nat) (y:nat) (z:nat), (x = y) -> (y = z) -> (x = z).
+
+ .. coqtop:: out
+
+ intros * H.
+
+ .. coqtop:: all
+
+ intros ->.
+
+.. _intropattern_inj_discr_ex:
+
+ .. example:: [=] intro pattern
+
+ The first :n:`intros [=]` uses :tacn:`injection` to strip :n:`(S ...)` from
+ both sides of the matched equality. The second uses :tacn:`discriminate` on
+ the contradiction :n:`1 = 2` (internally represented as :n:`(S O) = (S (S O))`)
+ to complete the goal.
+
+ .. coqtop:: reset none
+
+ Goal forall (n m:nat), (S n) = (S m) -> (S O)=(S (S O)) -> False.
+
+ .. coqtop:: out
+
+ intros *.
+
+ .. coqtop:: all
+
+ intros [= H].
+
+ .. coqtop:: all
+
+ intros [=].
+
+.. _intropattern_ampersand_ex:
+
+ .. example:: (A & B & ...) intro pattern
+
+ .. coqtop:: reset none
+
+ Parameters (A : Prop) (B: nat -> Prop) (C: Prop).
+
+ .. coqtop:: out
+
+ Goal A /\ (exists x:nat, B x /\ C) -> True.
+
+ .. coqtop:: all
+
+ intros (a & x & b & c).
+
+.. _intropattern_star_ex:
+
+ .. example:: * intro pattern
+
+ .. coqtop:: reset out
+
+ Goal forall (A: Prop) (B: Prop), A -> B.
+
+ .. coqtop:: all
+
+ intros *.
+
+.. _intropattern_2stars_ex:
+
+ .. example:: ** pattern ("intros \**" is equivalent to "intros")
+
+ .. coqtop:: reset out
+
+ Goal forall (A: Prop) (B: Prop), A -> B.
+
+ .. coqtop:: all
+
+ intros **.
+
+ .. example:: compound intro pattern
+
+ .. coqtop:: reset out
+
+ Goal forall A B C:Prop, A \/ B /\ C -> (A -> C) -> C.
+
+ .. coqtop:: all
+
+ intros * [a | (_,c)] f.
+ all: swap 1 2.
+
+.. _intropattern_injection_ex:
+
+ .. example:: combined intro pattern using [=] -> and %
+
+ .. coqtop:: reset none
+
+ Require Import Coq.Lists.List.
+ Section IntroPatterns.
+ Variables (A : Type) (xs ys : list A).
+
+ .. coqtop:: out
+
+ Example ThreeIntroPatternsCombined :
+ S (length ys) = 1 -> xs ++ ys = xs.
+
+ .. coqtop:: all
+
+ intros [=->%length_zero_iff_nil].
+
+ * `intros` would add :g:`H : S (length ys) = 1`
+ * `intros [=]` would additionally apply :tacn:`injection` to :g:`H` to yield :g:`H0 : length ys = 0`
+ * `intros [=->%length_zero_iff_nil]` applies the theorem, making H the equality :g:`l=nil`,
+ which is then applied as for :g:`->`.
+
+ .. coqdoc::
+
+ Theorem length_zero_iff_nil (l : list A):
+ length l = 0 <-> l=nil.
+
+ The example is based on `Tej Chajed's coq-tricks <https://github.com/tchajed/coq-tricks/blob/8e6efe4971ed828ac8bdb5512c1f615d7d62691e/src/IntroPatterns.v>`_
+
+.. _occurrencessets:
+
+Occurrence sets and occurrence clauses
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+An occurrence clause is a modifier to some tactics that obeys the
+following syntax:
+
+ .. productionlist:: sentence
+ occurrence_clause : in `goal_occurrences`
+ goal_occurrences : [`ident` [`at_occurrences`], ... , `ident` [`at_occurrences`] [|- [* [`at_occurrences`]]]]
+ : * |- [* [`at_occurrences`]]
+ : *
+ at_occurrences : at `occurrences`
+ occurrences : [-] `num` ... `num`
+
+The role of an occurrence clause is to select a set of occurrences of a term
+in a goal. In the first case, the :n:`@ident {? at {* num}}` parts indicate
+that occurrences have to be selected in the hypotheses named :token:`ident`.
+If no numbers are given for hypothesis :token:`ident`, then all the
+occurrences of :token:`term` in the hypothesis are selected. If numbers are
+given, they refer to occurrences of :token:`term` when the term is printed
+using option :flag:`Printing All`, counting from left to right. In particular,
+occurrences of :token:`term` in implicit arguments
+(see :ref:`ImplicitArguments`) or coercions (see :ref:`Coercions`) are
+counted.
+
+If a minus sign is given between ``at`` and the list of occurrences, it
+negates the condition so that the clause denotes all the occurrences
+except the ones explicitly mentioned after the minus sign.
+
+As an exception to the left-to-right order, the occurrences in
+the return subexpression of a match are considered *before* the
+occurrences in the matched term.
+
+In the second case, the ``*`` on the left of ``|-`` means that all occurrences
+of term are selected in every hypothesis.
+
+In the first and second case, if ``*`` is mentioned on the right of ``|-``, the
+occurrences of the conclusion of the goal have to be selected. If some numbers
+are given, then only the occurrences denoted by these numbers are selected. If
+no numbers are given, all occurrences of :token:`term` in the goal are selected.
+
+Finally, the last notation is an abbreviation for ``* |- *``. Note also
+that ``|-`` is optional in the first case when no ``*`` is given.
+
+Here are some tactics that understand occurrence clauses: :tacn:`set`,
+:tacn:`remember`, :tacn:`induction`, :tacn:`destruct`.
+
+
+.. seealso::
+
+ :ref:`Managingthelocalcontext`, :ref:`caseanalysisandinduction`,
+ :ref:`printing_constructions_full`.
+
+
+.. _applyingtheorems:
+
+Applying theorems
+---------------------
+
+.. tacn:: exact @term
+ :name: exact
+
+ This tactic applies to any goal. It gives directly the exact proof
+ term of the goal. Let ``T`` be our goal, let ``p`` be a term of type ``U`` then
+ ``exact p`` succeeds iff ``T`` and ``U`` are convertible (see
+ :ref:`Conversion-rules`).
+
+ .. exn:: Not an exact proof.
+ :undocumented:
+
+ .. tacv:: eexact @term.
+ :name: eexact
+
+ This tactic behaves like :tacn:`exact` but is able to handle terms and
+ goals with existential variables.
+
+.. tacn:: assumption
+ :name: assumption
+
+ This tactic looks in the local context for a hypothesis whose type is
+ convertible to the goal. If it is the case, the subgoal is proved.
+ Otherwise, it fails.
+
+ .. exn:: No such assumption.
+ :undocumented:
+
+ .. tacv:: eassumption
+ :name: eassumption
+
+ This tactic behaves like :tacn:`assumption` but is able to handle
+ goals with existential variables.
+
+.. tacn:: refine @term
+ :name: refine
+
+ This tactic applies to any goal. It behaves like :tacn:`exact` with a big
+ difference: the user can leave some holes (denoted by ``_``
+ or :n:`(_ : @type)`) in the term. :tacn:`refine` will generate as many
+ subgoals as there are holes in the term. The type of holes must be either
+ synthesized by the system or declared by an explicit cast
+ like ``(_ : nat -> Prop)``. Any subgoal that
+ occurs in other subgoals is automatically shelved, as if calling
+ :tacn:`shelve_unifiable`. This low-level tactic can be
+ useful to advanced users.
+
+ .. example::
+
+ .. coqtop:: reset all
+
+ Inductive Option : Set :=
+ | Fail : Option
+ | Ok : bool -> Option.
+
+ Definition get : forall x:Option, x <> Fail -> bool.
+ refine
+ (fun x:Option =>
+ match x return x <> Fail -> bool with
+ | Fail => _
+ | Ok b => fun _ => b
+ end).
+ intros; absurd (Fail = Fail); trivial.
+ Defined.
+
+ .. exn:: Invalid argument.
+
+ The tactic :tacn:`refine` does not know what to do with the term you gave.
+
+ .. exn:: Refine passed ill-formed term.
+
+ The term you gave is not a valid proof (not easy to debug in general). This
+ message may also occur in higher-level tactics that call :tacn:`refine`
+ internally.
+
+ .. exn:: Cannot infer a term for this placeholder.
+ :name: Cannot infer a term for this placeholder. (refine)
+
+ There is a hole in the term you gave whose type cannot be inferred. Put a
+ cast around it.
+
+ .. tacv:: simple refine @term
+ :name: simple refine
+
+ This tactic behaves like refine, but it does not shelve any subgoal. It does
+ not perform any beta-reduction either.
+
+ .. tacv:: notypeclasses refine @term
+ :name: notypeclasses refine
+
+ This tactic behaves like :tacn:`refine` except it performs type checking without
+ resolution of typeclasses.
+
+ .. tacv:: simple notypeclasses refine @term
+ :name: simple notypeclasses refine
+
+ This tactic behaves like :tacn:`simple refine` except it performs type checking
+ without resolution of typeclasses.
+
+ .. flag:: Debug Unification
+
+ Enables printing traces of unification steps used during
+ elaboration/typechecking and the :tacn:`refine` tactic.
+
+.. tacn:: apply @term
+ :name: apply
+
+ This tactic applies to any goal. The argument term is a term well-formed in
+ the local context. The tactic :tacn:`apply` tries to match the current goal
+ against the conclusion of the type of :token:`term`. If it succeeds, then
+ the tactic returns as many subgoals as the number of non-dependent premises
+ of the type of term. If the conclusion of the type of :token:`term` does
+ not match the goal *and* the conclusion is an inductive type isomorphic to
+ a tuple type, then each component of the tuple is recursively matched to
+ the goal in the left-to-right order.
+
+ The tactic :tacn:`apply` relies on first-order unification with dependent
+ types unless the conclusion of the type of :token:`term` is of the form
+ :n:`P (t__1 ... t__n)` with ``P`` to be instantiated. In the latter case,
+ the behavior depends on the form of the goal. If the goal is of the form
+ :n:`(fun x => Q) u__1 ... u__n` and the :n:`t__i` and :n:`u__i` unify,
+ then :g:`P` is taken to be :g:`(fun x => Q)`. Otherwise, :tacn:`apply`
+ tries to define :g:`P` by abstracting over :g:`t_1 ... t__n` in the goal.
+ See :tacn:`pattern` to transform the goal so that it
+ gets the form :n:`(fun x => Q) u__1 ... u__n`.
+
+ .. exn:: Unable to unify @term with @term.
+
+ The :tacn:`apply` tactic failed to match the conclusion of :token:`term`
+ and the current goal. You can help the :tacn:`apply` tactic by
+ transforming your goal with the :tacn:`change` or :tacn:`pattern`
+ tactics.
+
+ .. exn:: Unable to find an instance for the variables {+ @ident}.
+
+ This occurs when some instantiations of the premises of :token:`term` are not deducible
+ from the unification. This is the case, for instance, when you want to apply a
+ transitivity property. In this case, you have to use one of the variants below:
+
+ .. tacv:: apply @term with {+ @term}
+
+ Provides apply with explicit instantiations for all dependent premises of the
+ type of term that do not occur in the conclusion and consequently cannot be
+ found by unification. Notice that the collection :n:`{+ @term}` must be given
+ according to the order of these dependent premises of the type of term.
+
+ .. exn:: Not the right number of missing arguments.
+ :undocumented:
+
+ .. tacv:: apply @term with @bindings_list
+
+ This also provides apply with values for instantiating premises. Here, variables
+ are referred by names and non-dependent products by increasing numbers (see
+ :ref:`bindings list <bindingslist>`).
+
+ .. tacv:: apply {+, @term}
+
+ This is a shortcut for :n:`apply @term__1; [.. | ... ; [ .. | apply @term__n] ... ]`,
+ i.e. for the successive applications of :n:`@term`:sub:`i+1` on the last subgoal
+ generated by :n:`apply @term__i` , starting from the application of :n:`@term__1`.
+
+ .. tacv:: eapply @term
+ :name: eapply
+
+ The tactic :tacn:`eapply` behaves like :tacn:`apply` but it does not fail when no
+ instantiations are deducible for some variables in the premises. Rather, it
+ turns these variables into existential variables which are variables still to
+ instantiate (see :ref:`Existential-Variables`). The instantiation is
+ intended to be found later in the proof.
+
+ .. tacv:: simple apply @term.
+
+ This behaves like :tacn:`apply` but it reasons modulo conversion only on subterms
+ that contain no variables to instantiate. For instance, the following example
+ does not succeed because it would require the conversion of ``id ?foo`` and
+ :g:`O`.
+
+ .. example::
+
+ .. coqtop:: all
+
+ Definition id (x : nat) := x.
+ Parameter H : forall y, id y = y.
+ Goal O = O.
+ Fail simple apply H.
+
+ Because it reasons modulo a limited amount of conversion, :tacn:`simple apply` fails
+ quicker than :tacn:`apply` and it is then well-suited for uses in user-defined
+ tactics that backtrack often. Moreover, it does not traverse tuples as :tacn:`apply`
+ does.
+
+ .. tacv:: {? simple} apply {+, @term {? with @bindings_list}}
+ {? simple} eapply {+, @term {? with @bindings_list}}
+ :name: simple apply; simple eapply
+
+ This summarizes the different syntaxes for :tacn:`apply` and :tacn:`eapply`.
+
+ .. tacv:: lapply @term
+ :name: lapply
+
+ This tactic applies to any goal, say :g:`G`. The argument term has to be
+ well-formed in the current context, its type being reducible to a non-dependent
+ product :g:`A -> B` with :g:`B` possibly containing products. Then it generates
+ two subgoals :g:`B->G` and :g:`A`. Applying ``lapply H`` (where :g:`H` has type
+ :g:`A->B` and :g:`B` does not start with a product) does the same as giving the
+ sequence ``cut B. 2:apply H.`` where ``cut`` is described below.
+
+ .. warn:: When @term contains more than one non dependent product the tactic lapply only takes into account the first product.
+ :undocumented:
+
+.. example::
+
+ Assume we have a transitive relation ``R`` on ``nat``:
+
+ .. coqtop:: reset in
+
+ Parameter R : nat -> nat -> Prop.
+
+ Axiom Rtrans : forall x y z:nat, R x y -> R y z -> R x z.
+
+ Parameters n m p : nat.
+
+ Axiom Rnm : R n m.
+
+ Axiom Rmp : R m p.
+
+ Consider the goal ``(R n p)`` provable using the transitivity of ``R``:
+
+ .. coqtop:: in
+
+ Goal R n p.
+
+ The direct application of ``Rtrans`` with ``apply`` fails because no value
+ for ``y`` in ``Rtrans`` is found by ``apply``:
+
+ .. coqtop:: all fail
+
+ apply Rtrans.
+
+ A solution is to ``apply (Rtrans n m p)`` or ``(Rtrans n m)``.
+
+ .. coqtop:: all
+
+ apply (Rtrans n m p).
+
+ Note that ``n`` can be inferred from the goal, so the following would work
+ too.
+
+ .. coqtop:: in restart
+
+ apply (Rtrans _ m).
+
+ More elegantly, ``apply Rtrans with (y:=m)`` allows only mentioning the
+ unknown m:
+
+ .. coqtop:: in restart
+
+ apply Rtrans with (y := m).
+
+ Another solution is to mention the proof of ``(R x y)`` in ``Rtrans``
+
+ .. coqtop:: all restart
+
+ apply Rtrans with (1 := Rnm).
+
+ ... or the proof of ``(R y z)``.
+
+ .. coqtop:: all restart
+
+ apply Rtrans with (2 := Rmp).
+
+ On the opposite, one can use ``eapply`` which postpones the problem of
+ finding ``m``. Then one can apply the hypotheses ``Rnm`` and ``Rmp``. This
+ instantiates the existential variable and completes the proof.
+
+ .. coqtop:: all restart abort
+
+ eapply Rtrans.
+
+ apply Rnm.
+
+ apply Rmp.
+
+.. note::
+ When the conclusion of the type of the term to ``apply`` is an inductive
+ type isomorphic to a tuple type and ``apply`` looks recursively whether a
+ component of the tuple matches the goal, it excludes components whose
+ statement would result in applying an universal lemma of the form
+ ``forall A, ... -> A``. Excluding this kind of lemma can be avoided by
+ setting the following option:
+
+.. flag:: Universal Lemma Under Conjunction
+
+ This option, which preserves compatibility with versions of Coq prior to
+ 8.4 is also available for :n:`apply @term in @ident` (see :tacn:`apply ... in`).
+
+.. tacn:: apply @term in @ident
+ :name: apply ... in
+
+ This tactic applies to any goal. The argument :token:`term` is a term
+ well-formed in the local context and the argument :token:`ident` is an
+ hypothesis of the context.
+ The tactic :n:`apply @term in @ident` tries to match the conclusion of the
+ type of :token:`ident` against a non-dependent premise of the type
+ of :token:`term`, trying them from right to left. If it succeeds, the
+ statement of hypothesis :token:`ident` is replaced by the conclusion of
+ the type of :token:`term`. The tactic also returns as many subgoals as the
+ number of other non-dependent premises in the type of :token:`term` and of
+ the non-dependent premises of the type of :token:`ident`. If the conclusion
+ of the type of :token:`term` does not match the goal *and* the conclusion
+ is an inductive type isomorphic to a tuple type, then
+ the tuple is (recursively) decomposed and the first component of the tuple
+ of which a non-dependent premise matches the conclusion of the type of
+ :token:`ident`. Tuples are decomposed in a width-first left-to-right order
+ (for instance if the type of :g:`H1` is :g:`A <-> B` and the type of
+ :g:`H2` is :g:`A` then :g:`apply H1 in H2` transforms the type of :g:`H2`
+ into :g:`B`). The tactic :tacn:`apply` relies on first-order pattern matching
+ with dependent types.
+
+ .. exn:: Statement without assumptions.
+
+ This happens if the type of :token:`term` has no non-dependent premise.
+
+ .. exn:: Unable to apply.
+
+ This happens if the conclusion of :token:`ident` does not match any of
+ the non-dependent premises of the type of :token:`term`.
+
+ .. tacv:: apply {+, @term} in @ident
+
+ This applies each :token:`term` in sequence in :token:`ident`.
+
+ .. tacv:: apply {+, @term with @bindings_list} in @ident
+
+ This does the same but uses the bindings in each :n:`(@ident := @term)` to
+ instantiate the parameters of the corresponding type of :token:`term`
+ (see :ref:`bindings list <bindingslist>`).
+
+ .. tacv:: eapply {+, @term {? with @bindings_list } } in @ident
+
+ This works as :tacn:`apply ... in` but turns unresolved bindings into
+ existential variables, if any, instead of failing.
+
+ .. tacv:: apply {+, @term {? with @bindings_list } } in @ident as @simple_intropattern
+ :name: apply ... in ... as
+
+ This works as :tacn:`apply ... in` then applies the :token:`simple_intropattern`
+ to the hypothesis :token:`ident`.
+
+ .. tacv:: simple apply @term in @ident
+
+ This behaves like :tacn:`apply ... in` but it reasons modulo conversion
+ only on subterms that contain no variables to instantiate. For instance,
+ if :g:`id := fun x:nat => x` and :g:`H: forall y, id y = y -> True` and
+ :g:`H0 : O = O` then :g:`simple apply H in H0` does not succeed because it
+ would require the conversion of :g:`id ?x` and :g:`O` where :g:`?x` is
+ an existential variable to instantiate.
+ Tactic :n:`simple apply @term in @ident` does not
+ either traverse tuples as :n:`apply @term in @ident` does.
+
+ .. tacv:: {? simple} apply {+, @term {? with @bindings_list}} in @ident {? as @simple_intropattern}
+ {? simple} eapply {+, @term {? with @bindings_list}} in @ident {? as @simple_intropattern}
+
+ This summarizes the different syntactic variants of :n:`apply @term in @ident`
+ and :n:`eapply @term in @ident`.
+
+.. tacn:: constructor @num
+ :name: constructor
+
+ This tactic applies to a goal such that its conclusion is an inductive
+ type (say :g:`I`). The argument :token:`num` must be less or equal to the
+ numbers of constructor(s) of :g:`I`. Let :n:`c__i` be the i-th
+ constructor of :g:`I`, then :g:`constructor i` is equivalent to
+ :n:`intros; apply c__i`.
+
+ .. exn:: Not an inductive product.
+ :undocumented:
+
+ .. exn:: Not enough constructors.
+ :undocumented:
+
+ .. tacv:: constructor
+
+ This tries :g:`constructor 1` then :g:`constructor 2`, ..., then
+ :g:`constructor n` where ``n`` is the number of constructors of the head
+ of the goal.
+
+ .. tacv:: constructor @num with @bindings_list
+
+ Let ``c`` be the i-th constructor of :g:`I`, then
+ :n:`constructor i with @bindings_list` is equivalent to
+ :n:`intros; apply c with @bindings_list`.
+
+ .. warning::
+
+ The terms in the :token:`bindings_list` are checked in the context
+ where constructor is executed and not in the context where :tacn:`apply`
+ is executed (the introductions are not taken into account).
+
+ .. tacv:: split {? with @bindings_list }
+ :name: split
+
+ This applies only if :g:`I` has a single constructor. It is then
+ equivalent to :n:`constructor 1 {? with @bindings_list }`. It is
+ typically used in the case of a conjunction :math:`A \wedge B`.
+
+ .. tacv:: exists @bindings_list
+ :name: exists
+
+ This applies only if :g:`I` has a single constructor. It is then equivalent
+ to :n:`intros; constructor 1 with @bindings_list.` It is typically used in
+ the case of an existential quantification :math:`\exists x, P(x).`
+
+ .. tacv:: exists {+, @bindings_list }
+
+ This iteratively applies :n:`exists @bindings_list`.
+
+ .. exn:: Not an inductive goal with 1 constructor.
+ :undocumented:
+
+ .. tacv:: left {? with @bindings_list }
+ right {? with @bindings_list }
+ :name: left; right
+
+ These tactics apply only if :g:`I` has two constructors, for
+ instance in the case of a disjunction :math:`A \vee B`.
+ Then, they are respectively equivalent to
+ :n:`constructor 1 {? with @bindings_list }` and
+ :n:`constructor 2 {? with @bindings_list }`.
+
+ .. exn:: Not an inductive goal with 2 constructors.
+ :undocumented:
+
+ .. tacv:: econstructor
+ eexists
+ esplit
+ eleft
+ eright
+ :name: econstructor; eexists; esplit; eleft; eright
+
+ These tactics and their variants behave like :tacn:`constructor`,
+ :tacn:`exists`, :tacn:`split`, :tacn:`left`, :tacn:`right` and their
+ variants but they introduce existential variables instead of failing
+ when the instantiation of a variable cannot be found
+ (cf. :tacn:`eapply` and :tacn:`apply`).
+
+.. flag:: Debug Tactic Unification
+
+ Enables printing traces of unification steps in tactic unification.
+ Tactic unification is used in tactics such as :tacn:`apply` and :tacn:`rewrite`.
+
+.. _managingthelocalcontext:
+
+Managing the local context
+------------------------------
+
+.. tacn:: intro
+ :name: intro
+
+ This tactic applies to a goal that is either a product or starts with a
+ let-binder. If the goal is a product, the tactic implements the "Lam" rule
+ given in :ref:`Typing-rules` [1]_. If the goal starts with a let-binder,
+ then the tactic implements a mix of the "Let" and "Conv".
+
+ If the current goal is a dependent product :g:`forall x:T, U`
+ (resp :g:`let x:=t in U`) then :tacn:`intro` puts :g:`x:T` (resp :g:`x:=t`)
+ in the local context. The new subgoal is :g:`U`.
+
+ If the goal is a non-dependent product :math:`T \rightarrow U`, then it
+ puts in the local context either :g:`Hn:T` (if :g:`T` is of type :g:`Set`
+ or :g:`Prop`) or :g:`Xn:T` (if the type of :g:`T` is :g:`Type`).
+ The optional index ``n`` is such that ``Hn`` or ``Xn`` is a fresh
+ identifier. In both cases, the new subgoal is :g:`U`.
+
+ If the goal is an existential variable, :tacn:`intro` forces the resolution
+ of the existential variable into a dependent product :math:`\forall`\ :g:`x:?X, ?Y`,
+ puts :g:`x:?X` in the local context and leaves :g:`?Y` as a new subgoal
+ allowed to depend on :g:`x`.
+
+ The tactic :tacn:`intro` applies the tactic :tacn:`hnf`
+ until :tacn:`intro` can be applied or the goal is not head-reducible.
+
+ .. exn:: No product even after head-reduction.
+ :undocumented:
+
+ .. tacv:: intro @ident
+
+ This applies :tacn:`intro` but forces :token:`ident` to be the name of
+ the introduced hypothesis.
+
+ .. exn:: @ident is already used.
+ :undocumented:
+
+ .. note::
+
+ If a name used by intro hides the base name of a global constant then
+ the latter can still be referred to by a qualified name
+ (see :ref:`Qualified-names`).
+
+ .. tacv:: intros
+ :name: intros
+
+ This repeats :tacn:`intro` until it meets the head-constant. It never
+ reduces head-constants and it never fails.
+
+ .. tacv:: intros {+ @ident}.
+
+ This is equivalent to the composed tactic :n:`intro @ident; ... ; intro @ident`.
+
+ .. tacv:: intros until @ident
+
+ This repeats intro until it meets a premise of the goal having the
+ form :n:`(@ident : @type)` and discharges the variable
+ named :token:`ident` of the current goal.
+
+ .. exn:: No such hypothesis in current goal.
+ :undocumented:
+
+ .. tacv:: intros until @num
+
+ This repeats :tacn:`intro` until the :token:`num`\-th non-dependent
+ product.
+
+ .. example::
+
+ On the subgoal :g:`forall x y : nat, x = y -> y = x` the
+ tactic :n:`intros until 1` is equivalent to :n:`intros x y H`,
+ as :g:`x = y -> y = x` is the first non-dependent product.
+
+ On the subgoal :g:`forall x y z : nat, x = y -> y = x` the
+ tactic :n:`intros until 1` is equivalent to :n:`intros x y z`
+ as the product on :g:`z` can be rewritten as a non-dependent
+ product: :g:`forall x y : nat, nat -> x = y -> y = x`.
+
+ .. exn:: No such hypothesis in current goal.
+
+ This happens when :token:`num` is 0 or is greater than the number of
+ non-dependent products of the goal.
+
+ .. tacv:: intro {? @ident__1 } after @ident__2
+ intro {? @ident__1 } before @ident__2
+ intro {? @ident__1 } at top
+ intro {? @ident__1 } at bottom
+
+ These tactics apply :n:`intro {? @ident__1}` and move the freshly
+ introduced hypothesis respectively after the hypothesis :n:`@ident__2`,
+ before the hypothesis :n:`@ident__2`, at the top of the local context,
+ or at the bottom of the local context. All hypotheses on which the new
+ hypothesis depends are moved too so as to respect the order of
+ dependencies between hypotheses. It is equivalent to :n:`intro {? @ident__1 }`
+ followed by the appropriate call to :tacn:`move ... after ...`,
+ :tacn:`move ... before ...`, :tacn:`move ... at top`,
+ or :tacn:`move ... at bottom`.
+
+ .. note::
+
+ :n:`intro at bottom` is a synonym for :n:`intro` with no argument.
+
+ .. exn:: No such hypothesis: @ident.
+ :undocumented:
+
+.. tacn:: intros @intropattern_list
+ :name: intros ...
+
+ Introduces one or more variables or hypotheses from the goal by matching the
+ intro patterns. See the description in :ref:`intropatterns`.
+
+.. tacn:: eintros @intropattern_list
+ :name: eintros
+
+ Works just like :tacn:`intros ...` except that it creates existential variables
+ for any unresolved variables rather than failing.
+
+.. tacn:: clear @ident
+ :name: clear
+
+ This tactic erases the hypothesis named :n:`@ident` in the local context of
+ the current goal. As a consequence, :n:`@ident` is no more displayed and no
+ more usable in the proof development.
+
+ .. exn:: No such hypothesis.
+ :undocumented:
+
+ .. exn:: @ident is used in the conclusion.
+ :undocumented:
+
+ .. exn:: @ident is used in the hypothesis @ident.
+ :undocumented:
+
+ .. tacv:: clear {+ @ident}
+
+ This is equivalent to :n:`clear @ident. ... clear @ident.`
+
+ .. tacv:: clear - {+ @ident}
+
+ This variant clears all the hypotheses except the ones depending in the
+ hypotheses named :n:`{+ @ident}` and in the goal.
+
+ .. tacv:: clear
+
+ This variants clears all the hypotheses except the ones the goal depends on.
+
+ .. tacv:: clear dependent @ident
+
+ This clears the hypothesis :token:`ident` and all the hypotheses that
+ depend on it.
+
+ .. tacv:: clearbody {+ @ident}
+ :name: clearbody
+
+ This tactic expects :n:`{+ @ident}` to be local definitions and clears
+ their respective bodies.
+ In other words, it turns the given definitions into assumptions.
+
+ .. exn:: @ident is not a local definition.
+ :undocumented:
+
+.. tacn:: revert {+ @ident}
+ :name: revert
+
+ This applies to any goal with variables :n:`{+ @ident}`. It moves the hypotheses
+ (possibly defined) to the goal, if this respects dependencies. This tactic is
+ the inverse of :tacn:`intro`.
+
+ .. exn:: No such hypothesis.
+ :undocumented:
+
+ .. exn:: @ident__1 is used in the hypothesis @ident__2.
+ :undocumented:
+
+ .. tacv:: revert dependent @ident
+ :name: revert dependent
+
+ This moves to the goal the hypothesis :token:`ident` and all the
+ hypotheses that depend on it.
+
+.. tacn:: move @ident__1 after @ident__2
+ :name: move ... after ...
+
+ This moves the hypothesis named :n:`@ident__1` in the local context after
+ the hypothesis named :n:`@ident__2`, where “after” is in reference to the
+ direction of the move. The proof term is not changed.
+
+ If :n:`@ident__1` comes before :n:`@ident__2` in the order of dependencies,
+ then all the hypotheses between :n:`@ident__1` and :n:`@ident__2` that
+ (possibly indirectly) depend on :n:`@ident__1` are moved too, and all of
+ them are thus moved after :n:`@ident__2` in the order of dependencies.
+
+ If :n:`@ident__1` comes after :n:`@ident__2` in the order of dependencies,
+ then all the hypotheses between :n:`@ident__1` and :n:`@ident__2` that
+ (possibly indirectly) occur in the type of :n:`@ident__1` are moved too,
+ and all of them are thus moved before :n:`@ident__2` in the order of
+ dependencies.
+
+ .. tacv:: move @ident__1 before @ident__2
+ :name: move ... before ...
+
+ This moves :n:`@ident__1` towards and just before the hypothesis
+ named :n:`@ident__2`. As for :tacn:`move ... after ...`, dependencies
+ over :n:`@ident__1` (when :n:`@ident__1` comes before :n:`@ident__2` in
+ the order of dependencies) or in the type of :n:`@ident__1`
+ (when :n:`@ident__1` comes after :n:`@ident__2` in the order of
+ dependencies) are moved too.
+
+ .. tacv:: move @ident at top
+ :name: move ... at top
+
+ This moves :token:`ident` at the top of the local context (at the beginning
+ of the context).
+
+ .. tacv:: move @ident at bottom
+ :name: move ... at bottom
+
+ This moves :token:`ident` at the bottom of the local context (at the end of
+ the context).
+
+ .. exn:: No such hypothesis.
+ :undocumented:
+
+ .. exn:: Cannot move @ident__1 after @ident__2: it occurs in the type of @ident__2.
+ :undocumented:
+
+ .. exn:: Cannot move @ident__1 after @ident__2: it depends on @ident__2.
+ :undocumented:
+
+ .. example::
+
+ .. coqtop:: reset all
+
+ Goal forall x :nat, x = 0 -> forall z y:nat, y=y-> 0=x.
+ intros x H z y H0.
+ move x after H0.
+ Undo.
+ move x before H0.
+ Undo.
+ move H0 after H.
+ Undo.
+ move H0 before H.
+
+.. tacn:: rename @ident__1 into @ident__2
+ :name: rename
+
+ This renames hypothesis :n:`@ident__1` into :n:`@ident__2` in the current
+ context. The name of the hypothesis in the proof-term, however, is left
+ unchanged.
+
+ .. tacv:: rename {+, @ident__i into @ident__j}
+
+ This renames the variables :n:`@ident__i` into :n:`@ident__j` in parallel.
+ In particular, the target identifiers may contain identifiers that exist in
+ the source context, as long as the latter are also renamed by the same
+ tactic.
+
+ .. exn:: No such hypothesis.
+ :undocumented:
+
+ .. exn:: @ident is already used.
+ :undocumented:
+
+.. tacn:: set (@ident := @term)
+ :name: set
+
+ This replaces :token:`term` by :token:`ident` in the conclusion of the
+ current goal and adds the new definition :n:`@ident := @term` to the
+ local context.
+
+ If :token:`term` has holes (i.e. subexpressions of the form “`_`”), the
+ tactic first checks that all subterms matching the pattern are compatible
+ before doing the replacement using the leftmost subterm matching the
+ pattern.
+
+ .. exn:: The variable @ident is already defined.
+ :undocumented:
+
+ .. tacv:: set (@ident := @term) in @goal_occurrences
+
+ This notation allows specifying which occurrences of :token:`term` have
+ to be substituted in the context. The :n:`in @goal_occurrences` clause
+ is an occurrence clause whose syntax and behavior are described in
+ :ref:`goal occurrences <occurrencessets>`.
+
+ .. tacv:: set (@ident @binders := @term) {? in @goal_occurrences }
+
+ This is equivalent to :n:`set (@ident := fun @binders => @term) {? in @goal_occurrences }`.
+
+ .. tacv:: set @term {? in @goal_occurrences }
+
+ This behaves as :n:`set (@ident := @term) {? in @goal_occurrences }`
+ but :token:`ident` is generated by Coq.
+
+ .. tacv:: eset (@ident {? @binders } := @term) {? in @goal_occurrences }
+ eset @term {? in @goal_occurrences }
+ :name: eset; _
+
+ While the different variants of :tacn:`set` expect that no existential
+ variables are generated by the tactic, :tacn:`eset` removes this
+ constraint. In practice, this is relevant only when :tacn:`eset` is
+ used as a synonym of :tacn:`epose`, i.e. when the :token:`term` does
+ not occur in the goal.
+
+.. tacn:: remember @term as @ident__1 {? eqn:@naming_intropattern }
+ :name: remember
+
+ This behaves as :n:`set (@ident := @term) in *`, using a logical
+ (Leibniz’s) equality instead of a local definition.
+ Use :n:`@naming_intropattern` to name or split up the new equation.
+
+ .. tacv:: remember @term as @ident__1 {? eqn:@naming_intropattern } in @goal_occurrences
+
+ This is a more general form of :tacn:`remember` that remembers the
+ occurrences of :token:`term` specified by an occurrence set.
+
+ .. tacv:: eremember @term as @ident__1 {? eqn:@naming_intropattern } {? in @goal_occurrences }
+ :name: eremember
+
+ While the different variants of :tacn:`remember` expect that no
+ existential variables are generated by the tactic, :tacn:`eremember`
+ removes this constraint.
+
+.. tacn:: pose (@ident := @term)
+ :name: pose
+
+ This adds the local definition :n:`@ident := @term` to the current context
+ without performing any replacement in the goal or in the hypotheses. It is
+ equivalent to :n:`set (@ident := @term) in |-`.
+
+ .. tacv:: pose (@ident @binders := @term)
+
+ This is equivalent to :n:`pose (@ident := fun @binders => @term)`.
+
+ .. tacv:: pose @term
+
+ This behaves as :n:`pose (@ident := @term)` but :token:`ident` is
+ generated by Coq.
+
+ .. tacv:: epose (@ident {? @binders} := @term)
+ epose @term
+ :name: epose; _
+
+ While the different variants of :tacn:`pose` expect that no
+ existential variables are generated by the tactic, :tacn:`epose`
+ removes this constraint.
+
+.. tacn:: decompose [{+ @qualid}] @term
+ :name: decompose
+
+ This tactic recursively decomposes a complex proposition in order to
+ obtain atomic ones.
+
+ .. example::
+
+ .. coqtop:: reset all
+
+ Goal forall A B C:Prop, A /\ B /\ C \/ B /\ C \/ C /\ A -> C.
+ intros A B C H; decompose [and or] H.
+ all: assumption.
+ Qed.
+
+ .. note::
+
+ :tacn:`decompose` does not work on right-hand sides of implications or
+ products.
+
+ .. tacv:: decompose sum @term
+
+ This decomposes sum types (like :g:`or`).
+
+ .. tacv:: decompose record @term
+
+ This decomposes record types (inductive types with one constructor,
+ like :g:`and` and :g:`exists` and those defined with the :cmd:`Record`
+ command.
+
+
+.. _controllingtheproofflow:
+
+Controlling the proof flow
+------------------------------
+
+.. tacn:: assert (@ident : @type)
+ :name: assert
+
+ This tactic applies to any goal. :n:`assert (H : U)` adds a new hypothesis
+ of name :n:`H` asserting :g:`U` to the current goal and opens a new subgoal
+ :g:`U` [2]_. The subgoal :g:`U` comes first in the list of subgoals remaining to
+ prove.
+
+ .. exn:: Not a proposition or a type.
+
+ Arises when the argument :token:`type` is neither of type :g:`Prop`,
+ :g:`Set` nor :g:`Type`.
+
+ .. tacv:: assert @type
+
+ This behaves as :n:`assert (@ident : @type)` but :n:`@ident` is
+ generated by Coq.
+
+ .. tacv:: assert @type by @tactic
+
+ This tactic behaves like :tacn:`assert` but applies tactic to solve the
+ subgoals generated by assert.
+
+ .. exn:: Proof is not complete.
+ :name: Proof is not complete. (assert)
+ :undocumented:
+
+ .. tacv:: assert @type as @simple_intropattern
+
+ If :n:`simple_intropattern` is an intro pattern (see :ref:`intropatterns`),
+ the hypothesis is named after this introduction pattern (in particular, if
+ :n:`simple_intropattern` is :n:`@ident`, the tactic behaves like
+ :n:`assert (@ident : @type)`). If :n:`simple_intropattern` is an action
+ introduction pattern, the tactic behaves like :n:`assert @type` followed by
+ the action done by this introduction pattern.
+
+ .. tacv:: assert @type as @simple_intropattern by @tactic
+
+ This combines the two previous variants of :tacn:`assert`.
+
+ .. tacv:: assert (@ident := @term)
+
+ This behaves as :n:`assert (@ident : @type) by exact @term` where
+ :token:`type` is the type of :token:`term`. This is equivalent to using
+ :tacn:`pose proof`. If the head of term is :token:`ident`, the tactic
+ behaves as :tacn:`specialize`.
+
+ .. exn:: Variable @ident is already declared.
+ :undocumented:
+
+.. tacv:: eassert @type as @simple_intropattern by @tactic
+ :name: eassert
+
+ While the different variants of :tacn:`assert` expect that no existential
+ variables are generated by the tactic, :tacn:`eassert` removes this constraint.
+ This allows not to specify the asserted statement completeley before starting
+ to prove it.
+
+.. tacv:: pose proof @term {? as @simple_intropattern}
+ :name: pose proof
+
+ This tactic behaves like :n:`assert @type {? as @simple_intropattern} by exact @term`
+ where :token:`type` is the type of :token:`term`. In particular,
+ :n:`pose proof @term as @ident` behaves as :n:`assert (@ident := @term)`
+ and :n:`pose proof @term as @simple_intropattern` is the same as applying the
+ :token:`simple_intropattern` to :token:`term`.
+
+.. tacv:: epose proof @term {? as @simple_intropattern}
+ :name: epose proof
+
+ While :tacn:`pose proof` expects that no existential variables are generated by
+ the tactic, :tacn:`epose proof` removes this constraint.
+
+.. tacv:: enough (@ident : @type)
+ :name: enough
+
+ This adds a new hypothesis of name :token:`ident` asserting :token:`type` to the
+ goal the tactic :tacn:`enough` is applied to. A new subgoal stating :token:`type` is
+ inserted after the initial goal rather than before it as :tacn:`assert` would do.
+
+.. tacv:: enough @type
+
+ This behaves like :n:`enough (@ident : @type)` with the name :token:`ident` of
+ the hypothesis generated by Coq.
+
+.. tacv:: enough @type as @simple_intropattern
+
+ This behaves like :n:`enough @type` using :token:`simple_intropattern` to name or
+ destruct the new hypothesis.
+
+.. tacv:: enough (@ident : @type) by @tactic
+ enough @type {? as @simple_intropattern } by @tactic
+
+ This behaves as above but with :token:`tactic` expected to solve the initial goal
+ after the extra assumption :token:`type` is added and possibly destructed. If the
+ :n:`as @simple_intropattern` clause generates more than one subgoal, :token:`tactic` is
+ applied to all of them.
+
+.. tacv:: eenough @type {? as @simple_intropattern } {? by @tactic }
+ eenough (@ident : @type) {? by @tactic }
+ :name: eenough; _
+
+ While the different variants of :tacn:`enough` expect that no existential
+ variables are generated by the tactic, :tacn:`eenough` removes this constraint.
+
+.. tacv:: cut @type
+ :name: cut
+
+ This tactic applies to any goal. It implements the non-dependent case of
+ the “App” rule given in :ref:`typing-rules`. (This is Modus Ponens inference
+ rule.) :n:`cut U` transforms the current goal :g:`T` into the two following
+ subgoals: :g:`U -> T` and :g:`U`. The subgoal :g:`U -> T` comes first in the
+ list of remaining subgoal to prove.
+
+.. tacv:: specialize (@ident {* @term}) {? as @simple_intropattern}
+ specialize @ident with @bindings_list {? as @simple_intropattern}
+ :name: specialize; _
+
+ This tactic works on local hypothesis :n:`@ident`. The
+ premises of this hypothesis (either universal quantifications or
+ non-dependent implications) are instantiated by concrete terms coming either
+ from arguments :n:`{* @term}` or from a :ref:`bindings list <bindingslist>`.
+ In the first form the application to :n:`{* @term}` can be partial. The
+ first form is equivalent to :n:`assert (@ident := @ident {* @term})`. In the
+ second form, instantiation elements can also be partial. In this case the
+ uninstantiated arguments are inferred by unification if possible or left
+ quantified in the hypothesis otherwise. With the :n:`as` clause, the local
+ hypothesis :n:`@ident` is left unchanged and instead, the modified hypothesis
+ is introduced as specified by the :token:`simple_intropattern`. The name :n:`@ident`
+ can also refer to a global lemma or hypothesis. In this case, for
+ compatibility reasons, the behavior of :tacn:`specialize` is close to that of
+ :tacn:`generalize`: the instantiated statement becomes an additional premise of
+ the goal. The ``as`` clause is especially useful in this case to immediately
+ introduce the instantiated statement as a local hypothesis.
+
+ .. exn:: @ident is used in hypothesis @ident.
+ :undocumented:
+
+ .. exn:: @ident is used in conclusion.
+ :undocumented:
+
+.. tacn:: generalize @term
+ :name: generalize
+
+ This tactic applies to any goal. It generalizes the conclusion with
+ respect to some term.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ Goal forall x y:nat, 0 <= x + y + y.
+ Proof. intros *.
+
+ .. coqtop:: all
+
+ Show.
+ generalize (x + y + y).
+
+If the goal is :g:`G` and :g:`t` is a subterm of type :g:`T` in the goal,
+then :n:`generalize t` replaces the goal by :g:`forall (x:T), G′` where :g:`G′`
+is obtained from :g:`G` by replacing all occurrences of :g:`t` by :g:`x`. The
+name of the variable (here :g:`n`) is chosen based on :g:`T`.
+
+.. tacv:: generalize {+ @term}
+
+ This is equivalent to :n:`generalize @term; ... ; generalize @term`.
+ Note that the sequence of term :sub:`i` 's are processed from n to 1.
+
+.. tacv:: generalize @term at {+ @num}
+
+ This is equivalent to :n:`generalize @term` but it generalizes only over the
+ specified occurrences of :n:`@term` (counting from left to right on the
+ expression printed using option :flag:`Printing All`).
+
+.. tacv:: generalize @term as @ident
+
+ This is equivalent to :n:`generalize @term` but it uses :n:`@ident` to name
+ the generalized hypothesis.
+
+.. tacv:: generalize {+, @term at {+ @num} as @ident}
+
+ This is the most general form of :n:`generalize` that combines the previous
+ behaviors.
+
+.. tacv:: generalize dependent @term
+
+ This generalizes term but also *all* hypotheses that depend on :n:`@term`. It
+ clears the generalized hypotheses.
+
+.. tacn:: evar (@ident : @term)
+ :name: evar
+
+ The :n:`evar` tactic creates a new local definition named :n:`@ident` with type
+ :n:`@term` in the context. The body of this binding is a fresh existential
+ variable.
+
+.. tacn:: instantiate (@ident := @term )
+ :name: instantiate
+
+ The instantiate tactic refines (see :tacn:`refine`) an existential variable
+ :n:`@ident` with the term :n:`@term`. It is equivalent to only [ident]:
+ :n:`refine @term` (preferred alternative).
+
+ .. note:: To be able to refer to an existential variable by name, the user
+ must have given the name explicitly (see :ref:`Existential-Variables`).
+
+ .. note:: When you are referring to hypotheses which you did not name
+ explicitly, be aware that Coq may make a different decision on how to
+ name the variable in the current goal and in the context of the
+ existential variable. This can lead to surprising behaviors.
+
+.. tacv:: instantiate (@num := @term)
+
+ This variant allows to refer to an existential variable which was not named
+ by the user. The :n:`@num` argument is the position of the existential variable
+ from right to left in the goal. Because this variant is not robust to slight
+ changes in the goal, its use is strongly discouraged.
+
+.. tacv:: instantiate ( @num := @term ) in @ident
+ instantiate ( @num := @term ) in ( value of @ident )
+ instantiate ( @num := @term ) in ( type of @ident )
+
+ These allow to refer respectively to existential variables occurring in a
+ hypothesis or in the body or the type of a local definition.
+
+.. tacv:: instantiate
+
+ Without argument, the instantiate tactic tries to solve as many existential
+ variables as possible, using information gathered from other tactics in the
+ same tactical. This is automatically done after each complete tactic (i.e.
+ after a dot in proof mode), but not, for example, between each tactic when
+ they are sequenced by semicolons.
+
+.. tacn:: admit
+ :name: admit
+
+ This tactic allows temporarily skipping a subgoal so as to
+ progress further in the rest of the proof. A proof containing admitted
+ goals cannot be closed with :cmd:`Qed` but only with :cmd:`Admitted`.
+
+.. tacv:: give_up
+
+ Synonym of :tacn:`admit`.
+
+.. tacn:: absurd @term
+ :name: absurd
+
+ This tactic applies to any goal. The argument term is any proposition
+ :g:`P` of type :g:`Prop`. This tactic applies False elimination, that is it
+ deduces the current goal from False, and generates as subgoals :g:`∼P` and
+ :g:`P`. It is very useful in proofs by cases, where some cases are
+ impossible. In most cases, :g:`P` or :g:`∼P` is one of the hypotheses of the
+ local context.
+
+.. tacn:: contradiction
+ :name: contradiction
+
+ This tactic applies to any goal. The contradiction tactic attempts to
+ find in the current context (after all intros) a hypothesis that is
+ equivalent to an empty inductive type (e.g. :g:`False`), to the negation of
+ a singleton inductive type (e.g. :g:`True` or :g:`x=x`), or two contradictory
+ hypotheses.
+
+ .. exn:: No such assumption.
+ :undocumented:
+
+.. tacv:: contradiction @ident
+
+ The proof of False is searched in the hypothesis named :n:`@ident`.
+
+.. tacn:: contradict @ident
+ :name: contradict
+
+ This tactic allows manipulating negated hypothesis and goals. The name
+ :n:`@ident` should correspond to a hypothesis. With :n:`contradict H`, the
+ current goal and context is transformed in the following way:
+
+ + H:¬A ⊢ B becomes ⊢ A
+ + H:¬A ⊢ ¬B becomes H: B ⊢ A
+ + H: A ⊢ B becomes ⊢ ¬A
+ + H: A ⊢ ¬B becomes H: B ⊢ ¬A
+
+.. tacn:: exfalso
+ :name: exfalso
+
+ This tactic implements the “ex falso quodlibet” logical principle: an
+ elimination of False is performed on the current goal, and the user is
+ then required to prove that False is indeed provable in the current
+ context. This tactic is a macro for :n:`elimtype False`.
+
+.. _CaseAnalysisAndInduction:
+
+Case analysis and induction
+-------------------------------
+
+The tactics presented in this section implement induction or case
+analysis on inductive or co-inductive objects (see :ref:`inductive-definitions`).
+
+.. tacn:: destruct @term
+ :name: destruct
+
+ This tactic applies to any goal. The argument :token:`term` must be of
+ inductive or co-inductive type and the tactic generates subgoals, one
+ for each possible form of :token:`term`, i.e. one for each constructor of the
+ inductive or co-inductive type. Unlike :tacn:`induction`, no induction
+ hypothesis is generated by :tacn:`destruct`.
+
+ .. tacv:: destruct @ident
+
+ If :token:`ident` denotes a quantified variable of the conclusion
+ of the goal, then :n:`destruct @ident` behaves
+ as :n:`intros until @ident; destruct @ident`. If :token:`ident` is not
+ anymore dependent in the goal after application of :tacn:`destruct`, it
+ is erased (to avoid erasure, use parentheses, as in :n:`destruct (@ident)`).
+
+ If :token:`ident` is a hypothesis of the context, and :token:`ident`
+ is not anymore dependent in the goal after application
+ of :tacn:`destruct`, it is erased (to avoid erasure, use parentheses, as
+ in :n:`destruct (@ident)`).
+
+ .. tacv:: destruct @num
+
+ :n:`destruct @num` behaves as :n:`intros until @num`
+ followed by destruct applied to the last introduced hypothesis.
+
+ .. note::
+ For destruction of a numeral, use syntax :n:`destruct (@num)` (not
+ very interesting anyway).
+
+ .. tacv:: destruct @pattern
+
+ The argument of :tacn:`destruct` can also be a pattern of which holes are
+ denoted by “_”. In this case, the tactic checks that all subterms
+ matching the pattern in the conclusion and the hypotheses are compatible
+ and performs case analysis using this subterm.
+
+ .. tacv:: destruct {+, @term}
+
+ This is a shortcut for :n:`destruct @term; ...; destruct @term`.
+
+ .. tacv:: destruct @term as @or_and_intropattern_loc
+
+ This behaves as :n:`destruct @term` but uses the names
+ in :token:`or_and_intropattern_loc` to name the variables introduced in the
+ context. The :token:`or_and_intropattern_loc` must have the
+ form :n:`[p11 ... p1n | ... | pm1 ... pmn ]` with ``m`` being the
+ number of constructors of the type of :token:`term`. Each variable
+ introduced by :tacn:`destruct` in the context of the ``i``-th goal
+ gets its name from the list :n:`pi1 ... pin` in order. If there are not
+ enough names, :tacn:`destruct` invents names for the remaining variables
+ to introduce. More generally, the :n:`pij` can be any introduction
+ pattern (see :tacn:`intros`). This provides a concise notation for
+ chaining destruction of a hypothesis.
+
+ .. tacv:: destruct @term eqn:@naming_intropattern
+ :name: destruct ... eqn:
+
+ This behaves as :n:`destruct @term` but adds an equation
+ between :token:`term` and the value that it takes in each of the
+ possible cases. The name of the equation is specified
+ by :token:`naming_intropattern` (see :tacn:`intros`),
+ in particular ``?`` can be used to let Coq generate a fresh name.
+
+ .. tacv:: destruct @term with @bindings_list
+
+ This behaves like :n:`destruct @term` providing explicit instances for
+ the dependent premises of the type of :token:`term`.
+
+ .. tacv:: edestruct @term
+ :name: edestruct
+
+ This tactic behaves like :n:`destruct @term` except that it does not
+ fail if the instance of a dependent premises of the type
+ of :token:`term` is not inferable. Instead, the unresolved instances
+ are left as existential variables to be inferred later, in the same way
+ as :tacn:`eapply` does.
+
+ .. tacv:: destruct @term using @term {? with @bindings_list }
+
+ This is synonym of :n:`induction @term using @term {? with @bindings_list }`.
+
+ .. tacv:: destruct @term in @goal_occurrences
+
+ This syntax is used for selecting which occurrences of :token:`term`
+ the case analysis has to be done on. The :n:`in @goal_occurrences`
+ clause is an occurrence clause whose syntax and behavior is described
+ in :ref:`occurrences sets <occurrencessets>`.
+
+ .. tacv:: destruct @term {? with @bindings_list } {? as @or_and_intropattern_loc } {? eqn:@naming_intropattern } {? using @term {? with @bindings_list } } {? in @goal_occurrences }
+ edestruct @term {? with @bindings_list } {? as @or_and_intropattern_loc } {? eqn:@naming_intropattern } {? using @term {? with @bindings_list } } {? in @goal_occurrences }
+
+ These are the general forms of :tacn:`destruct` and :tacn:`edestruct`.
+ They combine the effects of the ``with``, ``as``, ``eqn:``, ``using``,
+ and ``in`` clauses.
+
+.. tacn:: case term
+ :name: case
+
+ The tactic :n:`case` is a more basic tactic to perform case analysis without
+ recursion. It behaves as :n:`elim @term` but using a case-analysis
+ elimination principle and not a recursive one.
+
+.. tacv:: case @term with @bindings_list
+
+ Analogous to :n:`elim @term with @bindings_list` above.
+
+.. tacv:: ecase @term {? with @bindings_list }
+ :name: ecase
+
+ In case the type of :n:`@term` has dependent premises, or dependent premises
+ whose values are not inferable from the :n:`with @bindings_list` clause,
+ :n:`ecase` turns them into existential variables to be resolved later on.
+
+.. tacv:: simple destruct @ident
+ :name: simple destruct
+
+ This tactic behaves as :n:`intros until @ident; case @ident` when :n:`@ident`
+ is a quantified variable of the goal.
+
+.. tacv:: simple destruct @num
+
+ This tactic behaves as :n:`intros until @num; case @ident` where :n:`@ident`
+ is the name given by :n:`intros until @num` to the :n:`@num` -th
+ non-dependent premise of the goal.
+
+.. tacv:: case_eq @term
+
+ The tactic :n:`case_eq` is a variant of the :n:`case` tactic that allows to
+ perform case analysis on a term without completely forgetting its original
+ form. This is done by generating equalities between the original form of the
+ term and the outcomes of the case analysis.
+
+.. tacn:: induction @term
+ :name: induction
+
+ This tactic applies to any goal. The argument :n:`@term` must be of
+ inductive type and the tactic :n:`induction` generates subgoals, one for
+ each possible form of :n:`@term`, i.e. one for each constructor of the
+ inductive type.
+
+ If the argument is dependent in either the conclusion or some
+ hypotheses of the goal, the argument is replaced by the appropriate
+ constructor form in each of the resulting subgoals and induction
+ hypotheses are added to the local context using names whose prefix
+ is **IH**.
+
+ There are particular cases:
+
+ + If term is an identifier :n:`@ident` denoting a quantified variable of the
+ conclusion of the goal, then inductionident behaves as :n:`intros until
+ @ident; induction @ident`. If :n:`@ident` is not anymore dependent in the
+ goal after application of :n:`induction`, it is erased (to avoid erasure,
+ use parentheses, as in :n:`induction (@ident)`).
+ + If :n:`@term` is a :n:`@num`, then :n:`induction @num` behaves as
+ :n:`intros until @num` followed by :n:`induction` applied to the last
+ introduced hypothesis.
+
+ .. note::
+ For simple induction on a numeral, use syntax induction (num)
+ (not very interesting anyway).
+
+ + In case term is a hypothesis :n:`@ident` of the context, and :n:`@ident`
+ is not anymore dependent in the goal after application of :n:`induction`,
+ it is erased (to avoid erasure, use parentheses, as in
+ :n:`induction (@ident)`).
+ + The argument :n:`@term` can also be a pattern of which holes are denoted
+ by “_”. In this case, the tactic checks that all subterms matching the
+ pattern in the conclusion and the hypotheses are compatible and
+ performs induction using this subterm.
+
+.. example::
+
+ .. coqtop:: reset all
+
+ Lemma induction_test : forall n:nat, n = n -> n <= n.
+ intros n H.
+ induction n.
+
+.. exn:: Not an inductive product.
+ :undocumented:
+
+.. exn:: Unable to find an instance for the variables @ident ... @ident.
+
+ Use in this case the variant :tacn:`elim ... with` below.
+
+.. tacv:: induction @term as @or_and_intropattern_loc
+
+ This behaves as :tacn:`induction` but uses the names in
+ :n:`@or_and_intropattern_loc` to name the variables introduced in the
+ context. The :n:`@or_and_intropattern_loc` must typically be of the form
+ :n:`[ p` :sub:`11` :n:`... p` :sub:`1n` :n:`| ... | p`:sub:`m1` :n:`... p`:sub:`mn` :n:`]`
+ with :n:`m` being the number of constructors of the type of :n:`@term`. Each
+ variable introduced by induction in the context of the i-th goal gets its
+ name from the list :n:`p`:sub:`i1` :n:`... p`:sub:`in` in order. If there are
+ not enough names, induction invents names for the remaining variables to
+ introduce. More generally, the :n:`p`:sub:`ij` can be any
+ disjunctive/conjunctive introduction pattern (see :tacn:`intros ...`). For
+ instance, for an inductive type with one constructor, the pattern notation
+ :n:`(p`:sub:`1` :n:`, ... , p`:sub:`n` :n:`)` can be used instead of
+ :n:`[ p`:sub:`1` :n:`... p`:sub:`n` :n:`]`.
+
+.. tacv:: induction @term with @bindings_list
+
+ This behaves like :tacn:`induction` providing explicit instances for the
+ premises of the type of :n:`term` (see :ref:`bindings list <bindingslist>`).
+
+.. tacv:: einduction @term
+ :name: einduction
+
+ This tactic behaves like :tacn:`induction` except that it does not fail if
+ some dependent premise of the type of :n:`@term` is not inferable. Instead,
+ the unresolved premises are posed as existential variables to be inferred
+ later, in the same way as :tacn:`eapply` does.
+
+.. tacv:: induction @term using @term
+ :name: induction ... using ...
+
+ This behaves as :tacn:`induction` but using :n:`@term` as induction scheme.
+ It does not expect the conclusion of the type of the first :n:`@term` to be
+ inductive.
+
+.. tacv:: induction @term using @term with @bindings_list
+
+ This behaves as :tacn:`induction ... using ...` but also providing instances
+ for the premises of the type of the second :n:`@term`.
+
+.. tacv:: induction {+, @term} using @qualid
+
+ This syntax is used for the case :n:`@qualid` denotes an induction principle
+ with complex predicates as the induction principles generated by
+ ``Function`` or ``Functional Scheme`` may be.
+
+.. tacv:: induction @term in @goal_occurrences
+
+ This syntax is used for selecting which occurrences of :n:`@term` the
+ induction has to be carried on. The :n:`in @goal_occurrences` clause is an
+ occurrence clause whose syntax and behavior is described in
+ :ref:`occurrences sets <occurrencessets>`. If variables or hypotheses not
+ mentioning :n:`@term` in their type are listed in :n:`@goal_occurrences`,
+ those are generalized as well in the statement to prove.
+
+ .. example::
+
+ .. coqtop:: reset all
+
+ Lemma comm x y : x + y = y + x.
+ induction y in x |- *.
+ Show 2.
+
+.. tacv:: induction @term with @bindings_list as @or_and_intropattern_loc using @term with @bindings_list in @goal_occurrences
+ einduction @term with @bindings_list as @or_and_intropattern_loc using @term with @bindings_list in @goal_occurrences
+
+ These are the most general forms of :tacn:`induction` and :tacn:`einduction`. It combines the
+ effects of the with, as, using, and in clauses.
+
+.. tacv:: elim @term
+ :name: elim
+
+ This is a more basic induction tactic. Again, the type of the argument
+ :n:`@term` must be an inductive type. Then, according to the type of the
+ goal, the tactic ``elim`` chooses the appropriate destructor and applies it
+ as the tactic :tacn:`apply` would do. For instance, if the proof context
+ contains :g:`n:nat` and the current goal is :g:`T` of type :g:`Prop`, then
+ :n:`elim n` is equivalent to :n:`apply nat_ind with (n:=n)`. The tactic
+ ``elim`` does not modify the context of the goal, neither introduces the
+ induction loading into the context of hypotheses. More generally,
+ :n:`elim @term` also works when the type of :n:`@term` is a statement
+ with premises and whose conclusion is inductive. In that case the tactic
+ performs induction on the conclusion of the type of :n:`@term` and leaves the
+ non-dependent premises of the type as subgoals. In the case of dependent
+ products, the tactic tries to find an instance for which the elimination
+ lemma applies and fails otherwise.
+
+.. tacv:: elim @term with @bindings_list
+ :name: elim ... with
+
+ Allows to give explicit instances to the premises of the type of :n:`@term`
+ (see :ref:`bindings list <bindingslist>`).
+
+.. tacv:: eelim @term
+ :name: eelim
+
+ In case the type of :n:`@term` has dependent premises, this turns them into
+ existential variables to be resolved later on.
+
+.. tacv:: elim @term using @term
+ elim @term using @term with @bindings_list
+
+ Allows the user to give explicitly an induction principle :n:`@term` that
+ is not the standard one for the underlying inductive type of :n:`@term`. The
+ :n:`@bindings_list` clause allows instantiating premises of the type of
+ :n:`@term`.
+
+.. tacv:: elim @term with @bindings_list using @term with @bindings_list
+ eelim @term with @bindings_list using @term with @bindings_list
+
+ These are the most general forms of :tacn:`elim` and :tacn:`eelim`. It combines the
+ effects of the ``using`` clause and of the two uses of the ``with`` clause.
+
+.. tacv:: elimtype @type
+ :name: elimtype
+
+ The argument :token:`type` must be inductively defined. :n:`elimtype I` is
+ equivalent to :n:`cut I. intro Hn; elim Hn; clear Hn.` Therefore the
+ hypothesis :g:`Hn` will not appear in the context(s) of the subgoal(s).
+ Conversely, if :g:`t` is a :n:`@term` of (inductive) type :g:`I` that does
+ not occur in the goal, then :n:`elim t` is equivalent to
+ :n:`elimtype I; 2:exact t.`
+
+.. tacv:: simple induction @ident
+ :name: simple induction
+
+ This tactic behaves as :n:`intros until @ident; elim @ident` when
+ :n:`@ident` is a quantified variable of the goal.
+
+.. tacv:: simple induction @num
+
+ This tactic behaves as :n:`intros until @num; elim @ident` where :n:`@ident`
+ is the name given by :n:`intros until @num` to the :n:`@num`-th non-dependent
+ premise of the goal.
+
+.. tacn:: double induction @ident @ident
+ :name: double induction
+
+ This tactic is deprecated and should be replaced by
+ :n:`induction @ident; induction @ident` (or
+ :n:`induction @ident ; destruct @ident` depending on the exact needs).
+
+.. tacv:: double induction num1 num2
+
+ This tactic is deprecated and should be replaced by
+ :n:`induction num1; induction num3` where :n:`num3` is the result
+ of :n:`num2 - num1`
+
+.. tacn:: dependent induction @ident
+ :name: dependent induction
+
+ The *experimental* tactic dependent induction performs induction-
+ inversion on an instantiated inductive predicate. One needs to first
+ require the Coq.Program.Equality module to use this tactic. The tactic
+ is based on the BasicElim tactic by Conor McBride
+ :cite:`DBLP:conf/types/McBride00` and the work of Cristina Cornes around
+ inversion :cite:`DBLP:conf/types/CornesT95`. From an instantiated
+ inductive predicate and a goal, it generates an equivalent goal where
+ the hypothesis has been generalized over its indexes which are then
+ constrained by equalities to be the right instances. This permits to
+ state lemmas without resorting to manually adding these equalities and
+ still get enough information in the proofs.
+
+.. example::
+
+ .. coqtop:: reset all
+
+ Lemma le_minus : forall n:nat, n < 1 -> n = 0.
+ intros n H ; induction H.
+
+ Here we did not get any information on the indexes to help fulfill
+ this proof. The problem is that, when we use the ``induction`` tactic, we
+ lose information on the hypothesis instance, notably that the second
+ argument is 1 here. Dependent induction solves this problem by adding
+ the corresponding equality to the context.
+
+ .. coqtop:: reset all
+
+ Require Import Coq.Program.Equality.
+ Lemma le_minus : forall n:nat, n < 1 -> n = 0.
+ intros n H ; dependent induction H.
+
+ The subgoal is cleaned up as the tactic tries to automatically
+ simplify the subgoals with respect to the generated equalities. In
+ this enriched context, it becomes possible to solve this subgoal.
+
+ .. coqtop:: all
+
+ reflexivity.
+
+ Now we are in a contradictory context and the proof can be solved.
+
+ .. coqtop:: all
+
+ inversion H.
+
+ This technique works with any inductive predicate. In fact, the
+ ``dependent induction`` tactic is just a wrapper around the ``induction``
+ tactic. One can make its own variant by just writing a new tactic
+ based on the definition found in ``Coq.Program.Equality``.
+
+.. tacv:: dependent induction @ident generalizing {+ @ident}
+
+ This performs dependent induction on the hypothesis :n:`@ident` but first
+ generalizes the goal by the given variables so that they are universally
+ quantified in the goal. This is generally what one wants to do with the
+ variables that are inside some constructors in the induction hypothesis. The
+ other ones need not be further generalized.
+
+.. tacv:: dependent destruction @ident
+ :name: dependent destruction
+
+ This performs the generalization of the instance :n:`@ident` but uses
+ ``destruct`` instead of induction on the generalized hypothesis. This gives
+ results equivalent to ``inversion`` or ``dependent inversion`` if the
+ hypothesis is dependent.
+
+See also the larger example of :tacn:`dependent induction`
+and an explanation of the underlying technique.
+
+.. tacn:: function induction (@qualid {+ @term})
+ :name: function induction
+
+ The tactic functional induction performs case analysis and induction
+ following the definition of a function. It makes use of a principle
+ generated by ``Function`` (see :ref:`advanced-recursive-functions`) or
+ ``Functional Scheme`` (see :ref:`functional-scheme`).
+ Note that this tactic is only available after a ``Require Import FunInd``.
+
+.. example::
+
+ .. coqtop:: reset all
+
+ Require Import FunInd.
+ Functional Scheme minus_ind := Induction for minus Sort Prop.
+ Check minus_ind.
+ Lemma le_minus (n m:nat) : n - m <= n.
+ functional induction (minus n m) using minus_ind; simpl; auto.
+ Qed.
+
+.. note::
+ :n:`(@qualid {+ @term})` must be a correct full application
+ of :n:`@qualid`. In particular, the rules for implicit arguments are the
+ same as usual. For example use :n:`@qualid` if you want to write implicit
+ arguments explicitly.
+
+.. note::
+ Parentheses around :n:`@qualid {+ @term}` are not mandatory and can be skipped.
+
+.. note::
+ :n:`functional induction (f x1 x2 x3)` is actually a wrapper for
+ :n:`induction x1, x2, x3, (f x1 x2 x3) using @qualid` followed by a cleaning
+ phase, where :n:`@qualid` is the induction principle registered for :g:`f`
+ (by the ``Function`` (see :ref:`advanced-recursive-functions`) or
+ ``Functional Scheme`` (see :ref:`functional-scheme`)
+ command) corresponding to the sort of the goal. Therefore
+ ``functional induction`` may fail if the induction scheme :n:`@qualid` is not
+ defined. See also :ref:`advanced-recursive-functions` for the function
+ terms accepted by ``Function``.
+
+.. note::
+ There is a difference between obtaining an induction scheme
+ for a function by using :g:`Function` (see :ref:`advanced-recursive-functions`)
+ and by using :g:`Functional Scheme` after a normal definition using
+ :g:`Fixpoint` or :g:`Definition`. See :ref:`advanced-recursive-functions`
+ for details.
+
+.. seealso:: :ref:`advanced-recursive-functions`, :ref:`functional-scheme` and :tacn:`inversion`
+
+.. exn:: Cannot find induction information on @qualid.
+ :undocumented:
+
+.. exn:: Not the right number of induction arguments.
+ :undocumented:
+
+.. tacv:: functional induction (@qualid {+ @term}) as @simple_intropattern using @term with @bindings_list
+
+ Similarly to :tacn:`induction` and :tacn:`elim`, this allows giving
+ explicitly the name of the introduced variables, the induction principle, and
+ the values of dependent premises of the elimination scheme, including
+ *predicates* for mutual induction when :n:`@qualid` is part of a mutually
+ recursive definition.
+
+.. tacn:: discriminate @term
+ :name: discriminate
+
+ This tactic proves any goal from an assumption stating that two
+ structurally different :n:`@terms` of an inductive set are equal. For
+ example, from :g:`(S (S O))=(S O)` we can derive by absurdity any
+ proposition.
+
+ The argument :n:`@term` is assumed to be a proof of a statement of
+ conclusion :n:`@term = @term` with the two terms being elements of an
+ inductive set. To build the proof, the tactic traverses the normal forms
+ [3]_ of the terms looking for a couple of subterms :g:`u` and :g:`w` (:g:`u`
+ subterm of the normal form of :n:`@term` and :g:`w` subterm of the normal
+ form of :n:`@term`), placed at the same positions and whose head symbols are
+ two different constructors. If such a couple of subterms exists, then the
+ proof of the current goal is completed, otherwise the tactic fails.
+
+.. note::
+ The syntax :n:`discriminate @ident` can be used to refer to a hypothesis
+ quantified in the goal. In this case, the quantified hypothesis whose name is
+ :n:`@ident` is first introduced in the local context using
+ :n:`intros until @ident`.
+
+.. exn:: No primitive equality found.
+ :undocumented:
+
+.. exn:: Not a discriminable equality.
+ :undocumented:
+
+.. tacv:: discriminate @num
+
+ This does the same thing as :n:`intros until @num` followed by
+ :n:`discriminate @ident` where :n:`@ident` is the identifier for the last
+ introduced hypothesis.
+
+.. tacv:: discriminate @term with @bindings_list
+
+ This does the same thing as :n:`discriminate @term` but using the given
+ bindings to instantiate parameters or hypotheses of :n:`@term`.
+
+.. tacv:: ediscriminate @num
+ ediscriminate @term {? with @bindings_list}
+ :name: ediscriminate; _
+
+ This works the same as :tacn:`discriminate` but if the type of :token:`term`, or the
+ type of the hypothesis referred to by :token:`num`, has uninstantiated
+ parameters, these parameters are left as existential variables.
+
+.. tacv:: discriminate
+
+ This behaves like :n:`discriminate @ident` if ident is the name of an
+ hypothesis to which ``discriminate`` is applicable; if the current goal is of
+ the form :n:`@term <> @term`, this behaves as
+ :n:`intro @ident; discriminate @ident`.
+
+ .. exn:: No discriminable equalities.
+ :undocumented:
+
+.. tacn:: injection @term
+ :name: injection
+
+ The injection tactic exploits the property that constructors of
+ inductive types are injective, i.e. that if :g:`c` is a constructor of an
+ inductive type and :g:`c t`:sub:`1` and :g:`c t`:sub:`2` are equal then
+ :g:`t`:sub:`1` and :g:`t`:sub:`2` are equal too.
+
+ If :n:`@term` is a proof of a statement of conclusion :n:`@term = @term`,
+ then :tacn:`injection` applies the injectivity of constructors as deep as
+ possible to derive the equality of all the subterms of :n:`@term` and
+ :n:`@term` at positions where the terms start to differ. For example, from
+ :g:`(S p, S n) = (q, S (S m))` we may derive :g:`S p = q` and
+ :g:`n = S m`. For this tactic to work, the terms should be typed with an
+ inductive type and they should be neither convertible, nor having a different
+ head constructor. If these conditions are satisfied, the tactic derives the
+ equality of all the subterms at positions where they differ and adds them as
+ antecedents to the conclusion of the current goal.
+
+ .. example::
+
+ Consider the following goal:
+
+ .. coqtop:: in
+
+ Inductive list : Set :=
+ | nil : list
+ | cons : nat -> list -> list.
+ Parameter P : list -> Prop.
+ Goal forall l n, P nil -> cons n l = cons 0 nil -> P l.
+
+ .. coqtop:: all
+
+ intros.
+ injection H0.
+
+ Beware that injection yields an equality in a sigma type whenever the
+ injected object has a dependent type :g:`P` with its two instances in
+ different types :g:`(P t`:sub:`1` :g:`... t`:sub:`n` :g:`)` and
+ :g:`(P u`:sub:`1` :g:`... u`:sub:`n` :sub:`)`. If :g:`t`:sub:`1` and
+ :g:`u`:sub:`1` are the same and have for type an inductive type for which a decidable
+ equality has been declared using the command :cmd:`Scheme Equality`
+ (see :ref:`proofschemes-induction-principles`),
+ the use of a sigma type is avoided.
+
+ .. note::
+ If some quantified hypothesis of the goal is named :n:`@ident`,
+ then :n:`injection @ident` first introduces the hypothesis in the local
+ context using :n:`intros until @ident`.
+
+ .. exn:: Not a projectable equality but a discriminable one.
+ :undocumented:
+
+ .. exn:: Nothing to do, it is an equality between convertible terms.
+ :undocumented:
+
+ .. exn:: Not a primitive equality.
+ :undocumented:
+
+ .. exn:: Nothing to inject.
+ :undocumented:
+
+ .. tacv:: injection @num
+
+ This does the same thing as :n:`intros until @num` followed by
+ :n:`injection @ident` where :n:`@ident` is the identifier for the last
+ introduced hypothesis.
+
+ .. tacv:: injection @term with @bindings_list
+
+ This does the same as :n:`injection @term` but using the given bindings to
+ instantiate parameters or hypotheses of :n:`@term`.
+
+ .. tacv:: einjection @num
+ einjection @term {? with @bindings_list}
+ :name: einjection; _
+
+ This works the same as :n:`injection` but if the type of :n:`@term`, or the
+ type of the hypothesis referred to by :n:`@num`, has uninstantiated
+ parameters, these parameters are left as existential variables.
+
+ .. tacv:: injection
+
+ If the current goal is of the form :n:`@term <> @term` , this behaves as
+ :n:`intro @ident; injection @ident`.
+
+ .. exn:: goal does not satisfy the expected preconditions.
+ :undocumented:
+
+ .. tacv:: injection @term {? with @bindings_list} as {+ @simple_intropattern}
+ injection @num as {+ simple_intropattern}
+ injection as {+ simple_intropattern}
+ einjection @term {? with @bindings_list} as {+ simple_intropattern}
+ einjection @num as {+ simple_intropattern}
+ einjection as {+ simple_intropattern}
+
+ These variants apply :n:`intros {+ @simple_intropattern}` after the call to
+ :tacn:`injection` or :tacn:`einjection` so that all equalities generated are moved in
+ the context of hypotheses. The number of :n:`@simple_intropattern` must not exceed
+ the number of equalities newly generated. If it is smaller, fresh
+ names are automatically generated to adjust the list of :n:`@simple_intropattern`
+ to the number of new equalities. The original equality is erased if it
+ corresponds to a hypothesis.
+
+ .. flag:: Structural Injection
+
+ This option ensure that :n:`injection @term` erases the original hypothesis
+ and leaves the generated equalities in the context rather than putting them
+ as antecedents of the current goal, as if giving :n:`injection @term as`
+ (with an empty list of names). This option is off by default.
+
+ .. flag:: Keep Proof Equalities
+
+ By default, :tacn:`injection` only creates new equalities between :n:`@terms`
+ whose type is in sort :g:`Type` or :g:`Set`, thus implementing a special
+ behavior for objects that are proofs of a statement in :g:`Prop`. This option
+ controls this behavior.
+
+.. tacn:: inversion @ident
+ :name: inversion
+
+ Let the type of :n:`@ident` in the local context be :g:`(I t)`, where :g:`I`
+ is a (co)inductive predicate. Then, ``inversion`` applied to :n:`@ident`
+ derives for each possible constructor :g:`c i` of :g:`(I t)`, all the
+ necessary conditions that should hold for the instance :g:`(I t)` to be
+ proved by :g:`c i`.
+
+.. note::
+ If :n:`@ident` does not denote a hypothesis in the local context but
+ refers to a hypothesis quantified in the goal, then the latter is
+ first introduced in the local context using :n:`intros until @ident`.
+
+.. note::
+ As ``inversion`` proofs may be large in size, we recommend the
+ user to stock the lemmas whenever the same instance needs to be
+ inverted several times. See :ref:`derive-inversion`.
+
+.. note::
+ Part of the behavior of the ``inversion`` tactic is to generate
+ equalities between expressions that appeared in the hypothesis that is
+ being processed. By default, no equalities are generated if they
+ relate two proofs (i.e. equalities between :token:`term`\s whose type is in sort
+ :g:`Prop`). This behavior can be turned off by using the
+ :flag:`Keep Proof Equalities` setting.
+
+.. tacv:: inversion @num
+
+ This does the same thing as :n:`intros until @num` then :n:`inversion @ident`
+ where :n:`@ident` is the identifier for the last introduced hypothesis.
+
+.. tacv:: inversion_clear @ident
+ :name: inversion_clear
+
+ This behaves as :n:`inversion` and then erases :n:`@ident` from the context.
+
+.. tacv:: inversion @ident as @or_and_intropattern_loc
+
+ This generally behaves as inversion but using names in :n:`@or_and_intropattern_loc`
+ for naming hypotheses. The :n:`@or_and_intropattern_loc` must have the form
+ :n:`[p`:sub:`11` :n:`... p`:sub:`1n` :n:`| ... | p`:sub:`m1` :n:`... p`:sub:`mn` :n:`]`
+ with `m` being the number of constructors of the type of :n:`@ident`. Be
+ careful that the list must be of length `m` even if ``inversion`` discards
+ some cases (which is precisely one of its roles): for the discarded
+ cases, just use an empty list (i.e. `n = 0`).The arguments of the i-th
+ constructor and the equalities that ``inversion`` introduces in the
+ context of the goal corresponding to the i-th constructor, if it
+ exists, get their names from the list :n:`p`:sub:`i1` :n:`... p`:sub:`in` in
+ order. If there are not enough names, ``inversion`` invents names for the
+ remaining variables to introduce. In case an equation splits into several
+ equations (because ``inversion`` applies ``injection`` on the equalities it
+ generates), the corresponding name :n:`p`:sub:`ij` in the list must be
+ replaced by a sublist of the form :n:`[p`:sub:`ij1` :n:`... p`:sub:`ijq` :n:`]`
+ (or, equivalently, :n:`(p`:sub:`ij1` :n:`, ..., p`:sub:`ijq` :n:`)`) where
+ `q` is the number of subequalities obtained from splitting the original
+ equation. Here is an example. The ``inversion ... as`` variant of
+ ``inversion`` generally behaves in a slightly more expectable way than
+ ``inversion`` (no artificial duplication of some hypotheses referring to
+ other hypotheses). To take benefit of these improvements, it is enough to use
+ ``inversion ... as []``, letting the names being finally chosen by Coq.
+
+ .. example::
+
+ .. coqtop:: reset all
+
+ Inductive contains0 : list nat -> Prop :=
+ | in_hd : forall l, contains0 (0 :: l)
+ | in_tl : forall l b, contains0 l -> contains0 (b :: l).
+ Goal forall l:list nat, contains0 (1 :: l) -> contains0 l.
+ intros l H; inversion H as [ | l' p Hl' [Heqp Heql'] ].
+
+.. tacv:: inversion @num as @or_and_intropattern_loc
+
+ This allows naming the hypotheses introduced by :n:`inversion @num` in the
+ context.
+
+.. tacv:: inversion_clear @ident as @or_and_intropattern_loc
+
+ This allows naming the hypotheses introduced by ``inversion_clear`` in the
+ context. Notice that hypothesis names can be provided as if ``inversion``
+ were called, even though the ``inversion_clear`` will eventually erase the
+ hypotheses.
+
+.. tacv:: inversion @ident in {+ @ident}
+
+ Let :n:`{+ @ident}` be identifiers in the local context. This tactic behaves as
+ generalizing :n:`{+ @ident}`, and then performing ``inversion``.
+
+.. tacv:: inversion @ident as @or_and_intropattern_loc in {+ @ident}
+
+ This allows naming the hypotheses introduced in the context by
+ :n:`inversion @ident in {+ @ident}`.
+
+.. tacv:: inversion_clear @ident in {+ @ident}
+
+ Let :n:`{+ @ident}` be identifiers in the local context. This tactic behaves
+ as generalizing :n:`{+ @ident}`, and then performing ``inversion_clear``.
+
+.. tacv:: inversion_clear @ident as @or_and_intropattern_loc in {+ @ident}
+
+ This allows naming the hypotheses introduced in the context by
+ :n:`inversion_clear @ident in {+ @ident}`.
+
+.. tacv:: dependent inversion @ident
+ :name: dependent inversion
+
+ That must be used when :n:`@ident` appears in the current goal. It acts like
+ ``inversion`` and then substitutes :n:`@ident` for the corresponding
+ :n:`@@term` in the goal.
+
+.. tacv:: dependent inversion @ident as @or_and_intropattern_loc
+
+ This allows naming the hypotheses introduced in the context by
+ :n:`dependent inversion @ident`.
+
+.. tacv:: dependent inversion_clear @ident
+
+ Like ``dependent inversion``, except that :n:`@ident` is cleared from the
+ local context.
+
+.. tacv:: dependent inversion_clear @ident as @or_and_intropattern_loc
+
+ This allows naming the hypotheses introduced in the context by
+ :n:`dependent inversion_clear @ident`.
+
+.. tacv:: dependent inversion @ident with @term
+ :name: dependent inversion ... with ...
+
+ This variant allows you to specify the generalization of the goal. It is
+ useful when the system fails to generalize the goal automatically. If
+ :n:`@ident` has type :g:`(I t)` and :g:`I` has type :g:`forall (x:T), s`,
+ then :n:`@term` must be of type :g:`I:forall (x:T), I x -> s'` where
+ :g:`s'` is the type of the goal.
+
+.. tacv:: dependent inversion @ident as @or_and_intropattern_loc with @term
+
+ This allows naming the hypotheses introduced in the context by
+ :n:`dependent inversion @ident with @term`.
+
+.. tacv:: dependent inversion_clear @ident with @term
+
+ Like :tacn:`dependent inversion ... with ...` with but clears :n:`@ident` from the
+ local context.
+
+.. tacv:: dependent inversion_clear @ident as @or_and_intropattern_loc with @term
+
+ This allows naming the hypotheses introduced in the context by
+ :n:`dependent inversion_clear @ident with @term`.
+
+.. tacv:: simple inversion @ident
+ :name: simple inversion
+
+ It is a very primitive inversion tactic that derives all the necessary
+ equalities but it does not simplify the constraints as ``inversion`` does.
+
+.. tacv:: simple inversion @ident as @or_and_intropattern_loc
+
+ This allows naming the hypotheses introduced in the context by
+ ``simple inversion``.
+
+.. tacv:: inversion @ident using @ident
+ :name: inversion ... using ...
+
+ Let :n:`@ident` have type :g:`(I t)` (:g:`I` an inductive predicate) in the
+ local context, and :n:`@ident` be a (dependent) inversion lemma. Then, this
+ tactic refines the current goal with the specified lemma.
+
+.. tacv:: inversion @ident using @ident in {+ @ident}
+
+ This tactic behaves as generalizing :n:`{+ @ident}`, then doing
+ :n:`inversion @ident using @ident`.
+
+.. tacv:: inversion_sigma
+ :name: inversion_sigma
+
+ This tactic turns equalities of dependent pairs (e.g.,
+ :g:`existT P x p = existT P y q`, frequently left over by inversion on
+ a dependent type family) into pairs of equalities (e.g., a hypothesis
+ :g:`H : x = y` and a hypothesis of type :g:`rew H in p = q`); these
+ hypotheses can subsequently be simplified using :tacn:`subst`, without ever
+ invoking any kind of axiom asserting uniqueness of identity proofs. If you
+ want to explicitly specify the hypothesis to be inverted, or name the
+ generated hypotheses, you can invoke
+ :n:`induction H as [H1 H2] using eq_sigT_rect.` This tactic also works for
+ :g:`sig`, :g:`sigT2`, and :g:`sig2`, and there are similar :g:`eq_sig`
+ :g:`***_rect` induction lemmas.
+
+.. example::
+
+ *Non-dependent inversion*.
+
+ Let us consider the relation :g:`Le` over natural numbers:
+
+ .. coqtop:: reset in
+
+ Inductive Le : nat -> nat -> Set :=
+ | LeO : forall n:nat, Le 0 n
+ | LeS : forall n m:nat, Le n m -> Le (S n) (S m).
+
+
+ Let us consider the following goal:
+
+ .. coqtop:: none
+
+ Section Section.
+ Variable P : nat -> nat -> Prop.
+ Variable Q : forall n m:nat, Le n m -> Prop.
+ Goal forall n m, Le (S n) m -> P n m.
+
+ .. coqtop:: out
+
+ intros.
+
+ To prove the goal, we may need to reason by cases on :g:`H` and to derive
+ that :g:`m` is necessarily of the form :g:`(S m0)` for certain :g:`m0` and that
+ :g:`(Le n m0)`. Deriving these conditions corresponds to proving that the only
+ possible constructor of :g:`(Le (S n) m)` is :g:`LeS` and that we can invert
+ the arrow in the type of :g:`LeS`. This inversion is possible because :g:`Le`
+ is the smallest set closed by the constructors :g:`LeO` and :g:`LeS`.
+
+ .. coqtop:: all
+
+ inversion_clear H.
+
+ Note that :g:`m` has been substituted in the goal for :g:`(S m0)` and that the
+ hypothesis :g:`(Le n m0)` has been added to the context.
+
+ Sometimes it is interesting to have the equality :g:`m = (S m0)` in the
+ context to use it after. In that case we can use :tacn:`inversion` that does
+ not clear the equalities:
+
+ .. coqtop:: none restart
+
+ intros.
+
+ .. coqtop:: all
+
+ inversion H.
+
+.. example::
+
+ *Dependent inversion.*
+
+ Let us consider the following goal:
+
+ .. coqtop:: none
+
+ Abort.
+ Goal forall n m (H:Le (S n) m), Q (S n) m H.
+
+ .. coqtop:: out
+
+ intros.
+
+ As :g:`H` occurs in the goal, we may want to reason by cases on its
+ structure and so, we would like inversion tactics to substitute :g:`H` by
+ the corresponding @term in constructor form. Neither :tacn:`inversion` nor
+ :tacn:`inversion_clear` do such a substitution. To have such a behavior we
+ use the dependent inversion tactics:
+
+ .. coqtop:: all
+
+ dependent inversion_clear H.
+
+ Note that :g:`H` has been substituted by :g:`(LeS n m0 l)` and :g:`m` by :g:`(S m0)`.
+
+.. example::
+
+ *Using inversion_sigma.*
+
+ Let us consider the following inductive type of
+ length-indexed lists, and a lemma about inverting equality of cons:
+
+ .. coqtop:: reset all
+
+ Require Import Coq.Logic.Eqdep_dec.
+
+ Inductive vec A : nat -> Type :=
+ | nil : vec A O
+ | cons {n} (x : A) (xs : vec A n) : vec A (S n).
+
+ Lemma invert_cons : forall A n x xs y ys,
+ @cons A n x xs = @cons A n y ys
+ -> xs = ys.
+
+ Proof.
+ intros A n x xs y ys H.
+
+ After performing inversion, we are left with an equality of existTs:
+
+ .. coqtop:: all
+
+ inversion H.
+
+ We can turn this equality into a usable form with inversion_sigma:
+
+ .. coqtop:: all
+
+ inversion_sigma.
+
+ To finish cleaning up the proof, we will need to use the fact that
+ that all proofs of n = n for n a nat are eq_refl:
+
+ .. coqtop:: all
+
+ let H := match goal with H : n = n |- _ => H end in
+ pose proof (Eqdep_dec.UIP_refl_nat _ H); subst H.
+ simpl in *.
+
+ Finally, we can finish the proof:
+
+ .. coqtop:: all
+
+ assumption.
+ Qed.
+
+.. tacn:: fix @ident @num
+ :name: fix
+
+ This tactic is a primitive tactic to start a proof by induction. In
+ general, it is easier to rely on higher-level induction tactics such
+ as the ones described in :tacn:`induction`.
+
+ In the syntax of the tactic, the identifier :n:`@ident` is the name given to
+ the induction hypothesis. The natural number :n:`@num` tells on which
+ premise of the current goal the induction acts, starting from 1,
+ counting both dependent and non dependent products, but skipping local
+ definitions. Especially, the current lemma must be composed of at
+ least :n:`@num` products.
+
+ Like in a fix expression, the induction hypotheses have to be used on
+ structurally smaller arguments. The verification that inductive proof
+ arguments are correct is done only at the time of registering the
+ lemma in the environment. To know if the use of induction hypotheses
+ is correct at some time of the interactive development of a proof, use
+ the command ``Guarded`` (see Section :ref:`requestinginformation`).
+
+.. tacv:: fix @ident @num with {+ (ident {+ @binder} [{struct @ident}] : @type)}
+
+ This starts a proof by mutual induction. The statements to be simultaneously
+ proved are respectively :g:`forall binder ... binder, type`.
+ The identifiers :n:`@ident` are the names of the induction hypotheses. The identifiers
+ :n:`@ident` are the respective names of the premises on which the induction
+ is performed in the statements to be simultaneously proved (if not given, the
+ system tries to guess itself what they are).
+
+.. tacn:: cofix @ident
+ :name: cofix
+
+ This tactic starts a proof by coinduction. The identifier :n:`@ident` is the
+ name given to the coinduction hypothesis. Like in a cofix expression,
+ the use of induction hypotheses have to guarded by a constructor. The
+ verification that the use of co-inductive hypotheses is correct is
+ done only at the time of registering the lemma in the environment. To
+ know if the use of coinduction hypotheses is correct at some time of
+ the interactive development of a proof, use the command ``Guarded``
+ (see Section :ref:`requestinginformation`).
+
+.. tacv:: cofix @ident with {+ (@ident {+ @binder} : @type)}
+
+ This starts a proof by mutual coinduction. The statements to be
+ simultaneously proved are respectively :g:`forall binder ... binder, type`
+ The identifiers :n:`@ident` are the names of the coinduction hypotheses.
+
+.. _rewritingexpressions:
+
+Rewriting expressions
+---------------------
+
+These tactics use the equality :g:`eq:forall A:Type, A->A->Prop` defined in
+file ``Logic.v`` (see :ref:`coq-library-logic`). The notation for :g:`eq T t u` is
+simply :g:`t=u` dropping the implicit type of :g:`t` and :g:`u`.
+
+.. tacn:: rewrite @term
+ :name: rewrite
+
+ This tactic applies to any goal. The type of :token:`term` must have the form
+
+ ``forall (x``:sub:`1` ``:A``:sub:`1` ``) ... (x``:sub:`n` ``:A``:sub:`n` ``). eq term``:sub:`1` ``term``:sub:`2` ``.``
+
+ where :g:`eq` is the Leibniz equality or a registered setoid equality.
+
+ Then :n:`rewrite @term` finds the first subterm matching `term`\ :sub:`1` in the goal,
+ resulting in instances `term`:sub:`1`' and `term`:sub:`2`' and then
+ replaces every occurrence of `term`:subscript:`1`' by `term`:subscript:`2`'.
+ Hence, some of the variables :g:`x`\ :sub:`i` are solved by unification,
+ and some of the types :g:`A`\ :sub:`1`:g:`, ..., A`\ :sub:`n` become new
+ subgoals.
+
+ .. exn:: The @term provided does not end with an equation.
+ :undocumented:
+
+ .. exn:: Tactic generated a subgoal identical to the original goal. This happens if @term does not occur in the goal.
+ :undocumented:
+
+ .. tacv:: rewrite -> @term
+
+ Is equivalent to :n:`rewrite @term`
+
+ .. tacv:: rewrite <- @term
+
+ Uses the equality :n:`@term`:sub:`1` :n:`= @term` :sub:`2` from right to left
+
+ .. tacv:: rewrite @term in clause
+
+ Analogous to :n:`rewrite @term` but rewriting is done following clause
+ (similarly to :ref:`performing computations <performingcomputations>`). For instance:
+
+ + :n:`rewrite H in H`:sub:`1` will rewrite `H` in the hypothesis
+ `H`:sub:`1` instead of the current goal.
+ + :n:`rewrite H in H`:sub:`1` :g:`at 1, H`:sub:`2` :g:`at - 2 |- *` means
+ :n:`rewrite H; rewrite H in H`:sub:`1` :g:`at 1; rewrite H in H`:sub:`2` :g:`at - 2.`
+ In particular a failure will happen if any of these three simpler tactics
+ fails.
+ + :n:`rewrite H in * |-` will do :n:`rewrite H in H`:sub:`i` for all hypotheses
+ :g:`H`:sub:`i` different from :g:`H`.
+ A success will happen as soon as at least one of these simpler tactics succeeds.
+ + :n:`rewrite H in *` is a combination of :n:`rewrite H` and :n:`rewrite H in * |-`
+ that succeeds if at least one of these two tactics succeeds.
+
+ Orientation :g:`->` or :g:`<-` can be inserted before the :token:`term` to rewrite.
+
+ .. tacv:: rewrite @term at occurrences
+
+ Rewrite only the given occurrences of :token:`term`. Occurrences are
+ specified from left to right as for pattern (:tacn:`pattern`). The rewrite is
+ always performed using setoid rewriting, even for Leibniz’s equality, so one
+ has to ``Import Setoid`` to use this variant.
+
+ .. tacv:: rewrite @term by tactic
+
+ Use tactic to completely solve the side-conditions arising from the
+ :tacn:`rewrite`.
+
+ .. tacv:: rewrite {+, @term}
+
+ Is equivalent to the `n` successive tactics :n:`{+; rewrite @term}`, each one
+ working on the first subgoal generated by the previous one. Orientation
+ :g:`->` or :g:`<-` can be inserted before each :token:`term` to rewrite. One
+ unique clause can be added at the end after the keyword in; it will then
+ affect all rewrite operations.
+
+ In all forms of rewrite described above, a :token:`term` to rewrite can be
+ immediately prefixed by one of the following modifiers:
+
+ + `?` : the tactic :n:`rewrite ?@term` performs the rewrite of :token:`term` as many
+ times as possible (perhaps zero time). This form never fails.
+ + :n:`@num?` : works similarly, except that it will do at most :token:`num` rewrites.
+ + `!` : works as `?`, except that at least one rewrite should succeed, otherwise
+ the tactic fails.
+ + :n:`@num!` (or simply :n:`@num`) : precisely :token:`num` rewrites of :token:`term` will be done,
+ leading to failure if these :token:`num` rewrites are not possible.
+
+ .. tacv:: erewrite @term
+ :name: erewrite
+
+ This tactic works as :n:`rewrite @term` but turning
+ unresolved bindings into existential variables, if any, instead of
+ failing. It has the same variants as :tacn:`rewrite` has.
+
+ .. flag:: Keyed Unification
+
+ Makes higher-order unification used by :tacn:`rewrite` rely on a set of keys to drive
+ unification. The subterms, considered as rewriting candidates, must start with
+ the same key as the left- or right-hand side of the lemma given to rewrite, and the arguments
+ are then unified up to full reduction.
+
+.. tacn:: replace @term with @term’
+ :name: replace
+
+ This tactic applies to any goal. It replaces all free occurrences of :n:`@term`
+ in the current goal with :n:`@term’` and generates an equality :n:`@term = @term’`
+ as a subgoal. This equality is automatically solved if it occurs among
+ the assumptions, or if its symmetric form occurs. It is equivalent to
+ :n:`cut @term = @term’; [intro H`:sub:`n` :n:`; rewrite <- H`:sub:`n` :n:`; clear H`:sub:`n`:n:`|| assumption || symmetry; try assumption]`.
+
+ .. exn:: Terms do not have convertible types.
+ :undocumented:
+
+ .. tacv:: replace @term with @term’ by @tactic
+
+ This acts as :n:`replace @term with @term’` but applies :token:`tactic` to solve the generated
+ subgoal :n:`@term = @term’`.
+
+ .. tacv:: replace @term
+
+ Replaces :n:`@term` with :n:`@term’` using the first assumption whose type has
+ the form :n:`@term = @term’` or :n:`@term’ = @term`.
+
+ .. tacv:: replace -> @term
+
+ Replaces :n:`@term` with :n:`@term’` using the first assumption whose type has
+ the form :n:`@term = @term’`
+
+ .. tacv:: replace <- @term
+
+ Replaces :n:`@term` with :n:`@term’` using the first assumption whose type has
+ the form :n:`@term’ = @term`
+
+ .. tacv:: replace @term {? with @term} in clause {? by @tactic}
+ replace -> @term in clause
+ replace <- @term in clause
+
+ Acts as before but the replacements take place in the specified clause (see
+ :ref:`performingcomputations`) and not only in the conclusion of the goal. The
+ clause argument must not contain any ``type of`` nor ``value of``.
+
+ .. tacv:: cutrewrite <- (@term = @term’)
+ :name: cutrewrite
+
+ This tactic is deprecated. It can be replaced by :n:`enough (@term = @term’) as <-`.
+
+ .. tacv:: cutrewrite -> (@term = @term’)
+
+ This tactic is deprecated. It can be replaced by :n:`enough (@term = @term’) as ->`.
+
+
+.. tacn:: subst @ident
+ :name: subst
+
+ This tactic applies to a goal that has :n:`@ident` in its context and (at
+ least) one hypothesis, say :g:`H`, of type :n:`@ident = t` or :n:`t = @ident`
+ with :n:`@ident` not occurring in :g:`t`. Then it replaces :n:`@ident` by
+ :g:`t` everywhere in the goal (in the hypotheses and in the conclusion) and
+ clears :n:`@ident` and :g:`H` from the context.
+
+ If :n:`@ident` is a local definition of the form :n:`@ident := t`, it is also
+ unfolded and cleared.
+
+ .. note::
+ + When several hypotheses have the form :n:`@ident = t` or :n:`t = @ident`, the
+ first one is used.
+
+ + If :g:`H` is itself dependent in the goal, it is replaced by the proof of
+ reflexivity of equality.
+
+ .. tacv:: subst {+ @ident}
+
+ This is equivalent to :n:`subst @ident`:sub:`1`:n:`; ...; subst @ident`:sub:`n`.
+
+ .. tacv:: subst
+
+ This applies subst repeatedly from top to bottom to all identifiers of the
+ context for which an equality of the form :n:`@ident = t` or :n:`t = @ident`
+ or :n:`@ident := t` exists, with :n:`@ident` not occurring in ``t``.
+
+ .. flag:: Regular Subst Tactic
+
+ This option controls the behavior of :tacn:`subst`. When it is
+ activated (it is by default), :tacn:`subst` also deals with the following corner cases:
+
+ + A context with ordered hypotheses :n:`@ident`:sub:`1` :n:`= @ident`:sub:`2`
+ and :n:`@ident`:sub:`1` :n:`= t`, or :n:`t′ = @ident`:sub:`1`` with `t′` not
+ a variable, and no other hypotheses of the form :n:`@ident`:sub:`2` :n:`= u`
+ or :n:`u = @ident`:sub:`2`; without the option, a second call to
+ subst would be necessary to replace :n:`@ident`:sub:`2` by `t` or
+ `t′` respectively.
+ + The presence of a recursive equation which without the option would
+ be a cause of failure of :tacn:`subst`.
+ + A context with cyclic dependencies as with hypotheses :n:`@ident`:sub:`1` :n:`= f @ident`:sub:`2`
+ and :n:`@ident`:sub:`2` :n:`= g @ident`:sub:`1` which without the
+ option would be a cause of failure of :tacn:`subst`.
+
+ Additionally, it prevents a local definition such as :n:`@ident := t` to be
+ unfolded which otherwise it would exceptionally unfold in configurations
+ containing hypotheses of the form :n:`@ident = u`, or :n:`u′ = @ident`
+ with `u′` not a variable. Finally, it preserves the initial order of
+ hypotheses, which without the option it may break.
+ default.
+
+
+.. tacn:: stepl @term
+ :name: stepl
+
+ This tactic is for chaining rewriting steps. It assumes a goal of the
+ form :n:`R @term @term` where ``R`` is a binary relation and relies on a
+ database of lemmas of the form :g:`forall x y z, R x y -> eq x z -> R z y`
+ where `eq` is typically a setoid equality. The application of :n:`stepl @term`
+ then replaces the goal by :n:`R @term @term` and adds a new goal stating
+ :n:`eq @term @term`.
+
+ .. cmd:: Declare Left Step @term
+
+ Adds :n:`@term` to the database used by :tacn:`stepl`.
+
+ This tactic is especially useful for parametric setoids which are not accepted
+ as regular setoids for :tacn:`rewrite` and :tacn:`setoid_replace` (see
+ :ref:`Generalizedrewriting`).
+
+ .. tacv:: stepl @term by @tactic
+
+ This applies :n:`stepl @term` then applies :token:`tactic` to the second goal.
+
+ .. tacv:: stepr @term stepr @term by tactic
+ :name: stepr
+
+ This behaves as :tacn:`stepl` but on the right-hand-side of the binary
+ relation. Lemmas are expected to be of the form
+ :g:`forall x y z, R x y -> eq y z -> R x z`.
+
+ .. cmd:: Declare Right Step @term
+
+ Adds :n:`@term` to the database used by :tacn:`stepr`.
+
+
+.. tacn:: change @term
+ :name: change
+
+ This tactic applies to any goal. It implements the rule ``Conv`` given in
+ :ref:`subtyping-rules`. :g:`change U` replaces the current goal `T`
+ with `U` providing that `U` is well-formed and that `T` and `U` are
+ convertible.
+
+ .. exn:: Not convertible.
+ :undocumented:
+
+ .. tacv:: change @term with @term’
+
+ This replaces the occurrences of :n:`@term` by :n:`@term’` in the current goal.
+ The term :n:`@term` and :n:`@term’` must be convertible.
+
+ .. tacv:: change @term at {+ @num} with @term’
+
+ This replaces the occurrences numbered :n:`{+ @num}` of :n:`@term` by :n:`@term’`
+ in the current goal. The terms :n:`@term` and :n:`@term’` must be convertible.
+
+ .. exn:: Too few occurrences.
+ :undocumented:
+
+ .. tacv:: change @term {? {? at {+ @num}} with @term} in @ident
+
+ This applies the :tacn:`change` tactic not to the goal but to the hypothesis :n:`@ident`.
+
+ .. tacv:: now_show @term
+
+ This is a synonym of :n:`change @term`. It can be used to
+ make some proof steps explicit when refactoring a proof script
+ to make it readable.
+
+ .. seealso:: :ref:`Performing computations <performingcomputations>`
+
+.. _performingcomputations:
+
+Performing computations
+---------------------------
+
+This set of tactics implements different specialized usages of the
+tactic :tacn:`change`.
+
+All conversion tactics (including :tacn:`change`) can be parameterized by the
+parts of the goal where the conversion can occur. This is done using
+*goal clauses* which consists in a list of hypotheses and, optionally,
+of a reference to the conclusion of the goal. For defined hypothesis
+it is possible to specify if the conversion should occur on the type
+part, the body part or both (default).
+
+Goal clauses are written after a conversion tactic (tactics :tacn:`set`,
+:tacn:`rewrite`, :tacn:`replace` and :tacn:`autorewrite` also use goal
+clauses) and are introduced by the keyword `in`. If no goal clause is
+provided, the default is to perform the conversion only in the
+conclusion.
+
+The syntax and description of the various goal clauses is the
+following:
+
++ :n:`in {+ @ident} |-` only in hypotheses :n:`{+ @ident}`
++ :n:`in {+ @ident} |- *` in hypotheses :n:`{+ @ident}` and in the
+ conclusion
++ :n:`in * |-` in every hypothesis
++ :n:`in *` (equivalent to in :n:`* |- *`) everywhere
++ :n:`in (type of @ident) (value of @ident) ... |-` in type part of
+ :n:`@ident`, in the value part of :n:`@ident`, etc.
+
+For backward compatibility, the notation :n:`in {+ @ident}` performs
+the conversion in hypotheses :n:`{+ @ident}`.
+
+.. tacn:: cbv {* @flag}
+ lazy {* @flag}
+ :name: cbv; lazy
+
+ These parameterized reduction tactics apply to any goal and perform
+ the normalization of the goal according to the specified flags. In
+ correspondence with the kinds of reduction considered in Coq namely
+ :math:`\beta` (reduction of functional application), :math:`\delta`
+ (unfolding of transparent constants, see :ref:`vernac-controlling-the-reduction-strategies`),
+ :math:`\iota` (reduction of
+ pattern matching over a constructed term, and unfolding of :g:`fix` and
+ :g:`cofix` expressions) and :math:`\zeta` (contraction of local definitions), the
+ flags are either ``beta``, ``delta``, ``match``, ``fix``, ``cofix``,
+ ``iota`` or ``zeta``. The ``iota`` flag is a shorthand for ``match``, ``fix``
+ and ``cofix``. The ``delta`` flag itself can be refined into
+ :n:`delta {+ @qualid}` or :n:`delta -{+ @qualid}`, restricting in the first
+ case the constants to unfold to the constants listed, and restricting in the
+ second case the constant to unfold to all but the ones explicitly mentioned.
+ Notice that the ``delta`` flag does not apply to variables bound by a let-in
+ construction inside the :n:`@term` itself (use here the ``zeta`` flag). In
+ any cases, opaque constants are not unfolded (see :ref:`vernac-controlling-the-reduction-strategies`).
+
+ Normalization according to the flags is done by first evaluating the
+ head of the expression into a *weak-head* normal form, i.e. until the
+ evaluation is blocked by a variable (or an opaque constant, or an
+ axiom), as e.g. in :g:`x u1 ... un` , or :g:`match x with ... end`, or
+ :g:`(fix f x {struct x} := ...) x`, or is a constructed form (a
+ :math:`\lambda`-expression, a constructor, a cofixpoint, an inductive type, a
+ product type, a sort), or is a redex that the flags prevent to reduce. Once a
+ weak-head normal form is obtained, subterms are recursively reduced using the
+ same strategy.
+
+ Reduction to weak-head normal form can be done using two strategies:
+ *lazy* (``lazy`` tactic), or *call-by-value* (``cbv`` tactic). The lazy
+ strategy is a call-by-need strategy, with sharing of reductions: the
+ arguments of a function call are weakly evaluated only when necessary,
+ and if an argument is used several times then it is weakly computed
+ only once. This reduction is efficient for reducing expressions with
+ dead code. For instance, the proofs of a proposition :g:`exists x. P(x)`
+ reduce to a pair of a witness :g:`t`, and a proof that :g:`t` satisfies the
+ predicate :g:`P`. Most of the time, :g:`t` may be computed without computing
+ the proof of :g:`P(t)`, thanks to the lazy strategy.
+
+ The call-by-value strategy is the one used in ML languages: the
+ arguments of a function call are systematically weakly evaluated
+ first. Despite the lazy strategy always performs fewer reductions than
+ the call-by-value strategy, the latter is generally more efficient for
+ evaluating purely computational expressions (i.e. with little dead code).
+
+.. tacv:: compute
+ cbv
+ :name: compute; _
+
+ These are synonyms for ``cbv beta delta iota zeta``.
+
+.. tacv:: lazy
+
+ This is a synonym for ``lazy beta delta iota zeta``.
+
+.. tacv:: compute {+ @qualid}
+ cbv {+ @qualid}
+
+ These are synonyms of :n:`cbv beta delta {+ @qualid} iota zeta`.
+
+.. tacv:: compute -{+ @qualid}
+ cbv -{+ @qualid}
+
+ These are synonyms of :n:`cbv beta delta -{+ @qualid} iota zeta`.
+
+.. tacv:: lazy {+ @qualid}
+ lazy -{+ @qualid}
+
+ These are respectively synonyms of :n:`lazy beta delta {+ @qualid} iota zeta`
+ and :n:`lazy beta delta -{+ @qualid} iota zeta`.
+
+.. tacv:: vm_compute
+ :name: vm_compute
+
+ This tactic evaluates the goal using the optimized call-by-value evaluation
+ bytecode-based virtual machine described in :cite:`CompiledStrongReduction`.
+ This algorithm is dramatically more efficient than the algorithm used for the
+ ``cbv`` tactic, but it cannot be fine-tuned. It is specially interesting for
+ full evaluation of algebraic objects. This includes the case of
+ reflection-based tactics.
+
+.. tacv:: native_compute
+ :name: native_compute
+
+ This tactic evaluates the goal by compilation to Objective Caml as described
+ in :cite:`FullReduction`. If Coq is running in native code, it can be
+ typically two to five times faster than ``vm_compute``. Note however that the
+ compilation cost is higher, so it is worth using only for intensive
+ computations.
+
+ .. flag:: NativeCompute Profiling
+
+ On Linux, if you have the ``perf`` profiler installed, this option makes
+ it possible to profile ``native_compute`` evaluations.
+
+ .. opt:: NativeCompute Profile Filename @string
+ :name: NativeCompute Profile Filename
+
+ This option specifies the profile output; the default is
+ ``native_compute_profile.data``. The actual filename used
+ will contain extra characters to avoid overwriting an existing file; that
+ filename is reported to the user.
+ That means you can individually profile multiple uses of
+ ``native_compute`` in a script. From the Linux command line, run ``perf report``
+ on the profile file to see the results. Consult the ``perf`` documentation
+ for more details.
+
+.. flag:: Debug Cbv
+
+ This option makes :tacn:`cbv` (and its derivative :tacn:`compute`) print
+ information about the constants it encounters and the unfolding decisions it
+ makes.
+
+.. tacn:: red
+ :name: red
+
+ This tactic applies to a goal that has the form::
+
+ forall (x:T1) ... (xk:Tk), T
+
+ with :g:`T` :math:`\beta`:math:`\iota`:math:`\zeta`-reducing to :g:`c t`:sub:`1` :g:`... t`:sub:`n` and :g:`c` a
+ constant. If :g:`c` is transparent then it replaces :g:`c` with its
+ definition (say :g:`t`) and then reduces
+ :g:`(t t`:sub:`1` :g:`... t`:sub:`n` :g:`)` according to :math:`\beta`:math:`\iota`:math:`\zeta`-reduction rules.
+
+.. exn:: Not reducible.
+ :undocumented:
+
+.. exn:: No head constant to reduce.
+ :undocumented:
+
+.. tacn:: hnf
+ :name: hnf
+
+ This tactic applies to any goal. It replaces the current goal with its
+ head normal form according to the :math:`\beta`:math:`\delta`:math:`\iota`:math:`\zeta`-reduction rules, i.e. it
+ reduces the head of the goal until it becomes a product or an
+ irreducible term. All inner :math:`\beta`:math:`\iota`-redexes are also reduced.
+
+ Example: The term :g:`fun n : nat => S n + S n` is not reduced by :n:`hnf`.
+
+.. note::
+ The :math:`\delta` rule only applies to transparent constants (see :ref:`vernac-controlling-the-reduction-strategies`
+ on transparency and opacity).
+
+.. tacn:: cbn
+ simpl
+ :name: cbn; simpl
+
+ These tactics apply to any goal. They try to reduce a term to
+ something still readable instead of fully normalizing it. They perform
+ a sort of strong normalization with two key differences:
+
+ + They unfold a constant if and only if it leads to a :math:`\iota`-reduction,
+ i.e. reducing a match or unfolding a fixpoint.
+ + While reducing a constant unfolding to (co)fixpoints, the tactics
+ use the name of the constant the (co)fixpoint comes from instead of
+ the (co)fixpoint definition in recursive calls.
+
+ The ``cbn`` tactic is claimed to be a more principled, faster and more
+ predictable replacement for ``simpl``.
+
+ The ``cbn`` tactic accepts the same flags as ``cbv`` and ``lazy``. The
+ behavior of both ``simpl`` and ``cbn`` can be tuned using the
+ Arguments vernacular command as follows:
+
+ + A constant can be marked to be never unfolded by ``cbn`` or ``simpl``:
+
+ .. example::
+
+ .. coqtop:: all
+
+ Arguments minus n m : simpl never.
+
+ After that command an expression like :g:`(minus (S x) y)` is left
+ untouched by the tactics ``cbn`` and ``simpl``.
+
+ + A constant can be marked to be unfolded only if applied to enough
+ arguments. The number of arguments required can be specified using the
+ ``/`` symbol in the argument list of the :cmd:`Arguments` vernacular command.
+
+ .. example::
+
+ .. coqtop:: all
+
+ Definition fcomp A B C f (g : A -> B) (x : A) : C := f (g x).
+ Arguments fcomp {A B C} f g x /.
+ Notation "f \o g" := (fcomp f g) (at level 50).
+
+ After that command the expression :g:`(f \o g)` is left untouched by
+ ``simpl`` while :g:`((f \o g) t)` is reduced to :g:`(f (g t))`.
+ The same mechanism can be used to make a constant volatile, i.e.
+ always unfolded.
+
+ .. example::
+
+ .. coqtop:: all
+
+ Definition volatile := fun x : nat => x.
+ Arguments volatile / x.
+
+ + A constant can be marked to be unfolded only if an entire set of
+ arguments evaluates to a constructor. The ``!`` symbol can be used to mark
+ such arguments.
+
+ .. example::
+
+ .. coqtop:: all
+
+ Arguments minus !n !m.
+
+ After that command, the expression :g:`(minus (S x) y)` is left untouched
+ by ``simpl``, while :g:`(minus (S x) (S y))` is reduced to :g:`(minus x y)`.
+
+ + A special heuristic to determine if a constant has to be unfolded
+ can be activated with the following command:
+
+ .. example::
+
+ .. coqtop:: all
+
+ Arguments minus n m : simpl nomatch.
+
+ The heuristic avoids to perform a simplification step that would expose a
+ match construct in head position. For example the expression
+ :g:`(minus (S (S x)) (S y))` is simplified to :g:`(minus (S x) y)`
+ even if an extra simplification is possible.
+
+ In detail, the tactic ``simpl`` first applies :math:`\beta`:math:`\iota`-reduction. Then, it
+ expands transparent constants and tries to reduce further using :math:`\beta`:math:`\iota`-
+ reduction. But, when no :math:`\iota` rule is applied after unfolding then
+ :math:`\delta`-reductions are not applied. For instance trying to use ``simpl`` on
+ :g:`(plus n O) = n` changes nothing.
+
+ Notice that only transparent constants whose name can be reused in the
+ recursive calls are possibly unfolded by ``simpl``. For instance a
+ constant defined by :g:`plus' := plus` is possibly unfolded and reused in
+ the recursive calls, but a constant such as :g:`succ := plus (S O)` is
+ never unfolded. This is the main difference between ``simpl`` and ``cbn``.
+ The tactic ``cbn`` reduces whenever it will be able to reuse it or not:
+ :g:`succ t` is reduced to :g:`S t`.
+
+.. tacv:: cbn {+ @qualid}
+ cbn -{+ @qualid}
+
+ These are respectively synonyms of :n:`cbn beta delta {+ @qualid} iota zeta`
+ and :n:`cbn beta delta -{+ @qualid} iota zeta` (see :tacn:`cbn`).
+
+.. tacv:: simpl @pattern
+
+ This applies ``simpl`` only to the subterms matching :n:`@pattern` in the
+ current goal.
+
+.. tacv:: simpl @pattern at {+ @num}
+
+ This applies ``simpl`` only to the :n:`{+ @num}` occurrences of the subterms
+ matching :n:`@pattern` in the current goal.
+
+ .. exn:: Too few occurrences.
+ :undocumented:
+
+.. tacv:: simpl @qualid
+ simpl @string
+
+ This applies :tacn:`simpl` only to the applicative subterms whose head occurrence
+ is the unfoldable constant :n:`@qualid` (the constant can be referred to by
+ its notation using :n:`@string` if such a notation exists).
+
+.. tacv:: simpl @qualid at {+ @num}
+ simpl @string at {+ @num}
+
+ This applies ``simpl`` only to the :n:`{+ @num}` applicative subterms whose
+ head occurrence is :n:`@qualid` (or :n:`@string`).
+
+.. flag:: Debug RAKAM
+
+ This option makes :tacn:`cbn` print various debugging information.
+ ``RAKAM`` is the Refolding Algebraic Krivine Abstract Machine.
+
+.. tacn:: unfold @qualid
+ :name: unfold
+
+ This tactic applies to any goal. The argument qualid must denote a
+ defined transparent constant or local definition (see
+ :ref:`gallina-definitions` and :ref:`vernac-controlling-the-reduction-strategies`). The tactic
+ ``unfold`` applies the :math:`\delta` rule to each occurrence of the constant to which
+ :n:`@qualid` refers in the current goal and then replaces it with its
+ :math:`\beta`:math:`\iota`-normal form.
+
+.. exn:: @qualid does not denote an evaluable constant.
+ :undocumented:
+
+.. tacv:: unfold @qualid in @ident
+
+ Replaces :n:`@qualid` in hypothesis :n:`@ident` with its definition
+ and replaces the hypothesis with its :math:`\beta`:math:`\iota` normal form.
+
+.. tacv:: unfold {+, @qualid}
+
+ Replaces *simultaneously* :n:`{+, @qualid}` with their definitions and
+ replaces the current goal with its :math:`\beta`:math:`\iota` normal form.
+
+.. tacv:: unfold {+, @qualid at {+, @num }}
+
+ The lists :n:`{+, @num}` specify the occurrences of :n:`@qualid` to be
+ unfolded. Occurrences are located from left to right.
+
+ .. exn:: Bad occurrence number of @qualid.
+ :undocumented:
+
+ .. exn:: @qualid does not occur.
+ :undocumented:
+
+.. tacv:: unfold @string
+
+ If :n:`@string` denotes the discriminating symbol of a notation (e.g. "+") or
+ an expression defining a notation (e.g. `"_ + _"`), and this notation refers to an unfoldable constant, then the
+ tactic unfolds it.
+
+.. tacv:: unfold @string%key
+
+ This is variant of :n:`unfold @string` where :n:`@string` gets its
+ interpretation from the scope bound to the delimiting key :n:`key`
+ instead of its default interpretation (see :ref:`Localinterpretationrulesfornotations`).
+.. tacv:: unfold {+, qualid_or_string at {+, @num}}
+
+ This is the most general form, where :n:`qualid_or_string` is either a
+ :n:`@qualid` or a :n:`@string` referring to a notation.
+
+.. tacn:: fold @term
+ :name: fold
+
+ This tactic applies to any goal. The term :n:`@term` is reduced using the
+ :tacn:`red` tactic. Every occurrence of the resulting :n:`@term` in the goal is
+ then replaced by :n:`@term`. This tactic is particularly useful when a fixpoint
+ definition has been wrongfully unfolded, making the goal very hard to read.
+ On the other hand, when an unfolded function applied to its argument has been
+ reduced, the :tacn:`fold` tactic won't do anything.
+
+ .. example::
+
+ .. coqtop:: all abort
+
+ Goal ~0=0.
+ unfold not.
+ Fail progress fold not.
+ pattern (0 = 0).
+ fold not.
+
+ .. tacv:: fold {+ @term}
+
+ Equivalent to :n:`fold @term ; ... ; fold @term`.
+
+.. tacn:: pattern @term
+ :name: pattern
+
+ This command applies to any goal. The argument :n:`@term` must be a free
+ subterm of the current goal. The command pattern performs :math:`\beta`-expansion
+ (the inverse of :math:`\beta`-reduction) of the current goal (say :g:`T`) by
+
+ + replacing all occurrences of :n:`@term` in :g:`T` with a fresh variable
+ + abstracting this variable
+ + applying the abstracted goal to :n:`@term`
+
+ For instance, if the current goal :g:`T` is expressible as
+ :math:`\varphi`:g:`(t)` where the notation captures all the instances of :g:`t`
+ in :math:`\varphi`:g:`(t)`, then :n:`pattern t` transforms it into
+ :g:`(fun x:A =>` :math:`\varphi`:g:`(x)) t`. This tactic can be used, for
+ instance, when the tactic ``apply`` fails on matching.
+
+.. tacv:: pattern @term at {+ @num}
+
+ Only the occurrences :n:`{+ @num}` of :n:`@term` are considered for
+ :math:`\beta`-expansion. Occurrences are located from left to right.
+
+.. tacv:: pattern @term at - {+ @num}
+
+ All occurrences except the occurrences of indexes :n:`{+ @num }`
+ of :n:`@term` are considered for :math:`\beta`-expansion. Occurrences are located from
+ left to right.
+
+.. tacv:: pattern {+, @term}
+
+ Starting from a goal :math:`\varphi`:g:`(t`:sub:`1` :g:`... t`:sub:`m`:g:`)`,
+ the tactic :n:`pattern t`:sub:`1`:n:`, ..., t`:sub:`m` generates the
+ equivalent goal
+ :g:`(fun (x`:sub:`1`:g:`:A`:sub:`1`:g:`) ... (x`:sub:`m` :g:`:A`:sub:`m` :g:`) =>`:math:`\varphi`:g:`(x`:sub:`1` :g:`... x`:sub:`m` :g:`)) t`:sub:`1` :g:`... t`:sub:`m`.
+ If :g:`t`:sub:`i` occurs in one of the generated types :g:`A`:sub:`j` these
+ occurrences will also be considered and possibly abstracted.
+
+.. tacv:: pattern {+, @term at {+ @num}}
+
+ This behaves as above but processing only the occurrences :n:`{+ @num}` of
+ :n:`@term` starting from :n:`@term`.
+
+.. tacv:: pattern {+, @term {? at {? -} {+, @num}}}
+
+ This is the most general syntax that combines the different variants.
+
+Conversion tactics applied to hypotheses
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. tacn:: conv_tactic in {+, @ident}
+
+ Applies the conversion tactic :n:`conv_tactic` to the hypotheses
+ :n:`{+ @ident}`. The tactic :n:`conv_tactic` is any of the conversion tactics
+ listed in this section.
+
+ If :n:`@ident` is a local definition, then :n:`@ident` can be replaced by
+ (type of :n:`@ident`) to address not the body but the type of the local
+ definition.
+
+ Example: :n:`unfold not in (type of H1) (type of H3)`.
+
+.. exn:: No such hypothesis: @ident.
+ :undocumented:
+
+
+.. _automation:
+
+Automation
+----------
+
+.. tacn:: auto
+ :name: auto
+
+ This tactic implements a Prolog-like resolution procedure to solve the
+ current goal. It first tries to solve the goal using the :tacn:`assumption`
+ tactic, then it reduces the goal to an atomic one using :tacn:`intros` and
+ introduces the newly generated hypotheses as hints. Then it looks at
+ the list of tactics associated to the head symbol of the goal and
+ tries to apply one of them (starting from the tactics with lower
+ cost). This process is recursively applied to the generated subgoals.
+
+ By default, :tacn:`auto` only uses the hypotheses of the current goal and
+ the hints of the database named ``core``.
+
+ .. warning::
+
+ :tacn:`auto` uses a weaker version of :tacn:`apply` that is closer to
+ :tacn:`simple apply` so it is expected that sometimes :tacn:`auto` will
+ fail even if applying manually one of the hints would succeed.
+
+ .. tacv:: auto @num
+
+ Forces the search depth to be :token:`num`. The maximal search depth
+ is 5 by default.
+
+ .. tacv:: auto with {+ @ident}
+
+ Uses the hint databases :n:`{+ @ident}` in addition to the database ``core``.
+
+ .. note::
+
+ Use the fake database `nocore` if you want to *not* use the `core`
+ database.
+
+ .. tacv:: auto with *
+
+ Uses all existing hint databases. Using this variant is highly discouraged
+ in finished scripts since it is both slower and less robust than the variant
+ where the required databases are explicitly listed.
+
+ .. seealso::
+ :ref:`The Hints Databases for auto and eauto <thehintsdatabasesforautoandeauto>` for the list of
+ pre-defined databases and the way to create or extend a database.
+
+ .. tacv:: auto using {+ @ident__i} {? with {+ @ident } }
+
+ Uses lemmas :n:`@ident__i` in addition to hints. If :n:`@ident` is an
+ inductive type, it is the collection of its constructors which are added
+ as hints.
+
+ .. note::
+
+ The hints passed through the `using` clause are used in the same
+ way as if they were passed through a hint database. Consequently,
+ they use a weaker version of :tacn:`apply` and :n:`auto using @ident`
+ may fail where :n:`apply @ident` succeeds.
+
+ Given that this can be seen as counter-intuitive, it could be useful
+ to have an option to use full-blown :tacn:`apply` for lemmas passed
+ through the `using` clause. Contributions welcome!
+
+ .. tacv:: info_auto
+
+ Behaves like :tacn:`auto` but shows the tactics it uses to solve the goal. This
+ variant is very useful for getting a better understanding of automation, or
+ to know what lemmas/assumptions were used.
+
+ .. tacv:: debug auto
+ :name: debug auto
+
+ Behaves like :tacn:`auto` but shows the tactics it tries to solve the goal,
+ including failing paths.
+
+ .. tacv:: {? info_}auto {? @num} {? using {+ @lemma}} {? with {+ @ident}}
+
+ This is the most general form, combining the various options.
+
+.. tacv:: trivial
+ :name: trivial
+
+ This tactic is a restriction of :tacn:`auto` that is not recursive
+ and tries only hints that cost `0`. Typically it solves trivial
+ equalities like :g:`X=X`.
+
+ .. tacv:: trivial with {+ @ident}
+ trivial with *
+ trivial using {+ @lemma}
+ debug trivial
+ info_trivial
+ {? info_}trivial {? using {+ @lemma}} {? with {+ @ident}}
+ :name: _; _; _; debug trivial; info_trivial; _
+ :undocumented:
+
+.. note::
+ :tacn:`auto` and :tacn:`trivial` either solve completely the goal or
+ else succeed without changing the goal. Use :g:`solve [ auto ]` and
+ :g:`solve [ trivial ]` if you would prefer these tactics to fail when
+ they do not manage to solve the goal.
+
+.. flag:: Info Auto
+ Debug Auto
+ Info Trivial
+ Debug Trivial
+
+ These options enable printing of informative or debug information for
+ the :tacn:`auto` and :tacn:`trivial` tactics.
+
+.. tacn:: eauto
+ :name: eauto
+
+ This tactic generalizes :tacn:`auto`. While :tacn:`auto` does not try
+ resolution hints which would leave existential variables in the goal,
+ :tacn:`eauto` does try them (informally speaking, it internally uses a tactic
+ close to :tacn:`simple eapply` instead of a tactic close to :tacn:`simple apply`
+ in the case of :tacn:`auto`). As a consequence, :tacn:`eauto`
+ can solve such a goal:
+
+ .. example::
+
+ .. coqtop:: all
+
+ Hint Resolve ex_intro : core.
+ Goal forall P:nat -> Prop, P 0 -> exists n, P n.
+ eauto.
+
+ Note that ``ex_intro`` should be declared as a hint.
+
+
+ .. tacv:: {? info_}eauto {? @num} {? using {+ @lemma}} {? with {+ @ident}}
+
+ The various options for :tacn:`eauto` are the same as for :tacn:`auto`.
+
+ :tacn:`eauto` also obeys the following options:
+
+ .. flag:: Info Eauto
+ Debug Eauto
+ :undocumented:
+
+ .. seealso:: :ref:`The Hints Databases for auto and eauto <thehintsdatabasesforautoandeauto>`
+
+
+.. tacn:: autounfold with {+ @ident}
+ :name: autounfold
+
+ This tactic unfolds constants that were declared through a :cmd:`Hint Unfold`
+ in the given databases.
+
+.. tacv:: autounfold with {+ @ident} in clause
+
+ Performs the unfolding in the given clause.
+
+.. tacv:: autounfold with *
+
+ Uses the unfold hints declared in all the hint databases.
+
+.. tacn:: autorewrite with {+ @ident}
+ :name: autorewrite
+
+ This tactic [4]_ carries out rewritings according to the rewriting rule
+ bases :n:`{+ @ident}`.
+
+ Each rewriting rule from the base :n:`@ident` is applied to the main subgoal until
+ it fails. Once all the rules have been processed, if the main subgoal has
+ progressed (e.g., if it is distinct from the initial main goal) then the rules
+ of this base are processed again. If the main subgoal has not progressed then
+ the next base is processed. For the bases, the behavior is exactly similar to
+ the processing of the rewriting rules.
+
+ The rewriting rule bases are built with the :cmd:`Hint Rewrite`
+ command.
+
+.. warning::
+
+ This tactic may loop if you build non terminating rewriting systems.
+
+.. tacv:: autorewrite with {+ @ident} using @tactic
+
+ Performs, in the same way, all the rewritings of the bases :n:`{+ @ident}`
+ applying tactic to the main subgoal after each rewriting step.
+
+.. tacv:: autorewrite with {+ @ident} in @qualid
+
+ Performs all the rewritings in hypothesis :n:`@qualid`.
+
+.. tacv:: autorewrite with {+ @ident} in @qualid using @tactic
+
+ Performs all the rewritings in hypothesis :n:`@qualid` applying :n:`@tactic`
+ to the main subgoal after each rewriting step.
+
+.. tacv:: autorewrite with {+ @ident} in @clause
+
+ Performs all the rewriting in the clause :n:`@clause`. The clause argument
+ must not contain any ``type of`` nor ``value of``.
+
+.. seealso::
+
+ :ref:`Hint-Rewrite <hintrewrite>` for feeding the database of lemmas used by
+ :tacn:`autorewrite` and :tacn:`autorewrite` for examples showing the use of this tactic.
+
+.. tacn:: easy
+ :name: easy
+
+ This tactic tries to solve the current goal by a number of standard closing steps.
+ In particular, it tries to close the current goal using the closing tactics
+ :tacn:`trivial`, :tacn:`reflexivity`, :tacn:`symmetry`, :tacn:`contradiction`
+ and :tacn:`inversion` of hypothesis.
+ If this fails, it tries introducing variables and splitting and-hypotheses,
+ using the closing tactics afterwards, and splitting the goal using
+ :tacn:`split` and recursing.
+
+ This tactic solves goals that belong to many common classes; in particular, many cases of
+ unsatisfiable hypotheses, and simple equality goals are usually solved by this tactic.
+
+.. tacv:: now @tactic
+ :name: now
+
+ Run :n:`@tactic` followed by :tacn:`easy`. This is a notation for :n:`@tactic; easy`.
+
+Controlling automation
+--------------------------
+
+.. _thehintsdatabasesforautoandeauto:
+
+The hints databases for auto and eauto
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The hints for :tacn:`auto` and :tacn:`eauto` are stored in databases. Each database
+maps head symbols to a list of hints.
+
+.. cmd:: Print Hint @ident
+
+ Use this command
+ to display the hints associated to the head symbol :n:`@ident`
+ (see :ref:`Print Hint <printhint>`). Each hint has a cost that is a nonnegative
+ integer, and an optional pattern. The hints with lower cost are tried first. A
+ hint is tried by :tacn:`auto` when the conclusion of the current goal matches its
+ pattern or when it has no pattern.
+
+Creating Hint databases
+```````````````````````
+
+One can optionally declare a hint database using the command
+:cmd:`Create HintDb`. If a hint is added to an unknown database, it will be
+automatically created.
+
+.. cmd:: Create HintDb @ident {? discriminated}
+
+ This command creates a new database named :n:`@ident`. The database is
+ implemented by a Discrimination Tree (DT) that serves as an index of
+ all the lemmas. The DT can use transparency information to decide if a
+ constant should be indexed or not
+ (c.f. :ref:`The hints databases for auto and eauto <thehintsdatabasesforautoandeauto>`),
+ making the retrieval more efficient. The legacy implementation (the default one
+ for new databases) uses the DT only on goals without existentials (i.e., :tacn:`auto`
+ goals), for non-Immediate hints and does not make use of transparency
+ hints, putting more work on the unification that is run after
+ retrieval (it keeps a list of the lemmas in case the DT is not used).
+ The new implementation enabled by the discriminated option makes use
+ of DTs in all cases and takes transparency information into account.
+ However, the order in which hints are retrieved from the DT may differ
+ from the order in which they were inserted, making this implementation
+ observationally different from the legacy one.
+
+The general command to add a hint to some databases :n:`{+ @ident}` is
+
+.. cmd:: Hint @hint_definition : {+ @ident}
+
+ .. cmdv:: Hint @hint_definition
+
+ No database name is given: the hint is registered in the ``core`` database.
+
+ .. deprecated:: 8.10
+
+ .. cmdv:: Local Hint @hint_definition : {+ @ident}
+
+ This is used to declare hints that must not be exported to the other modules
+ that require and import the current module. Inside a section, the option
+ Local is useless since hints do not survive anyway to the closure of
+ sections.
+
+ .. cmdv:: Hint Resolve @term {? | {? @num} {? @pattern}} : @ident
+ :name: Hint Resolve
+
+ This command adds :n:`simple apply @term` to the hint list with the head
+ symbol of the type of :n:`@term`. The cost of that hint is the number of
+ subgoals generated by :n:`simple apply @term` or :n:`@num` if specified. The
+ associated :n:`@pattern` is inferred from the conclusion of the type of
+ :n:`@term` or the given :n:`@pattern` if specified. In case the inferred type
+ of :n:`@term` does not start with a product the tactic added in the hint list
+ is :n:`exact @term`. In case this type can however be reduced to a type
+ starting with a product, the tactic :n:`simple apply @term` is also stored in
+ the hints list. If the inferred type of :n:`@term` contains a dependent
+ quantification on a variable which occurs only in the premisses of the type
+ and not in its conclusion, no instance could be inferred for the variable by
+ unification with the goal. In this case, the hint is added to the hint list
+ of :tacn:`eauto` instead of the hint list of auto and a warning is printed. A
+ typical example of a hint that is used only by :tacn:`eauto` is a transitivity
+ lemma.
+
+ .. exn:: @term cannot be used as a hint
+
+ The head symbol of the type of :n:`@term` is a bound variable
+ such that this tactic cannot be associated to a constant.
+
+ .. cmdv:: Hint Resolve {+ @term} : @ident
+
+ Adds each :n:`Hint Resolve @term`.
+
+ .. cmdv:: Hint Resolve -> @term : @ident
+
+ Adds the left-to-right implication of an equivalence as a hint (informally
+ the hint will be used as :n:`apply <- @term`, although as mentionned
+ before, the tactic actually used is a restricted version of
+ :tacn:`apply`).
+
+ .. cmdv:: Resolve <- @term
+
+ Adds the right-to-left implication of an equivalence as a hint.
+
+ .. cmdv:: Hint Immediate @term : @ident
+ :name: Hint Immediate
+
+ This command adds :n:`simple apply @term; trivial` to the hint list associated
+ with the head symbol of the type of :n:`@ident` in the given database. This
+ tactic will fail if all the subgoals generated by :n:`simple apply @term` are
+ not solved immediately by the :tacn:`trivial` tactic (which only tries tactics
+ with cost 0).This command is useful for theorems such as the symmetry of
+ equality or :g:`n+1=m+1 -> n=m` that we may like to introduce with a limited
+ use in order to avoid useless proof-search. The cost of this tactic (which
+ never generates subgoals) is always 1, so that it is not used by :tacn:`trivial`
+ itself.
+
+ .. exn:: @term cannot be used as a hint
+ :undocumented:
+
+ .. cmdv:: Immediate {+ @term} : @ident
+
+ Adds each :n:`Hint Immediate @term`.
+
+ .. cmdv:: Hint Constructors @qualid : @ident
+ :name: Hint Constructors
+
+ If :token:`qualid` is an inductive type, this command adds all its constructors as
+ hints of type ``Resolve``. Then, when the conclusion of current goal has the form
+ :n:`(@qualid ...)`, :tacn:`auto` will try to apply each constructor.
+
+ .. exn:: @qualid is not an inductive type
+ :undocumented:
+
+ .. cmdv:: Hint Constructors {+ @qualid} : @ident
+
+ Extends the previous command for several inductive types.
+
+ .. cmdv:: Hint Unfold @qualid : @ident
+ :name: Hint Unfold
+
+ This adds the tactic :n:`unfold @qualid` to the hint list that will only be
+ used when the head constant of the goal is :token:`qualid`.
+ Its cost is 4.
+
+ .. cmdv:: Hint Unfold {+ @qualid}
+
+ Extends the previous command for several defined constants.
+
+ .. cmdv:: Hint Transparent {+ @qualid} : @ident
+ Hint Opaque {+ @qualid} : @ident
+ :name: Hint Transparent; Hint Opaque
+
+ This adds transparency hints to the database, making :n:`@qualid`
+ transparent or opaque constants during resolution. This information is used
+ during unification of the goal with any lemma in the database and inside the
+ discrimination network to relax or constrain it in the case of discriminated
+ databases.
+
+ .. cmdv:: Hint Variables %( Transparent %| Opaque %) : @ident
+ Hint Constants %( Transparent %| Opaque %) : @ident
+ :name: Hint Variables; Hint Constants
+
+ This sets the transparency flag used during unification of
+ hints in the database for all constants or all variables,
+ overwritting the existing settings of opacity. It is advised
+ to use this just after a :cmd:`Create HintDb` command.
+
+ .. cmdv:: Hint Extern @num {? @pattern} => @tactic : @ident
+ :name: Hint Extern
+
+ This hint type is to extend :tacn:`auto` with tactics other than :tacn:`apply` and
+ :tacn:`unfold`. For that, we must specify a cost, an optional :n:`@pattern` and a
+ :n:`@tactic` to execute.
+
+ .. example::
+
+ .. coqtop:: in
+
+ Hint Extern 4 (~(_ = _)) => discriminate : core.
+
+ Now, when the head of the goal is a disequality, ``auto`` will try
+ discriminate if it does not manage to solve the goal with hints with a
+ cost less than 4.
+
+ One can even use some sub-patterns of the pattern in
+ the tactic script. A sub-pattern is a question mark followed by an
+ identifier, like ``?X1`` or ``?X2``. Here is an example:
+
+ .. example::
+
+ .. coqtop:: reset all
+
+ Require Import List.
+ Hint Extern 5 ({?X1 = ?X2} + {?X1 <> ?X2}) => generalize X1, X2; decide equality : eqdec.
+ Goal forall a b:list (nat * nat), {a = b} + {a <> b}.
+ Info 1 auto with eqdec.
+
+ .. cmdv:: Hint Cut @regexp : @ident
+ :name: Hint Cut
+
+ .. warning::
+
+ These hints currently only apply to typeclass proof search and the
+ :tacn:`typeclasses eauto` tactic.
+
+ This command can be used to cut the proof-search tree according to a regular
+ expression matching paths to be cut. The grammar for regular expressions is
+ the following. Beware, there is no operator precedence during parsing, one can
+ check with :cmd:`Print HintDb` to verify the current cut expression:
+
+ .. productionlist:: regexp
+ e : `ident` hint or instance identifier
+ : _ any hint
+ : `e` | `e` disjunction
+ : `e` `e` sequence
+ : `e` * Kleene star
+ : emp empty
+ : eps epsilon
+ : ( `e` )
+
+ The `emp` regexp does not match any search path while `eps`
+ matches the empty path. During proof search, the path of
+ successive successful hints on a search branch is recorded, as a
+ list of identifiers for the hints (note that Hint Extern’s do not have
+ an associated identifier).
+ Before applying any hint :n:`@ident` the current path `p` extended with
+ :n:`@ident` is matched against the current cut expression `c` associated to
+ the hint database. If matching succeeds, the hint is *not* applied. The
+ semantics of ``Hint Cut e`` is to set the cut expression to ``c | e``, the
+ initial cut expression being `emp`.
+
+ .. cmdv:: Hint Mode @qualid {* (+ | ! | -)} : @ident
+ :name: Hint Mode
+
+ This sets an optional mode of use of the identifier :n:`@qualid`. When
+ proof-search faces a goal that ends in an application of :n:`@qualid` to
+ arguments :n:`@term ... @term`, the mode tells if the hints associated to
+ :n:`@qualid` can be applied or not. A mode specification is a list of n ``+``,
+ ``!`` or ``-`` items that specify if an argument of the identifier is to be
+ treated as an input (``+``), if its head only is an input (``!``) or an output
+ (``-``) of the identifier. For a mode to match a list of arguments, input
+ terms and input heads *must not* contain existential variables or be
+ existential variables respectively, while outputs can be any term. Multiple
+ modes can be declared for a single identifier, in that case only one mode
+ needs to match the arguments for the hints to be applied.The head of a term
+ is understood here as the applicative head, or the match or projection
+ scrutinee’s head, recursively, casts being ignored. ``Hint Mode`` is
+ especially useful for typeclasses, when one does not want to support default
+ instances and avoid ambiguity in general. Setting a parameter of a class as an
+ input forces proof-search to be driven by that index of the class, with ``!``
+ giving more flexibility by allowing existentials to still appear deeper in the
+ index but not at its head.
+
+ .. note::
+
+ One can use an ``Extern`` hint with no pattern to do pattern matching on
+ hypotheses using ``match goal`` with inside the tactic.
+
+
+Hint databases defined in the Coq standard library
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Several hint databases are defined in the Coq standard library. The
+actual content of a database is the collection of hints declared
+to belong to this database in each of the various modules currently
+loaded. Especially, requiring new modules may extend the database.
+At Coq startup, only the core database is nonempty and can be used.
+
+:core: This special database is automatically used by ``auto``, except when
+ pseudo-database ``nocore`` is given to ``auto``. The core database
+ contains only basic lemmas about negation, conjunction, and so on.
+ Most of the hints in this database come from the Init and Logic directories.
+
+:arith: This database contains all lemmas about Peano’s arithmetic proved in the
+ directories Init and Arith.
+
+:zarith: contains lemmas about binary signed integers from the directories
+ theories/ZArith. When required, the module Omega also extends the
+ database zarith with a high-cost hint that calls ``omega`` on equations
+ and inequalities in ``nat`` or ``Z``.
+
+:bool: contains lemmas about booleans, mostly from directory theories/Bool.
+
+:datatypes: is for lemmas about lists, streams and so on that are mainly proved
+ in the Lists subdirectory.
+
+:sets: contains lemmas about sets and relations from the directories Sets and
+ Relations.
+
+:typeclass_instances: contains all the typeclass instances declared in the
+ environment, including those used for ``setoid_rewrite``,
+ from the Classes directory.
+
+:fset: internal database for the implementation of the ``FSets`` library.
+
+You are advised not to put your own hints in the core database, but
+use one or several databases specific to your development.
+
+.. _removehints:
+
+.. cmd:: Remove Hints {+ @term} : {+ @ident}
+
+ This command removes the hints associated to terms :n:`{+ @term}` in databases
+ :n:`{+ @ident}`.
+
+.. _printhint:
+
+.. cmd:: Print Hint
+
+ This command displays all hints that apply to the current goal. It
+ fails if no proof is being edited, while the two variants can be used
+ at every moment.
+
+**Variants:**
+
+
+.. cmd:: Print Hint @ident
+
+ This command displays only tactics associated with :n:`@ident` in the hints
+ list. This is independent of the goal being edited, so this command will not
+ fail if no goal is being edited.
+
+.. cmd:: Print Hint *
+
+ This command displays all declared hints.
+
+.. cmd:: Print HintDb @ident
+
+ This command displays all hints from database :n:`@ident`.
+
+.. _hintrewrite:
+
+.. cmd:: Hint Rewrite {+ @term} : {+ @ident}
+
+ This vernacular command adds the terms :n:`{+ @term}` (their types must be
+ equalities) in the rewriting bases :n:`{+ @ident}` with the default orientation
+ (left to right). Notice that the rewriting bases are distinct from the ``auto``
+ hint bases and thatauto does not take them into account.
+
+ This command is synchronous with the section mechanism (see :ref:`section-mechanism`):
+ when closing a section, all aliases created by ``Hint Rewrite`` in that
+ section are lost. Conversely, when loading a module, all ``Hint Rewrite``
+ declarations at the global level of that module are loaded.
+
+**Variants:**
+
+.. cmd:: Hint Rewrite -> {+ @term} : {+ @ident}
+
+ This is strictly equivalent to the command above (we only make explicit the
+ orientation which otherwise defaults to ->).
+
+.. cmd:: Hint Rewrite <- {+ @term} : {+ @ident}
+
+ Adds the rewriting rules :n:`{+ @term}` with a right-to-left orientation in
+ the bases :n:`{+ @ident}`.
+
+.. cmd:: Hint Rewrite {+ @term} using tactic : {+ @ident}
+
+ When the rewriting rules :n:`{+ @term}` in :n:`{+ @ident}` will be used, the
+ tactic ``tactic`` will be applied to the generated subgoals, the main subgoal
+ excluded.
+
+.. cmd:: Print Rewrite HintDb @ident
+
+ This command displays all rewrite hints contained in :n:`@ident`.
+
+Hint locality
+~~~~~~~~~~~~~
+
+Hints provided by the ``Hint`` commands are erased when closing a section.
+Conversely, all hints of a module ``A`` that are not defined inside a
+section (and not defined with option ``Local``) become available when the
+module ``A`` is imported (using e.g. ``Require Import A.``).
+
+As of today, hints only have a binary behavior regarding locality, as
+described above: either they disappear at the end of a section scope,
+or they remain global forever. This causes a scalability issue,
+because hints coming from an unrelated part of the code may badly
+influence another development. It can be mitigated to some extent
+thanks to the :cmd:`Remove Hints` command,
+but this is a mere workaround and has some limitations (for instance, external
+hints cannot be removed).
+
+A proper way to fix this issue is to bind the hints to their module scope, as
+for most of the other objects Coq uses. Hints should only be made available when
+the module they are defined in is imported, not just required. It is very
+difficult to change the historical behavior, as it would break a lot of scripts.
+We propose a smooth transitional path by providing the :opt:`Loose Hint Behavior`
+option which accepts three flags allowing for a fine-grained handling of
+non-imported hints.
+
+.. opt:: Loose Hint Behavior %( "Lax" %| "Warn" %| "Strict" %)
+ :name: Loose Hint Behavior
+
+ This option accepts three values, which control the behavior of hints w.r.t.
+ :cmd:`Import`:
+
+ - "Lax": this is the default, and corresponds to the historical behavior,
+ that is, hints defined outside of a section have a global scope.
+
+ - "Warn": outputs a warning when a non-imported hint is used. Note that this
+ is an over-approximation, because a hint may be triggered by a run that
+ will eventually fail and backtrack, resulting in the hint not being
+ actually useful for the proof.
+
+ - "Strict": changes the behavior of an unloaded hint to a immediate fail
+ tactic, allowing to emulate an import-scoped hint mechanism.
+
+.. _tactics-implicit-automation:
+
+Setting implicit automation tactics
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. cmd:: Proof with @tactic
+
+ This command may be used to start a proof. It defines a default tactic
+ to be used each time a tactic command ``tactic``:sub:`1` is ended by ``...``.
+ In this case the tactic command typed by the user is equivalent to
+ ``tactic``:sub:`1` ``;tactic``.
+
+ .. seealso:: :cmd:`Proof` in :ref:`proof-editing-mode`.
+
+
+ .. cmdv:: Proof with tactic using {+ @ident}
+
+ Combines in a single line ``Proof with`` and ``Proof using``, see :ref:`proof-editing-mode`
+
+ .. cmdv:: Proof using {+ @ident} with @tactic
+
+ Combines in a single line ``Proof with`` and ``Proof using``, see :ref:`proof-editing-mode`
+
+.. _decisionprocedures:
+
+Decision procedures
+-------------------
+
+.. tacn:: tauto
+ :name: tauto
+
+ This tactic implements a decision procedure for intuitionistic propositional
+ calculus based on the contraction-free sequent calculi LJT* of Roy Dyckhoff
+ :cite:`Dyc92`. Note that :tacn:`tauto` succeeds on any instance of an
+ intuitionistic tautological proposition. :tacn:`tauto` unfolds negations and
+ logical equivalence but does not unfold any other definition.
+
+.. example::
+
+ The following goal can be proved by :tacn:`tauto` whereas :tacn:`auto` would
+ fail:
+
+ .. coqtop:: reset all
+
+ Goal forall (x:nat) (P:nat -> Prop), x = 0 \/ P x -> x <> 0 -> P x.
+ intros.
+ tauto.
+
+Moreover, if it has nothing else to do, :tacn:`tauto` performs introductions.
+Therefore, the use of :tacn:`intros` in the previous proof is unnecessary.
+:tacn:`tauto` can for instance for:
+
+.. example::
+
+ .. coqtop:: reset all
+
+ Goal forall (A:Prop) (P:nat -> Prop), A \/ (forall x:nat, ~ A -> P x) -> forall x:nat, ~ A -> P x.
+ tauto.
+
+.. note::
+ In contrast, :tacn:`tauto` cannot solve the following goal
+ :g:`Goal forall (A:Prop) (P:nat -> Prop), A \/ (forall x:nat, ~ A -> P x) ->`
+ :g:`forall x:nat, ~ ~ (A \/ P x).`
+ because :g:`(forall x:nat, ~ A -> P x)` cannot be treated as atomic and
+ an instantiation of `x` is necessary.
+
+.. tacv:: dtauto
+ :name: dtauto
+
+ While :tacn:`tauto` recognizes inductively defined connectives isomorphic to
+ the standard connectives ``and``, ``prod``, ``or``, ``sum``, ``False``,
+ ``Empty_set``, ``unit``, ``True``, :tacn:`dtauto` also recognizes all inductive
+ types with one constructor and no indices, i.e. record-style connectives.
+
+.. tacn:: intuition @tactic
+ :name: intuition
+
+ The tactic :tacn:`intuition` takes advantage of the search-tree built by the
+ decision procedure involved in the tactic :tacn:`tauto`. It uses this
+ information to generate a set of subgoals equivalent to the original one (but
+ simpler than it) and applies the tactic :n:`@tactic` to them :cite:`Mun94`. If
+ this tactic fails on some goals then :tacn:`intuition` fails. In fact,
+ :tacn:`tauto` is simply :g:`intuition fail`.
+
+ .. example::
+
+ For instance, the tactic :g:`intuition auto` applied to the goal::
+
+ (forall (x:nat), P x) /\ B -> (forall (y:nat), P y) /\ P O \/ B /\ P O
+
+ internally replaces it by the equivalent one::
+
+ (forall (x:nat), P x), B |- P O
+
+ and then uses :tacn:`auto` which completes the proof.
+
+Originally due to César Muñoz, these tactics (:tacn:`tauto` and
+:tacn:`intuition`) have been completely re-engineered by David Delahaye using
+mainly the tactic language (see :ref:`ltac`). The code is
+now much shorter and a significant increase in performance has been noticed.
+The general behavior with respect to dependent types, unfolding and
+introductions has slightly changed to get clearer semantics. This may lead to
+some incompatibilities.
+
+.. tacv:: intuition
+
+ Is equivalent to :g:`intuition auto with *`.
+
+.. tacv:: dintuition
+ :name: dintuition
+
+ While :tacn:`intuition` recognizes inductively defined connectives
+ isomorphic to the standard connectives ``and``, ``prod``, ``or``, ``sum``, ``False``,
+ ``Empty_set``, ``unit``, ``True``, :tacn:`dintuition` also recognizes all inductive
+ types with one constructor and no indices, i.e. record-style connectives.
+
+.. flag:: Intuition Negation Unfolding
+
+ Controls whether :tacn:`intuition` unfolds inner negations which do not need
+ to be unfolded. This option is on by default.
+
+.. tacn:: rtauto
+ :name: rtauto
+
+ The :tacn:`rtauto` tactic solves propositional tautologies similarly to what
+ :tacn:`tauto` does. The main difference is that the proof term is built using a
+ reflection scheme applied to a sequent calculus proof of the goal. The search
+ procedure is also implemented using a different technique.
+
+ Users should be aware that this difference may result in faster proof-search
+ but slower proof-checking, and :tacn:`rtauto` might not solve goals that
+ :tacn:`tauto` would be able to solve (e.g. goals involving universal
+ quantifiers).
+
+ Note that this tactic is only available after a ``Require Import Rtauto``.
+
+.. tacn:: firstorder
+ :name: firstorder
+
+ The tactic :tacn:`firstorder` is an experimental extension of :tacn:`tauto` to
+ first- order reasoning, written by Pierre Corbineau. It is not restricted to
+ usual logical connectives but instead may reason about any first-order class
+ inductive definition.
+
+.. opt:: Firstorder Solver @tactic
+ :name: Firstorder Solver
+
+ The default tactic used by :tacn:`firstorder` when no rule applies is
+ :g:`auto with *`, it can be reset locally or globally using this option.
+
+ .. cmd:: Print Firstorder Solver
+
+ Prints the default tactic used by :tacn:`firstorder` when no rule applies.
+
+.. tacv:: firstorder @tactic
+
+ Tries to solve the goal with :n:`@tactic` when no logical rule may apply.
+
+.. tacv:: firstorder using {+ @qualid}
+
+ Adds lemmas :n:`{+ @qualid}` to the proof-search environment. If :n:`@qualid`
+ refers to an inductive type, it is the collection of its constructors which are
+ added to the proof-search environment.
+
+.. tacv:: firstorder with {+ @ident}
+
+ Adds lemmas from :tacn:`auto` hint bases :n:`{+ @ident}` to the proof-search
+ environment.
+
+.. tacv:: firstorder tactic using {+ @qualid} with {+ @ident}
+
+ This combines the effects of the different variants of :tacn:`firstorder`.
+
+.. opt:: Firstorder Depth @num
+ :name: Firstorder Depth
+
+ This option controls the proof-search depth bound.
+
+.. tacn:: congruence
+ :name: congruence
+
+ The tactic :tacn:`congruence`, by Pierre Corbineau, implements the standard
+ Nelson and Oppen congruence closure algorithm, which is a decision procedure
+ for ground equalities with uninterpreted symbols. It also includes
+ constructor theory (see :tacn:`injection` and :tacn:`discriminate`). If the goal
+ is a non-quantified equality, congruence tries to prove it with non-quantified
+ equalities in the context. Otherwise it tries to infer a discriminable equality
+ from those in the context. Alternatively, congruence tries to prove that a
+ hypothesis is equal to the goal or to the negation of another hypothesis.
+
+ :tacn:`congruence` is also able to take advantage of hypotheses stating
+ quantified equalities, but you have to provide a bound for the number of extra
+ equalities generated that way. Please note that one of the sides of the
+ equality must contain all the quantified variables in order for congruence to
+ match against it.
+
+.. example::
+
+ .. coqtop:: reset all
+
+ Theorem T (A:Type) (f:A -> A) (g: A -> A -> A) a b: a=(f a) -> (g b (f a))=(f (f a)) -> (g a b)=(f (g b a)) -> (g a b)=a.
+ intros.
+ congruence.
+ Qed.
+
+ Theorem inj (A:Type) (f:A -> A * A) (a c d: A) : f = pair a -> Some (f c) = Some (f d) -> c=d.
+ intros.
+ congruence.
+ Qed.
+
+.. tacv:: congruence n
+
+ Tries to add at most `n` instances of hypotheses stating quantified equalities
+ to the problem in order to solve it. A bigger value of `n` does not make
+ success slower, only failure. You might consider adding some lemmas as
+ hypotheses using assert in order for :tacn:`congruence` to use them.
+
+.. tacv:: congruence with {+ @term}
+ :name: congruence with
+
+ Adds :n:`{+ @term}` to the pool of terms used by :tacn:`congruence`. This helps
+ in case you have partially applied constructors in your goal.
+
+.. exn:: I don’t know how to handle dependent equality.
+
+ The decision procedure managed to find a proof of the goal or of a
+ discriminable equality but this proof could not be built in Coq because of
+ dependently-typed functions.
+
+.. exn:: Goal is solvable by congruence but some arguments are missing. Try congruence with {+ @term}, replacing metavariables by arbitrary terms.
+
+ The decision procedure could solve the goal with the provision that additional
+ arguments are supplied for some partially applied constructors. Any term of an
+ appropriate type will allow the tactic to successfully solve the goal. Those
+ additional arguments can be given to congruence by filling in the holes in the
+ terms given in the error message, using the :tacn:`congruence with` variant described above.
+
+.. flag:: Congruence Verbose
+
+ This option makes :tacn:`congruence` print debug information.
+
+
+Checking properties of terms
+----------------------------
+
+Each of the following tactics acts as the identity if the check
+succeeds, and results in an error otherwise.
+
+.. tacn:: constr_eq @term @term
+ :name: constr_eq
+
+ This tactic checks whether its arguments are equal modulo alpha
+ conversion, casts and universe constraints. It may unify universes.
+
+.. exn:: Not equal.
+ :undocumented:
+
+.. exn:: Not equal (due to universes).
+ :undocumented:
+
+.. tacn:: constr_eq_strict @term @term
+ :name: constr_eq_strict
+
+ This tactic checks whether its arguments are equal modulo alpha
+ conversion, casts and universe constraints. It does not add new
+ constraints.
+
+.. exn:: Not equal.
+ :undocumented:
+
+.. exn:: Not equal (due to universes).
+ :undocumented:
+
+.. tacn:: unify @term @term
+ :name: unify
+
+ This tactic checks whether its arguments are unifiable, potentially
+ instantiating existential variables.
+
+.. exn:: Unable to unify @term with @term.
+ :undocumented:
+
+.. tacv:: unify @term @term with @ident
+
+ Unification takes the transparency information defined in the hint database
+ :n:`@ident` into account (see :ref:`the hints databases for auto and eauto <thehintsdatabasesforautoandeauto>`).
+
+.. tacn:: is_evar @term
+ :name: is_evar
+
+ This tactic checks whether its argument is a current existential
+ variable. Existential variables are uninstantiated variables generated
+ by :tacn:`eapply` and some other tactics.
+
+.. exn:: Not an evar.
+ :undocumented:
+
+.. tacn:: has_evar @term
+ :name: has_evar
+
+ This tactic checks whether its argument has an existential variable as
+ a subterm. Unlike context patterns combined with ``is_evar``, this tactic
+ scans all subterms, including those under binders.
+
+.. exn:: No evars.
+ :undocumented:
+
+.. tacn:: is_var @term
+ :name: is_var
+
+ This tactic checks whether its argument is a variable or hypothesis in
+ the current goal context or in the opened sections.
+
+.. exn:: Not a variable or hypothesis.
+ :undocumented:
+
+
+.. _equality:
+
+Equality
+--------
+
+
+.. tacn:: f_equal
+ :name: f_equal
+
+ This tactic applies to a goal of the form :g:`f a`:sub:`1` :g:`... a`:sub:`n`
+ :g:`= f′a′`:sub:`1` :g:`... a′`:sub:`n`. Using :tacn:`f_equal` on such a goal
+ leads to subgoals :g:`f=f′` and :g:`a`:sub:`1` = :g:`a′`:sub:`1` and so on up
+ to :g:`a`:sub:`n` :g:`= a′`:sub:`n`. Amongst these subgoals, the simple ones
+ (e.g. provable by :tacn:`reflexivity` or :tacn:`congruence`) are automatically
+ solved by :tacn:`f_equal`.
+
+
+.. tacn:: reflexivity
+ :name: reflexivity
+
+ This tactic applies to a goal that has the form :g:`t=u`. It checks that `t`
+ and `u` are convertible and then solves the goal. It is equivalent to
+ ``apply refl_equal``.
+
+ .. exn:: The conclusion is not a substitutive equation.
+ :undocumented:
+
+ .. exn:: Unable to unify ... with ...
+ :undocumented:
+
+
+.. tacn:: symmetry
+ :name: symmetry
+
+ This tactic applies to a goal that has the form :g:`t=u` and changes it into
+ :g:`u=t`.
+
+
+.. tacv:: symmetry in @ident
+
+ If the statement of the hypothesis ident has the form :g:`t=u`, the tactic
+ changes it to :g:`u=t`.
+
+
+.. tacn:: transitivity @term
+ :name: transitivity
+
+ This tactic applies to a goal that has the form :g:`t=u` and transforms it
+ into the two subgoals :n:`t=@term` and :n:`@term=u`.
+
+
+Equality and inductive sets
+---------------------------
+
+We describe in this section some special purpose tactics dealing with
+equality and inductive sets or types. These tactics use the
+equality :g:`eq:forall (A:Type), A->A->Prop`, simply written with the infix
+symbol :g:`=`.
+
+.. tacn:: decide equality
+ :name: decide equality
+
+ This tactic solves a goal of the form :g:`forall x y : R, {x = y} + {~ x = y}`,
+ where :g:`R` is an inductive type such that its constructors do not take
+ proofs or functions as arguments, nor objects in dependent types. It
+ solves goals of the form :g:`{x = y} + {~ x = y}` as well.
+
+.. tacn:: compare @term @term
+ :name: compare
+
+ This tactic compares two given objects :n:`@term` and :n:`@term` of an
+ inductive datatype. If :g:`G` is the current goal, it leaves the sub-
+ goals :n:`@term =@term -> G` and :n:`~ @term = @term -> G`. The type of
+ :n:`@term` and :n:`@term` must satisfy the same restrictions as in the
+ tactic ``decide equality``.
+
+.. tacn:: simplify_eq @term
+ :name: simplify_eq
+
+ Let :n:`@term` be the proof of a statement of conclusion :n:`@term = @term`.
+ If :n:`@term` and :n:`@term` are structurally different (in the sense
+ described for the tactic :tacn:`discriminate`), then the tactic
+ ``simplify_eq`` behaves as :n:`discriminate @term`, otherwise it behaves as
+ :n:`injection @term`.
+
+.. note::
+ If some quantified hypothesis of the goal is named :n:`@ident`,
+ then :n:`simplify_eq @ident` first introduces the hypothesis in the local
+ context using :n:`intros until @ident`.
+
+.. tacv:: simplify_eq @num
+
+ This does the same thing as :n:`intros until @num` then
+ :n:`simplify_eq @ident` where :n:`@ident` is the identifier for the last
+ introduced hypothesis.
+
+.. tacv:: simplify_eq @term with @bindings_list
+
+ This does the same as :n:`simplify_eq @term` but using the given bindings to
+ instantiate parameters or hypotheses of :n:`@term`.
+
+.. tacv:: esimplify_eq @num
+ esimplify_eq @term {? with @bindings_list}
+ :name: esimplify_eq; _
+
+ This works the same as :tacn:`simplify_eq` but if the type of :n:`@term`, or the
+ type of the hypothesis referred to by :n:`@num`, has uninstantiated
+ parameters, these parameters are left as existential variables.
+
+.. tacv:: simplify_eq
+
+ If the current goal has form :g:`t1 <> t2`, it behaves as
+ :n:`intro @ident; simplify_eq @ident`.
+
+.. tacn:: dependent rewrite -> @ident
+ :name: dependent rewrite ->
+
+ This tactic applies to any goal. If :n:`@ident` has type
+ :g:`(existT B a b)=(existT B a' b')` in the local context (i.e. each
+ :n:`@term` of the equality has a sigma type :g:`{ a:A & (B a)}`) this tactic
+ rewrites :g:`a` into :g:`a'` and :g:`b` into :g:`b'` in the current goal.
+ This tactic works even if :g:`B` is also a sigma type. This kind of
+ equalities between dependent pairs may be derived by the
+ :tacn:`injection` and :tacn:`inversion` tactics.
+
+.. tacv:: dependent rewrite <- @ident
+ :name: dependent rewrite <-
+
+ Analogous to :tacn:`dependent rewrite ->` but uses the equality from right to
+ left.
+
+Inversion
+---------
+
+.. tacn:: functional inversion @ident
+ :name: functional inversion
+
+ :tacn:`functional inversion` is a tactic that performs inversion on hypothesis
+ :n:`@ident` of the form :n:`@qualid {+ @term} = @term` or :n:`@term = @qualid
+ {+ @term}` where :n:`@qualid` must have been defined using Function (see
+ :ref:`advanced-recursive-functions`). Note that this tactic is only
+ available after a ``Require Import FunInd``.
+
+ .. exn:: Hypothesis @ident must contain at least one Function.
+ :undocumented:
+
+ .. exn:: Cannot find inversion information for hypothesis @ident.
+
+ This error may be raised when some inversion lemma failed to be generated by
+ Function.
+
+
+ .. tacv:: functional inversion @num
+
+ This does the same thing as :n:`intros until @num` folowed by
+ :n:`functional inversion @ident` where :token:`ident` is the
+ identifier for the last introduced hypothesis.
+
+ .. tacv:: functional inversion @ident @qualid
+ functional inversion @num @qualid
+
+ If the hypothesis :token:`ident` (or :token:`num`) has a type of the form
+ :n:`@qualid__1 {+ @term__i } = @qualid__2 {+ @term__j }` where
+ :n:`@qualid__1` and :n:`@qualid__2` are valid candidates to
+ functional inversion, this variant allows choosing which :token:`qualid`
+ is inverted.
+
+Classical tactics
+-----------------
+
+In order to ease the proving process, when the Classical module is
+loaded. A few more tactics are available. Make sure to load the module
+using the ``Require Import`` command.
+
+.. tacn:: classical_left
+ classical_right
+ :name: classical_left; classical_right
+
+ These tactics are the analog of :tacn:`left` and :tacn:`right`
+ but using classical logic. They can only be used for
+ disjunctions. Use :tacn:`classical_left` to prove the left part of the
+ disjunction with the assumption that the negation of right part holds.
+ Use :tacn:`classical_right` to prove the right part of the disjunction with
+ the assumption that the negation of left part holds.
+
+.. _tactics-automating:
+
+Automating
+------------
+
+
+.. tacn:: btauto
+ :name: btauto
+
+ The tactic :tacn:`btauto` implements a reflexive solver for boolean
+ tautologies. It solves goals of the form :g:`t = u` where `t` and `u` are
+ constructed over the following grammar:
+
+ .. _btauto_grammar:
+
+ .. productionlist:: sentence
+ t : `x`
+ : true
+ : false
+ : orb `t` `t`
+ : andb `t` `t`
+ : xorb `t` `t`
+ : negb `t`
+ : if `t` then `t` else `t`
+
+ Whenever the formula supplied is not a tautology, it also provides a
+ counter-example.
+
+ Internally, it uses a system very similar to the one of the ring
+ tactic.
+
+ Note that this tactic is only available after a ``Require Import Btauto``.
+
+ .. exn:: Cannot recognize a boolean equality.
+
+ The goal is not of the form :g:`t = u`. Especially note that :tacn:`btauto`
+ doesn't introduce variables into the context on its own.
+
+.. tacn:: omega
+ :name: omega
+
+ The tactic :tacn:`omega`, due to Pierre Crégut, is an automatic decision
+ procedure for Presburger arithmetic. It solves quantifier-free
+ formulas built with `~`, `\/`, `/\`, `->` on top of equalities,
+ inequalities and disequalities on both the type :g:`nat` of natural numbers
+ and :g:`Z` of binary integers. This tactic must be loaded by the command
+ ``Require Import Omega``. See the additional documentation about omega
+ (see Chapter :ref:`omega`).
+
+
+.. tacn:: ring
+ :name: ring
+
+ This tactic solves equations upon polynomial expressions of a ring
+ (or semiring) structure. It proceeds by normalizing both hand sides
+ of the equation (w.r.t. associativity, commutativity and
+ distributivity, constant propagation) and comparing syntactically the
+ results.
+
+.. tacn:: ring_simplify {* @term}
+ :name: ring_simplify
+
+ This tactic applies the normalization procedure described above to
+ the given terms. The tactic then replaces all occurrences of the terms
+ given in the conclusion of the goal by their normal forms. If no term
+ is given, then the conclusion should be an equation and both hand
+ sides are normalized.
+
+See :ref:`Theringandfieldtacticfamilies` for more information on
+the tactic and how to declare new ring structures. All declared field structures
+can be printed with the ``Print Rings`` command.
+
+.. tacn:: field
+ field_simplify {* @term}
+ field_simplify_eq
+ :name: field; field_simplify; field_simplify_eq
+
+ The field tactic is built on the same ideas as ring: this is a
+ reflexive tactic that solves or simplifies equations in a field
+ structure. The main idea is to reduce a field expression (which is an
+ extension of ring expressions with the inverse and division
+ operations) to a fraction made of two polynomial expressions.
+
+ Tactic :n:`field` is used to solve subgoals, whereas :n:`field_simplify {+ @term}`
+ replaces the provided terms by their reduced fraction.
+ :n:`field_simplify_eq` applies when the conclusion is an equation: it
+ simplifies both hand sides and multiplies so as to cancel
+ denominators. So it produces an equation without division nor inverse.
+
+ All of these 3 tactics may generate a subgoal in order to prove that
+ denominators are different from zero.
+
+ See :ref:`Theringandfieldtacticfamilies` for more information on the tactic and how to
+ declare new field structures. All declared field structures can be
+ printed with the Print Fields command.
+
+.. example::
+
+ .. coqtop:: reset all
+
+ Require Import Reals.
+ Goal forall x y:R,
+ (x * y > 0)%R ->
+ (x * (1 / x + x / (x + y)))%R =
+ ((- 1 / y) * y * (- x * (x / (x + y)) - 1))%R.
+
+ intros; field.
+
+.. seealso::
+
+ File plugins/setoid_ring/RealField.v for an example of instantiation,
+ theory theories/Reals for many examples of use of field.
+
+Non-logical tactics
+------------------------
+
+
+.. tacn:: cycle @num
+ :name: cycle
+
+ This tactic puts the :n:`@num` first goals at the end of the list of goals.
+ If :n:`@num` is negative, it will put the last :math:`|num|` goals at the
+ beginning of the list.
+
+.. example::
+
+ .. coqtop:: all reset
+
+ Parameter P : nat -> Prop.
+ Goal P 1 /\ P 2 /\ P 3 /\ P 4 /\ P 5.
+ repeat split.
+ all: cycle 2.
+ all: cycle -3.
+
+.. tacn:: swap @num @num
+ :name: swap
+
+ This tactic switches the position of the goals of indices :n:`@num` and
+ :n:`@num`. If either :n:`@num` or :n:`@num` is negative then goals are
+ counted from the end of the focused goal list. Goals are indexed from 1,
+ there is no goal with position 0.
+
+.. example::
+
+ .. coqtop:: reset all
+
+ Parameter P : nat -> Prop.
+ Goal P 1 /\ P 2 /\ P 3 /\ P 4 /\ P 5.
+ repeat split.
+ all: swap 1 3.
+ all: swap 1 -1.
+
+.. tacn:: revgoals
+ :name: revgoals
+
+ This tactics reverses the list of the focused goals.
+
+ .. example::
+
+ .. coqtop:: all reset
+
+ Parameter P : nat -> Prop.
+ Goal P 1 /\ P 2 /\ P 3 /\ P 4 /\ P 5.
+ repeat split.
+ all: revgoals.
+
+.. tacn:: shelve
+ :name: shelve
+
+ This tactic moves all goals under focus to a shelf. While on the
+ shelf, goals will not be focused on. They can be solved by
+ unification, or they can be called back into focus with the command
+ :cmd:`Unshelve`.
+
+ .. tacv:: shelve_unifiable
+ :name: shelve_unifiable
+
+ Shelves only the goals under focus that are mentioned in other goals.
+ Goals that appear in the type of other goals can be solved by unification.
+
+ .. example::
+
+ .. coqtop:: all reset
+
+ Goal exists n, n=0.
+ refine (ex_intro _ _ _).
+ all: shelve_unifiable.
+ reflexivity.
+
+.. cmd:: Unshelve
+
+ This command moves all the goals on the shelf (see :tacn:`shelve`)
+ from the shelf into focus, by appending them to the end of the current
+ list of focused goals.
+
+.. tacn:: give_up
+ :name: give_up
+
+ This tactic removes the focused goals from the proof. They are not
+ solved, and cannot be solved later in the proof. As the goals are not
+ solved, the proof cannot be closed.
+
+ The ``give_up`` tactic can be used while editing a proof, to choose to
+ write the proof script in a non-sequential order.
+
+Simple tactic macros
+-------------------------
+
+A simple example has more value than a long explanation:
+
+.. example::
+
+ .. coqtop:: reset all
+
+ Ltac Solve := simpl; intros; auto.
+
+ Ltac ElimBoolRewrite b H1 H2 :=
+ elim b; [ intros; rewrite H1; eauto | intros; rewrite H2; eauto ].
+
+The tactics macros are synchronous with the Coq section mechanism: a
+tactic definition is deleted from the current environment when you
+close the section (see also :ref:`section-mechanism`) where it was
+defined. If you want that a tactic macro defined in a module is usable in the
+modules that require it, you should put it outside of any section.
+
+:ref:`ltac` gives examples of more complex
+user-defined tactics.
+
+.. [1] Actually, only the second subgoal will be generated since the
+ other one can be automatically checked.
+.. [2] This corresponds to the cut rule of sequent calculus.
+.. [3] Reminder: opaque constants will not be expanded by δ reductions.
+.. [4] The behavior of this tactic has changed a lot compared to the
+ versions available in the previous distributions (V6). This may cause
+ significant changes in your theories to obtain the same result. As a
+ drawback of the re-engineering of the code, this tactic has also been
+ completely revised to get a very compact and readable version.
+
+Delaying solving unification constraints
+----------------------------------------
+
+.. tacn:: solve_constraints
+ :name: solve_constraints
+ :undocumented:
+
+.. flag:: Solve Unification Constraints
+
+ By default, after each tactic application, postponed typechecking unification
+ problems are resolved using heuristics. Unsetting this flag disables this
+ behavior, allowing tactics to leave unification constraints unsolved. Use the
+ :tacn:`solve_constraints` tactic at any point to solve the constraints.
+
+Proof maintenance
+-----------------
+
+*Experimental.* Many tactics, such as :tacn:`intros`, can automatically generate names, such
+as "H0" or "H1" for a new hypothesis introduced from a goal. Subsequent proof steps
+may explicitly refer to these names. However, future versions of Coq may not assign
+names exactly the same way, which could cause the proof to fail because the
+new names don't match the explicit references in the proof.
+
+The following "Mangle Names" settings let users find all the
+places where proofs rely on automatically generated names, which can
+then be named explicitly to avoid any incompatibility. These
+settings cause Coq to generate different names, producing errors for
+references to automatically generated names.
+
+.. flag:: Mangle Names
+
+ When set, generated names use the prefix specified in the following
+ option instead of the default prefix.
+
+.. opt:: Mangle Names Prefix @string
+ :name: Mangle Names Prefix
+
+ Specifies the prefix to use when generating names.
diff --git a/doc/sphinx/proof-engine/vernacular-commands.rst b/doc/sphinx/proof-engine/vernacular-commands.rst
new file mode 100644
index 0000000000..e207a072cc
--- /dev/null
+++ b/doc/sphinx/proof-engine/vernacular-commands.rst
@@ -0,0 +1,1282 @@
+.. _vernacularcommands:
+
+Vernacular commands
+=============================
+
+.. _displaying:
+
+Displaying
+--------------
+
+
+.. _Print:
+
+.. cmd:: Print @qualid
+ :name: Print
+
+ This command displays on the screen information about the declared or
+ defined object referred by :n:`@qualid`.
+
+ Error messages:
+
+ .. exn:: @qualid not a defined object.
+ :undocumented:
+
+ .. exn:: Universe instance should have length @num.
+ :undocumented:
+
+ .. exn:: This object does not support universe names.
+ :undocumented:
+
+
+ .. cmdv:: Print Term @qualid
+ :name: Print Term
+
+ This is a synonym of :cmd:`Print` :n:`@qualid` when :n:`@qualid`
+ denotes a global constant.
+
+ .. cmdv:: Print {? Term } @qualid\@@name
+
+ This locally renames the polymorphic universes of :n:`@qualid`.
+ An underscore means the usual name is printed.
+
+
+.. cmd:: About @qualid
+ :name: About
+
+ This displays various information about the object
+ denoted by :n:`@qualid`: its kind (module, constant, assumption, inductive,
+ constructor, abbreviation, …), long name, type, implicit arguments and
+ argument scopes. It does not print the body of definitions or proofs.
+
+ .. cmdv:: About @qualid\@@name
+
+ This locally renames the polymorphic universes of :n:`@qualid`.
+ An underscore means the usual name is printed.
+
+
+.. cmd:: Print All
+
+ This command displays information about the current state of the
+ environment, including sections and modules.
+
+ .. cmdv:: Inspect @num
+ :name: Inspect
+
+ This command displays the :n:`@num` last objects of the
+ current environment, including sections and modules.
+
+ .. cmdv:: Print Section @ident
+
+ The name :n:`@ident` should correspond to a currently open section,
+ this command displays the objects defined since the beginning of this
+ section.
+
+
+.. _flags-options-tables:
+
+Flags, Options and Tables
+-----------------------------
+
+Coq has many settings to control its behavior. Setting types include flags, options
+and tables:
+
+* A :production:`flag` has a boolean value, such as :flag:`Asymmetric Patterns`.
+* An :production:`option` generally has a numeric or string value, such as :opt:`Firstorder Depth`.
+* A :production:`table` contains a set of strings or qualids.
+* In addition, some commands provide settings, such as :cmd:`Extraction Language`.
+
+.. FIXME Convert "Extraction Language" to an option.
+
+Flags, options and tables are identified by a series of identifiers, each with an initial
+capital letter.
+
+.. cmd:: {? Local | Global | Export } Set @flag
+ :name: Set
+
+ Sets :token:`flag` on. Scoping qualifiers are
+ described :ref:`here <set_unset_scope_qualifiers>`.
+
+.. cmd:: {? Local | Global | Export } Unset @flag
+ :name: Unset
+
+ Sets :token:`flag` off. Scoping qualifiers are
+ described :ref:`here <set_unset_scope_qualifiers>`.
+
+.. cmd:: Test @flag
+
+ Prints the current value of :token:`flag`.
+
+
+.. cmd:: {? Local | Global | Export } Set @option ( @num | @string )
+ :name: Set @option
+
+ Sets :token:`option` to the specified value. Scoping qualifiers are
+ described :ref:`here <set_unset_scope_qualifiers>`.
+
+.. cmd:: {? Local | Global | Export } Unset @option
+ :name: Unset @option
+
+ Sets :token:`option` to its default value. Scoping qualifiers are
+ described :ref:`here <set_unset_scope_qualifiers>`.
+
+.. cmd:: Test @option
+
+ Prints the current value of :token:`option`.
+
+.. cmd:: Print Options
+
+ Prints the current value of all flags and options, and the names of all tables.
+
+
+.. cmd:: Add @table ( @string | @qualid )
+ :name: Add @table
+
+ Adds the specified value to :token:`table`.
+
+.. cmd:: Remove @table ( @string | @qualid )
+ :name: Remove @table
+
+ Removes the specified value from :token:`table`.
+
+.. cmd:: Test @table for ( @string | @qualid )
+ :name: Test @table for
+
+ Reports whether :token:`table` contains the specified value.
+
+.. cmd:: Print Table @table
+ :name: Print Table @table
+
+ Prints the values in :token:`table`.
+
+.. cmd:: Test @table
+
+ A synonym for :cmd:`Print Table @table`.
+
+.. cmd:: Print Tables
+
+ A synonym for :cmd:`Print Options`.
+
+.. _set_unset_scope_qualifiers:
+
+Scope qualifiers for :cmd:`Set` and :cmd:`Unset`
+`````````````````````````````````````````````````
+
+:n:`{? Local | Global | Export }`
+
+Flag and option settings can be global in scope or local to nested scopes created by
+:cmd:`Module` and :cmd:`Section` commands. There are four alternatives:
+
+* no qualifier: the original setting is *not* restored at the end of the current module or section.
+* **Local**: the setting is applied within the current scope. The original value of the option
+ or flag is restored at the end of the current module or section.
+* **Global**: similar to no qualifier, the original setting is *not* restored at the end of the current
+ module or section. In addition, if the value is set in a file, then :cmd:`Require`-ing
+ the file sets the option.
+* **Export**: similar to **Local**, the original value of the option or flag is restored at the
+ end of the current module or section. In addition, if the value is set in a file, then :cmd:`Import`-ing
+ the file sets the option.
+
+Newly opened scopes inherit the current settings.
+
+.. _requests-to-the-environment:
+
+Requests to the environment
+-------------------------------
+
+.. cmd:: Check @term
+
+ This command displays the type of :n:`@term`. When called in proof mode, the
+ term is checked in the local context of the current subgoal.
+
+
+ .. TODO : selector is not a syntax entry
+
+ .. cmdv:: @selector: Check @term
+
+ This variant specifies on which subgoal to perform typing
+ (see Section :ref:`invocation-of-tactics`).
+
+
+.. TODO : convtactic is not a syntax entry
+
+.. cmd:: Eval @convtactic in @term
+
+ This command performs the specified reduction on :n:`@term`, and displays
+ the resulting term with its type. The term to be reduced may depend on
+ hypothesis introduced in the first subgoal (if a proof is in
+ progress).
+
+ .. seealso:: Section :ref:`performingcomputations`.
+
+
+.. cmd:: Compute @term
+
+ This command performs a call-by-value evaluation of term by using the
+ bytecode-based virtual machine. It is a shortcut for ``Eval vm_compute in``
+ :n:`@term`.
+
+ .. seealso:: Section :ref:`performingcomputations`.
+
+
+.. cmd:: Print Assumptions @qualid
+
+ This commands display all the assumptions (axioms, parameters and
+ variables) a theorem or definition depends on. Especially, it informs
+ on the assumptions with respect to which the validity of a theorem
+ relies.
+
+ .. cmdv:: Print Opaque Dependencies @qualid
+ :name: Print Opaque Dependencies
+
+ Displays the set of opaque constants :n:`@qualid` relies on in addition to
+ the assumptions.
+
+ .. cmdv:: Print Transparent Dependencies @qualid
+ :name: Print Transparent Dependencies
+
+ Displays the set of transparent constants :n:`@qualid` relies on
+ in addition to the assumptions.
+
+ .. cmdv:: Print All Dependencies @qualid
+ :name: Print All Dependencies
+
+ Displays all assumptions and constants :n:`@qualid` relies on.
+
+
+.. cmd:: Search @qualid
+
+ This command displays the name and type of all objects (hypothesis of
+ the current goal, theorems, axioms, etc) of the current context whose
+ statement contains :n:`@qualid`. This command is useful to remind the user
+ of the name of library lemmas.
+
+ .. exn:: The reference @qualid was not found in the current environment.
+
+ There is no constant in the environment named qualid.
+
+ .. cmdv:: Search @string
+
+ If :n:`@string` is a valid identifier, this command
+ displays the name and type of all objects (theorems, axioms, etc) of
+ the current context whose name contains string. If string is a
+ notation’s string denoting some reference :n:`@qualid` (referred to by its
+ main symbol as in `"+"` or by its notation’s string as in `"_ + _"` or
+ `"_ 'U' _"`, see Section :ref:`notations`), the command works like ``Search`` :n:`@qualid`.
+
+ .. cmdv:: Search @string%@key
+
+ The string string must be a notation or the main
+ symbol of a notation which is then interpreted in the scope bound to
+ the delimiting key :n:`@key` (see Section :ref:`LocalInterpretationRulesForNotations`).
+
+ .. cmdv:: Search @term_pattern
+
+ This searches for all statements or types of
+ definition that contains a subterm that matches the pattern
+ :token:`term_pattern` (holes of the pattern are either denoted by `_` or by
+ :n:`?@ident` when non linear patterns are expected).
+
+ .. cmdv:: Search { + [-]@term_pattern_string }
+
+ where
+ :n:`@term_pattern_string` is a term_pattern, a string, or a string followed
+ by a scope delimiting key `%key`. This generalization of ``Search`` searches
+ for all objects whose statement or type contains a subterm matching
+ :n:`@term_pattern` (or :n:`@qualid` if :n:`@string` is the notation for a reference
+ qualid) and whose name contains all string of the request that
+ correspond to valid identifiers. If a term_pattern or a string is
+ prefixed by `-`, the search excludes the objects that mention that
+ term_pattern or that string.
+
+ .. cmdv:: Search @term_pattern_string … @term_pattern_string inside {+ @qualid }
+
+ This restricts the search to constructions defined in the modules
+ named by the given :n:`qualid` sequence.
+
+ .. cmdv:: Search @term_pattern_string … @term_pattern_string outside {+ @qualid }
+
+ This restricts the search to constructions not defined in the modules
+ named by the given :n:`qualid` sequence.
+
+ .. cmdv:: @selector: Search [-]@term_pattern_string … [-]@term_pattern_string
+
+ This specifies the goal on which to search hypothesis (see
+ Section :ref:`invocation-of-tactics`).
+ By default the 1st goal is searched. This variant can
+ be combined with other variants presented here.
+
+ .. example::
+
+ .. coqtop:: in
+
+ Require Import ZArith.
+
+ .. coqtop:: all
+
+ Search Z.mul Z.add "distr".
+
+ Search "+"%Z "*"%Z "distr" -positive -Prop.
+
+ Search (?x * _ + ?x * _)%Z outside OmegaLemmas.
+
+ .. cmdv:: SearchAbout
+ :name: SearchAbout
+
+ .. deprecated:: 8.5
+
+ Up to |Coq| version 8.4, :cmd:`Search` had the behavior of current
+ :cmd:`SearchHead` and the behavior of current :cmd:`Search` was obtained with
+ command :cmd:`SearchAbout`. For compatibility, the deprecated name
+ :cmd:`SearchAbout` can still be used as a synonym of :cmd:`Search`. For
+ compatibility, the list of objects to search when using :cmd:`SearchAbout`
+ may also be enclosed by optional ``[ ]`` delimiters.
+
+
+.. cmd:: SearchHead @term
+
+ This command displays the name and type of all hypothesis of the
+ current goal (if any) and theorems of the current context whose
+ statement’s conclusion has the form `(term t1 .. tn)`. This command is
+ useful to remind the user of the name of library lemmas.
+
+ .. example::
+
+ .. coqtop:: reset all
+
+ SearchHead le.
+
+ SearchHead (@eq bool).
+
+ .. cmdv:: SearchHead @term inside {+ @qualid }
+
+ This restricts the search to constructions defined in the modules named
+ by the given :n:`qualid` sequence.
+
+ .. cmdv:: SearchHead term outside {+ @qualid }
+
+ This restricts the search to constructions not defined in the modules
+ named by the given :n:`qualid` sequence.
+
+ .. exn:: Module/section @qualid not found.
+
+ No module :n:`@qualid` has been required (see Section :ref:`compiled-files`).
+
+ .. cmdv:: @selector: SearchHead @term
+
+ This specifies the goal on which to
+ search hypothesis (see Section :ref:`invocation-of-tactics`).
+ By default the 1st goal is searched. This variant can be combined
+ with other variants presented here.
+
+ .. note:: Up to |Coq| version 8.4, ``SearchHead`` was named ``Search``.
+
+
+.. cmd:: SearchPattern @term
+
+ This command displays the name and type of all hypothesis of the
+ current goal (if any) and theorems of the current context whose
+ statement’s conclusion or last hypothesis and conclusion matches the
+ expressionterm where holes in the latter are denoted by `_`.
+ It is a variant of :n:`Search @term_pattern` that does not look for subterms
+ but searches for statements whose conclusion has exactly the expected
+ form, or whose statement finishes by the given series of
+ hypothesis/conclusion.
+
+ .. example::
+
+ .. coqtop:: in
+
+ Require Import Arith.
+
+ .. coqtop:: all
+
+ SearchPattern (_ + _ = _ + _).
+
+ SearchPattern (nat -> bool).
+
+ SearchPattern (forall l : list _, _ l l).
+
+ Patterns need not be linear: you can express that the same expression
+ must occur in two places by using pattern variables `?ident`.
+
+
+ .. example::
+
+ .. coqtop:: all
+
+ SearchPattern (?X1 + _ = _ + ?X1).
+
+ .. cmdv:: SearchPattern @term inside {+ @qualid }
+
+ This restricts the search to constructions defined in the modules
+ named by the given :n:`qualid` sequence.
+
+ .. cmdv:: SearchPattern @term outside {+ @qualid }
+
+ This restricts the search to constructions not defined in the modules
+ named by the given :n:`qualid` sequence.
+
+ .. cmdv:: @selector: SearchPattern @term
+
+ This specifies the goal on which to
+ search hypothesis (see Section :ref:`invocation-of-tactics`).
+ By default the 1st goal is
+ searched. This variant can be combined with other variants presented
+ here.
+
+
+.. cmd:: SearchRewrite @term
+
+ This command displays the name and type of all hypothesis of the
+ current goal (if any) and theorems of the current context whose
+ statement’s conclusion is an equality of which one side matches the
+ expression term. Holes in term are denoted by “_”.
+
+ .. example::
+
+ .. coqtop:: in
+
+ Require Import Arith.
+
+ .. coqtop:: all
+
+ SearchRewrite (_ + _ + _).
+
+ .. cmdv:: SearchRewrite term inside {+ @qualid }
+
+ This restricts the search to constructions defined in the modules
+ named by the given :n:`qualid` sequence.
+
+ .. cmdv:: SearchRewrite @term outside {+ @qualid }
+
+ This restricts the search to constructions not defined in the modules
+ named by the given :n:`qualid` sequence.
+
+ .. cmdv:: @selector: SearchRewrite @term
+
+ This specifies the goal on which to
+ search hypothesis (see Section :ref:`invocation-of-tactics`).
+ By default the 1st goal is
+ searched. This variant can be combined with other variants presented
+ here.
+
+.. note::
+
+ .. table:: Search Blacklist @string
+ :name: Search Blacklist
+
+ Specifies a set of strings used to exclude lemmas from the results of :cmd:`Search`,
+ :cmd:`SearchHead`, :cmd:`SearchPattern` and :cmd:`SearchRewrite` queries. A lemma whose
+ fully-qualified name contains any of the strings will be excluded from the
+ search results. The default blacklisted substrings are ``_subterm``, ``_subproof`` and
+ ``Private_``.
+
+ Use the :cmd:`Add @table` and :cmd:`Remove @table` commands to update the set of
+ blacklisted strings.
+
+.. cmd:: Locate @qualid
+
+ This command displays the full name of objects whose name is a prefix
+ of the qualified identifier :n:`@qualid`, and consequently the |Coq| module in
+ which they are defined. It searches for objects from the different
+ qualified namespaces of |Coq|: terms, modules, Ltac, etc.
+
+ .. example::
+
+ .. coqtop:: all
+
+ Locate nat.
+
+ Locate Datatypes.O.
+
+ Locate Init.Datatypes.O.
+
+ Locate Coq.Init.Datatypes.O.
+
+ Locate I.Dont.Exist.
+
+ .. cmdv:: Locate Term @qualid
+
+ As Locate but restricted to terms.
+
+ .. cmdv:: Locate Module @qualid
+
+ As Locate but restricted to modules.
+
+ .. cmdv:: Locate Ltac @qualid
+
+ As Locate but restricted to tactics.
+
+.. seealso:: Section :ref:`locating-notations`
+
+.. _printing-flags:
+
+Printing flags
+-------------------------------
+
+.. flag:: Fast Name Printing
+
+ When turned on, |Coq| uses an asymptotically faster algorithm for the
+ generation of unambiguous names of bound variables while printing terms.
+ While faster, it is also less clever and results in a typically less elegant
+ display, e.g. it will generate more names rather than reusing certain names
+ across subterms. This flag is not enabled by default, because as Ltac
+ observes bound names, turning it on can break existing proof scripts.
+
+
+.. _loading-files:
+
+Loading files
+-----------------
+
+|Coq| offers the possibility of loading different parts of a whole
+development stored in separate files. Their contents will be loaded as
+if they were entered from the keyboard. This means that the loaded
+files are ASCII files containing sequences of commands for |Coq|’s
+toplevel. This kind of file is called a *script* for |Coq|. The standard
+(and default) extension of |Coq|’s script files is .v.
+
+
+.. cmd:: Load @ident
+
+ This command loads the file named :n:`ident`.v, searching successively in
+ each of the directories specified in the *loadpath*. (see Section
+ :ref:`libraries-and-filesystem`)
+
+ Files loaded this way cannot leave proofs open, and the ``Load``
+ command cannot be used inside a proof either.
+
+ .. cmdv:: Load @string
+
+ Loads the file denoted by the string :n:`@string`, where
+ string is any complete filename. Then the `~` and .. abbreviations are
+ allowed as well as shell variables. If no extension is specified, |Coq|
+ will use the default extension ``.v``.
+
+ .. cmdv:: Load Verbose @ident
+ Load Verbose @string
+
+ Display, while loading,
+ the answers of |Coq| to each command (including tactics) contained in
+ the loaded file.
+
+ .. seealso:: Section :ref:`controlling-display`.
+
+ .. exn:: Can’t find file @ident on loadpath.
+ :undocumented:
+
+ .. exn:: Load is not supported inside proofs.
+ :undocumented:
+
+ .. exn:: Files processed by Load cannot leave open proofs.
+ :undocumented:
+
+.. _compiled-files:
+
+Compiled files
+------------------
+
+This section describes the commands used to load compiled files (see
+Chapter :ref:`thecoqcommands` for documentation on how to compile a file). A compiled
+file is a particular case of module called *library file*.
+
+
+.. cmd:: Require @qualid
+
+ This command looks in the loadpath for a file containing module :n:`@qualid`
+ and adds the corresponding module to the environment of |Coq|. As
+ library files have dependencies in other library files, the command
+ :cmd:`Require` :n:`@qualid` recursively requires all library files the module
+ qualid depends on and adds the corresponding modules to the
+ environment of |Coq| too. |Coq| assumes that the compiled files have been
+ produced by a valid |Coq| compiler and their contents are then not
+ replayed nor rechecked.
+
+ To locate the file in the file system, :n:`@qualid` is decomposed under the
+ form :n:`dirpath.@ident` and the file :n:`@ident.vo` is searched in the physical
+ directory of the file system that is mapped in |Coq| loadpath to the
+ logical path dirpath (see Section :ref:`libraries-and-filesystem`). The mapping between
+ physical directories and logical names at the time of requiring the
+ file must be consistent with the mapping used to compile the file. If
+ several files match, one of them is picked in an unspecified fashion.
+
+
+ .. cmdv:: Require Import @qualid
+ :name: Require Import
+
+ This loads and declares the module :n:`@qualid`
+ and its dependencies then imports the contents of :n:`@qualid` as described
+ :ref:`here <import_qualid>`. It does not import the modules on which
+ qualid depends unless these modules were themselves required in module
+ :n:`@qualid`
+ using :cmd:`Require Export`, as described below, or recursively required
+ through a sequence of :cmd:`Require Export`. If the module required has
+ already been loaded, :cmd:`Require Import` :n:`@qualid` simply imports it, as
+ :cmd:`Import` :n:`@qualid` would.
+
+ .. cmdv:: Require Export @qualid
+ :name: Require Export
+
+ This command acts as :cmd:`Require Import` :n:`@qualid`,
+ but if a further module, say `A`, contains a command :cmd:`Require Export` `B`,
+ then the command :cmd:`Require Import` `A` also imports the module `B.`
+
+ .. cmdv:: Require [Import | Export] {+ @qualid }
+
+ This loads the
+ modules named by the :token:`qualid` sequence and their recursive
+ dependencies. If
+ ``Import`` or ``Export`` is given, it also imports these modules and
+ all the recursive dependencies that were marked or transitively marked
+ as ``Export``.
+
+ .. cmdv:: From @dirpath Require @qualid
+
+ This command acts as :cmd:`Require`, but picks
+ any library whose absolute name is of the form :n:`@dirpath.@dirpath’.@qualid`
+ for some :n:`@dirpath’`. This is useful to ensure that the :token:`qualid` library
+ comes from a given package by making explicit its absolute root.
+
+ .. exn:: Cannot load qualid: no physical path bound to dirpath.
+ :undocumented:
+
+ .. exn:: Cannot find library foo in loadpath.
+
+ The command did not find the
+ file foo.vo. Either foo.v exists but is not compiled or foo.vo is in a
+ directory which is not in your LoadPath (see Section :ref:`libraries-and-filesystem`).
+
+ .. exn:: Compiled library @ident.vo makes inconsistent assumptions over library qualid.
+
+ The command tried to load library file :n:`@ident`.vo that
+ depends on some specific version of library :n:`@qualid` which is not the
+ one already loaded in the current |Coq| session. Probably :n:`@ident.v` was
+ not properly recompiled with the last version of the file containing
+ module :token:`qualid`.
+
+ .. exn:: Bad magic number.
+
+ The file :n:`@ident.vo` was found but either it is not a
+ |Coq| compiled module, or it was compiled with an incompatible
+ version of |Coq|.
+
+ .. exn:: The file :n:`@ident.vo` contains library dirpath and not library dirpath’.
+
+ The library file :n:`@dirpath’` is indirectly required by the
+ ``Require`` command but it is bound in the current loadpath to the
+ file :n:`@ident.vo` which was bound to a different library name :token:`dirpath` at
+ the time it was compiled.
+
+
+ .. exn:: Require is not allowed inside a module or a module type.
+
+ This command
+ is not allowed inside a module or a module type being defined. It is
+ meant to describe a dependency between compilation units. Note however
+ that the commands ``Import`` and ``Export`` alone can be used inside modules
+ (see Section :ref:`Import <import_qualid>`).
+
+ .. seealso:: Chapter :ref:`thecoqcommands`
+
+.. cmd:: Print Libraries
+
+ This command displays the list of library files loaded in the
+ current |Coq| session. For each of these libraries, it also tells if it
+ is imported.
+
+
+.. cmd:: Declare ML Module {+ @string }
+
+ This commands loads the OCaml compiled files
+ with names given by the :token:`string` sequence
+ (dynamic link). It is mainly used to load tactics dynamically. The
+ files are searched into the current OCaml loadpath (see the
+ command :cmd:`Add ML Path`).
+ Loading of OCaml files is only possible under the bytecode version of
+ ``coqtop`` (i.e. ``coqtop`` called with option ``-byte``, see chapter
+ :ref:`thecoqcommands`), or when |Coq| has been compiled with a
+ version of OCaml that supports native Dynlink (≥ 3.11).
+
+ .. cmdv:: Local Declare ML Module {+ @string }
+
+ This variant is not exported to the modules that import the module
+ where they occur, even if outside a section.
+
+ .. exn:: File not found on loadpath: @string.
+ :undocumented:
+
+ .. exn:: Loading of ML object file forbidden in a native Coq.
+ :undocumented:
+
+
+.. cmd:: Print ML Modules
+
+ This prints the name of all OCaml modules loaded with :cmd:`Declare ML Module`.
+ To know from where these module were loaded, the user
+ should use the command :cmd:`Locate File`.
+
+
+.. _loadpath:
+
+Loadpath
+------------
+
+Loadpaths are preferably managed using |Coq| command line options (see
+Section `libraries-and-filesystem`) but there remain vernacular commands to manage them
+for practical purposes. Such commands are only meant to be issued in
+the toplevel, and using them in source files is discouraged.
+
+
+.. cmd:: Pwd
+
+ This command displays the current working directory.
+
+
+.. cmd:: Cd @string
+
+ This command changes the current directory according to :token:`string` which
+ can be any valid path.
+
+ .. cmdv:: Cd
+
+ Is equivalent to Pwd.
+
+
+.. cmd:: Add LoadPath @string as @dirpath
+
+ This command is equivalent to the command line option
+ :n:`-Q @string @dirpath`. It adds the physical directory string to the current
+ |Coq| loadpath and maps it to the logical directory dirpath.
+
+ .. cmdv:: Add LoadPath @string
+
+ Performs as :n:`Add LoadPath @string @dirpath` but
+ for the empty directory path.
+
+
+.. cmd:: Add Rec LoadPath @string as @dirpath
+
+ This command is equivalent to the command line option
+ :n:`-R @string @dirpath`. It adds the physical directory string and all its
+ subdirectories to the current |Coq| loadpath.
+
+ .. cmdv:: Add Rec LoadPath @string
+
+ Works as :n:`Add Rec LoadPath @string as @dirpath` but for the empty
+ logical directory path.
+
+
+.. cmd:: Remove LoadPath @string
+
+ This command removes the path :n:`@string` from the current |Coq| loadpath.
+
+
+.. cmd:: Print LoadPath
+
+ This command displays the current |Coq| loadpath.
+
+ .. cmdv:: Print LoadPath @dirpath
+
+ Works as :cmd:`Print LoadPath` but displays only
+ the paths that extend the :n:`@dirpath` prefix.
+
+
+.. cmd:: Add ML Path @string
+
+ This command adds the path :n:`@string` to the current OCaml
+ loadpath (see the command `Declare ML Module`` in Section :ref:`compiled-files`).
+
+
+.. cmd:: Add Rec ML Path @string
+
+ This command adds the directory :n:`@string` and all its subdirectories to
+ the current OCaml loadpath (see the command :cmd:`Declare ML Module`).
+
+
+.. cmd:: Print ML Path @string
+
+ This command displays the current OCaml loadpath. This
+ command makes sense only under the bytecode version of ``coqtop``, i.e.
+ using option ``-byte``
+ (see the command Declare ML Module in Section :ref:`compiled-files`).
+
+.. _locate-file:
+
+.. cmd:: Locate File @string
+
+ This command displays the location of file string in the current
+ loadpath. Typically, string is a ``.cmo`` or ``.vo`` or ``.v`` file.
+
+
+.. cmd:: Locate Library @dirpath
+
+ This command gives the status of the |Coq| module dirpath. It tells if
+ the module is loaded and if not searches in the load path for a module
+ of logical name :n:`@dirpath`.
+
+
+.. _backtracking:
+
+Backtracking
+----------------
+
+The backtracking commands described in this section can only be used
+interactively, they cannot be part of a vernacular file loaded via
+``Load`` or compiled by ``coqc``.
+
+
+.. cmd:: Reset @ident
+
+ This command removes all the objects in the environment since :n:`@ident`
+ was introduced, including :n:`@ident`. :n:`@ident` may be the name of a defined or
+ declared object as well as the name of a section. One cannot reset
+ over the name of a module or of an object inside a module.
+
+ .. exn:: @ident: no such entry.
+ :undocumented:
+
+ .. cmdv:: Reset Initial
+
+ Goes back to the initial state, just after the start
+ of the interactive session.
+
+
+.. cmd:: Back
+
+ This command undoes all the effects of the last vernacular command.
+ Commands read from a vernacular file via a :cmd:`Load` are considered as a
+ single command. Proof management commands are also handled by this
+ command (see Chapter :ref:`proofhandling`). For that, Back may have to undo more than
+ one command in order to reach a state where the proof management
+ information is available. For instance, when the last command is a
+ :cmd:`Qed`, the management information about the closed proof has been
+ discarded. In this case, :cmd:`Back` will then undo all the proof steps up to
+ the statement of this proof.
+
+ .. cmdv:: Back @num
+
+ Undo :n:`@num` vernacular commands. As for Back, some extra
+ commands may be undone in order to reach an adequate state. For
+ instance Back :n:`@num` will not re-enter a closed proof, but rather go just
+ before that proof.
+
+ .. exn:: Invalid backtrack.
+
+ The user wants to undo more commands than available in the history.
+
+.. cmd:: BackTo @num
+
+ This command brings back the system to the state labeled :n:`@num`,
+ forgetting the effect of all commands executed after this state. The
+ state label is an integer which grows after each successful command.
+ It is displayed in the prompt when in -emacs mode. Just as :cmd:`Back` (see
+ above), the :cmd:`BackTo` command now handles proof states. For that, it may
+ have to undo some extra commands and end on a state :n:`@num′ ≤ @num` if
+ necessary.
+
+ .. cmdv:: Backtrack @num @num @num
+ :name: Backtrack
+
+ .. deprecated:: 8.4
+
+ :cmd:`Backtrack` is a *deprecated* form of
+ :cmd:`BackTo` which allows explicitly manipulating the proof environment. The
+ three numbers represent the following:
+
+ + *first number* : State label to reach, as for :cmd:`BackTo`.
+ + *second number* : *Proof state number* to unbury once aborts have been done.
+ |Coq| will compute the number of :cmd:`Undo` to perform (see Chapter :ref:`proofhandling`).
+ + *third number* : Number of :cmd:`Abort` to perform, i.e. the number of currently
+ opened nested proofs that must be canceled (see Chapter :ref:`proofhandling`).
+
+ .. exn:: Invalid backtrack.
+
+ The destination state label is unknown.
+
+
+.. _quitting-and-debugging:
+
+Quitting and debugging
+--------------------------
+
+
+.. cmd:: Quit
+
+ This command permits to quit |Coq|.
+
+
+.. cmd:: Drop
+
+ This is used mostly as a debug facility by |Coq|’s implementers and does
+ not concern the casual user. This command permits to leave |Coq|
+ temporarily and enter the OCaml toplevel. The OCaml
+ command:
+
+ ::
+
+ #use "include";;
+
+ adds the right loadpaths and loads some toplevel printers for all
+ abstract types of |Coq|- section_path, identifiers, terms, judgments, ….
+ You can also use the file base_include instead, that loads only the
+ pretty-printers for section_paths and identifiers. You can return back
+ to |Coq| with the command:
+
+ ::
+
+ go();;
+
+ .. warning::
+
+ #. It only works with the bytecode version of |Coq| (i.e. `coqtop.byte`,
+ see Section `interactive-use`).
+ #. You must have compiled |Coq| from the source package and set the
+ environment variable COQTOP to the root of your copy of the sources
+ (see Section `customization-by-environment-variables`).
+
+
+.. TODO : command is not a syntax entry
+
+.. cmd:: Time @command
+
+ This command executes the vernacular command :n:`@command` and displays the
+ time needed to execute it.
+
+
+.. cmd:: Redirect @string @command
+
+ This command executes the vernacular command :n:`@command`, redirecting its
+ output to ":n:`@string`.out".
+
+
+.. cmd:: Timeout @num @command
+
+ This command executes the vernacular command :n:`@command`. If the command
+ has not terminated after the time specified by the :n:`@num` (time
+ expressed in seconds), then it is interrupted and an error message is
+ displayed.
+
+ .. opt:: Default Timeout @num
+ :name: Default Timeout
+
+ This option controls a default timeout for subsequent commands, as if they
+ were passed to a :cmd:`Timeout` command. Commands already starting by a
+ :cmd:`Timeout` are unaffected.
+
+
+.. cmd:: Fail @command
+
+ For debugging scripts, sometimes it is desirable to know
+ whether a command or a tactic fails. If the given :n:`@command`
+ fails, the ``Fail`` statement succeeds, without changing the proof
+ state, and in interactive mode, the system
+ prints a message confirming the failure.
+ If the given :n:`@command` succeeds, the statement is an error, and
+ it prints a message indicating that the failure did not occur.
+
+ .. exn:: The command has not failed!
+ :undocumented:
+
+
+.. _controlling-display:
+
+Controlling display
+-----------------------
+
+.. flag:: Silent
+
+ This option controls the normal displaying.
+
+.. opt:: Warnings "{+, {? %( - %| + %) } @ident }"
+ :name: Warnings
+
+ This option configures the display of warnings. It is experimental, and
+ expects, between quotes, a comma-separated list of warning names or
+ categories. Adding - in front of a warning or category disables it, adding +
+ makes it an error. It is possible to use the special categories all and
+ default, the latter containing the warnings enabled by default. The flags are
+ interpreted from left to right, so in case of an overlap, the flags on the
+ right have higher priority, meaning that `A,-A` is equivalent to `-A`.
+
+.. flag:: Search Output Name Only
+
+ This option restricts the output of search commands to identifier names;
+ turning it on causes invocations of :cmd:`Search`, :cmd:`SearchHead`,
+ :cmd:`SearchPattern`, :cmd:`SearchRewrite` etc. to omit types from their
+ output, printing only identifiers.
+
+.. opt:: Printing Width @num
+ :name: Printing Width
+
+ This command sets which left-aligned part of the width of the screen is used
+ for display. At the time of writing this documentation, the default value
+ is 78.
+
+.. opt:: Printing Depth @num
+ :name: Printing Depth
+
+ This option controls the nesting depth of the formatter used for pretty-
+ printing. Beyond this depth, display of subterms is replaced by dots. At the
+ time of writing this documentation, the default value is 50.
+
+.. flag:: Printing Compact Contexts
+
+ This option controls the compact display mode for goals contexts. When on,
+ the printer tries to reduce the vertical size of goals contexts by putting
+ several variables (even if of different types) on the same line provided it
+ does not exceed the printing width (see :opt:`Printing Width`). At the time
+ of writing this documentation, it is off by default.
+
+.. flag:: Printing Unfocused
+
+ This option controls whether unfocused goals are displayed. Such goals are
+ created by focusing other goals with bullets (see :ref:`bullets` or
+ :ref:`curly braces <curly-braces>`). It is off by default.
+
+.. flag:: Printing Dependent Evars Line
+
+ This option controls the printing of the “(dependent evars: …)” line when
+ ``-emacs`` is passed.
+
+
+.. _vernac-controlling-the-reduction-strategies:
+
+Controlling the reduction strategies and the conversion algorithm
+----------------------------------------------------------------------
+
+
+|Coq| provides reduction strategies that the tactics can invoke and two
+different algorithms to check the convertibility of types. The first
+conversion algorithm lazily compares applicative terms while the other
+is a brute-force but efficient algorithm that first normalizes the
+terms before comparing them. The second algorithm is based on a
+bytecode representation of terms similar to the bytecode
+representation used in the ZINC virtual machine :cite:`Leroy90`. It is
+especially useful for intensive computation of algebraic values, such
+as numbers, and for reflection-based tactics. The commands to fine-
+tune the reduction strategies and the lazy conversion algorithm are
+described first.
+
+.. cmd:: Opaque {+ @qualid }
+
+ This command has an effect on unfoldable constants, i.e. on constants
+ defined by :cmd:`Definition` or :cmd:`Let` (with an explicit body), or by a command
+ assimilated to a definition such as :cmd:`Fixpoint`, :cmd:`Program Definition`, etc,
+ or by a proof ended by :cmd:`Defined`. The command tells not to unfold the
+ constants in the :n:`@qualid` sequence in tactics using δ-conversion (unfolding
+ a constant is replacing it by its definition).
+
+ :cmd:`Opaque` has also an effect on the conversion algorithm of |Coq|, telling
+ it to delay the unfolding of a constant as much as possible when |Coq|
+ has to check the conversion (see Section :ref:`conversion-rules`) of two distinct
+ applied constants.
+
+ .. cmdv:: Global Opaque {+ @qualid }
+ :name: Global Opaque
+
+ The scope of :cmd:`Opaque` is limited to the current section, or current
+ file, unless the variant :cmd:`Global Opaque` is used.
+
+ .. seealso::
+
+ Sections :ref:`performingcomputations`, :ref:`tactics-automating`,
+ :ref:`proof-editing-mode`
+
+ .. exn:: The reference @qualid was not found in the current environment.
+
+ There is no constant referred by :n:`@qualid` in the environment.
+ Nevertheless, if you asked :cmd:`Opaque` `foo` `bar` and if `bar` does
+ not exist, `foo` is set opaque.
+
+.. cmd:: Transparent {+ @qualid }
+
+ This command is the converse of :cmd:`Opaque` and it applies on unfoldable
+ constants to restore their unfoldability after an Opaque command.
+
+ Note in particular that constants defined by a proof ended by Qed are
+ not unfoldable and Transparent has no effect on them. This is to keep
+ with the usual mathematical practice of *proof irrelevance*: what
+ matters in a mathematical development is the sequence of lemma
+ statements, not their actual proofs. This distinguishes lemmas from
+ the usual defined constants, whose actual values are of course
+ relevant in general.
+
+ .. cmdv:: Global Transparent {+ @qualid }
+ :name: Global Transparent
+
+ The scope of Transparent is limited to the current section, or current
+ file, unless the variant :cmd:`Global Transparent` is
+ used.
+
+ .. exn:: The reference @qualid was not found in the current environment.
+
+ There is no constant referred by :n:`@qualid` in the environment.
+
+ .. seealso::
+
+ Sections :ref:`performingcomputations`,
+ :ref:`tactics-automating`, :ref:`proof-editing-mode`
+
+.. _vernac-strategy:
+
+.. cmd:: Strategy @level [ {+ @qualid } ]
+
+ This command generalizes the behavior of Opaque and Transparent
+ commands. It is used to fine-tune the strategy for unfolding
+ constants, both at the tactic level and at the kernel level. This
+ command associates a level to the qualified names in the :n:`@qualid`
+ sequence. Whenever two
+ expressions with two distinct head constants are compared (for
+ instance, this comparison can be triggered by a type cast), the one
+ with lower level is expanded first. In case of a tie, the second one
+ (appearing in the cast type) is expanded.
+
+ Levels can be one of the following (higher to lower):
+
+ + ``opaque`` : level of opaque constants. They cannot be expanded by
+ tactics (behaves like +∞, see next item).
+ + :n:`@num` : levels indexed by an integer. Level 0 corresponds to the
+ default behavior, which corresponds to transparent constants. This
+ level can also be referred to as transparent. Negative levels
+ correspond to constants to be expanded before normal transparent
+ constants, while positive levels correspond to constants to be
+ expanded after normal transparent constants.
+ + ``expand`` : level of constants that should be expanded first (behaves
+ like −∞)
+
+ .. cmdv:: Local Strategy @level [ {+ @qualid } ]
+
+ These directives survive section and module closure, unless the
+ command is prefixed by ``Local``. In the latter case, the behavior
+ regarding sections and modules is the same as for the :cmd:`Transparent` and
+ :cmd:`Opaque` commands.
+
+
+.. cmd:: Print Strategy @qualid
+
+ This command prints the strategy currently associated to :n:`@qualid`. It
+ fails if :n:`@qualid` is not an unfoldable reference, that is, neither a
+ variable nor a constant.
+
+ .. exn:: The reference is not unfoldable.
+ :undocumented:
+
+ .. cmdv:: Print Strategies
+
+ Print all the currently non-transparent strategies.
+
+
+.. cmd:: Declare Reduction @ident := @convtactic
+
+ This command allows giving a short name to a reduction expression, for
+ instance lazy beta delta [foo bar]. This short name can then be used
+ in :n:`Eval @ident in` or ``eval`` directives. This command
+ accepts the
+ Local modifier, for discarding this reduction name at the end of the
+ file or module. For the moment the name cannot be qualified. In
+ particular declaring the same name in several modules or in several
+ functor applications will be refused if these declarations are not
+ local. The name :n:`@ident` cannot be used directly as an Ltac tactic, but
+ nothing prevents the user to also perform a
+ :n:`Ltac @ident := @convtactic`.
+
+ .. seealso:: :ref:`performingcomputations`
+
+
+.. _controlling-locality-of-commands:
+
+Controlling the locality of commands
+-----------------------------------------
+
+
+.. cmd:: Local @command
+ Global @command
+
+ Some commands support a Local or Global prefix modifier to control the
+ scope of their effect. There are four kinds of commands:
+
+
+ + Commands whose default is to extend their effect both outside the
+ section and the module or library file they occur in. For these
+ commands, the Local modifier limits the effect of the command to the
+ current section or module it occurs in. As an example, the :cmd:`Coercion`
+ and :cmd:`Strategy` commands belong to this category.
+ + Commands whose default behavior is to stop their effect at the end
+ of the section they occur in but to extend their effect outside the module or
+ library file they occur in. For these commands, the Local modifier limits the
+ effect of the command to the current module if the command does not occur in a
+ section and the Global modifier extends the effect outside the current
+ sections and current module if the command occurs in a section. As an example,
+ the :cmd:`Arguments`, :cmd:`Ltac` or :cmd:`Notation` commands belong
+ to this category. Notice that a subclass of these commands do not support
+ extension of their scope outside sections at all and the Global modifier is not
+ applicable to them.
+ + Commands whose default behavior is to stop their effect at the end
+ of the section or module they occur in. For these commands, the ``Global``
+ modifier extends their effect outside the sections and modules they
+ occur in. The :cmd:`Transparent` and :cmd:`Opaque`
+ (see Section :ref:`vernac-controlling-the-reduction-strategies`) commands
+ belong to this category.
+ + Commands whose default behavior is to extend their effect outside
+ sections but not outside modules when they occur in a section and to
+ extend their effect outside the module or library file they occur in
+ when no section contains them.For these commands, the Local modifier
+ limits the effect to the current section or module while the Global
+ modifier extends the effect outside the module even when the command
+ occurs in a section. The :cmd:`Set` and :cmd:`Unset` commands belong to this
+ category.
+
+.. _internal-registration-commands:
+
+Internal registration commands
+--------------------------------
+
+Due to their internal nature, the commands that are presented in this section
+are not for general use. They are meant to appear only in standard libraries and
+in support libraries of plug-ins.
+
+.. _exposing-constants-to-ocaml-libraries:
+
+Exposing constants to OCaml libraries
+````````````````````````````````````````````````````````````````
+
+.. cmd:: Register @qualid__1 as @qualid__2
+
+ This command exposes the constant :n:`@qualid__1` to OCaml libraries under
+ the name :n:`@qualid__2`. This constant can then be dynamically located
+ calling :n:`Coqlib.lib_ref "@qualid__2"`; i.e., there is no need to known
+ where is the constant defined (file, module, library, etc.).
+
+ As a special case, when the first segment of :n:`@qualid__2` is :g:`kernel`,
+ the constant is exposed to the kernel. For instance, the `Int63` module
+ features the following declaration:
+
+ .. coqdoc::
+
+ Register bool as kernel.ind_bool.
+
+ This makes the kernel aware of what is the type of boolean values. This
+ information is used for instance to define the return type of the
+ :g:`#int63_eq` primitive.
+
+ .. seealso:: :ref:`primitive-integers`
+
+Inlining hints for the fast reduction machines
+````````````````````````````````````````````````````````````````
+
+.. cmd:: Register Inline @qualid
+
+ This command gives as a hint to the reduction machines (VM and native) that
+ the body of the constant :n:`@qualid` should be inlined in the generated code.
+
+Registering primitive operations
+````````````````````````````````
+
+.. cmd:: Primitive @ident__1 := #@ident__2.
+
+ Declares :n:`@ident__1` as the primitive operator :n:`#@ident__2`. When
+ running this command, the type of the primitive should be already known by
+ the kernel (this is achieved through this command for primitive types and
+ through the :cmd:`Register` command with the :g:`kernel` name-space for other
+ types).