2384 "allpairs f (xs @ ys) zs = allpairs f xs zs @ allpairs f ys zs" |
2384 "allpairs f (xs @ ys) zs = allpairs f xs zs @ allpairs f ys zs" |
2385 by(induct xs) auto |
2385 by(induct xs) auto |
2386 |
2386 |
2387 subsubsection {* @{text lists}: the list-forming operator over sets *} |
2387 subsubsection {* @{text lists}: the list-forming operator over sets *} |
2388 |
2388 |
2389 inductive2 |
2389 inductive_set |
2390 listsp :: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> bool" |
2390 lists :: "'a set => 'a list set" |
2391 for A :: "'a \<Rightarrow> bool" |
2391 for A :: "'a set" |
2392 where |
2392 where |
2393 Nil [intro!]: "listsp A []" |
2393 Nil [intro!]: "[]: lists A" |
2394 | Cons [intro!]: "[| A a; listsp A l |] ==> listsp A (a # l)" |
2394 | Cons [intro!]: "[| a: A;l: lists A|] ==> a#l : lists A" |
2395 |
2395 |
2396 constdefs |
2396 inductive_cases listsE [elim!]: "x#l : lists A" |
2397 lists :: "'a set => 'a list set" |
2397 inductive_cases listspE [elim!]: "listsp A (x # l)" |
2398 "lists A == Collect (listsp (member A))" |
2398 |
2399 |
2399 lemma listsp_mono [mono]: "A \<le> B ==> listsp A \<le> listsp B" |
2400 lemma listsp_lists_eq [pred_set_conv]: "listsp (member A) = member (lists A)" |
|
2401 by (simp add: lists_def) |
|
2402 |
|
2403 lemmas lists_intros [intro!] = listsp.intros [to_set] |
|
2404 |
|
2405 lemmas lists_induct [consumes 1, case_names Nil Cons, induct set: lists] = |
|
2406 listsp.induct [to_set] |
|
2407 |
|
2408 inductive_cases2 listspE [elim!]: "listsp A (x # l)" |
|
2409 |
|
2410 lemmas listsE [elim!] = listspE [to_set] |
|
2411 |
|
2412 lemma listsp_mono [mono2]: "A \<le> B ==> listsp A \<le> listsp B" |
|
2413 by (clarify, erule listsp.induct, blast+) |
2400 by (clarify, erule listsp.induct, blast+) |
2414 |
2401 |
2415 lemmas lists_mono [mono] = listsp_mono [to_set] |
2402 lemmas lists_mono = listsp_mono [to_set] |
2416 |
2403 |
2417 lemma listsp_infI: |
2404 lemma listsp_infI: |
2418 assumes l: "listsp A l" shows "listsp B l ==> listsp (inf A B) l" using l |
2405 assumes l: "listsp A l" shows "listsp B l ==> listsp (inf A B) l" using l |
2419 by induct blast+ |
2406 by induct blast+ |
2420 |
2407 |
2709 setup FundefDatatype.setup |
2696 setup FundefDatatype.setup |
2710 |
2697 |
2711 |
2698 |
2712 subsubsection{*Lifting a Relation on List Elements to the Lists*} |
2699 subsubsection{*Lifting a Relation on List Elements to the Lists*} |
2713 |
2700 |
2714 inductive2 |
2701 inductive_set |
2715 list_all2' :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'b list \<Rightarrow> bool" |
2702 listrel :: "('a * 'a)set => ('a list * 'a list)set" |
2716 for r :: "'a \<Rightarrow> 'b \<Rightarrow> bool" |
2703 for r :: "('a * 'a)set" |
2717 where |
2704 where |
2718 Nil: "list_all2' r [] []" |
2705 Nil: "([],[]) \<in> listrel r" |
2719 | Cons: "[| r x y; list_all2' r xs ys |] ==> list_all2' r (x#xs) (y#ys)" |
2706 | Cons: "[| (x,y) \<in> r; (xs,ys) \<in> listrel r |] ==> (x#xs, y#ys) \<in> listrel r" |
2720 |
2707 |
2721 constdefs |
2708 inductive_cases listrel_Nil1 [elim!]: "([],xs) \<in> listrel r" |
2722 listrel :: "('a * 'b) set => ('a list * 'b list) set" |
2709 inductive_cases listrel_Nil2 [elim!]: "(xs,[]) \<in> listrel r" |
2723 "listrel r == Collect2 (list_all2' (member2 r))" |
2710 inductive_cases listrel_Cons1 [elim!]: "(y#ys,xs) \<in> listrel r" |
2724 |
2711 inductive_cases listrel_Cons2 [elim!]: "(xs,y#ys) \<in> listrel r" |
2725 lemma list_all2_listrel_eq [pred_set_conv]: |
|
2726 "list_all2' (member2 r) = member2 (listrel r)" |
|
2727 by (simp add: listrel_def) |
|
2728 |
|
2729 lemmas listrel_induct [consumes 1, case_names Nil Cons, induct set: listrel] = |
|
2730 list_all2'.induct [to_set] |
|
2731 |
|
2732 lemmas listrel_intros = list_all2'.intros [to_set] |
|
2733 |
|
2734 inductive_cases2 listrel_Nil1 [to_set, elim!]: "list_all2' r [] xs" |
|
2735 inductive_cases2 listrel_Nil2 [to_set, elim!]: "list_all2' r xs []" |
|
2736 inductive_cases2 listrel_Cons1 [to_set, elim!]: "list_all2' r (y#ys) xs" |
|
2737 inductive_cases2 listrel_Cons2 [to_set, elim!]: "list_all2' r xs (y#ys)" |
|
2738 |
2712 |
2739 |
2713 |
2740 lemma listrel_mono: "r \<subseteq> s \<Longrightarrow> listrel r \<subseteq> listrel s" |
2714 lemma listrel_mono: "r \<subseteq> s \<Longrightarrow> listrel r \<subseteq> listrel s" |
2741 apply clarify |
2715 apply clarify |
2742 apply (erule listrel_induct) |
2716 apply (erule listrel.induct) |
2743 apply (blast intro: listrel_intros)+ |
2717 apply (blast intro: listrel.intros)+ |
2744 done |
2718 done |
2745 |
2719 |
2746 lemma listrel_subset: "r \<subseteq> A \<times> A \<Longrightarrow> listrel r \<subseteq> lists A \<times> lists A" |
2720 lemma listrel_subset: "r \<subseteq> A \<times> A \<Longrightarrow> listrel r \<subseteq> lists A \<times> lists A" |
2747 apply clarify |
2721 apply clarify |
2748 apply (erule listrel_induct, auto) |
2722 apply (erule listrel.induct, auto) |
2749 done |
2723 done |
2750 |
2724 |
2751 lemma listrel_refl: "refl A r \<Longrightarrow> refl (lists A) (listrel r)" |
2725 lemma listrel_refl: "refl A r \<Longrightarrow> refl (lists A) (listrel r)" |
2752 apply (simp add: refl_def listrel_subset Ball_def) |
2726 apply (simp add: refl_def listrel_subset Ball_def) |
2753 apply (rule allI) |
2727 apply (rule allI) |
2754 apply (induct_tac x) |
2728 apply (induct_tac x) |
2755 apply (auto intro: listrel_intros) |
2729 apply (auto intro: listrel.intros) |
2756 done |
2730 done |
2757 |
2731 |
2758 lemma listrel_sym: "sym r \<Longrightarrow> sym (listrel r)" |
2732 lemma listrel_sym: "sym r \<Longrightarrow> sym (listrel r)" |
2759 apply (auto simp add: sym_def) |
2733 apply (auto simp add: sym_def) |
2760 apply (erule listrel_induct) |
2734 apply (erule listrel.induct) |
2761 apply (blast intro: listrel_intros)+ |
2735 apply (blast intro: listrel.intros)+ |
2762 done |
2736 done |
2763 |
2737 |
2764 lemma listrel_trans: "trans r \<Longrightarrow> trans (listrel r)" |
2738 lemma listrel_trans: "trans r \<Longrightarrow> trans (listrel r)" |
2765 apply (simp add: trans_def) |
2739 apply (simp add: trans_def) |
2766 apply (intro allI) |
2740 apply (intro allI) |
2767 apply (rule impI) |
2741 apply (rule impI) |
2768 apply (erule listrel_induct) |
2742 apply (erule listrel.induct) |
2769 apply (blast intro: listrel_intros)+ |
2743 apply (blast intro: listrel.intros)+ |
2770 done |
2744 done |
2771 |
2745 |
2772 theorem equiv_listrel: "equiv A r \<Longrightarrow> equiv (lists A) (listrel r)" |
2746 theorem equiv_listrel: "equiv A r \<Longrightarrow> equiv (lists A) (listrel r)" |
2773 by (simp add: equiv_def listrel_refl listrel_sym listrel_trans) |
2747 by (simp add: equiv_def listrel_refl listrel_sym listrel_trans) |
2774 |
2748 |
2775 lemma listrel_Nil [simp]: "listrel r `` {[]} = {[]}" |
2749 lemma listrel_Nil [simp]: "listrel r `` {[]} = {[]}" |
2776 by (blast intro: listrel_intros) |
2750 by (blast intro: listrel.intros) |
2777 |
2751 |
2778 lemma listrel_Cons: |
2752 lemma listrel_Cons: |
2779 "listrel r `` {x#xs} = set_Cons (r``{x}) (listrel r `` {xs})"; |
2753 "listrel r `` {x#xs} = set_Cons (r``{x}) (listrel r `` {xs})"; |
2780 by (auto simp add: set_Cons_def intro: listrel_intros) |
2754 by (auto simp add: set_Cons_def intro: listrel.intros) |
2781 |
2755 |
2782 |
2756 |
2783 subsection{*Miscellany*} |
2757 subsection{*Miscellany*} |
2784 |
2758 |
2785 subsubsection {* Characters and strings *} |
2759 subsubsection {* Characters and strings *} |