(* How to discriminate values built with different constructors *) (* Chapter 1: propagation of confusion *) (* Confusing the 2 Boolean constructors *) Definition f1 (b: bool) : nat := match b with | true => 4 | false => 2 end. (* New tactic: 'change' [conclusion'] which replaces the current conclusion with a computationally equal formula. Already known tactics such as 'simpl', 'red', 'unfold are actually special cases of 'change'. *) Lemma tf_confusing : true = false -> 4 = 2. Proof. intro e. change (f1 true = f1 false). rewrite e. reflexivity. Qed. (* The following does not work, as expected *) Lemma tt_confusing : true = true -> 4 = 2. Proof. intro e. change 4 with (f1 true). try rewrite e. (* no effect *) Abort. (* Generalization *) Definition g1 (A:Type) (x y: A) (b: bool) : A := match b with | true => x | false => y end. (* If true = false, all values collapse in any type *) Lemma gtf_confusing : true = false -> forall A: Type, forall x y: A, x = y. Proof. intros e A x y. change (g1 A x y true = g1 A x y false). rewrite e. reflexivity. Qed. (* Confusing 0 and successors *) Definition f2 (n: nat) : nat := match n with | O => 4 | S n => 2 end. Lemma O1_confusing : O = 1 -> 4 = 2. Proof. intro e. change (f2 O = f2 1). rewrite <- e. reflexivity. Qed. (* Exercise: state and prove that if 23 = 55, then all values collapse in any type *) (* FILL HERE *) (* ------------------------------------------------------------ *) (* Chapter 2: discriminating constructors *) (* Constructors with distinguishable names, say C1 and C2, make different values, i.e., ~ (C1 params1 = C2 params2), that is, C1 params1 = C2 params2 -> False. This amounts to propagate confusion at the level of Prop, namely, to confuse False with a provable proposition, e.g. true = true, or the simplest one which is called True. *) Print True. (* Discriminating natural numbers *) (* Version 1 *) Definition g3 (n: nat) : Prop := match n with | 0 => False | S n => true = true end. (* Version 2 *) Definition g4 (n: nat) : Prop := match n with | 0 => False | S n => True end. Lemma O1_impossible_g3 : O = 1 -> False. Proof. intro e. change (g3 0). rewrite e. unfold g3. reflexivity. Qed. Lemma O1_impossible_g4 : O = 1 -> False. Proof. intro e. change (g4 0). rewrite e. unfold g4. apply I. Qed. (* The above trick is used by the Coq tactic called 'discriminate' *) Lemma O1_impossible_disc : O = 1 -> False. Proof. intro e. discriminate e. Qed. (* The tactic 'discriminate' can be used whatever the conclusion *) Lemma tf_impossible_any_conclusion : true = false -> 10 <= 87. Proof. intro e. discriminate e. Qed. (* Exercises : an other way to discriminate *) Fixpoint nat_Peq (n m: nat) : Prop := match n, m with | O, O => True | S n, S m => nat_Peq n m | _, _ => False end. Theorem eq_nat_Peq : forall n m, n = m -> nat_Peq n m. Proof. Admitted. (* Use Defined rather than Qed here *) Lemma t_3_5 : 3 = 5 -> False. Proof. (* use eq_nat_Peq here *) Admitted. (* Use Defined rather than Qed here *) Lemma t_3_5_disc : 3 = 5 -> False. Proof. intro e. discriminate e. Defined. (* Now the following two commands should provide the same (or very similar) answers. *) Eval compute in t_3_5. Print t_3_5_disc. (* ------------------------------------------------------------ *) (* Chapter 3: on induction *) (* Prepare lecture 06 -- nothing to do with discrimination. The point is to find the right induction. This will be discussed in lecture 06, so don't worry if you don't find the solution: you are expected to try, in order to get better prepared. Hints: tactics [revert hypothesis] and [generalize term] can be useful *) Theorem nat_Peq_correct : forall n m, nat_Peq n m -> n = m. Proof. Admitted. (* Additional variations on False -- 5 STARS *) Inductive another_False : Prop := AF: another_False -> another_False. Inductive wrongnat : Set := Swn : wrongnat -> wrongnat. Lemma no_wrongnat : wrongnat -> False. Admitted. Lemma another_False_False : another_False -> False. Admitted.