(** * Auto: More Automation *)
Set Warnings "-notation-overridden,-parsing".
(** Up to now, we've used the more manual part of Coq's tactic facilities.  In this chapter, we'll learn more about some of Coq's powerful automation features: proof search via the [auto] tactic, automated forward reasoning via the [Ltac] hypothesis matching machinery, and deferred instantiation of existential variables using [eapply] and [eauto].  Using these features together with Ltac's scripting facilities will enable us to make our proofs startlingly short!  Used properly, they can also make proofs more maintainable and robust to changes in underlying definitions.  A deeper treatment of [auto] and [eauto] can be found in the [UseAuto] chapter.  There's another major category of automation we haven't discussed much yet, namely built-in decision procedures for specific kinds of problems: [omega] is one example, but there are others.  This topic will be deferred for a while longer.  Our motivating example will be this proof, repeated with just a few small changes from the [Imp] chapter.  We will simplify this proof in several stages. *)
Ltac inv H := inversion H; subst; clear H.
(** The [auto] tactic frees us from this drudgery by _searching_ for a sequence of applications that will prove the goal *)
Example auto_example_1' : forall (P Q R: Prop),
(P -> Q) -> (Q -> R) -> P -> R.
(** The [auto] tactic solves goals that are solvable by any combination of - [intros] and - [apply] (of hypotheses from the local context, by default). *)
(** Using [auto] is always "safe" in the sense that it will never fail and will never change the proof state: either it completely solves the current goal, or it does nothing. *)
(** Here is a more interesting example showing [auto]'s power: *)
Example auto_example_2 : forall P Q R S T U : Prop,
(P -> Q) ->
(P -> R) ->
(T -> R) ->
(S -> T -> U) ->
((P->Q) -> (P->S)) ->
T ->
P ->
U.
(** When searching for potential proofs of the current goal, [auto] considers the hypotheses in the current context together with a _hint database_ of other lemmas and constructors.  Some common lemmas about equality and logical operators are installed in this hint database by default. *)
Example auto_example_4 : forall P Q R : Prop,
Q ->
(Q -> R) ->
P \/ (Q /\ R).
(** Of course, in any given development there will probably be some specific constructors and lemmas that are used very often in proofs.  We can add these to the global hint database by writing  Hint Resolve T.  at the top level, where [T] is a top-level theorem or a constructor of an inductively defined proposition (i.e., anything whose type is an implication).  As a shorthand, we can write  Hint Constructors c.  to tell Coq to do a [Hint Resolve] for _all_ of the constructors from the inductive definition of [c].  It is also sometimes necessary to add  Hint Unfold d.  where [d] is a defined symbol, so that [auto] knows to expand uses of [d], thus enabling further possibilities for applying lemmas that it knows about. *)
Hint Resolve le_antisym.
Example auto_example_6' : forall n m p : nat,
(n<= p -> (n <= m /\ m <= n)) ->
n <= p ->
n = m.
Definition is_fortytwo x := x = 42.
Example auto_example_7: forall x, (x <= 42 /\ 42 <= x) -> is_fortytwo x.
(** When we are using a particular tactic many times in a proof, we can use a variant of the [Proof] command to make that tactic into a default within the proof.  Saying [Proof with t] (where [t] is an arbitrary tactic) allows us to use [t1...] as a shorthand for [t1;t] within the proof.  As an illustration, here is an alternate version of the previous proof, using [Proof with auto]. *)

Theorem ceval_deterministic'_alt: forall c st st1 st2,
c / st \\ st1  ->
c / st \\ st2 ->
st1 = st2.