\chapter{Proof schemes}

\section{Generation of induction principles with {\tt Scheme}}
\label{Scheme}
\index{Schemes}
\comindex{Scheme}

The {\tt Scheme} command is a high-level tool for generating
automatically (possibly mutual) induction principles for given types
and sorts.  Its syntax follows the schema:
\begin{quote}
{\tt Scheme {\ident$_1$} := Induction for \ident'$_1$ Sort {\sort$_1$} \\
  with\\
  \mbox{}\hspace{0.1cm} \dots\\
        with {\ident$_m$} := Induction for {\ident'$_m$} Sort
        {\sort$_m$}}
\end{quote}
where \ident'$_1$ \dots\ \ident'$_m$ are different inductive type
identifiers belonging to the same package of mutual inductive
definitions. This command generates {\ident$_1$}\dots{} {\ident$_m$}
to be mutually recursive definitions. Each term {\ident$_i$} proves a
general principle of mutual induction for objects in type {\term$_i$}.

\begin{Variants}
\item {\tt Scheme {\ident$_1$} := Minimality for \ident'$_1$ Sort {\sort$_1$} \\
    with\\
    \mbox{}\hspace{0.1cm} \dots\ \\
    with {\ident$_m$} := Minimality for {\ident'$_m$} Sort
    {\sort$_m$}}

  Same as before but defines a non-dependent elimination principle more
  natural in case of inductively defined relations.

\item {\tt Scheme Equality for \ident$_1$\comindex{Scheme Equality}}

  Tries to generate a Boolean equality and a proof of the
  decidability of the usual equality. If \ident$_i$ involves
  some other inductive types, their equality has to be defined first.

\item {\tt Scheme Induction for \ident$_1$ Sort {\sort$_1$} \\
  with\\
  \mbox{}\hspace{0.1cm} \dots\\
        with Induction for {\ident$_m$} Sort
        {\sort$_m$}}

  If you do not provide the name of the schemes, they will be automatically
  computed from the sorts involved (works also with Minimality).

\end{Variants}
\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{Automatic declaration of schemes
\optindex{Boolean Equality Schemes}
\optindex{Elimination Schemes}
\optindex{Nonrecursive Elimination Schemes}
\optindex{Case Analysis Schemes}
\optindex{Decidable Equality Schemes}
\label{set-nonrecursive-elimination-schemes}
}

It is possible to deactivate the automatic declaration of the induction
 principles when defining a new inductive type  with the
 {\tt Unset Elimination Schemes} command. It may be
reactivated at any time with {\tt Set Elimination Schemes}.

The types declared with the keywords {\tt Variant} (see~\ref{Variant})
and {\tt Record} (see~\ref{Record}) do not have an automatic
declaration of the induction principles. It can be activated with the
command {\tt Set Nonrecursive Elimination Schemes}. It can be
deactivated again with {\tt Unset Nonrecursive Elimination Schemes}.

In addition, the {\tt Case Analysis Schemes} flag governs the generation of
case analysis lemmas for inductive types, i.e. corresponding to the
pattern-matching term alone and without fixpoint.
\\

You can also activate the automatic declaration of those Boolean equalities
(see the second variant of {\tt Scheme})
with respectively the commands {\tt Set Boolean Equality Schemes} and
{\tt Set Decidable Equality Schemes}.
However you have to be careful with this option since
\Coq~ may now reject well-defined inductive types because it cannot compute
a Boolean equality for them.

\subsection{\tt Combined Scheme}
\label{CombinedScheme}
\comindex{Combined Scheme}

The {\tt Combined Scheme} command is a tool for combining
induction principles generated by the {\tt Scheme} command.
Its syntax follows the schema :
\begin{quote}
{\tt Combined Scheme {\ident$_0$} from {\ident$_1$}, .., {\ident$_n$}}
\end{quote}
where
\ident$_1$ \ldots \ident$_n$ are different inductive principles that must belong to
the same package of mutual inductive principle definitions. This command
generates {\ident$_0$} to be the conjunction of the principles: it is
built from the common premises of the principles and concluded by the
conjunction of their conclusions.

\Example
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{Generation of induction principles with {\tt Functional Scheme}}
\label{FunScheme}
\comindex{Functional Scheme}

The {\tt Functional Scheme} command is a high-level experimental
tool for generating automatically induction principles
corresponding to (possibly mutually recursive) functions.  Its
syntax follows the schema:
\begin{quote}
{\tt Functional Scheme {\ident$_1$} := Induction for \ident'$_1$ Sort {\sort$_1$} \\
  with\\
  \mbox{}\hspace{0.1cm} \dots\ \\
        with {\ident$_m$} := Induction for {\ident'$_m$} Sort
        {\sort$_m$}}
\end{quote}
where \ident'$_1$ \dots\ \ident'$_m$ are different mutually defined function
names (they must be in the same order as when they were defined).
This command generates the induction principles
\ident$_1$\dots\ident$_m$, following the recursive structure and case
analyses of the functions \ident'$_1$ \dots\ \ident'$_m$.

\Rem
There is a difference between obtaining an induction scheme by using
\texttt{Functional Scheme} on a function defined by \texttt{Function}
or not. Indeed \texttt{Function} generally produces smaller
principles, closer to the definition written by the user.

\firstexample
\example{Induction scheme for \texttt{div2}}
\label{FunScheme-examples}

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:
\tacindex{functional induction}

\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*}

\Rem \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{Generation of inversion principles with \tt Derive Inversion}
\label{Derive-Inversion}
\comindex{Derive Inversion}

The syntax of {\tt Derive Inversion} follows the schema:
\begin{quote}
{\tt Derive Inversion {\ident} with forall
  $(\vec{x} : \vec{T})$, $I~\vec{t}$ Sort \sort}
\end{quote}

This command generates an inversion principle for the
\texttt{inversion \dots\ using} tactic.
\tacindex{inversion \dots\ using}
Let $I$ be an inductive predicate and $\vec{x}$ the variables
occurring in $\vec{t}$. This command generates and stocks the
inversion lemma for the sort \sort~ corresponding to the instance
$\forall (\vec{x}:\vec{T}), I~\vec{t}$ with the name {\ident} in the {\bf
global} environment. When applied, it is equivalent to having inverted
the instance with the tactic {\tt inversion}.

\begin{Variants}
\item \texttt{Derive Inversion\_clear {\ident} with forall
  $(\vec{x}:\vec{T})$, $I~\vec{t}$ Sort \sort}\\
  \comindex{Derive Inversion\_clear}
  When applied, it is equivalent to having
  inverted the instance with the tactic \texttt{inversion}
  replaced by the tactic \texttt{inversion\_clear}.
\item \texttt{Derive Dependent Inversion {\ident} with forall
  $(\vec{x}:\vec{T})$, $I~\vec{t}$ Sort \sort}\\
  \comindex{Derive Dependent Inversion}
  When applied, it is equivalent to having
  inverted the instance with the tactic \texttt{dependent inversion}.
\item \texttt{Derive Dependent Inversion\_clear {\ident} with forall
  $(\vec{x}:\vec{T})$, $I~\vec{t}$ Sort \sort}\\
  \comindex{Derive Dependent Inversion\_clear}
  When applied, it is equivalent to having
  inverted the instance with the tactic \texttt{dependent inversion\_clear}.
\end{Variants}

\Example

Let us consider the relation \texttt{Le} over natural numbers and the
following variable:

\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.
\end{coq_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_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}

\begin{coq_example}
inversion H using leminv.
\end{coq_example}

