Inversion
Techniques
Let us consider
the following theorem.
The
induction H tactic call applied the induction principle le_ind with P := fun m : nat ->n = m.
How
did we solve this problem in good old times?
We could prove the following
[inversion lemma] (a kind of reciprocal of the constructors).
Note that le_inv is an expression of the minimality of le, with
explicit
equalities that can be used with injection
and discriminate.
Let us
come back to our initial lemma
The
inversion tactic
The inversion tactic derives all the necessary conditions to an inductive
hypothesis. If no condition can realize this hypothesis,
the goal is
proved by ex
falso quod libet. See also :inversion_clear
Comparison
with other kinds of predicate definitions
Let us consider le again. Several other definitions can be given for
this mathematical concept.
First, we could
use the plus function.
We can also
give a recursive predicate :
Both definitions
are equivalent to le of Coq
(exercise).
Predicates
and Boolean functions
Let us consider
the following function :
le
or leb ?
Just try
Print L5 45. !
We can build a bridge between both
aspects by proving the following theorems :
A
more abstract example
R is transitive, then its transitive closure is included in R :
Inductive
definitions and functions
It is sometimes very difficult to
represent a function f : A -> B as
a Coq function, for instance because of
the :
4 Undecidability
(or hard proof) of termination
4 Undecidability
of the domain characterization
This situation often arises when
studying the semantic of programming languages.
In that case, describing functions as
inductive relations is really efficient.
Exercise
Specifying
programs with inductive predicates
Programs are
computational objects.
Inductive types
provide structured specifications.
How to get the
best of both worlds?
We can easily specify whether some
value of this type is consistent with an arithmetic inequality, through a three
place predicate.
We can specify
whether some comparison function is correct :
In order to understand
specifications like compare_spec, let us open a section :
How
to use compare_spec
Let us consider
a goal of the form P n p (cmp
n p) where
P : nat→nat→Comparison→Prop.
A call to the
tactic destruct (cmpP n p) produces three
subgoals :
Hlt: n < p
===========
P n p Lt
Heq: n = p
===========
P n p Eq
Hgt: p < n
===========
P n p Gt
Example
Let us define functions for
computing the greatest [lowest] of tho numbers :
Proofs of properties of maxn and minn can use this pattern, which will give values to maxn n p, and
generate hypotheses of the form n < p, n = p, and p < n.
Each one of the
three subgoals is solved with [auto with arith].
The following
proofs use the same pattern :
Notice that all the proofs above use
only the specification of a comparison function and not a
concrete definition.
What
you think is not what you get
An odd
alternative definition of le :
The third constructor is useless !
It may increase the size of the proofs by induction.
Advice
for crafting useful inductive definitions
4 Constructors
are [axioms] :they should be intuitively true...
4 Constructors should as often as
possible deal with mutually exclusive cases, to ease proofs by induction ;
4 When an argument always appears with
the same value, make it a parameter
4 Test your
predicate on negative and positive cases !
A last example :The
toy programming language
We can also define a boolean
function for testing equality on variables :
We define a
Boolean test for the [assigned] property :
Bridge
lemmas
A
small program