X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=matita%2Fmatita%2Flib%2Ftutorial%2Fchapter4.ma;h=6c794ccb196f98a9ad7333886fe0148636355fb5;hb=aad5588b82d0f2991c336f7ac2f3fadd76768eeb;hp=30fae3df079b77fe2bc8d1ce765bc21843b514e4;hpb=770ba48ba232d7f1782629c572820a0f1bfe4fde;p=helm.git diff --git a/matita/matita/lib/tutorial/chapter4.ma b/matita/matita/lib/tutorial/chapter4.ma index 30fae3df0..6c794ccb1 100644 --- a/matita/matita/lib/tutorial/chapter4.ma +++ b/matita/matita/lib/tutorial/chapter4.ma @@ -1,337 +1,563 @@ -(* -Naif Set Theory - +(* + Propositions as Types *) -include "basics/types.ma". -include "basics/bool.ma". -(* -In this Chapter we shall develop a naif theory of sets represented as -characteristic predicates over some universe A, that is as objects of type -A→Prop. -For instance the empty set is defined by the always false function: *) -definition empty_set ≝ λA:Type[0].λa:A.False. -notation "\emptyv" non associative with precedence 90 for @{'empty_set}. -interpretation "empty set" 'empty_set = (empty_set ?). +include "basics/logic.ma". -(* Similarly, a singleton set contaning containing an element a, is defined -by by the characteristic function asserting equality with a *) +(* In the previous section, we introduced many interesting logical connectives +by means of inductive definitions in the sort Prop. Do the same constructions +make any sense in Type? The answer is yes! Not only they make sense, but they +are indeed very familiar constructions: cartesian product, disjoint sum, empty +and singleton types, and ``sigma types'' (disjoint union of families of types +indexed over a given base type). This is not a coincidence, but a consequence of +a strong principle known under the name of ``Propositions as Types analogy'' (or +Curry-Howard correspondence). -definition singleton ≝ λA.λx,a:A.x=a. -(* notation "{x}" non associative with precedence 90 for @{'sing_lang $x}. *) -interpretation "singleton" 'singl x = (singleton ? x). +We shall first discuss the constructions, and then we shall come back on the +general analogy.*) -(* The membership relation between an element of type A and a set S:A →Prop is -simply the predicate resulting from the application of S to a. -The operations of union, intersection, complement and substraction -are easily defined in terms of the propositional connectives of dijunction, -conjunction and negation *) +(***************************** Cartesian Product ******************************) -definition union : ∀A:Type[0].∀P,Q.A → Prop ≝ λA,P,Q,a.P a ∨ Q a. -interpretation "union" 'union a b = (union ? a b). +(* The cartesian product of two types A and B is defined as follows: *) -definition intersection : ∀A:Type[0].∀P,Q.A→Prop ≝ λA,P,Q,a.P a ∧ Q a. -interpretation "intersection" 'intersects a b = (intersection ? a b). +inductive Prod (A,B:Type[0]) : Type[0] ≝ + pair : A → B → Prod A B. + +(* Observe that the definition is identical to the definition of the logical +conjunction, but for the fact that the sort Prop has been replaced by Type[0]. -definition complement ≝ λU:Type[0].λA:U → Prop.λw.¬ A w. -interpretation "complement" 'not a = (complement ? a). +The following declarations allows us to use the canonical notations A × B for +the product and 〈a,b〉 for the pair of the two elements a and b. *) -definition substraction := λU:Type[0].λA,B:U → Prop.λw.A w ∧ ¬ B w. -interpretation "substraction" 'minus a b = (substraction ? a b). +notation "hvbox(x break × y)" with precedence 70 for @{ 'product $x $y}. +interpretation "Cartesian product" 'product A B = (Prod A B). -(* Finally, we use implication to define the inclusion relation between -sets *) +notation "hvbox(\langle term 19 a, break term 19 b\rangle)" + with precedence 90 for @{ 'pair $a $b}. +interpretation "Pair construction" 'pair x y = (pair ?? x y). -definition subset: ∀A:Type[0].∀P,Q:A→Prop.Prop ≝ λA,P,Q.∀a:A.(P a → Q a). -interpretation "subset" 'subseteq a b = (subset ? a b). +(* We can define the two projections fst and snd by a simple case analysis of +the term: *) -(* -Set Equality +definition fst ≝ λA,B.λp:A×B. match p with [pair a b ⇒ a]. +definition snd ≝ λA,B.λp:A×B. match p with [pair a b ⇒ b]. -Two sets are equals if and only if they have the same elements, that is, -if the two characteristic functions are extensionally equivalent: *) +(* As in the case of inductive propositions, Matita automatically generates +elimination principles for A × B. In this case, however, it becomes interesting +to consider the possibility that the proposition towards which we are +eliminating a given pair p:A × B$ contains a copy of p itself. In other words, +if we have p:A × B in the current context, it is possible that p also occurs in +the current goal, that is that the current goal "depends" on p. -definition eqP ≝ λA:Type[0].λP,Q:A → Prop.∀a:A.P a ↔ Q a. -notation "A =1 B" non associative with precedence 45 for @{'eqP $A $B}. -interpretation "extensional equality" 'eqP a b = (eqP ? a b). +A typical example is in the proof of the so called ``surjective pairing'' +property: *) -(* -This notion of equality is different from the intensional equality of -functions; the fact it defines an equivalence relation must be explicitly -proved: *) +lemma surjective_pair: ∀A,B.∀p:A×B. p = 〈fst ?? p, snd ?? p〉. -lemma eqP_sym: ∀U.∀A,B:U →Prop. - A =1 B → B =1 A. -#U #A #B #eqAB #a @iff_sym @eqAB qed. - -lemma eqP_trans: ∀U.∀A,B,C:U →Prop. - A =1 B → B =1 C → A =1 C. -#U #A #B #C #eqAB #eqBC #a @iff_trans // qed. +(* where p explicitly occurs in the conclusion. The proof is straightforward: we +introduce A, B and p and proceed by cases on p: since p is a pair, the only +possible case is that it is of the form 〈a,b〉 for some a and b.*) -(* For the same reason, we must also prove that all the operations behave well -with respect to eqP: *) +#A #B #p cases p #a #b -lemma eqP_union_r: ∀U.∀A,B,C:U →Prop. - A =1 C → A ∪ B =1 C ∪ B. -#U #A #B #C #eqAB #a @iff_or_r @eqAB qed. - -lemma eqP_union_l: ∀U.∀A,B,C:U →Prop. - B =1 C → A ∪ B =1 A ∪ C. -#U #A #B #C #eqBC #a @iff_or_l @eqBC qed. - -lemma eqP_intersect_r: ∀U.∀A,B,C:U →Prop. - A =1 C → A ∩ B =1 C ∩ B. -#U #A #B #C #eqAB #a @iff_and_r @eqAB qed. - -lemma eqP_intersect_l: ∀U.∀A,B,C:U →Prop. - B =1 C → A ∩ B =1 A ∩ C. -#U #A #B #C #eqBC #a @iff_and_l @eqBC qed. +(* At this point the goal looks like + 〈a,b〉 = 〈fst A B 〈a,b〉, snd A B 〈a,b〉〉 +and the two sides of the equation are convertible. *) +// qed. -lemma eqP_substract_r: ∀U.∀A,B,C:U →Prop. - A =1 C → A - B =1 C - B. -#U #A #B #C #eqAB #a @iff_and_r @eqAB qed. +(* When we call cases p we are actually applying the dependent elimination +principle Prod_ind for the product, so it becomes interesting to have a look at +it (we shall postpone the discussion of the way it is generated in a later +section): + + ∀A,B.∀P:A×B →Prop.(∀a:A,∀b:B. P 〈a,b〉) → ∀x:A×B.P x -lemma eqP_substract_l: ∀U.∀A,B,C:U →Prop. - B =1 C → A - B =1 A - C. -#U #A #B #C #eqBC #a @iff_and_l /2/ qed. +The previous principle has a very natural backward reading: in order to prove +that the property (P x) holds for any x of type A×B it is enough to prove P〈a,b〉 +for any a:A and b:B. *) -(* -Simple properties of sets +(******************************* Disjoint Sum *********************************) -We can now prove several properties of the previous set-theoretic operations. -In particular, union is commutative and associative, and the empty set is an -identity element: *) +(* By reflecting in Type the definition of the logical disjunction we obtain the +disjoint union (the sum) of two types: *) -lemma union_empty_r: ∀U.∀A:U→Prop. - A ∪ ∅ =1 A. -#U #A #w % [* // normalize #abs @False_ind /2/ | /2/] -qed. +inductive Sum (A,B:Type[0]) : Type[0] ≝ + inl : A → Sum A B +| inr : B → Sum A B. -lemma union_comm : ∀U.∀A,B:U →Prop. - A ∪ B =1 B ∪ A. -#U #A #B #a % * /2/ qed. +notation "hvbox(a break + b)" + left associative with precedence 55 for @{ 'plus $a $b }. -lemma union_assoc: ∀U.∀A,B,C:U → Prop. - A ∪ B ∪ C =1 A ∪ (B ∪ C). -#S #A #B #C #w % [* [* /3/ | /3/ ] | * [/3/ | * /3/] -qed. +interpretation "Disjoint union" 'plus A B = (Sum A B). -(* In the same way we prove commutativity and associativity for set -interesection *) +(* The two constructors are the left and right injections. The dependent +elimination principle Sum_ind has the following shape: -lemma cap_comm : ∀U.∀A,B:U →Prop. - A ∩ B =1 B ∩ A. -#U #A #B #a % * /2/ qed. + ∀A,B.∀P:A+B →Prop. + (∀a:A.P (inl A B a)) → (∀b:B.P (inr A B b)) → ∀x:A×B.P x + +that is, in order to prove the property (P x) for any x:A+B it is enough to +prove P (inl A B a) and P (inr A B b) for all a:A and b:B. *) -lemma cap_assoc: ∀U.∀A,B,C:U→Prop. - A ∩ (B ∩ C) =1 (A ∩ B) ∩ C. -#U #A #B #C #w % [ * #Aw * /3/ | * * /3/ ] -qed. +(************************* Empty Type and Unit Type ***************************) -(* We can also easily prove idempotency for union and intersection *) +(* The counterparts of False and True are, respectively, an empty type and a +singleton type: *) -lemma union_idemp: ∀U.∀A:U →Prop. - A ∪ A =1 A. -#U #A #a % [* // | /2/] qed. +inductive void : Type[0] ≝. +inductive unit : Type[0] ≝ it: unit. -lemma cap_idemp: ∀U.∀A:U →Prop. - A ∩ A =1 A. -#U #A #a % [* // | /2/] qed. +(* The elimination principle void_ind for void is simply -(* We conclude our examples with a couple of distributivity theorems, and a -characterization of substraction in terms of interesection and complementation. *) + ∀P:void→Prop.∀x:void.P x + +stating that any property is true for an element of type void (since we have no +such element). -lemma distribute_intersect : ∀U.∀A,B,C:U→Prop. - (A ∪ B) ∩ C =1 (A ∩ C) ∪ (B ∩ C). -#U #A #B #C #w % [* * /3/ | * * /3/] -qed. +Similarly, the elimination principle for the unit type is: + + ∀P:unit→Prop. P it → ∀x:unit.P x -lemma distribute_substract : ∀U.∀A,B,C:U→Prop. - (A ∪ B) - C =1 (A - C) ∪ (B - C). -#U #A #B #C #w % [* * /3/ | * * /3/] -qed. +Indeed, in order to prove that a property is true for any element of the unit +type, it is enough to prove it for the unique (canonical) inhabitant "it". -lemma substract_def:∀U.∀A,B:U→Prop. A-B =1 A ∩ ¬B. -#U #A #B #w normalize /2/ -qed. +As an exercise, let us prove that all inhabitants of unit are equal to each +other: *) -(* -Bool vs. Prop +lemma eq_unit: ∀a,b:unit. a = b. -In several situation it is important to assume to have a decidable equality -between elements of a set U, namely a boolean function eqb: U→U→bool such that -for any pair of elements a and b in U, (eqb x y) is true if and only if x=y. -A set equipped with such an equality is called a DeqSet: *) +(* The idea is to proceed by cases on a and b: we have only one possibility, +namely a=it and b=it, hence we end up to prove it=it, that is trivial. Here is +the proof: *) -record DeqSet : Type[1] ≝ { carr :> Type[0]; - eqb: carr → carr → bool; - eqb_true: ∀x,y. (eqb x y = true) ↔ (x = y) -}. +#a cases a #b cases b // qed. (* also: * * // qed. *) -(* We use the notation == to denote the decidable equality, to distinguish it -from the propositional equality. In particular, a term of the form a==b is a -boolean, while a=b is a proposition. *) +(* It is interesting to observe that we get exactly the same behavior by +directly applying unit_ind instead of proceeding by cases. In fact, this is an +alternative proof: *) -notation "a == b" non associative with precedence 45 for @{ 'eqb $a $b }. -interpretation "eqb" 'eqb a b = (eqb ? a b). +lemma eq_unit_again: ∀a,b:unit. a = b. +@unit_ind @unit_ind // qed. -(* -Small Scale Reflection +(********************* Sigma Types and dependent matching *********************) -It is convenient to have a simple way to reflect a proof of the fact -that (eqb a b) is true into a proof of the proposition (a = b); to this aim, -we introduce two operators "\P" and "\b". *) +(* As a final example, let us consider ``type'' variants of the existential +quantifier; in this case we have two interesting possibilities: *) -notation "\P H" non associative with precedence 90 - for @{(proj1 … (eqb_true ???) $H)}. +inductive Sig (A:Type[0]) (Q:A → Prop) : Type[0] ≝ + Sig_intro: ∀x:A. Q x → Sig A Q. -notation "\b H" non associative with precedence 90 - for @{(proj2 … (eqb_true ???) $H)}. - -(* If H:eqb a b = true, then \P H: a = b, and conversely if h:a = b, then -\b h: eqb a b = true. Let us see an example of their use: the following -statement asserts that we can reflect a proof that eqb a b is false into -a proof of the proposition a ≠ b. *) +inductive DPair (A:Type[0]) (Q:A → Type[0]) : Type[0] ≝ + DPair_intro: ∀x:A. Q x → DPair A Q. -lemma eqb_false: ∀S:DeqSet.∀a,b:S. - (eqb ? a b) = false ↔ a ≠ b. +(* We shall use the notation Σx:A.Q x for the sigma type, and the similar +notation ∑x:A.Q x for dependent pairs. *) -(* We start the proof introducing the hypothesis, and then split the "if" and -"only if" cases *) - -#S #a #b % #H +notation "hvbox(\Sigma ident i : ty break . p)" + left associative with precedence 20 +for @{'sigma (\lambda ${ident i} : $ty. $p) }. -(* The latter is easily reduced to prove the goal true=false under the assumption -H1: a = b *) - [@(not_to_not … not_eq_true_false) #H1 - -(* since by assumption H false is equal to (a==b), by rewriting we obtain the goal -true=(a==b) that is just the boolean version of H1 *) +notation "hvbox(\Sigma ident i break . p)" + with precedence 20 for @{'sigma (\lambda ${ident i}. $p) }. + +interpretation "Sigma" 'sigma x = (Sig ? x). - (\P eqa) >(\P eqb) // - |#H destruct normalize >(\b (refl … a2)) >(\b (refl … b2)) // - ] -qed. -definition DeqProd ≝ λA,B:DeqSet. - mk_DeqSet (A×B) (eq_pairs A B) (eq_pairs_true A B). - -(* Having an unification problem of the kind T1×T2 = carr X, what kind -of hint can we give to the system? We expect T1 to be the carrier of a -DeqSet C1, T2 to be the carrier of a DeqSet C2, and X to be DeqProd C1 C2. -This is expressed by the following hint: *) - -unification hint 0 ≔ C1,C2; - T1 ≟ carr C1, - T2 ≟ carr C2, - X ≟ DeqProd C1 C2 -(* ---------------------------------------- *) ⊢ - T1×T2 ≡ carr X. - -unification hint 0 ≔ T1,T2,p1,p2; - X ≟ DeqProd T1 T2 -(* ---------------------------------------- *) ⊢ - eq_pairs T1 T2 p1 p2 ≡ eqb X p1 p2. - -example hint2: ∀b1,b2. - 〈b1,true〉==〈false,b2〉=true → 〈b1,true〉=〈false,b2〉. -#b1 #b2 #H @(\P H). \ No newline at end of file