Lecture 8: Inductive properties - part 2

(credits: Assia Mahboubi and Piere Casteran and Yves Bertot)

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

Prove the proposition syracuse steps 5 6.

Specifying programs with inductive predicates

Programs are computational objects.

Inductive types provide structured specifications.

How to get the best of both worlds?

By combining programs with inductive specifications.

Let us consider a datatype for comparison w.r.t. some decidable total order. This type already exists in the Standard Library.

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 : natnatComparisonProp.

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.

We are now able to provide an implementation of a comparison function, and prove its correctness :

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