(** * Relations as propositions *** Version of 10/22/2008 *) (* A proposition parameterized over a number (like [evenI]) can be thought of as a PREDICATE -- i.e., the subset of [nat] for which the proposition is provable. A two-argument proposition can be thought of as a RELATION -- i.e., the set of pairs for which the proposition is provable. In this chapter, we explore this idea in detail. *) Require Export logic2. (* We'll skip logic3 *) (* For example, here is the "less than or equal" relation on numbers. *) Inductive le (n:nat) : nat -> Prop := | le_n : le n n | le_S : forall m:nat, (le n m) -> (le n (S m)). Notation "m <= n" := (le m n). (* Note that the left-hand argument [n] to [le] is the same everywhere in the definition, so we've made it a general parameter. This leads to a simpler induction principle. *) (* THOUGHT EXERCISE: Print out the induction principle for [le] and check that you understand it. Then try redefining [le] with [n] as an index rather than a general parameter (i.e., write the first line as [Inductive le : nat -> nat -> Prop]) and check how the generated induction principle changes. *) (* Some sanity checks on the definition. (Notice that, although these are the same kind of simple "unit tests" as we gave for the testing functions we wrote in the first few lectures, we must construct their proofs explicitly -- [simpl] doesn't do the job for us. *) Lemma test_le1 : 3 <= 3. Proof. apply le_n. Qed. Lemma test_le2 : 3 <= 6. Proof. apply le_S. apply le_S. apply le_S. apply le_n. Qed. Lemma test_le3 : ~ (2 <= 1). Proof. intros H. inversion H. inversion H1. Qed. (* The "strictly less than" relation [n < m] can now be defined on top of [le]. *) Definition lt (n m:nat) := le (S n) m. Notation "m < n" := (lt m n). (* Here are a few more simple relations on numbers *) Inductive square_of : nat -> nat -> Prop := sq : forall n:nat, square_of n (times n n). Inductive next_nat (n:nat) : nat -> Prop := | nn : next_nat n (S n). Inductive next_even (n:nat) : nat -> Prop := | ne_1 : evenI (S n) -> next_even n (S n) | ne_2 : evenI (S (S n)) -> next_even n (S (S n)). (* EXERCISE: define an inductive relation [total_relation] that holds between every pair of natural numbers. *) (* FILL IN HERE *) (* EXERCISE: define an inductive relation [empty_relation] (on numbers) that never holds. *) (* FILL IN HERE *) (* --------------------------------------------------------- *) (* Relations, in general *) (* We've now defined a few particular relations. As you may remember from an undergraduate discrete math course, there are a lot of ways of discussing and describing relations *in general* -- ways of classifying relations (are they reflexive, transitive, etc.), theorems that can be proved generically about classes of relations, constructions that build one relation from another, etc. Let us pause here to review a few of these that will be useful in what follows. *) (* A RELATION on a set [X] is a proposition parameterized by two [X]s -- i.e., it is a logical assertion involving two values from the set [X]. *) Definition relation (X: Set) := X->X->Prop. (* A relation [R] on a set [X] is a PARTIAL FUNCTION if, for every [x : X], there is at most one [y] such that [R x y] -- or, to put it differently, if [R x y1] and [R x y2] together imply [y1 = y2]. *) Definition partial_function (X: Set) (R: relation X) := forall x y1 y2 : X, R x y1 -> R x y2 -> y1 = y2. Implicit Arguments partial_function [X]. Lemma next_nat_partial_function : partial_function next_nat. Proof. unfold partial_function. intros x y1 y2 P Q. inversion P. inversion Q. reflexivity. Qed. Lemma le_not_a_partial_function : ~ (partial_function le). Proof. unfold not. unfold partial_function. intros H. assert (1 = 2) as Nonsense. Case "Proof of assertion". apply H with 0. apply le_S. apply le_n. apply le_S. apply le_S. apply le_n. inversion Nonsense. Qed. (* EXERCISE: Show that the [total_relation] you defined above is not a partial function, but that [empty_relation] is. *) (* FILL IN HERE *) Definition reflexive (X: Set) (R: relation X) := forall a : X, R a a. Implicit Arguments reflexive [X]. Lemma le_reflexive : reflexive le. Proof. unfold reflexive. intros n. apply le_n. Qed. Definition transitive (X: Set) (R: relation X) := forall a b c : X, (R a b) -> (R b c) -> (R a c). Implicit Arguments transitive [X]. Lemma le_transitive : transitive le. Proof. intros m n o Hmn Hno. induction Hno. apply Hmn. apply le_S. apply IHHno. Qed. Lemma lt_transitive: transitive lt. Proof. unfold lt. unfold transitive. intros m n o Hmn Hno. destruct o. Case "le_n". inversion Hno. Case "le_S". apply le_S in Hmn. apply le_transitive with (a := (S m)) (b := (S n)) (c := (S o)). apply Hmn. apply Hno. Qed. (* We can also prove lt_transitive more laboriously by induction, without using le_transitive. *) Lemma lt_transitive' : transitive lt. Proof. (* Prove this by induction on evidence that [n] is less than [o] *) unfold lt. unfold transitive. intros m n o Hmn Hno. induction Hno. (* FILL IN HERE (and delete "Admitted") *) Admitted. Lemma lt_transitive'' : transitive lt. Proof. (* Prove the same thing again by induction on [o] *) unfold lt. unfold transitive. intros m n o Hmn Hno. induction o. (* FILL IN HERE (and delete "Admitted") *) Admitted. (* The transitivity of [le], in turn, can be used to prove some facts that are useful for the proof of antisymmetry below... *) Lemma le_S_le : forall n m, S n <= m -> n <= m. Proof. intros n m H. apply le_transitive with (b := S n). apply le_S. apply le_n. apply H. Qed. Lemma Sn_le_Sm__n_le_m : forall n m, (S n <= S m) -> (n <= m). Proof. intros n m H. inversion H. apply le_n. apply le_S_le. apply H1. Qed. Lemma Sn_not_le_n : forall n, ~ (S n <= n). Proof. induction n. Case "O". intros H. inversion H. Case "S". intros H. unfold not in IHn. apply IHn. apply Sn_le_Sm__n_le_m. apply H. Qed. Definition symmetric (X: Set) (R: relation X) := forall a b : X, (R a b) -> (R b a). Implicit Arguments symmetric [X]. Lemma le_not_symmetric : ~ (symmetric le). Proof. (* FILL IN HERE (and delete "Admitted") *) Admitted. Definition antisymmetric (X: Set) (R: relation X) := forall a b : X, (R a b) -> (R b a) -> a = b. Implicit Arguments antisymmetric [X]. Lemma le_antisymmetric : antisymmetric le. Proof. (* FILL IN HERE (and delete "Admitted") *) Admitted. Definition equivalence (X:Set) (R: relation X) := (reflexive R) /\ (symmetric R) /\ (transitive R). Implicit Arguments equivalence [X]. Definition partial_order (X:Set) (R: relation X) := (reflexive R) /\ (antisymmetric R) /\ (transitive R). Implicit Arguments partial_order [X]. Definition preorder (X:Set) (R: relation X) := (reflexive R) /\ (transitive R). Implicit Arguments preorder [X]. Lemma le_partial_order : partial_order le. Proof. unfold partial_order. split. Case "refl". apply le_reflexive. split. Case "antisym". apply le_antisymmetric. Case "transitive.". apply le_transitive. Qed. (* Now we'll show a way to build one relation from another *) Inductive refl_trans_closure (X:Set) (R: relation X) : X -> X -> Prop := | rtc_R : forall (x y : X), R x y -> refl_trans_closure X R x y | rtc_refl : forall (x : X), refl_trans_closure X R x x | rtc_trans : forall (x y z : X), refl_trans_closure X R x y -> refl_trans_closure X R y z -> refl_trans_closure X R x z. Implicit Arguments refl_trans_closure [X]. (* For example, the reflexive and transitive closure of the [next_nat] relation "is" [le]. Note how we show these two relations "are" the same using <-> *) Lemma next_nat_closure_is_le : forall n m, (n <= m) <-> ((refl_trans_closure next_nat) n m). Proof. intros n m. split. Case "->". intro H. induction H. apply rtc_refl. apply rtc_trans with m. apply IHle. apply rtc_R. apply nn. Case "<-". intro H. induction H. SCase "rtc_R". inversion H. apply le_S. apply le_n. SCase "rtc_refl". apply le_n. SCase "rtc_trans". apply le_transitive with y. apply IHrefl_trans_closure1. apply IHrefl_trans_closure2. Qed. Lemma rtc_idempotent : forall (X:Set) (R: relation X) (x y: X), refl_trans_closure (refl_trans_closure R) x y <-> refl_trans_closure R x y. Proof. (* FILL IN HERE (and delete "Admitted") *) Admitted. (* Define what it means for a relation to preserve a property *) Definition preserves (X: Set) (R: relation X) (P: X->Prop) := forall (x y : X), P x -> R x y -> P y. Implicit Arguments preserves [X]. Lemma rtc_preserves : forall (X: Set) (R: relation X) (P: X->Prop), preserves R P -> preserves (refl_trans_closure R) P. Proof. (* OPTIONAL EXERCISE *) Admitted. (* This definition of reflexive, transitive closure is the natural one -- it says, explicitly, that the reflexive and transitive closure of [R] is the least relation that includes [R] and that is closed under rules of reflexivity and transitivity. But this definition turns out not always to be convenient for doing proofs -- the "nondeterminism" of the rtc_trans rule can sometimes lead to tricky inductions. Here is a more useful definition... *) Inductive refl_step_closure (X:Set) (R: relation X) : X -> X -> Prop := | refl : forall (x : X), refl_step_closure X R x x | step : forall (x y z : X), R x y -> refl_step_closure X R y z -> refl_step_closure X R x z. Implicit Arguments refl_step_closure [X]. (* This new definition "bundles together" the rtc_R and rtc_trans rules into the single rule step. The left-hand premise of this step is a single use of R, leading to a much simpler induction principle. Before we go on, we should check that the 2 definitions do indeed define the same relation... *) Lemma rsc_transitive : forall (X:Set) (R: relation X) (x y z : X), refl_step_closure R x y -> refl_step_closure R y z -> refl_step_closure R x z. Proof. (* OPTIONAL EXERCISE *) Admitted. Lemma two_versions_of_rtc_coincide : forall (X:Set) (R: relation X) (x y : X), refl_trans_closure R x y <-> refl_step_closure R x y. Proof. (* OPTIONAL EXERCISE *) Admitted.