From 61dc740ed1c3780cccaec00d059a28f0d31d0052 Mon Sep 17 00:00:00 2001 From: Stephane Glondu Date: Mon, 4 Jun 2012 12:07:52 +0200 Subject: Imported Upstream version 8.4~gamma0+really8.4beta2 --- doc/refman/RefMan-tacex.tex | 584 -------------------------------------------- 1 file changed, 584 deletions(-) (limited to 'doc/refman/RefMan-tacex.tex') diff --git a/doc/refman/RefMan-tacex.tex b/doc/refman/RefMan-tacex.tex index 8330a434..83a8cd11 100644 --- a/doc/refman/RefMan-tacex.tex +++ b/doc/refman/RefMan-tacex.tex @@ -3,590 +3,6 @@ This chapter presents detailed examples of certain tactics, to illustrate their behavior. -\section[\tt refine]{\tt refine\tacindex{refine} -\label{refine-example}} - -This tactic applies to any goal. It behaves like {\tt exact} with a -big difference : the user can leave some holes (denoted by \texttt{\_} or -{\tt (\_:}{\it type}{\tt )}) in the term. -{\tt refine} will generate as many -subgoals as they are holes in the term. The type of holes must be -either synthesized by the system or declared by an -explicit cast like \verb|(\_:nat->Prop)|. This low-level -tactic can be useful to advanced users. - -%\firstexample -\Example - -\begin{coq_example*} -Inductive Option : Set := - | Fail : Option - | Ok : bool -> Option. -\end{coq_example} -\begin{coq_example} -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. -\end{coq_example} -\begin{coq_example*} -Defined. -\end{coq_example*} - -% \example{Using Refine to build a poor-man's ``Cases'' tactic} - -% \texttt{Refine} is actually the only way for the user to do -% a proof with the same structure as a {\tt Cases} definition. Actually, -% the tactics \texttt{case} (see \ref{case}) and \texttt{Elim} (see -% \ref{elim}) only allow one step of elementary induction. - -% \begin{coq_example*} -% Require Bool. -% Require Arith. -% \end{coq_example*} -% %\begin{coq_eval} -% %Abort. -% %\end{coq_eval} -% \begin{coq_example} -% Definition one_two_or_five := [x:nat] -% Cases x of -% (1) => true -% | (2) => true -% | (5) => true -% | _ => false -% end. -% Goal (x:nat)(Is_true (one_two_or_five x)) -> x=(1)\/x=(2)\/x=(5). -% \end{coq_example} - -% A traditional script would be the following: - -% \begin{coq_example*} -% Destruct x. -% Tauto. -% Destruct n. -% Auto. -% Destruct n0. -% Auto. -% Destruct n1. -% Tauto. -% Destruct n2. -% Tauto. -% Destruct n3. -% Auto. -% Intros; Inversion H. -% \end{coq_example*} - -% With the tactic \texttt{Refine}, it becomes quite shorter: - -% \begin{coq_example*} -% Restart. -% \end{coq_example*} -% \begin{coq_example} -% Refine [x:nat] -% <[y:nat](Is_true (one_two_or_five y))->(y=(1)\/y=(2)\/y=(5))> -% Cases x of -% (1) => [H]? -% | (2) => [H]? -% | (5) => [H]? -% | n => [H](False_ind ? H) -% end; Auto. -% \end{coq_example} -% \begin{coq_eval} -% Abort. -% \end{coq_eval} - -\section[\tt eapply]{\tt eapply\tacindex{eapply} -\label{eapply-example}} -\Example -Assume we have a relation on {\tt nat} which is transitive: - -\begin{coq_example*} -Variable R : nat -> nat -> Prop. -Hypothesis Rtrans : forall x y z:nat, R x y -> R y z -> R x z. -Variables n m p : nat. -Hypothesis Rnm : R n m. -Hypothesis Rmp : R m p. -\end{coq_example*} - -Consider the goal {\tt (R n p)} provable using the transitivity of -{\tt R}: - -\begin{coq_example*} -Goal R n p. -\end{coq_example*} - -The direct application of {\tt Rtrans} with {\tt apply} fails because -no value for {\tt y} in {\tt Rtrans} is found by {\tt apply}: - -\begin{coq_eval} -Set Printing Depth 50. -(********** The following is not correct and should produce **********) -(**** Error: generated subgoal (R n ?17) has metavariables in it *****) -\end{coq_eval} -\begin{coq_example} -apply Rtrans. -\end{coq_example} - -A solution is to rather apply {\tt (Rtrans n m p)}. - -\begin{coq_example} -apply (Rtrans n m p). -\end{coq_example} - -\begin{coq_eval} -Undo. -\end{coq_eval} - -More elegantly, {\tt apply Rtrans with (y:=m)} allows to only mention -the unknown {\tt m}: - -\begin{coq_example} - - apply Rtrans with (y := m). -\end{coq_example} - -\begin{coq_eval} -Undo. -\end{coq_eval} - -Another solution is to mention the proof of {\tt (R x y)} in {\tt -Rtrans}... - -\begin{coq_example} - - apply Rtrans with (1 := Rnm). -\end{coq_example} - -\begin{coq_eval} -Undo. -\end{coq_eval} - -... or the proof of {\tt (R y z)}: - -\begin{coq_example} - - apply Rtrans with (2 := Rmp). -\end{coq_example} - -\begin{coq_eval} -Undo. -\end{coq_eval} - -On the opposite, one can use {\tt eapply} which postpone the problem -of finding {\tt m}. Then one can apply the hypotheses {\tt Rnm} and {\tt -Rmp}. This instantiates the existential variable and completes the proof. - -\begin{coq_example} -eapply Rtrans. -apply Rnm. -apply Rmp. -\end{coq_example} - -\begin{coq_eval} -Reset R. -\end{coq_eval} - -\section[{\tt Scheme}]{{\tt Scheme}\comindex{Scheme} -\label{Scheme-examples}} - -\firstexample -\example{Induction scheme for \texttt{tree} and \texttt{forest}} - -The definition of principle of mutual induction for {\tt tree} and -{\tt forest} over the sort {\tt Set} is defined by the command: - -\begin{coq_eval} -Reset Initial. -Variables A B : - Set. -\end{coq_eval} - -\begin{coq_example*} -Inductive tree : Set := - node : A -> forest -> tree -with forest : Set := - | leaf : B -> forest - | cons : tree -> forest -> forest. - -Scheme tree_forest_rec := Induction for tree Sort Set - with forest_tree_rec := Induction for forest Sort Set. -\end{coq_example*} - -You may now look at the type of {\tt tree\_forest\_rec}: - -\begin{coq_example} -Check tree_forest_rec. -\end{coq_example} - -This principle involves two different predicates for {\tt trees} and -{\tt forests}; it also has three premises each one corresponding to a -constructor of one of the inductive definitions. - -The principle {\tt forest\_tree\_rec} shares exactly the same -premises, only the conclusion now refers to the property of forests. - -\begin{coq_example} -Check forest_tree_rec. -\end{coq_example} - -\example{Predicates {\tt odd} and {\tt even} on naturals} - -Let {\tt odd} and {\tt even} be inductively defined as: - -% Reset Initial. -\begin{coq_eval} -Open Scope nat_scope. -\end{coq_eval} - -\begin{coq_example*} -Inductive odd : nat -> Prop := - oddS : forall n:nat, even n -> odd (S n) -with even : nat -> Prop := - | evenO : even 0 - | evenS : forall n:nat, odd n -> even (S n). -\end{coq_example*} - -The following command generates a powerful elimination -principle: - -\begin{coq_example} -Scheme odd_even := Minimality for odd Sort Prop - with even_odd := Minimality for even Sort Prop. -\end{coq_example} - -The type of {\tt odd\_even} for instance will be: - -\begin{coq_example} -Check odd_even. -\end{coq_example} - -The type of {\tt even\_odd} shares the same premises but the -conclusion is {\tt (n:nat)(even n)->(Q n)}. - -\subsection[{\tt Combined Scheme}]{{\tt Combined Scheme}\comindex{Combined Scheme} -\label{CombinedScheme-examples}} - -We can define the induction principles for trees and forests using: -\begin{coq_example} -Scheme tree_forest_ind := Induction for tree Sort Prop - with forest_tree_ind := Induction for forest Sort Prop. -\end{coq_example} - -Then we can build the combined induction principle which gives the -conjunction of the conclusions of each individual principle: -\begin{coq_example} -Combined Scheme tree_forest_mutind from tree_forest_ind, forest_tree_ind. -\end{coq_example} - -The type of {\tt tree\_forest\_mutrec} will be: -\begin{coq_example} -Check tree_forest_mutind. -\end{coq_example} - -\section[{\tt Functional Scheme} and {\tt functional induction}]{{\tt Functional Scheme} and {\tt functional induction}\comindex{Functional Scheme}\tacindex{functional induction} -\label{FunScheme-examples}} - -\firstexample -\example{Induction scheme for \texttt{div2}} - -We define the function \texttt{div2} as follows: - -\begin{coq_eval} -Reset Initial. -\end{coq_eval} - -\begin{coq_example*} -Require Import Arith. -Fixpoint div2 (n:nat) : nat := - match n with - | O => 0 - | S O => 0 - | S (S n') => S (div2 n') - end. -\end{coq_example*} - -The definition of a principle of induction corresponding to the -recursive structure of \texttt{div2} is defined by the command: - -\begin{coq_example} -Functional Scheme div2_ind := Induction for div2 Sort Prop. -\end{coq_example} - -You may now look at the type of {\tt div2\_ind}: - -\begin{coq_example} -Check div2_ind. -\end{coq_example} - -We can now prove the following lemma using this principle: - - -\begin{coq_example*} -Lemma div2_le' : forall n:nat, div2 n <= n. -intro n. - pattern n , (div2 n). -\end{coq_example*} - - -\begin{coq_example} -apply div2_ind; intros. -\end{coq_example} - -\begin{coq_example*} -auto with arith. -auto with arith. -simpl; auto with arith. -Qed. -\end{coq_example*} - -We can use directly the \texttt{functional induction} -(\ref{FunInduction}) tactic instead of the pattern/apply trick: - -\begin{coq_example*} -Reset div2_le'. -Lemma div2_le : forall n:nat, div2 n <= n. -intro n. -\end{coq_example*} - -\begin{coq_example} -functional induction (div2 n). -\end{coq_example} - -\begin{coq_example*} -auto with arith. -auto with arith. -auto with arith. -Qed. -\end{coq_example*} - -\Rem There is a difference between obtaining an induction scheme for a -function by using \texttt{Function} (see Section~\ref{Function}) and by -using \texttt{Functional Scheme} after a normal definition using -\texttt{Fixpoint} or \texttt{Definition}. See \ref{Function} for -details. - - -\example{Induction scheme for \texttt{tree\_size}} - -\begin{coq_eval} -Reset Initial. -\end{coq_eval} - -We define trees by the following mutual inductive type: - -\begin{coq_example*} -Variable A : Set. -Inductive tree : Set := - node : A -> forest -> tree -with forest : Set := - | empty : forest - | cons : tree -> forest -> forest. -\end{coq_example*} - -We define the function \texttt{tree\_size} that computes the size -of a tree or a forest. Note that we use \texttt{Function} which -generally produces better principles. - -\begin{coq_example*} -Function tree_size (t:tree) : nat := - match t with - | node A f => S (forest_size f) - end - with forest_size (f:forest) : nat := - match f with - | empty => 0 - | cons t f' => (tree_size t + forest_size f') - end. -\end{coq_example*} - -Remark: \texttt{Function} generates itself non mutual induction -principles {\tt tree\_size\_ind} and {\tt forest\_size\_ind}: - -\begin{coq_example} -Check tree_size_ind. -\end{coq_example} - -The definition of mutual induction principles following the recursive -structure of \texttt{tree\_size} and \texttt{forest\_size} is defined -by the command: - -\begin{coq_example*} -Functional Scheme tree_size_ind2 := Induction for tree_size Sort Prop -with forest_size_ind2 := Induction for forest_size Sort Prop. -\end{coq_example*} - -You may now look at the type of {\tt tree\_size\_ind2}: - -\begin{coq_example} -Check tree_size_ind2. -\end{coq_example} - - - - -\section[{\tt inversion}]{{\tt inversion}\tacindex{inversion} -\label{inversion-examples}} - -\subsection*{Generalities about inversion} - -When working with (co)inductive predicates, we are very often faced to -some of these situations: -\begin{itemize} -\item we have an inconsistent instance of an inductive predicate in the - local context of hypotheses. Thus, the current goal can be trivially - proved by absurdity. -\item we have a hypothesis that is an instance of an inductive - predicate, and the instance has some variables whose constraints we - would like to derive. -\end{itemize} - -The inversion tactics are very useful to simplify the work in these -cases. Inversion tools can be classified in three groups: - -\begin{enumerate} -\item tactics for inverting an instance without stocking the inversion - lemma in the context; this includes the tactics - (\texttt{dependent}) \texttt{inversion} and - (\texttt{dependent}) \texttt{inversion\_clear}. -\item commands for generating and stocking in the context the inversion - lemma corresponding to an instance; this includes \texttt{Derive} - (\texttt{Dependent}) \texttt{Inversion} and \texttt{Derive} - (\texttt{Dependent}) \texttt{Inversion\_clear}. -\item tactics for inverting an instance using an already defined - inversion lemma; this includes the tactic \texttt{inversion \ldots using}. -\end{enumerate} - -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. - -\firstexample -\example{Non-dependent inversion} - -Let's consider the relation \texttt{Le} over natural numbers and the -following variables: - -\begin{coq_eval} -Reset Initial. -\end{coq_eval} - -\begin{coq_example*} -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). -Variable P : nat -> nat -> Prop. -Variable Q : forall n m:nat, Le n m -> Prop. -\end{coq_example*} - -For example, consider the goal: - -\begin{coq_eval} -Lemma ex : forall n m:nat, Le (S n) m -> P n m. -intros. -\end{coq_eval} - -\begin{coq_example} -Show. -\end{coq_example} - -To prove the goal we may need to reason by cases on \texttt{H} and to - derive that \texttt{m} is necessarily of -the form $(S~m_0)$ for certain $m_0$ and that $(Le~n~m_0)$. -Deriving these conditions corresponds to prove that the -only possible constructor of \texttt{(Le (S n) m)} is -\texttt{LeS} and that we can invert the -\texttt{->} in the type of \texttt{LeS}. -This inversion is possible because \texttt{Le} is the smallest set closed by -the constructors \texttt{LeO} and \texttt{LeS}. - -\begin{coq_example} -inversion_clear H. -\end{coq_example} - -Note that \texttt{m} has been substituted in the goal for \texttt{(S m0)} -and that the hypothesis \texttt{(Le n m0)} has been added to the -context. - -Sometimes it is -interesting to have the equality \texttt{m=(S m0)} in the -context to use it after. In that case we can use \texttt{inversion} that -does not clear the equalities: - -\begin{coq_example*} -Undo. -\end{coq_example*} - -\begin{coq_example} -inversion H. -\end{coq_example} - -\begin{coq_eval} -Undo. -\end{coq_eval} - -\example{Dependent Inversion} - -Let us consider the following goal: - -\begin{coq_eval} -Lemma ex_dep : forall (n m:nat) (H:Le (S n) m), Q (S n) m H. -intros. -\end{coq_eval} - -\begin{coq_example} -Show. -\end{coq_example} - -As \texttt{H} occurs in the goal, we may want to reason by cases on its -structure and so, we would like inversion tactics to -substitute \texttt{H} by the corresponding term in constructor form. -Neither \texttt{Inversion} nor {\tt Inversion\_clear} make such a -substitution. -To have such a behavior we use the dependent inversion tactics: - -\begin{coq_example} -dependent inversion_clear H. -\end{coq_example} - -Note that \texttt{H} has been substituted by \texttt{(LeS n m0 l)} and -\texttt{m} by \texttt{(S m0)}. - -\example{using already defined inversion lemmas} - -\begin{coq_eval} -Abort. -\end{coq_eval} - -For example, to generate the inversion lemma for the instance -\texttt{(Le (S n) m)} and the sort \texttt{Prop} we do: - -\begin{coq_example*} -Derive Inversion_clear leminv with (forall n m:nat, Le (S n) m) Sort - Prop. -\end{coq_example*} - -\begin{coq_example} -Check leminv. -\end{coq_example} - -Then we can use the proven inversion lemma: - -\begin{coq_example} -Show. -\end{coq_example} - -\begin{coq_example} -inversion H using leminv. -\end{coq_example} - -\begin{coq_eval} -Reset Initial. -\end{coq_eval} - \section[\tt dependent induction]{\tt dependent induction\label{dependent-induction-example}} \def\depind{{\tt dependent induction}~} \def\depdestr{{\tt dependent destruction}~} -- cgit v1.2.3