]> matita.cs.unibo.it Git - helm.git/blobdiff - weblib/tutorial/chapter4.ma
Complete outline. Raw scripts.
[helm.git] / weblib / tutorial / chapter4.ma
index 79b6bafff14a082f5ed40334cd1b60332c84b79c..b358f823245894dc6803ce927dafbe7943013ed1 100644 (file)
-include "tutorial/chapter3.ma".
+include "basics/logic.ma".
 
-(* As a simple application of lists, let us now consider strings of characters 
-over a given alphabet Alpha. We shall assume to have a decidable equality between 
-characters, that is a (computable) function eqb associating a boolean value true 
-or false to each pair of characters; eqb is correct, in the sense that (eqb x y) 
-if and only if (x = y). The type Alpha of alphabets is hence defined by the 
-following record *)
+(**** a subset of A is just an object of type A→Prop ****)
 
-interpretation "iff" 'iff a b = (iff a b). 
+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 ?).
 
-record Alpha : Type[1] ≝ { carr :> Type[0];
-   eqb: carr → carr → \ 5a href="cic:/matita/basics/bool/bool.ind(1,0,0)"\ 6bool\ 5/a\ 6;
-   eqb_true: ∀x,y. (eqb x y \ 5a title="leibnitz's equality" href="cic:/fakeuri.def(1)"\ 6=\ 5/a\ 6 \ 5a href="cic:/matita/basics/bool/bool.con(0,1,0)"\ 6true\ 5/a\ 6\ 5a title="iff" href="cic:/fakeuri.def(1)"\ 6\ 5/a\ 6 (x \ 5a title="leibnitz's equality" href="cic:/fakeuri.def(1)"\ 6=\ 5/a\ 6 y)
-}.
-notation "a == b" non associative with precedence 45 for @{ 'eqb $a $b }.
-interpretation "eqb" 'eqb a b = (eqb ? a b).
-
-definition word ≝ λS: \ 5a href="cic:/matita/tutorial/chapter4/Alpha.ind(1,0,0)"\ 6Alpha\ 5/a\ 6.\ 5a href="cic:/matita/tutorial/chapter3/list.ind(1,0,1)"\ 6list\ 5/a\ 6 S.
+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).
 
-inductive re (S: \ 5a href="cic:/matita/tutorial/chapter4/Alpha.ind(1,0,0)"\ 6Alpha\ 5/a\ 6) : Type[0] ≝
-   zero: re S
- | epsilon: re S
- | char: S → re S
- | concat: re S → re S → re S
- | or: re S → re S → re S
- | star: re S → re S.
-(* notation < "a \sup ⋇" non associative with precedence 90 for @{ 'pk $a}. *)
-notation "a ^ *" non associative with precedence 90 for @{ 'kstar $a}.
-interpretation "star" 'kstar a = (star ? a).
-interpretation "or" 'plus a b = (or ? a b).
-           
-notation "a · b" non associative with precedence 60 for @{ 'concat $a $b}.
-interpretation "cat" 'concat a b = (concat ? a b).
-
-(* to get rid of \middot 
-coercion c  : ∀S:Alpha.∀p:re S.  re S →  re S   ≝ c  on _p : re ?  to ∀_:?.?. *)
-
-(* notation < "a" non associative with precedence 90 for @{ 'ps $a}. *)
-notation "` term 90 a" non associative with precedence 90 for @{ 'atom $a}.
-interpretation "atom" 'atom a = (char ? a).
-
-notation "ϵ" non associative with precedence 90 for @{ 'epsilon }.
-interpretation "epsilon" 'epsilon = (epsilon ?).
-
-notation "∅" (* slash emptyv *) non associative with precedence 90 for @{ 'empty }.
-interpretation "empty" 'empty = (zero ?).
-
-let rec flatten (S : \ 5a href="cic:/matita/tutorial/chapter4/Alpha.ind(1,0,0)"\ 6Alpha\ 5/a\ 6) (l : \ 5a href="cic:/matita/tutorial/chapter3/list.ind(1,0,1)"\ 6list\ 5/a\ 6 (\ 5a href="cic:/matita/tutorial/chapter4/word.def(3)"\ 6word\ 5/a\ 6 S)) on l : \ 5a href="cic:/matita/tutorial/chapter4/word.def(3)"\ 6word\ 5/a\ 6 S ≝ 
-match l with [ nil ⇒ \ 5a title="nil" href="cic:/fakeuri.def(1)"\ 6[\ 5/a\ 6 ] | cons w tl ⇒ w \ 5a title="append" href="cic:/fakeuri.def(1)"\ 6@\ 5/a\ 6 flatten ? tl ].
-
-let rec conjunct (S : \ 5a href="cic:/matita/tutorial/chapter4/Alpha.ind(1,0,0)"\ 6Alpha\ 5/a\ 6) (l : \ 5a href="cic:/matita/tutorial/chapter3/list.ind(1,0,1)"\ 6list\ 5/a\ 6 (\ 5a href="cic:/matita/tutorial/chapter4/word.def(3)"\ 6word\ 5/a\ 6 S)) (L :\ 5a href="cic:/matita/tutorial/chapter4/word.def(3)"\ 6word\ 5/a\ 6 S → Prop) on l: Prop ≝
-match l with [ nil ⇒ \ 5a href="cic:/matita/basics/logic/True.ind(1,0,0)"\ 6True\ 5/a\ 6 | cons w tl ⇒ L w \ 5a title="logical and" href="cic:/fakeuri.def(1)"\ 6\ 5/a\ 6 conjunct ? tl L ]. 
-
-definition empty_lang ≝ λS.λw:\ 5a href="cic:/matita/tutorial/chapter4/word.def(3)"\ 6word\ 5/a\ 6 S.\ 5a href="cic:/matita/basics/logic/False.ind(1,0,0)"\ 6False\ 5/a\ 6.  
-(* notation "{}" non associative with precedence 90 for @{'empty_lang}. *)
-interpretation "empty lang" 'empty = (empty_lang ?).
-
-definition sing_lang ≝ λS.λx,w:\ 5a href="cic:/matita/tutorial/chapter4/word.def(3)"\ 6word\ 5/a\ 6 S.x \ 5a title="leibnitz's equality" href="cic:/fakeuri.def(1)"\ 6=\ 5/a\ 6 w.
-notation "{: x }" non associative with precedence 90 for @{'sing_lang $x}.
-interpretation "sing lang" 'sing_lang x = (sing_lang ? x).
-
-definition union : ∀S,L1,L2,w.Prop ≝ λS,L1,L2.λw: \ 5a href="cic:/matita/tutorial/chapter4/word.def(3)"\ 6word\ 5/a\ 6 S.L1 w \ 5a title="logical or" href="cic:/fakeuri.def(1)"\ 6\ 5/a\ 6 L2 w.
-interpretation "union lang" 'union a b = (union ? a b).
-
-definition cat : ∀S,l1,l2,w.Prop ≝ 
-  λS.λl1,l2.λw:\ 5a href="cic:/matita/tutorial/chapter4/word.def(3)"\ 6word\ 5/a\ 6 S.\ 5a title="exists" href="cic:/fakeuri.def(1)"\ 6\ 5/a\ 6w1,w2.w1 \ 5a title="append" href="cic:/fakeuri.def(1)"\ 6@\ 5/a\ 6 w2 \ 5a title="leibnitz's equality" href="cic:/fakeuri.def(1)"\ 6=\ 5/a\ 6 w \ 5a title="logical and" href="cic:/fakeuri.def(1)"\ 6\ 5/a\ 6 l1 w1 \ 5a title="logical and" href="cic:/fakeuri.def(1)"\ 6\ 5/a\ 6 l2 w2.
-interpretation "cat lang" 'concat a b = (cat ? a b).
-
-definition star ≝ λS.λl.λw:\ 5a href="cic:/matita/tutorial/chapter4/word.def(3)"\ 6word\ 5/a\ 6 S.\ 5a title="exists" href="cic:/fakeuri.def(1)"\ 6\ 5/a\ 6lw. \ 5a href="cic:/matita/tutorial/chapter4/flatten.fix(0,1,4)"\ 6flatten\ 5/a\ 6 ? lw \ 5a title="leibnitz's equality" href="cic:/fakeuri.def(1)"\ 6=\ 5/a\ 6 w \ 5a title="logical and" href="cic:/fakeuri.def(1)"\ 6\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter4/conjunct.fix(0,1,4)"\ 6conjunct\ 5/a\ 6 ? lw l. 
-interpretation "star lang" 'kstar l = (star ? l).
-
-notation "ℓ term 70 E" non associative with precedence 75 for @{in_l ? $E}.
-
-let rec in_l (S : \ 5a href="cic:/matita/tutorial/chapter4/Alpha.ind(1,0,0)"\ 6Alpha\ 5/a\ 6) (r : \ 5a href="cic:/matita/tutorial/chapter4/re.ind(1,0,1)"\ 6re\ 5/a\ 6 S) on r : \ 5a href="cic:/matita/tutorial/chapter4/word.def(3)"\ 6word\ 5/a\ 6 S → Prop ≝ 
-match r with
- [ zero ⇒ \ 5a title="empty lang" href="cic:/fakeuri.def(1)"\ 6\ 5/a\ 6 
- | epsilon ⇒ \ 5a title="sing lang" href="cic:/fakeuri.def(1)"\ 6{\ 5/a\ 6\ 5a title="nil" href="cic:/fakeuri.def(1)"\ 6[\ 5/a\ 6] }
- |  char x ⇒ \ 5a title="sing lang" href="cic:/fakeuri.def(1)"\ 6{\ 5/a\ 6: x\ 5a title="cons" href="cic:/fakeuri.def(1)"\ 6:\ 5/a\ 6:\ 5a title="nil" href="cic:/fakeuri.def(1)"\ 6[\ 5/a\ 6] }
- | concat r1 r2 ⇒ ℓ r1 \ 5a title="cat lang" href="cic:/fakeuri.def(1)"\ 6·\ 5/a\ 6 ℓ r2 
- | or r1 r2 ⇒ ℓ r1 \ 5a title="union lang" href="cic:/fakeuri.def(1)"\ 6\ 5/a\ 6 ℓ r2 
- | star r1 ⇒ (ℓ r1)\ 5a title="star lang" href="cic:/fakeuri.def(1)"\ 6^\ 5/a\ 6
- ].
-
-notation "ℓ term 70 E" non associative with precedence 75 for @{'in_l $E}.
-interpretation "in_l" 'in_l E = (in_l ? E).
-interpretation "in_l mem" 'mem w l = (in_l ? l w).
-
-notation "a ∨ b" left associative with precedence 30 for @{'orb $a $b}.
-interpretation "orb" 'orb a b = (orb a b).
-
-(* ndefinition if_then_else ≝ λT:Type[0].λe,t,f.match e return λ_.T with [ true ⇒ t | false ⇒ f].
-notation > "'if' term 19 e 'then' term 19 t 'else' term 19 f" non associative with precedence 19 for @{ 'if_then_else $e $t $f }.
-notation < "'if' \nbsp term 19 e \nbsp 'then' \nbsp term 19 t \nbsp 'else' \nbsp term 90 f \nbsp" non associative with precedence 19 for @{ 'if_then_else $e $t $f }.
-interpretation "if_then_else" 'if_then_else e t f = (if_then_else ? e t f). *)
-
-inductive pitem (S: \ 5a href="cic:/matita/tutorial/chapter4/Alpha.ind(1,0,0)"\ 6Alpha\ 5/a\ 6) : Type[0] ≝
- | pzero: pitem S
- | pepsilon: pitem S
- | pchar: S → pitem S
- | ppoint: S → pitem S
- | pconcat: pitem S → pitem S → pitem S
- | por: pitem S → pitem S → pitem S
- | pstar: pitem S → pitem S.
-definition pre ≝ λS.\ 5a href="cic:/matita/tutorial/chapter4/pitem.ind(1,0,1)"\ 6pitem\ 5/a\ 6 S \ 5a title="Product" href="cic:/fakeuri.def(1)"\ 6×\ 5/a\ 6 \ 5a href="cic:/matita/basics/bool/bool.ind(1,0,0)" title="null"\ 6bool\ 5/a\ 6.
+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).
 
-interpretation "pstar" 'kstar a = (pstar ? a).
-interpretation "por" 'plus a b = (por ? a b).
-interpretation "pcat" 'concat a b = (pconcat ? a b).
+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).
 
-notation "• a" non associative with precedence 90 for @{ 'ppoint $a}.
-(* notation > "`. term 90 a" non associative with precedence 90 for @{ 'pp $a}. *)
+definition complement ≝ λU:Type[0].λA:U → Prop.λw.¬ A w.
+interpretation "complement" 'not a = (complement ? a).
 
-interpretation "ppatom" 'ppoint a = (ppoint ? a).
-(* to get rid of \middot 
-ncoercion pc : ∀S.∀p:pitem S. pitem S → pitem S  ≝ pc on _p : pitem ? to ∀_:?.?. *)
-interpretation "patom" 'pchar a = (pchar ? a).
-interpretation "pepsilon" 'epsilon = (pepsilon ?).
-interpretation "pempty" 'empty = (pzero ?).
+definition substraction := λU:Type[0].λA,B:U → Prop.λw.A w ∧ ¬ B w.
+interpretation "substraction" 'minus a b = (substraction ? a b).
 
-notation "\boxv term 19 e \boxv" (* slash boxv *) non associative with precedence 70 for @{forget ? $e}.
+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).
 
-let rec forget (S: \ 5a href="cic:/matita/tutorial/chapter4/Alpha.ind(1,0,0)"\ 6Alpha\ 5/a\ 6) (l : \ 5a href="cic:/matita/tutorial/chapter4/pitem.ind(1,0,1)"\ 6pitem\ 5/a\ 6 S) on l: \ 5a href="cic:/matita/tutorial/chapter4/re.ind(1,0,1)"\ 6re\ 5/a\ 6 S ≝
- match l with
-  [ pzero ⇒ \ 5a title="empty" href="cic:/fakeuri.def(1)"\ 6\ 5/a\ 6
-  | pepsilon ⇒ \ 5a title="epsilon" href="cic:/fakeuri.def(1)"\ 6ϵ\ 5/a\ 6
-  | pchar x ⇒ \ 5a href="cic:/matita/tutorial/chapter4/re.con(0,3,1)"\ 6char\ 5/a\ 6 ? x 
-  | ppoint x ⇒ \ 5a href="cic:/matita/tutorial/chapter4/re.con(0,3,1)"\ 6char\ 5/a\ 6 ? x  
-  | pconcat e1 e2 ⇒ │e1│ \ 5a title="cat" href="cic:/fakeuri.def(1)"\ 6·\ 5/a\ 6 │e2│
-  | por e1 e2 ⇒ │e1│  \ 5a title="or" href="cic:/fakeuri.def(1)"\ 6+\ 5/a\ 6 │e2│
-  | pstar e ⇒ │e│\ 5a title="star" href="cic:/fakeuri.def(1)"\ 6^\ 5/a\ 6
-  ].
+(* extensional equality *)
+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).
 
-notation < "|term 19 e|" non associative with precedence 70 for @{'forget $e}.
-interpretation "forget" 'forget a = (forget ? a).
+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.
+
+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.
+
+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.
+  
+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.
+
+(* set equalities *)
+lemma union_empty_r: ∀U.∀A:U→Prop. 
+  A ∪ ∅ =1 A.
+#U #A #w % [* // normalize #abs @False_ind /2/ | /2/]
+qed.
+
+lemma union_comm : ∀U.∀A,B:U →Prop. 
+  A ∪ B =1 B ∪ A.
+#U #A #B #a % * /2/ qed. 
+
+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.   
+
+lemma cap_comm : ∀U.∀A,B:U →Prop. 
+  A ∩ B =1 B ∩ A.
+#U #A #B #a % * /2/ qed. 
+
+lemma union_idemp: ∀U.∀A:U →Prop. 
+  A ∪ A =1 A.
+#U #A #a % [* // | /2/] qed. 
+
+lemma cap_idemp: ∀U.∀A:U →Prop. 
+  A ∩ A =1 A.
+#U #A #a % [* // | /2/] qed. 
+
+(*distributivities *)
+
+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.
+  
+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.
+
+(* substraction *)
+lemma substract_def:∀U.∀A,B:U→Prop. A-B =1 A ∩ ¬B.
+#U #A #B #w normalize /2/
+qed.
+
+include "basics/types.ma".
+include "basics/bool.ma".
+
+(****** DeqSet: a set with a decidbale equality ******)
+
+record DeqSet : Type[1] ≝ { carr :> Type[0];
+   eqb: carr → carr → bool;
+   eqb_true: ∀x,y. (eqb x y = true) ↔ (x = y)
+}.
 
+notation "a == b" non associative with precedence 45 for @{ 'eqb $a $b }.
+interpretation "eqb" 'eqb a b = (eqb ? a b).
 
-notation "\fst term 90 x" non associative with precedence 90 for @{'fst $x}.  
+notation "\P H" non associative with precedence 90 
+  for @{(proj1 … (eqb_true ???) $H)}. 
+
+notation "\b H" non associative with precedence 90 
+  for @{(proj2 … (eqb_true ???) $H)}. 
+  
+lemma eqb_false: ∀S:DeqSet.∀a,b:S. 
+  (eqb ? a b) = false ↔ a ≠ b.
+#S #a #b % #H 
+  [@(not_to_not … not_eq_true_false) #H1 <H @sym_eq @(\b H1)
+  |cases (true_or_false (eqb ? a b)) // #H1 @False_ind @(absurd … (\P H1) H)
+  ]
+qed.
+notation "\Pf H" non associative with precedence 90 
+  for @{(proj1 … (eqb_false ???) $H)}. 
+
+notation "\bf H" non associative with precedence 90 
+  for @{(proj2 … (eqb_false ???) $H)}. 
+  
+lemma dec_eq: ∀S:DeqSet.∀a,b:S. a = b ∨ a ≠ b.
+#S #a #b cases (true_or_false (eqb ? a b)) #H
+  [%1 @(\P H) | %2 @(\Pf H)]
+qed.
+
+definition beqb ≝ λb1,b2.
+  match b1 with [ true ⇒ b2 | false ⇒ notb b2].
+
+notation < "a == b" non associative with precedence 45 for @{beqb $a $b }.
+lemma beqb_true: ∀b1,b2. iff (beqb b1 b2 = true) (b1 = b2).
+#b1 #b2 cases b1 cases b2 normalize /2/
+qed. 
+
+definition DeqBool ≝ mk_DeqSet bool beqb beqb_true.
+
+unification hint  0 ≔ ; 
+    X ≟ mk_DeqSet bool beqb beqb_true
+(* ---------------------------------------- *) ⊢ 
+    bool ≡ carr X.
+    
+unification hint  0 ≔ b1,b2:bool; 
+    X ≟ mk_DeqSet bool beqb beqb_true
+(* ---------------------------------------- *) ⊢ 
+    beqb b1 b2 ≡ eqb X b1 b2.
+    
+example exhint: ∀b:bool. (b == false) = true → b = false. 
+#b #H @(\P H).
+qed.
+
+(* pairs *)
+definition eq_pairs ≝
+  λA,B:DeqSet.λp1,p2:A×B.(\fst p1 == \fst p2) ∧ (\snd p1 == \snd p2).
+
+lemma eq_pairs_true: ∀A,B:DeqSet.∀p1,p2:A×B.
+  eq_pairs A B p1 p2 = true ↔ p1 = p2.
+#A #B * #a1 #b1 * #a2 #b2 %
+  [#H cases (andb_true …H) #eqa #eqb >(\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).
+  
+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