diff -r 8f394f266025 -r 01fa0c8dbc92 src/ZF/upair.thy --- a/src/ZF/upair.thy Fri Jun 28 20:01:09 2002 +0200 +++ b/src/ZF/upair.thy Sat Jun 29 21:33:06 2002 +0200 @@ -2,6 +2,14 @@ ID: $Id$ Author: Lawrence C Paulson and Martin D Coen, CU Computer Laboratory Copyright 1993 University of Cambridge + +UNORDERED pairs in Zermelo-Fraenkel Set Theory + +Observe the order of dependence: + Upair is defined in terms of Replace + Un is defined in terms of Upair and Union (similarly for Int) + cons is defined in terms of Upair and Un + Ordered pairs and descriptions are defined using cons ("set notation") *) theory upair = ZF @@ -10,4 +18,379 @@ setup TypeCheck.setup declare atomize_ball [symmetric, rulify] +(*** Lemmas about power sets ***) + +lemmas Pow_bottom = empty_subsetI [THEN PowI] (* 0 : Pow(B) *) +lemmas Pow_top = subset_refl [THEN PowI] (* A : Pow(A) *) + + +(*** Unordered pairs - Upair ***) + +lemma Upair_iff [simp]: "c : Upair(a,b) <-> (c=a | c=b)" +by (unfold Upair_def, blast) + +lemma UpairI1: "a : Upair(a,b)" +by simp + +lemma UpairI2: "b : Upair(a,b)" +by simp + +lemma UpairE: + "[| a : Upair(b,c); a=b ==> P; a=c ==> P |] ==> P" +apply simp +apply blast +done + +(*** Rules for binary union -- Un -- defined via Upair ***) + +lemma Un_iff [simp]: "c : A Un B <-> (c:A | c:B)" +apply (simp add: Un_def) +apply (blast intro: UpairI1 UpairI2 elim: UpairE) +done + +lemma UnI1: "c : A ==> c : A Un B" +by simp + +lemma UnI2: "c : B ==> c : A Un B" +by simp + +lemma UnE [elim!]: "[| c : A Un B; c:A ==> P; c:B ==> P |] ==> P" +apply simp +apply blast +done + +(*Stronger version of the rule above*) +lemma UnE': "[| c : A Un B; c:A ==> P; [| c:B; c~:A |] ==> P |] ==> P" +apply simp +apply blast +done + +(*Classical introduction rule: no commitment to A vs B*) +lemma UnCI [intro!]: "(c ~: B ==> c : A) ==> c : A Un B" +apply simp +apply blast +done + + +(*** Rules for small intersection -- Int -- defined via Upair ***) + +lemma Int_iff [simp]: "c : A Int B <-> (c:A & c:B)" +apply (unfold Int_def) +apply (blast intro: UpairI1 UpairI2 elim: UpairE) +done + +lemma IntI [intro!]: "[| c : A; c : B |] ==> c : A Int B" +by simp + +lemma IntD1: "c : A Int B ==> c : A" +by simp + +lemma IntD2: "c : A Int B ==> c : B" +by simp + +lemma IntE [elim!]: "[| c : A Int B; [| c:A; c:B |] ==> P |] ==> P" +by simp + + +(*** Rules for set difference -- defined via Upair ***) + +lemma Diff_iff [simp]: "c : A-B <-> (c:A & c~:B)" +by (unfold Diff_def, blast) + +lemma DiffI [intro!]: "[| c : A; c ~: B |] ==> c : A - B" +by simp + +lemma DiffD1: "c : A - B ==> c : A" +by simp + +lemma DiffD2: "c : A - B ==> c ~: B" +by simp + +lemma DiffE [elim!]: "[| c : A - B; [| c:A; c~:B |] ==> P |] ==> P" +by simp + + +(*** Rules for cons -- defined via Un and Upair ***) + +lemma cons_iff [simp]: "a : cons(b,A) <-> (a=b | a:A)" +apply (unfold cons_def) +apply (blast intro: UpairI1 UpairI2 elim: UpairE) +done + +(*risky as a typechecking rule, but solves otherwise unconstrained goals of +the form x : ?A*) +lemma consI1 [simp,TC]: "a : cons(a,B)" +by simp + + +lemma consI2: "a : B ==> a : cons(b,B)" +by simp + +lemma consE [elim!]: + "[| a : cons(b,A); a=b ==> P; a:A ==> P |] ==> P" +apply simp +apply blast +done + +(*Stronger version of the rule above*) +lemma consE': + "[| a : cons(b,A); a=b ==> P; [| a:A; a~=b |] ==> P |] ==> P" +apply simp +apply blast +done + +(*Classical introduction rule*) +lemma consCI [intro!]: "(a~:B ==> a=b) ==> a: cons(b,B)" +apply simp +apply blast +done + +lemma cons_not_0 [simp]: "cons(a,B) ~= 0" +by (blast elim: equalityE) + +lemmas cons_neq_0 = cons_not_0 [THEN notE, standard] + +declare cons_not_0 [THEN not_sym, simp] + + +(*** Singletons - using cons ***) + +lemma singleton_iff: "a : {b} <-> a=b" +by simp + +lemma singletonI [intro!]: "a : {a}" +by (rule consI1) + +lemmas singletonE = singleton_iff [THEN iffD1, elim_format, standard, elim!] + + +(*** Rules for Descriptions ***) + +lemma the_equality [intro]: + "[| P(a); !!x. P(x) ==> x=a |] ==> (THE x. P(x)) = a" +apply (unfold the_def) +apply (fast dest: subst) +done + +(* Only use this if you already know EX!x. P(x) *) +lemma the_equality2: "[| EX! x. P(x); P(a) |] ==> (THE x. P(x)) = a" +by blast + +lemma theI: "EX! x. P(x) ==> P(THE x. P(x))" +apply (erule ex1E) +apply (subst the_equality) +apply (blast+) +done + +(*the_cong is no longer necessary: if (ALL y.P(y)<->Q(y)) then + (THE x.P(x)) rewrites to (THE x. Q(x)) *) + +(*If it's "undefined", it's zero!*) +lemma the_0: "~ (EX! x. P(x)) ==> (THE x. P(x))=0" +apply (unfold the_def) +apply (blast elim!: ReplaceE) +done + +(*Easier to apply than theI: conclusion has only one occurrence of P*) +lemma theI2: + assumes p1: "~ Q(0) ==> EX! x. P(x)" + and p2: "!!x. P(x) ==> Q(x)" + shows "Q(THE x. P(x))" +apply (rule classical) +apply (rule p2) +apply (rule theI) +apply (rule classical) +apply (rule p1) +apply (erule the_0 [THEN subst], assumption) +done + +(*** if -- a conditional expression for formulae ***) + +lemma if_true [simp]: "(if True then a else b) = a" +by (unfold if_def, blast) + +lemma if_false [simp]: "(if False then a else b) = b" +by (unfold if_def, blast) + +(*Never use with case splitting, or if P is known to be true or false*) +lemma if_cong: + "[| P<->Q; Q ==> a=c; ~Q ==> b=d |] + ==> (if P then a else b) = (if Q then c else d)" +by (simp add: if_def cong add: conj_cong) + +(*Prevents simplification of x and y: faster and allows the execution + of functional programs. NOW THE DEFAULT.*) +lemma if_weak_cong: "P<->Q ==> (if P then x else y) = (if Q then x else y)" +by simp + +(*Not needed for rewriting, since P would rewrite to True anyway*) +lemma if_P: "P ==> (if P then a else b) = a" +by (unfold if_def, blast) + +(*Not needed for rewriting, since P would rewrite to False anyway*) +lemma if_not_P: "~P ==> (if P then a else b) = b" +by (unfold if_def, blast) + +lemma split_if: "P(if Q then x else y) <-> ((Q --> P(x)) & (~Q --> P(y)))" +(*no case_tac yet!*) +apply (rule_tac P=Q in case_split_thm, simp_all) +done + +(** Rewrite rules for boolean case-splitting: faster than + addsplits[split_if] +**) + +lemmas split_if_eq1 = split_if [of "%x. x = b", standard] +lemmas split_if_eq2 = split_if [of "%x. a = x", standard] + +lemmas split_if_mem1 = split_if [of "%x. x : b", standard] +lemmas split_if_mem2 = split_if [of "%x. a : x", standard] + +lemmas split_ifs = split_if_eq1 split_if_eq2 split_if_mem1 split_if_mem2 + +(*Logically equivalent to split_if_mem2*) +lemma if_iff: "a: (if P then x else y) <-> P & a:x | ~P & a:y" +by (simp split add: split_if) + +lemma if_type [TC]: + "[| P ==> a: A; ~P ==> b: A |] ==> (if P then a else b): A" +by (simp split add: split_if) + + +(*** Foundation lemmas ***) + +(*was called mem_anti_sym*) +lemma mem_asym: "[| a:b; ~P ==> b:a |] ==> P" +apply (rule classical) +apply (rule_tac A1 = "{a,b}" in foundation [THEN disjE]) +apply (blast elim!: equalityE)+ +done + +(*was called mem_anti_refl*) +lemma mem_irrefl: "a:a ==> P" +by (blast intro: mem_asym) + +(*mem_irrefl should NOT be added to default databases: + it would be tried on most goals, making proofs slower!*) + +lemma mem_not_refl: "a ~: a" +apply (rule notI) +apply (erule mem_irrefl) +done + +(*Good for proving inequalities by rewriting*) +lemma mem_imp_not_eq: "a:A ==> a ~= A" +by (blast elim!: mem_irrefl) + +(*** Rules for succ ***) + +lemma succ_iff: "i : succ(j) <-> i=j | i:j" +by (unfold succ_def, blast) + +lemma succI1 [simp]: "i : succ(i)" +by (simp add: succ_iff) + +lemma succI2: "i : j ==> i : succ(j)" +by (simp add: succ_iff) + +lemma succE [elim!]: + "[| i : succ(j); i=j ==> P; i:j ==> P |] ==> P" +apply (simp add: succ_iff, blast) +done + +(*Classical introduction rule*) +lemma succCI [intro!]: "(i~:j ==> i=j) ==> i: succ(j)" +by (simp add: succ_iff, blast) + +lemma succ_not_0 [simp]: "succ(n) ~= 0" +by (blast elim!: equalityE) + +lemmas succ_neq_0 = succ_not_0 [THEN notE, standard, elim!] + +declare succ_not_0 [THEN not_sym, simp] +declare sym [THEN succ_neq_0, elim!] + +(* succ(c) <= B ==> c : B *) +lemmas succ_subsetD = succI1 [THEN [2] subsetD] + +(* succ(b) ~= b *) +lemmas succ_neq_self = succI1 [THEN mem_imp_not_eq, THEN not_sym, standard] + +lemma succ_inject_iff [simp]: "succ(m) = succ(n) <-> m=n" +by (blast elim: mem_asym elim!: equalityE) + +lemmas succ_inject = succ_inject_iff [THEN iffD1, standard, dest!] + +ML +{* +val Pow_bottom = thm "Pow_bottom"; +val Pow_top = thm "Pow_top"; +val Upair_iff = thm "Upair_iff"; +val UpairI1 = thm "UpairI1"; +val UpairI2 = thm "UpairI2"; +val UpairE = thm "UpairE"; +val Un_iff = thm "Un_iff"; +val UnI1 = thm "UnI1"; +val UnI2 = thm "UnI2"; +val UnE = thm "UnE"; +val UnE' = thm "UnE'"; +val UnCI = thm "UnCI"; +val Int_iff = thm "Int_iff"; +val IntI = thm "IntI"; +val IntD1 = thm "IntD1"; +val IntD2 = thm "IntD2"; +val IntE = thm "IntE"; +val Diff_iff = thm "Diff_iff"; +val DiffI = thm "DiffI"; +val DiffD1 = thm "DiffD1"; +val DiffD2 = thm "DiffD2"; +val DiffE = thm "DiffE"; +val cons_iff = thm "cons_iff"; +val consI1 = thm "consI1"; +val consI2 = thm "consI2"; +val consE = thm "consE"; +val consE' = thm "consE'"; +val consCI = thm "consCI"; +val cons_not_0 = thm "cons_not_0"; +val cons_neq_0 = thm "cons_neq_0"; +val singleton_iff = thm "singleton_iff"; +val singletonI = thm "singletonI"; +val singletonE = thm "singletonE"; +val the_equality = thm "the_equality"; +val the_equality2 = thm "the_equality2"; +val theI = thm "theI"; +val the_0 = thm "the_0"; +val theI2 = thm "theI2"; +val if_true = thm "if_true"; +val if_false = thm "if_false"; +val if_cong = thm "if_cong"; +val if_weak_cong = thm "if_weak_cong"; +val if_P = thm "if_P"; +val if_not_P = thm "if_not_P"; +val split_if = thm "split_if"; +val split_if_eq1 = thm "split_if_eq1"; +val split_if_eq2 = thm "split_if_eq2"; +val split_if_mem1 = thm "split_if_mem1"; +val split_if_mem2 = thm "split_if_mem2"; +val if_iff = thm "if_iff"; +val if_type = thm "if_type"; +val mem_asym = thm "mem_asym"; +val mem_irrefl = thm "mem_irrefl"; +val mem_not_refl = thm "mem_not_refl"; +val mem_imp_not_eq = thm "mem_imp_not_eq"; +val succ_iff = thm "succ_iff"; +val succI1 = thm "succI1"; +val succI2 = thm "succI2"; +val succE = thm "succE"; +val succCI = thm "succCI"; +val succ_not_0 = thm "succ_not_0"; +val succ_neq_0 = thm "succ_neq_0"; +val succ_subsetD = thm "succ_subsetD"; +val succ_neq_self = thm "succ_neq_self"; +val succ_inject_iff = thm "succ_inject_iff"; +val succ_inject = thm "succ_inject"; + +val split_ifs = thms "split_ifs"; +*} + end