1 / 27 Inductive Definitions, continued Assia Mahboubi Jan 7th, 2016
2 / 27 Last lecture Introduction to Coq s inductive types: Introduction, elimination and computation rules; Twofold implementation : match... with... and fix; Enumerated, recursive, parameterized and indexed inductive types; Distinction between parameters and indices; Elimination, dependent elimination; Syntactic criteria for termination of fixpoints.
Warm up 3 / 27
4 / 27 Elimination rules Is it possible to define a function which takes a (single) boolean argument b and outputs (0 : nat) if b is true and (tt : unit) if b is false?
5 / 27 Tactics for case analysis case t is the most primitive. It: generates a (proof) term of the form match t with...; guesses the return type from the goal (under the line); does not introduce/name the arguments of the constructor by default, but there is a syntax for chosing names. The case_eq variant modifies the guessing of the return type so that equalities are generated. The destruct variant modifies the guessing of the return type so that it generalizes the hypotheses depending on t.
5 / 27 Tactics for case analysis case t is the most primitive. It: generates a (proof) term of the form match t with...; guesses the return type from the goal (under the line); does not introduce/name the arguments of the constructor by default, but there is a syntax for chosing names. The case_eq variant modifies the guessing of the return type so that equalities are generated. The destruct variant modifies the guessing of the return type so that it generalizes the hypotheses depending on t. Good practice: Code indentation (bullets) Use of introduction patterns to give explicit names.
6 / 27 Tactics related to equality The (polymorphic) equality predicate defined in Coq as: Inductive eq (A : Type) (x : A) : A -> Prop := eq_refl : eq x x. Notation x = y := (eq x y).
6 / 27 Tactics related to equality The (polymorphic) equality predicate defined in Coq as: Inductive eq (A : Type) (x : A) : A -> Prop := eq_refl : eq x x. Notation x = y := (eq x y). Its induction principle has the form: eq_ind : forall (A : Type) (x : A) (P : A -> Prop), P x -> forall y : A, eq x y -> P y
6 / 27 Tactics related to equality The (polymorphic) equality predicate defined in Coq as: Inductive eq (A : Type) (x : A) : A -> Prop := eq_refl : eq x x. Notation x = y := (eq x y). Its induction principle has the form: eq_ind : forall (A : Type) (x : A) (P : A -> Prop), P x -> forall y : A, eq x y -> P y Why is eq a symmetric predicate?
6 / 27 Tactics related to equality The (polymorphic) equality predicate defined in Coq as: Inductive eq (A : Type) (x : A) : A -> Prop := eq_refl : eq x x. Notation x = y := (eq x y). Its induction principle has the form: eq_ind : forall (A : Type) (x : A) (P : A -> Prop), P x -> forall y : A, eq x y -> P y Why is eq a symmetric predicate? Tactics: f_equal (congruence) discriminate (see 0 <> 1 -> False, lecture 2) injection (injectivity of constructors) inversion (necessary conditions) rewrite (substitution) symmetry, transitivity
7 / 27 Tactics related to equality Define is_zero: nat -> bool which has value true iff its argument is O. State and prove a lemma which expresses the later fact, using eq. Prove the following statement: Lemma is_zero_s n m : S n = S m -> is_zero n = is_zero m.
8 / 27 Tactics for induction fix <n>, where <n> is a numeral is the most primitive. It: generates a (proof) term of the form: fun g1 g2 => fix f h1 h2 t h3 {struct t} :=?F h1 h2 t where: g1, g2 are the objects in the context (above the line); h1, h2, t, h3 are the objects quantified in the goal (under the line);?f can call f (= recursive calls); the termination of f is should eventually be guaranteed by structural recursion on t; Qed checks the well-formedness, which was not guaranteed so far: error messages come late and may be difficult to interpret.
Tactics for induction elim t applies an induction scheme, i.e. a lemma of the form: forall P : T -> Type,... -> forall t : T, P t It guesses argument P from the goal (under the line), abstracting all the occurrences of t. It guesses the elimination scheme to be used (T_ind, T_rect,...) from the sort of the goal and the type of t. The elim t using S variant allows to provide a custom elimination scheme (or lemma!) S, with the same unification heuristic. The induction t tactic guesses argument P taking into account the possible hypotheses depending on t present in the context (above the line). Plus it can introduce and name things automatically. Remark: the rewrite tactic does a similar guessing job... 9 / 27
10 / 27 Tactics for induction Require Import List. Inductive list (A : Type) : Type := nil : list A cons : A -> list A -> list A Implement a function belast: nat -> list nat -> list nat such that: belast x nil = nil belast x (cons y l)= cons x (belast y l) Show the following statement: Lemma length_belast (x : nat) (s : list nat) : length (belast x s) = length s.
11 / 27 Tactics for induction Require Import List. Inductive list (A : Type) : Type := nil : list A cons : A -> list A -> list A Implement a function skip: list nat -> list nat such that: skip nil = nil skip cons x nil = nil skip cons x (cons y nil)= skip (cons y nil) Show the following statement: Lemma length_skip l : 2 * length (skip l) <= length l.
Well-formed inductive definitions 12 / 27
13 / 27 Issues Constructors of the inductive definition I have type: Γ : (z 1 : C 1 )... (z k : C k ).I a 1... a n where C i can feature intances of I. Question: can these instances be arbitrary?
13 / 27 Issues Constructors of the inductive definition I have type: Γ : (z 1 : C 1 )... (z k : C k ).I a 1... a n where C i can feature intances of I. Question: can these instances be arbitrary? Example: Inductive lambda : Type := Lam : (lambda -> lambda) -> lambda
13 / 27 Issues Constructors of the inductive definition I have type: Γ : (z 1 : C 1 )... (z k : C k ).I a 1... a n where C i can feature intances of I. Question: can these instances be arbitrary? Example: Inductive lambda : Type := Lam : (lambda -> lambda) -> lambda We define: Definition app (x y:lambda) := match x with (Lam f) => f y end. Definition Delta := Lam (fun x => app x x). Definition Omega := app Delta Delta. and the evaluation of Ω loops.
14 / 27 Necessity of restrictions Things can even be worst: Inductive lambda : Type := Lam : (lambda -> lambda) -> lambda Now define: Fixpoint lambda_to_nat (t : lambda) : nat := match t with Lam f -> S (lambda_to_nat (f t)) end.
14 / 27 Necessity of restrictions Things can even be worst: Inductive lambda : Type := Lam : (lambda -> lambda) -> lambda Now define: Fixpoint lambda_to_nat (t : lambda) : nat := match t with Lam f -> S (lambda_to_nat (f t)) end. What happens with (lambda_to_nat (Lam (fun x => x)))?
15 / 27 The way out: (strict) positivity condition An inductive type is defined as the smallest type generated by a set (Γ i ) 1 i n of constructors. We can see it as µx, 1 i n Γ i (X) (with µ a fixpoint operator on types). The existence of this smallest type can be proved at the impredicative level when the operator λx, 1 i n Γ i (X) is monotonic. In order both to ensure monotonicity and to avoid paradox, Coq enforces a strict positivity condition: X should never appear on the left of an arrow in the type of its constructors.
The way out: (strict) positivity condition More precisely, if the type (a.k.a arity) of a constructor is: c : C1 ->... -> Ck : I a1.. ak it is well-formed when: I a1.. ak is well-formed w.r.t. the uniformity of parametric arguments and typing constraints; T does not appear in any of the a1,... ak; Each ti should be of the form: C 1 ->... C m -> (g (I b11... b1k)... (I bj1... bjk)) well typed and with no other occurrence of T. And the rule generalizes as such to dependent products (instead of arrow). 16 / 27
Sorts and elimination rules 17 / 27
18 / 27 Sorts of Inductive definitions Reminder: The Calculus of predicative Inductive Constructions has sorts Prop, Set = Type 0, Type 1, Type 2,... Prop and Set are said small (because they do not type another sort) sorts Type i (for i 1) are said large (because they type Prop and Set) In the standard mode (i.e. unless we turn on the impredicative-set flag): Prop Set = Type 0 Type 1 Type 2,...
Conditions on sorts for the inductive definitions arity and sort of the inductive definition I : (x 1 : A 1 )... (x n : A n )s a constructor has the form c : (y 1 : B 1 )... (y p : B p )I u 1... u n typing condition I : (x 1 : A 1 )... (x n : A n )s (y 1 : B 1 )... (y p : B p )I u 1... u n : s The sort of a predicative inductive definition (in the hierarchy Type) is the maximum of sorts of the types of the arguments of its constructors. Impredicative inductive definitions (type Prop) have no such constraint on arities. 19 / 27
20 / 27 Restrictions of elimination depending on sorts Elimination rule for type bool (available for any possible sort s): Γ t : bool Γ, x : bool A(x) : s Γ t 1 : A(true) Γ t 2 : A(false) Γ (match t as x return A(x) with true t 1 false t 2 end) : A(t)
20 / 27 Restrictions of elimination depending on sorts Elimination rule for type bool (available for any possible sort s): Γ t : bool Γ, x : bool A(x) : s Γ t 1 : A(true) Γ t 2 : A(false) Γ (match t as x return A(x) with true t 1 false t 2 end) : A(t) Elimination rule for the type or A B (only on Prop) Γ t : or A B Γ, p : A t 1 : C(or_introl p) Γ, x : or A B C(x) : Prop Γ, q : B t 2 : C(or_intror q) match t as x return C(x) with Γ or_introl p t 1 or_intror q t 2 : C(t) end
21 / 27 Rules on the sorts for the elimination Terminology: Propositional elimination: towards Prop sort only; Weak elimination: towards Prop and Set sorts only; Strong elimination: towards Type sort(s).
22 / 27 Rules on the sorts for the elimination The elimination of inductive types in Type (predicative hierarchy) has no restriction: weak strong eliminations Elimination of inductive types in Prop is restricted : in general, one cannot build a type in Type by case on the proof-term in a proposition according to the implicit interpretation of Prop as proof-irrelevant: propositional elimination only.
22 / 27 Rules on the sorts for the elimination The elimination of inductive types in Type (predicative hierarchy) has no restriction: weak strong eliminations Elimination of inductive types in Prop is restricted : in general, one cannot build a type in Type by case on the proof-term in a proposition according to the implicit interpretation of Prop as proof-irrelevant: propositional elimination only. exception Singleton types : if the type in Prop has zero constructor (absurdity) or a unique constructor whose arguments are in Prop (equality, conjunction... ): weak and strong eliminations.
22 / 27 Rules on the sorts for the elimination The elimination of inductive types in Type (predicative hierarchy) has no restriction: weak strong eliminations Elimination of inductive types in Prop is restricted : in general, one cannot build a type in Type by case on the proof-term in a proposition according to the implicit interpretation of Prop as proof-irrelevant: propositional elimination only. exception Singleton types : if the type in Prop has zero constructor (absurdity) or a unique constructor whose arguments are in Prop (equality, conjunction... ): weak and strong eliminations. partial exception : if the type in Prop has a unique constructor which arguments are either propositions of type Prop or small arities (type schemes which build in Prop), then elimination towards Set is allowed: weak elimination.
23 / 27 In pratice in Coq For each inductive definition of a type I, Coq defines automatically associated elimination schemes (when allowed): strong elimination (to Type) : I_rect elimination to small computational types (to Set) : I_rec elimination to logical propositions (to Prop) : I_ind Moreover, by default these elimination schemes are: the dependent form when I is computational (in sort Set or Type); the non-dependent form when in I is in sort Prop.
24 / 27 Exercises Execute the command Set Printing All. Compare the types True and unit. What is the difference? Observe the consequence on the generated inductive schemes. Prove the dependent scheme for True. Same questions with types and and prod Same questions with types sig and ex. What is (each time) the main difference in behavior between these two datatypes? Execute the command Unset Printing All.
25 / 27 Exercises The so-called Markov princple, or countable choice principle, states that for a boolean predicate on natural numbers, the two notions of existence coincide. State and prove the easy implication. State the non-trivial implication. Require Import Arith. Open a Section Markov, postulate a boolean predicate P : nat -> bool on natural numbers, and the hypothesis exp that the Prop existence of a witness for P holds. Define the following predicate: Inductive acc_nat (i : nat) : Prop := AccNat0 : P i = true -> acc_nat i AccNatS : acc_nat (S i) -> acc_nat i. What does it mean intuitively?
26 / 27 Exercises Prove: Lemma acc_nat_plus : forall x n : nat, P (x + n) = true -> acc_nat n. Prove: Lemma acc_nat_0 : acc_nat 0. Prove: Lemma find_ex :forall n : nat, acc_nat n -> {m : nat P m = true}. by induction on the hypothesis acc_nat n: start with tactic fix 2 and observe the answer of Show Proof; the tactic case_eq might be useful later on.
27 / 27 What happened? Because of the restriction in elimination rules, this is not allowed: Fixpoint find_ex n (a : acc_nat n) : nat := match a with AccNat0 =>... AccNatS a => if P n then n else find_ex (S n) a end. But this variant is accepted by the termination checker: Fixpoint find_ex n (a : acc_nat n) : nat := if P n then n (* n is the witness *) else find_ex (S n) (match a with (* we go on searching *) AccNat0 =>... (* cannot happen: P n = false in this branch of the if *) AccNatS a => find_ex a end) end.