1 (* Title: ZF/func.thy |
1 (* Title: ZF/func.thy |
2 ID: $Id$ |
2 ID: $Id$ |
3 Author: Lawrence C Paulson, Cambridge University Computer Laboratory |
3 Author: Lawrence C Paulson, Cambridge University Computer Laboratory |
4 Copyright 1991 University of Cambridge |
4 Copyright 1991 University of Cambridge |
5 |
5 |
6 Functions in Zermelo-Fraenkel Set Theory |
|
7 *) |
6 *) |
8 |
7 |
|
8 header{*Functions, Function Spaces, Lambda-Abstraction*} |
|
9 |
9 theory func = equalities: |
10 theory func = equalities: |
|
11 |
|
12 subsection{*The Pi Operator: Dependent Function Space*} |
10 |
13 |
11 lemma subset_Sigma_imp_relation: "r <= Sigma(A,B) ==> relation(r)" |
14 lemma subset_Sigma_imp_relation: "r <= Sigma(A,B) ==> relation(r)" |
12 by (simp add: relation_def, blast) |
15 by (simp add: relation_def, blast) |
13 |
16 |
14 lemma relation_converse_converse [simp]: |
17 lemma relation_converse_converse [simp]: |
15 "relation(r) ==> converse(converse(r)) = r" |
18 "relation(r) ==> converse(converse(r)) = r" |
16 by (simp add: relation_def, blast) |
19 by (simp add: relation_def, blast) |
17 |
20 |
18 lemma relation_restrict [simp]: "relation(restrict(r,A))" |
21 lemma relation_restrict [simp]: "relation(restrict(r,A))" |
19 by (simp add: restrict_def relation_def, blast) |
22 by (simp add: restrict_def relation_def, blast) |
20 |
|
21 (*** The Pi operator -- dependent function space ***) |
|
22 |
23 |
23 lemma Pi_iff: |
24 lemma Pi_iff: |
24 "f: Pi(A,B) <-> function(f) & f<=Sigma(A,B) & A<=domain(f)" |
25 "f: Pi(A,B) <-> function(f) & f<=Sigma(A,B) & A<=domain(f)" |
25 by (unfold Pi_def, blast) |
26 by (unfold Pi_def, blast) |
26 |
27 |
54 |
55 |
55 (*Weakening one function type to another; see also Pi_type*) |
56 (*Weakening one function type to another; see also Pi_type*) |
56 lemma fun_weaken_type: "[| f: A->B; B<=D |] ==> f: A->D" |
57 lemma fun_weaken_type: "[| f: A->B; B<=D |] ==> f: A->D" |
57 by (unfold Pi_def, best) |
58 by (unfold Pi_def, best) |
58 |
59 |
59 (*** Function Application ***) |
60 subsection{*Function Application*} |
60 |
61 |
61 lemma apply_equality2: "[| <a,b>: f; <a,c>: f; f: Pi(A,B) |] ==> b=c" |
62 lemma apply_equality2: "[| <a,b>: f; <a,c>: f; f: Pi(A,B) |] ==> b=c" |
62 by (unfold Pi_def function_def, blast) |
63 by (unfold Pi_def function_def, blast) |
63 |
64 |
64 lemma function_apply_equality: "[| <a,b>: f; function(f) |] ==> f`a = b" |
65 lemma function_apply_equality: "[| <a,b>: f; function(f) |] ==> f`a = b" |
128 by (blast dest: fun_is_rel) |
129 by (blast dest: fun_is_rel) |
129 |
130 |
130 lemma Pair_mem_PiD: "[| <a,b>: f; f: Pi(A,B) |] ==> a:A & b:B(a) & f`a = b" |
131 lemma Pair_mem_PiD: "[| <a,b>: f; f: Pi(A,B) |] ==> a:A & b:B(a) & f`a = b" |
131 by (blast intro: domain_type range_type apply_equality) |
132 by (blast intro: domain_type range_type apply_equality) |
132 |
133 |
133 (*** Lambda Abstraction ***) |
134 subsection{*Lambda Abstraction*} |
134 |
135 |
135 lemma lamI: "a:A ==> <a,b(a)> : (lam x:A. b(x))" |
136 lemma lamI: "a:A ==> <a,b(a)> : (lam x:A. b(x))" |
136 apply (unfold lam_def) |
137 apply (unfold lam_def) |
137 apply (erule RepFunI) |
138 apply (erule RepFunI) |
138 done |
139 done |
241 apply (rule_tac [2] eta [symmetric]) |
242 apply (rule_tac [2] eta [symmetric]) |
242 apply (blast intro: major apply_type)+ |
243 apply (blast intro: major apply_type)+ |
243 done |
244 done |
244 |
245 |
245 |
246 |
246 (** Images of functions **) |
247 subsection{*Images of Functions*} |
247 |
248 |
248 lemma image_lam: "C <= A ==> (lam x:A. b(x)) `` C = {b(x). x:C}" |
249 lemma image_lam: "C <= A ==> (lam x:A. b(x)) `` C = {b(x). x:C}" |
249 by (unfold lam_def, blast) |
250 by (unfold lam_def, blast) |
250 |
251 |
251 lemma Repfun_function_if: |
252 lemma Repfun_function_if: |
273 lemma Pi_image_cons: |
274 lemma Pi_image_cons: |
274 "[| f: Pi(A,B); x: A |] ==> f `` cons(x,y) = cons(f`x, f``y)" |
275 "[| f: Pi(A,B); x: A |] ==> f `` cons(x,y) = cons(f`x, f``y)" |
275 by (blast dest: apply_equality apply_Pair) |
276 by (blast dest: apply_equality apply_Pair) |
276 |
277 |
277 |
278 |
278 (*** properties of "restrict" ***) |
279 subsection{*Properties of @{term "restrict(f,A)"}*} |
279 |
280 |
280 lemma restrict_subset: "restrict(f,A) <= f" |
281 lemma restrict_subset: "restrict(f,A) <= f" |
281 by (unfold restrict_def, blast) |
282 by (unfold restrict_def, blast) |
282 |
283 |
283 lemma function_restrictI: |
284 lemma function_restrictI: |
333 prefer 2 apply (blast intro: apply_Pair restrict_subset [THEN subsetD]) |
334 prefer 2 apply (blast intro: apply_Pair restrict_subset [THEN subsetD]) |
334 apply (auto dest!: Pi_memberD simp add: restrict_def lam_def) |
335 apply (auto dest!: Pi_memberD simp add: restrict_def lam_def) |
335 done |
336 done |
336 |
337 |
337 |
338 |
338 (*** Unions of functions ***) |
339 subsection{*Unions of Functions*} |
339 |
340 |
340 (** The Union of a set of COMPATIBLE functions is a function **) |
341 (** The Union of a set of COMPATIBLE functions is a function **) |
341 |
342 |
342 lemma function_Union: |
343 lemma function_Union: |
343 "[| ALL x:S. function(x); |
344 "[| ALL x:S. function(x); |
376 by (simp add: apply_def, blast) |
377 by (simp add: apply_def, blast) |
377 |
378 |
378 lemma fun_disjoint_apply2: "c \<notin> domain(f) ==> (f Un g)`c = g`c" |
379 lemma fun_disjoint_apply2: "c \<notin> domain(f) ==> (f Un g)`c = g`c" |
379 by (simp add: apply_def, blast) |
380 by (simp add: apply_def, blast) |
380 |
381 |
381 (** Domain and range of a function/relation **) |
382 subsection{*Domain and Range of a Function or Relation*} |
382 |
383 |
383 lemma domain_of_fun: "f : Pi(A,B) ==> domain(f)=A" |
384 lemma domain_of_fun: "f : Pi(A,B) ==> domain(f)=A" |
384 by (unfold Pi_def, blast) |
385 by (unfold Pi_def, blast) |
385 |
386 |
386 lemma apply_rangeI: "[| f : Pi(A,B); a: A |] ==> f`a : range(f)" |
387 lemma apply_rangeI: "[| f : Pi(A,B); a: A |] ==> f`a : range(f)" |
387 by (erule apply_Pair [THEN rangeI], assumption) |
388 by (erule apply_Pair [THEN rangeI], assumption) |
388 |
389 |
389 lemma range_of_fun: "f : Pi(A,B) ==> f : A->range(f)" |
390 lemma range_of_fun: "f : Pi(A,B) ==> f : A->range(f)" |
390 by (blast intro: Pi_type apply_rangeI) |
391 by (blast intro: Pi_type apply_rangeI) |
391 |
392 |
392 (*** Extensions of functions ***) |
393 subsection{*Extensions of Functions*} |
393 |
394 |
394 lemma fun_extend: |
395 lemma fun_extend: |
395 "[| f: A->B; c~:A |] ==> cons(<c,b>,f) : cons(c,A) -> cons(b,B)" |
396 "[| f: A->B; c~:A |] ==> cons(<c,b>,f) : cons(c,A) -> cons(b,B)" |
396 apply (frule singleton_fun [THEN fun_disjoint_Un], blast) |
397 apply (frule singleton_fun [THEN fun_disjoint_Un], blast) |
397 apply (simp add: cons_eq) |
398 apply (simp add: cons_eq) |
432 apply (erule consE, simp_all) |
433 apply (erule consE, simp_all) |
433 done |
434 done |
434 |
435 |
435 lemma succ_fun_eq: "succ(n) -> B = (\<Union>f \<in> n->B. \<Union>b\<in>B. {cons(<n,b>, f)})" |
436 lemma succ_fun_eq: "succ(n) -> B = (\<Union>f \<in> n->B. \<Union>b\<in>B. {cons(<n,b>, f)})" |
436 by (simp add: succ_def mem_not_refl cons_fun_eq) |
437 by (simp add: succ_def mem_not_refl cons_fun_eq) |
|
438 |
|
439 |
|
440 subsection{*Function Updates*} |
|
441 |
|
442 constdefs |
|
443 update :: "[i,i,i] => i" |
|
444 "update(f,a,b) == lam x: cons(a, domain(f)). if(x=a, b, f`x)" |
|
445 |
|
446 nonterminals |
|
447 updbinds updbind |
|
448 |
|
449 syntax |
|
450 |
|
451 (* Let expressions *) |
|
452 |
|
453 "_updbind" :: "[i, i] => updbind" ("(2_ :=/ _)") |
|
454 "" :: "updbind => updbinds" ("_") |
|
455 "_updbinds" :: "[updbind, updbinds] => updbinds" ("_,/ _") |
|
456 "_Update" :: "[i, updbinds] => i" ("_/'((_)')" [900,0] 900) |
|
457 |
|
458 translations |
|
459 "_Update (f, _updbinds(b,bs))" == "_Update (_Update(f,b), bs)" |
|
460 "f(x:=y)" == "update(f,x,y)" |
|
461 |
|
462 |
|
463 lemma update_apply [simp]: "f(x:=y) ` z = (if z=x then y else f`z)" |
|
464 apply (simp add: update_def) |
|
465 apply (rule_tac P="z \<in> domain(f)" in case_split_thm) |
|
466 apply (simp_all add: apply_0) |
|
467 done |
|
468 |
|
469 lemma update_idem: "[| f`x = y; f: Pi(A,B); x: A |] ==> f(x:=y) = f" |
|
470 apply (unfold update_def) |
|
471 apply (simp add: domain_of_fun cons_absorb) |
|
472 apply (rule fun_extension) |
|
473 apply (best intro: apply_type if_type lam_type, assumption, simp) |
|
474 done |
|
475 |
|
476 |
|
477 (* [| f: Pi(A, B); x:A |] ==> f(x := f`x) = f *) |
|
478 declare refl [THEN update_idem, simp] |
|
479 |
|
480 lemma domain_update [simp]: "domain(f(x:=y)) = cons(x, domain(f))" |
|
481 by (unfold update_def, simp) |
|
482 |
|
483 lemma update_type: "[| f: A -> B; x : A; y: B |] ==> f(x:=y) : A -> B" |
|
484 apply (unfold update_def) |
|
485 apply (simp add: domain_of_fun cons_absorb apply_funtype lam_type) |
|
486 done |
|
487 |
437 |
488 |
438 ML |
489 ML |
439 {* |
490 {* |
440 val Pi_iff = thm "Pi_iff"; |
491 val Pi_iff = thm "Pi_iff"; |
441 val Pi_iff_old = thm "Pi_iff_old"; |
492 val Pi_iff_old = thm "Pi_iff_old"; |
506 val fun_extend = thm "fun_extend"; |
557 val fun_extend = thm "fun_extend"; |
507 val fun_extend3 = thm "fun_extend3"; |
558 val fun_extend3 = thm "fun_extend3"; |
508 val fun_extend_apply = thm "fun_extend_apply"; |
559 val fun_extend_apply = thm "fun_extend_apply"; |
509 val singleton_apply = thm "singleton_apply"; |
560 val singleton_apply = thm "singleton_apply"; |
510 val cons_fun_eq = thm "cons_fun_eq"; |
561 val cons_fun_eq = thm "cons_fun_eq"; |
|
562 |
|
563 val update_def = thm "update_def"; |
|
564 val update_apply = thm "update_apply"; |
|
565 val update_idem = thm "update_idem"; |
|
566 val domain_update = thm "domain_update"; |
|
567 val update_type = thm "update_type"; |
511 *} |
568 *} |
512 |
569 |
513 end |
570 end |