(** * TP 5 : Dependent pattern matching and accessibility *) (* To build an html version of the TD sheet, use the command "coqdoc -utf8 --no-lib-name --no-index --lib-subtitles file.v" *) (************************************) (** * Dependent pattern-matching **) (************************************) (** The most general form of pattern matching in Coq is [[ match t as n in T return P with ... ]] where - [t] is the term to be destructed - [n] is a name used to refer to [t] (used when it is an application) - [T] is the type of [t], in case it contains terms that need to be bound for the matching branches (dependent types) - [P] is the elimination predicate, the type of the matching branches (necessary when it differs between branches and cannot be infered) **) (** 1) Define a type [listn T n] of lists of size [n] containing elements of type [T]. You can draw inspiration from Coq's type [list]. **) (** 2) Write a concatenating function for this type by directly writing its term (i.e. without using the tactic mode). You will need the full power of pattern matching. **) (********************************) (** * The "injection" tactic **) (********************************) (** We want to see how the "injection" tactic works. Remember that "injection" is used to show injectivity of constructors of an inductive type: a term of an inductive type built with a constructor "c₁" cannot be equal to a term built with constructor "c₂" different from "c₁". **) (** For simplicity we take an inductive type with 2 constructors. **) Inductive Two : Set := Zero | One. (** 3) Define the elimination function of the equality type by directly writing its term. This function takes proofs of [P x] and [x = y] and returns a proof of [P y]. **) Definition eq_elim (A : Type) (P : A -> Prop) (x y : A) (Px : P x) (equality : x = y) : P y := ... (** The crucial part for [diff] is "strong elimination" : it allows building a type (here a [Prop]) by pattern matching values from a small type like [nat]. **) Definition diff (P Q : Prop) x : Prop := match x with | Zero => P | One => Q end. (** 4) Give now the proof term that says [Zero <> One]. **) Definition NonConf : Zero = One -> False := ... (******************************************) (** * The [Acc] accessiblity predicate **) (******************************************) (** In previous sessions, we used well-foundedness to prove properties and to define recursive functions. Let us now take a closer look at what it means: [Print well_founded.] returns [[ well_founded = fun (A : Type) (R : A -> A -> Prop) => forall a : A, Acc R a : forall A : Type, (A -> A -> Prop) -> Prop Argument A is implicit Argument scopes are [type_scope _] ]] which means that a relation [R : A -> A -> Prop] is well founded if all its elements are accessible: [forall a : A, Acc R a]. Being accessible is in turn defined by [[ Inductive Acc (A : Type) (R : A -> A -> Prop) (x : A) : Prop := Acc_intro : (forall y : A, R y x -> Acc R y) -> Acc R x ]] saying that if all predecessors of [x] by [R] are accessible, then [x] is accessible too. **) (** 5) How does the accessibility property start off? **) (** When we want to prove [Acc] for an element [x], we usually start by inspecting the shape of [x] (especially if [A] is inductive). With the shape of [x], we know if [R y x] can hold or not. Keep in mind that [Acc] is an inductive predicate, so you can always use induction on a proof of [Acc x] to prove another property. **) (** ** First example: [lt] and its lexicographic product. **) Require Import Relations. Require Import Arith. Require Import Omega. (** The following line turn implicit all arguments that can be infered from other arguments, this removing the need to explicitely tag them with [{ }]. **) Set Implicit Arguments. (** 6) As an example, prove the lemmas [Acc lt 0], [Acc lt 1], and [Acc lt 2]. **) (** 7) What is the structure of a proof of [Acc lt n]? **) (** 8) Prove (on paper) that any natural number is accessible by [<]. Then (and only then), translate this proof to Coq. **) Theorem lt_wf : well_founded lt. Proof. ... Qed. (** 9) Define [lt2] the lexicographic product of [<]. **) Definition lt2 : relation (nat*nat) := ... Notation "x << y " := (lt2 x y) (at level 70). (** 10) Prove that [lt2] is a strict order, i.e. is irreflexive and transitive. You can use [SearchPattern] or [SearchAbout] to look for lemmas you might need about [lt] and [le]. **) (** 11) Prove (on paper) that the strict lexicographic ordering on [nat*nat] is well-founded. Then (and only then) translate this proof to Coq. **) Lemma lt2_wf : well_founded lt2. Proof. ... Qed. (** ** Operations on well founded relations **) (** 12) Prove the inversion lemma for [Acc]. **) Lemma Acc_inv : forall (A : Type) (R : relation A) x y, R x y -> Acc R y -> Acc R x. Proof. ... Qed. (** *** Sub-relation **) (** 13) Define relation inclusion. **) Definition rel_incl (A : Type) (R S : relation A) := ... (** 14) Prove that if [R] is included in [S] and [S] is well-founded, then [R] is well-founded. **) Theorem rel_incl_wf (A : Type) (R S : relation A) : rel_incl R S -> well_founded S -> well_founded R. Proof. ... Qed. (** *** Inverse image **) Section Inverse_image. Variables (A B : Type) (R : relation B) (f : A -> B). Definition R' x y := R (f x) (f y). (** 15) Prove the following lemma relating [Acc R] and [Acc R']. **) Lemma Acc_inverse_eq : forall y, Acc R y -> forall x, y = (f x) -> Acc R' x. Proof. ... Qed. (** 16) Deduce from this lemma that the reverse image of a well-founded relation by any function is a well-founded relation. **) Lemma wf_inverse_image : well_founded R -> well_founded R'. Proof. ... Qed. End Inverse_image. (** *** Transitive closure **) (** 17) Define the (non-reflexive) transitive closure operator. **) (** 18) Prove that if [x] is accessible by [R] then [x] is accessible from the transitive closure of [x]. You will need the lemma [Acc_inv]. **) Lemma Acc_trans (A : Type) (R : relation A) : forall x, Acc R x -> Acc (trans R) x. Proof. ... Qed. (** 19) Prove that if [R] is well-founded, then its transitive closure is well-founded. **) Theorem wf_trans : forall (A : Type) (R : relation A), well_founded R -> well_founded (trans R). Proof. intros A R wfR x. apply Acc_trans. apply wfR. Qed. (** *** Lexicographic product **) (** 20) Define the lexicographic product of two relations. **) Definition lexprod (A B : Type) (RA : relation A) (RB : relation B) : relation (A*B) := ... (** 21) prove that the lexicographic product of two well-founded relations is a well-founded relation. **) Theorem lexprod_wf (A B : Type) (RA : relation A) (RB : relation B) : well_founded RA -> well_founded RB -> well_founded (lexprod RA RB). Proof. ... Qed. (** 22) Bonus: What about the dependent lexicographic product? (i.e. when the type of the second component of the pair depends on the value of the first component) **)