Nominal/FSet.thy
changeset 2539 a8f5611dbd65
parent 2538 c9deccd12476
child 2540 135ac0fb2686
equal deleted inserted replaced
2538:c9deccd12476 2539:a8f5611dbd65
    52   rsp_fold
    52   rsp_fold
    53 where
    53 where
    54   "rsp_fold f \<equiv> \<forall>u v w. (f u (f v w) = f v (f u w))"
    54   "rsp_fold f \<equiv> \<forall>u v w. (f u (f v w) = f v (f u w))"
    55 
    55 
    56 primrec
    56 primrec
    57   ffold_raw :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a list \<Rightarrow> 'b"
    57   ffold_list :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a list \<Rightarrow> 'b"
    58 where
    58 where
    59   "ffold_raw f z [] = z"
    59   "ffold_list f z [] = z"
    60 | "ffold_raw f z (a # xs) =
    60 | "ffold_list f z (a # xs) =
    61      (if (rsp_fold f) then
    61      (if (rsp_fold f) then
    62        if a \<in> set xs then ffold_raw f z xs
    62        if a \<in> set xs then ffold_list f z xs
    63        else f a (ffold_raw f z xs)
    63        else f a (ffold_list f z xs)
    64      else z)"
    64      else z)"
    65 
    65 
    66 
    66 
    67 section {* Quotient composition lemmas *}
    67 section {* Quotient composition lemmas *}
    68 
    68 
   194 
   194 
   195 lemma filter_rsp [quot_respect]:
   195 lemma filter_rsp [quot_respect]:
   196   shows "(op = ===> op \<approx> ===> op \<approx>) filter filter"
   196   shows "(op = ===> op \<approx> ===> op \<approx>) filter filter"
   197   by simp
   197   by simp
   198 
   198 
   199 lemma memb_commute_ffold_raw:
   199 lemma memb_commute_ffold_list:
   200   "rsp_fold f \<Longrightarrow> h \<in> set b \<Longrightarrow> ffold_raw f z b = f h (ffold_raw f z (removeAll h b))"
   200   "rsp_fold f \<Longrightarrow> h \<in> set b \<Longrightarrow> ffold_list f z b = f h (ffold_list f z (removeAll h b))"
   201   apply (induct b)
   201   apply (induct b)
   202   apply (auto simp add: rsp_fold_def)
   202   apply (auto simp add: rsp_fold_def)
   203   done
   203   done
   204 
   204 
   205 lemma ffold_raw_rsp_pre:
   205 lemma ffold_list_rsp_pre:
   206   "set a = set b \<Longrightarrow> ffold_raw f z a = ffold_raw f z b"
   206   "set a = set b \<Longrightarrow> ffold_list f z a = ffold_list f z b"
   207   apply (induct a arbitrary: b)
   207   apply (induct a arbitrary: b)
   208   apply (simp)
   208   apply (simp)
   209   apply (simp (no_asm_use))
   209   apply (simp (no_asm_use))
   210   apply (rule conjI)
   210   apply (rule conjI)
   211   apply (rule_tac [!] impI)
   211   apply (rule_tac [!] impI)
   212   apply (rule_tac [!] conjI)
   212   apply (rule_tac [!] conjI)
   213   apply (rule_tac [!] impI)
   213   apply (rule_tac [!] impI)
   214   apply (metis insert_absorb)
   214   apply (metis insert_absorb)
   215   apply (metis List.insert_def List.set.simps(2) List.set_insert ffold_raw.simps(2))
   215   apply (metis List.insert_def List.set.simps(2) List.set_insert ffold_list.simps(2))
   216   apply (metis Diff_insert_absorb insertI1 memb_commute_ffold_raw set_removeAll)
   216   apply (metis Diff_insert_absorb insertI1 memb_commute_ffold_list set_removeAll)
   217   apply(drule_tac x="removeAll a1 b" in meta_spec)
   217   apply(drule_tac x="removeAll a1 b" in meta_spec)
   218   apply(auto)
   218   apply(auto)
   219   apply(drule meta_mp)
   219   apply(drule meta_mp)
   220   apply(blast)
   220   apply(blast)
   221   by (metis List.set.simps(2) emptyE ffold_raw.simps(2) in_listsp_conv_set listsp.simps mem_def)
   221   by (metis List.set.simps(2) emptyE ffold_list.simps(2) in_listsp_conv_set listsp.simps mem_def)
   222 
   222 
   223 lemma ffold_raw_rsp [quot_respect]:
   223 lemma ffold_list_rsp [quot_respect]:
   224   shows "(op = ===> op = ===> op \<approx> ===> op =) ffold_raw ffold_raw"
   224   shows "(op = ===> op = ===> op \<approx> ===> op =) ffold_list ffold_list"
   225   unfolding fun_rel_def
   225   unfolding fun_rel_def
   226   by(auto intro: ffold_raw_rsp_pre)
   226   by(auto intro: ffold_list_rsp_pre)
   227 
   227 
   228 lemma concat_rsp_pre:
   228 lemma concat_rsp_pre:
   229   assumes a: "list_all2 op \<approx> x x'"
   229   assumes a: "list_all2 op \<approx> x x'"
   230   and     b: "x' \<approx> y'"
   230   and     b: "x' \<approx> y'"
   231   and     c: "list_all2 op \<approx> y' y"
   231   and     c: "list_all2 op \<approx> y' y"
   262       show "\<exists>xa\<in>set a. x \<in> set xa" by (rule concat_rsp_pre[OF c' b' a' e])
   262       show "\<exists>xa\<in>set a. x \<in> set xa" by (rule concat_rsp_pre[OF c' b' a' e])
   263     qed
   263     qed
   264   qed
   264   qed
   265   then show "concat a \<approx> concat b" by auto
   265   then show "concat a \<approx> concat b" by auto
   266 qed
   266 qed
       
   267 
       
   268 
       
   269 
       
   270 section {* Quotient definitions for fsets *}
   267 
   271 
   268 
   272 
   269 subsection {* Finite sets are a bounded, distributive lattice with minus *}
   273 subsection {* Finite sets are a bounded, distributive lattice with minus *}
   270 
   274 
   271 instantiation fset :: (type) "{bounded_lattice_bot, distrib_lattice, minus}"
   275 instantiation fset :: (type) "{bounded_lattice_bot, distrib_lattice, minus}"
   364     by (descending) (auto simp add: inter_list_def sub_list_def memb_def)
   368     by (descending) (auto simp add: inter_list_def sub_list_def memb_def)
   365 qed
   369 qed
   366 
   370 
   367 end
   371 end
   368 
   372 
   369 
       
   370 section {* Quotient definitions for fsets *}
       
   371 
       
   372 
       
   373 quotient_definition
   373 quotient_definition
   374   "finsert :: 'a \<Rightarrow> 'a fset \<Rightarrow> 'a fset"
   374   "finsert :: 'a \<Rightarrow> 'a fset \<Rightarrow> 'a fset"
   375   is "Cons"
   375   is "Cons"
   376 
   376 
   377 syntax
   377 syntax
   409   "fset :: 'a fset \<Rightarrow> 'a set"
   409   "fset :: 'a fset \<Rightarrow> 'a set"
   410   is "set"
   410   is "set"
   411 
   411 
   412 quotient_definition
   412 quotient_definition
   413   "ffold :: ('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a fset \<Rightarrow> 'b"
   413   "ffold :: ('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a fset \<Rightarrow> 'b"
   414   is ffold_raw
   414   is ffold_list
   415 
   415 
   416 quotient_definition
   416 quotient_definition
   417   "fconcat :: ('a fset) fset \<Rightarrow> 'a fset"
   417   "fconcat :: ('a fset) fset \<Rightarrow> 'a fset"
   418   is concat
   418   is concat
   419 
   419 
   420 quotient_definition
   420 quotient_definition
   421   "ffilter :: ('a \<Rightarrow> bool) \<Rightarrow> 'a fset \<Rightarrow> 'a fset"
   421   "ffilter :: ('a \<Rightarrow> bool) \<Rightarrow> 'a fset \<Rightarrow> 'a fset"
   422   is filter
   422   is filter
   423 
   423 
   424 
   424 
   425 subsection {* Compositional Respectfulness and Preservation *}
   425 section {* Compositional respectfulness and preservation lemmas *}
   426 
   426 
   427 lemma [quot_respect]: "(list_all2 op \<approx> OOO op \<approx>) [] []"
   427 lemma Nil_rsp2 [quot_respect]: 
       
   428   shows "(list_all2 op \<approx> OOO op \<approx>) Nil Nil"
   428   by (fact compose_list_refl)
   429   by (fact compose_list_refl)
   429 
   430 
   430 lemma  [quot_preserve]: "(abs_fset \<circ> map f) [] = abs_fset []"
   431 lemma Cons_rsp2 [quot_respect]:
   431   by simp
       
   432 
       
   433 lemma [quot_respect]:
       
   434   shows "(op \<approx> ===> list_all2 op \<approx> OOO op \<approx> ===> list_all2 op \<approx> OOO op \<approx>) Cons Cons"
   432   shows "(op \<approx> ===> list_all2 op \<approx> OOO op \<approx> ===> list_all2 op \<approx> OOO op \<approx>) Cons Cons"
   435   apply auto
   433   apply auto
   436   apply (rule_tac b="x # b" in pred_compI)
   434   apply (rule_tac b="x # b" in pred_compI)
   437   apply auto
   435   apply auto
   438   apply (rule_tac b="x # ba" in pred_compI)
   436   apply (rule_tac b="x # ba" in pred_compI)
   439   apply auto
   437   apply auto
   440   done
   438   done
   441 
   439 
   442 lemma [quot_preserve]:
   440 lemma map_prs [quot_preserve]: 
       
   441   shows "(abs_fset \<circ> map f) [] = abs_fset []"
       
   442   by simp
       
   443 
       
   444 lemma finsert_rsp [quot_preserve]:
   443   "(rep_fset ---> (map rep_fset \<circ> rep_fset) ---> (abs_fset \<circ> map abs_fset)) op # = finsert"
   445   "(rep_fset ---> (map rep_fset \<circ> rep_fset) ---> (abs_fset \<circ> map abs_fset)) op # = finsert"
   444   by (simp add: fun_eq_iff Quotient_abs_rep[OF Quotient_fset]
   446   by (simp add: fun_eq_iff Quotient_abs_rep[OF Quotient_fset]
   445       abs_o_rep[OF Quotient_fset] map_id finsert_def)
   447       abs_o_rep[OF Quotient_fset] map_id finsert_def)
   446 
   448 
   447 lemma [quot_preserve]:
   449 lemma funion_rsp [quot_preserve]:
   448   "((map rep_fset \<circ> rep_fset) ---> (map rep_fset \<circ> rep_fset) ---> (abs_fset \<circ> map abs_fset)) op @ = funion"
   450   "((map rep_fset \<circ> rep_fset) ---> (map rep_fset \<circ> rep_fset) ---> (abs_fset \<circ> map abs_fset)) op @ = funion"
   449   by (simp add: fun_eq_iff Quotient_abs_rep[OF Quotient_fset]
   451   by (simp add: fun_eq_iff Quotient_abs_rep[OF Quotient_fset]
   450       abs_o_rep[OF Quotient_fset] map_id sup_fset_def)
   452       abs_o_rep[OF Quotient_fset] map_id sup_fset_def)
   451 
   453 
   452 lemma list_all2_app_l:
   454 lemma list_all2_app_l:
   485   apply (rule append_rsp2_pre1)
   487   apply (rule append_rsp2_pre1)
   486   apply simp
   488   apply simp
   487   done
   489   done
   488 
   490 
   489 lemma [quot_respect]:
   491 lemma [quot_respect]:
   490   "(list_all2 op \<approx> OOO op \<approx> ===> list_all2 op \<approx> OOO op \<approx> ===> list_all2 op \<approx> OOO op \<approx>) op @ op @"
   492   "(list_all2 op \<approx> OOO op \<approx> ===> list_all2 op \<approx> OOO op \<approx> ===> list_all2 op \<approx> OOO op \<approx>) append append"
   491 proof (intro fun_relI, elim pred_compE)
   493 proof (intro fun_relI, elim pred_compE)
   492   fix x y z w x' z' y' w' :: "'a list list"
   494   fix x y z w x' z' y' w' :: "'a list list"
   493   assume a:"list_all2 op \<approx> x x'"
   495   assume a:"list_all2 op \<approx> x x'"
   494   and b:    "x' \<approx> y'"
   496   and b:    "x' \<approx> y'"
   495   and c:    "list_all2 op \<approx> y' y"
   497   and c:    "list_all2 op \<approx> y' y"
   505     by (rule pred_compI) (rule a', rule d')
   507     by (rule pred_compI) (rule a', rule d')
   506 qed
   508 qed
   507 
   509 
   508 
   510 
   509 
   511 
   510 section {* Cases *}
   512 section {* Lifted theorems *}
   511 
   513 
       
   514 
       
   515 subsection {* fin *}
       
   516 
       
   517 lemma not_fin_fnil: 
       
   518   shows "x |\<notin>| {||}"
       
   519   by (descending) (simp add: memb_def)
       
   520 
       
   521 lemma fin_set: 
       
   522   shows "x |\<in>| S \<longleftrightarrow> x \<in> fset S"
       
   523   by (descending) (simp add: memb_def)
       
   524 
       
   525 lemma fnotin_set: 
       
   526   shows "x |\<notin>| S \<longleftrightarrow> x \<notin> fset S"
       
   527   by (descending) (simp add: memb_def)
       
   528 
       
   529 lemma fset_eq_iff:
       
   530   shows "S = T \<longleftrightarrow> (\<forall>x. (x |\<in>| S) = (x |\<in>| T))"
       
   531   by (descending) (auto simp add: memb_def)
       
   532 
       
   533 lemma none_fin_fempty:
       
   534   shows "(\<forall>x. x |\<notin>| S) \<longleftrightarrow> S = {||}"
       
   535   by (descending) (simp add: memb_def)
       
   536 
       
   537 
       
   538 subsection {* finsert *}
       
   539 
       
   540 lemma fin_finsert_iff[simp]:
       
   541   shows "x |\<in>| finsert y S \<longleftrightarrow> x = y \<or> x |\<in>| S"
       
   542   by (descending) (simp add: memb_def)
       
   543 
       
   544 lemma
       
   545   shows finsertI1: "x |\<in>| finsert x S"
       
   546   and   finsertI2: "x |\<in>| S \<Longrightarrow> x |\<in>| finsert y S"
       
   547   by (descending, simp add: memb_def)+
       
   548 
       
   549 lemma finsert_absorb[simp]:
       
   550   shows "x |\<in>| S \<Longrightarrow> finsert x S = S"
       
   551   by (descending) (auto simp add: memb_def)
       
   552 
       
   553 lemma fempty_not_finsert[simp]:
       
   554   shows "{||} \<noteq> finsert x S"
       
   555   and   "finsert x S \<noteq> {||}"
       
   556   by (descending, simp)+
       
   557 
       
   558 lemma finsert_left_comm:
       
   559   shows "finsert x (finsert y S) = finsert y (finsert x S)"
       
   560   by (descending) (auto)
       
   561 
       
   562 lemma finsert_left_idem:
       
   563   shows "finsert x (finsert x S) = finsert x S"
       
   564   by (descending) (auto)
       
   565 
       
   566 lemma fsingleton_eq[simp]:
       
   567   shows "{|x|} = {|y|} \<longleftrightarrow> x = y"
       
   568   by (descending) (auto)
       
   569 
       
   570 
       
   571 (* FIXME: is this in any case a useful lemma *)
       
   572 lemma fin_mdef:
       
   573   shows "x |\<in>| F \<longleftrightarrow> x |\<notin>| (F - {|x|}) \<and> F = finsert x (F - {|x|})"
       
   574   by (descending) (auto simp add: memb_def diff_list_def)
       
   575 
       
   576 
       
   577 subsection {* fset *}
       
   578 
       
   579 lemma fset_simps[simp]:
       
   580   "fset {||} = ({} :: 'a set)"
       
   581   "fset (finsert (x :: 'a) S) = insert x (fset S)"
       
   582   by (lifting set.simps)
       
   583 
       
   584 lemma finite_fset [simp]: 
       
   585   shows "finite (fset S)"
       
   586   by (descending) (simp)
       
   587 
       
   588 lemma fset_cong:
       
   589   shows "fset S = fset T \<longleftrightarrow> S = T"
       
   590   by (descending) (simp)
       
   591 
       
   592 lemma ffilter_set [simp]: 
       
   593   shows "fset (ffilter P xs) = P \<inter> fset xs"
       
   594   by (descending) (auto simp add: mem_def)
       
   595 
       
   596 lemma fdelete_set [simp]: 
       
   597   shows "fset (fdelete x xs) = fset xs - {x}"
       
   598   by (descending) (simp)
       
   599 
       
   600 lemma finter_set [simp]: 
       
   601   shows "fset (xs |\<inter>| ys) = fset xs \<inter> fset ys"
       
   602   by (descending) (auto simp add: inter_list_def)
       
   603 
       
   604 lemma funion_set [simp]: 
       
   605   shows "fset (xs |\<union>| ys) = fset xs \<union> fset ys"
       
   606   by (lifting set_append)
       
   607 
       
   608 lemma fminus_set [simp]: 
       
   609   shows "fset (xs - ys) = fset xs - fset ys"
       
   610   by (descending) (auto simp add: diff_list_def)
       
   611 
       
   612 
       
   613 subsection {* funion *}
       
   614 
       
   615 lemmas [simp] =
       
   616   sup_bot_left[where 'a="'a fset", standard]
       
   617   sup_bot_right[where 'a="'a fset", standard]
       
   618 
       
   619 lemma funion_finsert[simp]:
       
   620   shows "finsert x S |\<union>| T = finsert x (S |\<union>| T)"
       
   621   by (lifting append.simps(2))
       
   622 
       
   623 lemma singleton_funion_left:
       
   624   shows "{|a|} |\<union>| S = finsert a S"
       
   625   by simp
       
   626 
       
   627 lemma singleton_funion_right:
       
   628   shows "S |\<union>| {|a|} = finsert a S"
       
   629   by (subst sup.commute) simp
       
   630 
       
   631 lemma fin_funion:
       
   632   shows "x |\<in>| S |\<union>| T \<longleftrightarrow> x |\<in>| S \<or> x |\<in>| T"
       
   633   by (descending) (simp add: memb_def)
       
   634 
       
   635 
       
   636 subsection {* fminus *}
       
   637 
       
   638 lemma fminus_fin: 
       
   639   shows "x |\<in>| (xs - ys) \<longleftrightarrow> x |\<in>| xs \<and> x |\<notin>| ys"
       
   640   by (descending) (simp add: diff_list_def memb_def)
       
   641 
       
   642 lemma fminus_red: 
       
   643   shows "finsert x xs - ys = (if x |\<in>| ys then xs - ys else finsert x (xs - ys))"
       
   644   by (descending) (auto simp add: diff_list_def memb_def)
       
   645 
       
   646 lemma fminus_red_fin[simp]: 
       
   647   shows "x |\<in>| ys \<Longrightarrow> finsert x xs - ys = xs - ys"
       
   648   by (simp add: fminus_red)
       
   649 
       
   650 lemma fminus_red_fnotin[simp]: 
       
   651   shows "x |\<notin>| ys \<Longrightarrow> finsert x xs - ys = finsert x (xs - ys)"
       
   652   by (simp add: fminus_red)
       
   653 
       
   654 lemma fin_fminus_fnotin: 
       
   655   shows "x |\<in>| F - S \<Longrightarrow> x |\<notin>| S"
       
   656   unfolding fin_set fminus_set
       
   657   by blast
       
   658 
       
   659 lemma fin_fnotin_fminus: 
       
   660   shows "x |\<in>| S \<Longrightarrow> x |\<notin>| F - S"
       
   661   unfolding fin_set fminus_set
       
   662   by blast
       
   663 
       
   664 
       
   665 section {* fdelete *}
       
   666 
       
   667 lemma fin_fdelete:
       
   668   shows "x |\<in>| fdelete y S \<longleftrightarrow> x |\<in>| S \<and> x \<noteq> y"
       
   669   by (descending) (simp add: memb_def)
       
   670 
       
   671 lemma fnotin_fdelete:
       
   672   shows "x |\<notin>| fdelete x S"
       
   673   by (descending) (simp add: memb_def)
       
   674 
       
   675 lemma fnotin_fdelete_ident:
       
   676   shows "x |\<notin>| S \<Longrightarrow> fdelete x S = S"
       
   677   by (descending) (simp add: memb_def)
       
   678 
       
   679 lemma fset_fdelete_cases:
       
   680   shows "S = {||} \<or> (\<exists>x. x |\<in>| S \<and> S = finsert x (fdelete x S))"
       
   681   by (descending) (auto simp add: memb_def insert_absorb)
       
   682   
       
   683 
       
   684 section {* finter *}
       
   685 
       
   686 lemma finter_empty_l:
       
   687   shows "{||} |\<inter>| S = {||}"
       
   688   by simp
       
   689 
       
   690 lemma finter_empty_r:
       
   691   shows "S |\<inter>| {||} = {||}"
       
   692   by simp
       
   693 
       
   694 lemma finter_finsert:
       
   695   shows "finsert x S |\<inter>| T = (if x |\<in>| T then finsert x (S |\<inter>| T) else S |\<inter>| T)"
       
   696   by (descending) (auto simp add: inter_list_def memb_def)
       
   697 
       
   698 lemma fin_finter:
       
   699   shows "x |\<in>| (S |\<inter>| T) \<longleftrightarrow> x |\<in>| S \<and> x |\<in>| T"
       
   700   by (descending) (simp add: inter_list_def memb_def)
       
   701 
       
   702 
       
   703 subsection {* fsubset *}
       
   704 
       
   705 lemma fsubseteq_set: 
       
   706   shows "xs |\<subseteq>| ys \<longleftrightarrow> fset xs \<subseteq> fset ys"
       
   707   by (descending) (simp add: sub_list_def)
       
   708 
       
   709 lemma fsubset_set: 
       
   710   shows "xs |\<subset>| ys \<longleftrightarrow> fset xs \<subset> fset ys"
       
   711   unfolding less_fset_def 
       
   712   by (descending) (auto simp add: sub_list_def)
       
   713 
       
   714 lemma fsubseteq_finsert:
       
   715   shows "(finsert x xs) |\<subseteq>| ys \<longleftrightarrow> x |\<in>| ys \<and> xs |\<subseteq>| ys"
       
   716   by (descending) (simp add: sub_list_def memb_def)
       
   717 
       
   718 lemma fsubset_fin: 
       
   719   shows "xs |\<subseteq>| ys = (\<forall>x. x |\<in>| xs \<longrightarrow> x |\<in>| ys)"
       
   720   by (descending) (auto simp add: sub_list_def memb_def)
       
   721 
       
   722 lemma fsubseteq_fempty:
       
   723   shows "xs |\<subseteq>| {||} \<longleftrightarrow> xs = {||}"
       
   724   by (descending) (simp add: sub_list_def)
       
   725 
       
   726 lemma not_fsubset_fnil: 
       
   727   shows "\<not> xs |\<subset>| {||}"
       
   728   by (metis fset_simps(1) fsubset_set not_psubset_empty)
       
   729 
       
   730 
       
   731 section {* fmap *}
       
   732 
       
   733 lemma fmap_simps [simp]:
       
   734    shows "fmap f {||} = {||}"
       
   735   and   "fmap f (finsert x S) = finsert (f x) (fmap f S)"
       
   736   by (descending, simp)+
       
   737 
       
   738 lemma fmap_set_image [simp]:
       
   739   shows "fset (fmap f S) = f ` (fset S)"
       
   740   by (descending) (simp)
       
   741 
       
   742 lemma inj_fmap_eq_iff:
       
   743   shows "inj f \<Longrightarrow> fmap f S = fmap f T \<longleftrightarrow> S = T"
       
   744   by (descending) (metis inj_vimage_image_eq list_eq.simps set_map)
       
   745 
       
   746 lemma fmap_funion: 
       
   747   shows "fmap f (S |\<union>| T) = fmap f S |\<union>| fmap f T"
       
   748   by (descending) (simp)
       
   749 
       
   750 
       
   751 subsection {* fcard *}
       
   752 
       
   753 lemma fcard_set: 
       
   754   shows "fcard xs = card (fset xs)"
       
   755   by (lifting card_list_def)
       
   756 
       
   757 lemma fcard_finsert_if [simp]:
       
   758   shows "fcard (finsert x S) = (if x |\<in>| S then fcard S else Suc (fcard S))"
       
   759   by (descending) (auto simp add: card_list_def memb_def insert_absorb)
       
   760 
       
   761 lemma fcard_0[simp]:
       
   762   shows "fcard S = 0 \<longleftrightarrow> S = {||}"
       
   763   by (descending) (simp add: card_list_def)
       
   764 
       
   765 lemma fcard_fempty[simp]:
       
   766   shows "fcard {||} = 0"
       
   767   by (simp add: fcard_0)
       
   768 
       
   769 lemma fcard_1:
       
   770   shows "fcard S = 1 \<longleftrightarrow> (\<exists>x. S = {|x|})"
       
   771   by (descending) (auto simp add: card_list_def card_Suc_eq)
       
   772 
       
   773 lemma fcard_gt_0:
       
   774   shows "x \<in> fset S \<Longrightarrow> 0 < fcard S"
       
   775   by (descending) (auto simp add: card_list_def card_gt_0_iff)
       
   776   
       
   777 lemma fcard_not_fin:
       
   778   shows "(x |\<notin>| S) = (fcard (finsert x S) = Suc (fcard S))"
       
   779   by (descending) (auto simp add: memb_def card_list_def insert_absorb)
       
   780 
       
   781 lemma fcard_suc: 
       
   782   shows "fcard S = Suc n \<Longrightarrow> \<exists>x T. x |\<notin>| T \<and> S = finsert x T \<and> fcard T = n"
       
   783   apply(descending)
       
   784   apply(auto simp add: card_list_def memb_def)
       
   785   apply(drule card_eq_SucD)
       
   786   apply(auto)
       
   787   apply(rule_tac x="b" in exI)
       
   788   apply(rule_tac x="removeAll b S" in exI)
       
   789   apply(auto)
       
   790   done
       
   791 
       
   792 lemma fcard_delete:
       
   793   shows "fcard (fdelete y S) = (if y |\<in>| S then fcard S - 1 else fcard S)"
       
   794   by (descending) (simp add: card_list_def memb_def)
       
   795 
       
   796 lemma fcard_suc_memb: 
       
   797   shows "fcard A = Suc n \<Longrightarrow> \<exists>a. a |\<in>| A"
       
   798   apply(descending)
       
   799   apply(simp add: card_list_def memb_def)
       
   800   apply(drule card_eq_SucD)
       
   801   apply(auto)
       
   802   done
       
   803 
       
   804 lemma fin_fcard_not_0: 
       
   805   shows "a |\<in>| A \<Longrightarrow> fcard A \<noteq> 0"
       
   806   by (descending) (auto simp add: card_list_def memb_def)
       
   807 
       
   808 lemma fcard_mono: 
       
   809   shows "xs |\<subseteq>| ys \<Longrightarrow> fcard xs \<le> fcard ys"
       
   810   unfolding fcard_set fsubseteq_set
       
   811   by (simp add: card_mono[OF finite_fset])
       
   812 
       
   813 lemma fcard_fsubset_eq: 
       
   814   shows "xs |\<subseteq>| ys \<Longrightarrow> fcard ys \<le> fcard xs \<Longrightarrow> xs = ys"
       
   815   unfolding fcard_set fsubseteq_set
       
   816   by (auto dest: card_seteq[OF finite_fset] simp add: fset_cong)
       
   817 
       
   818 lemma psubset_fcard_mono: 
       
   819   shows "xs |\<subset>| ys \<Longrightarrow> fcard xs < fcard ys"
       
   820   unfolding fcard_set fsubset_set
       
   821   by (rule psubset_card_mono[OF finite_fset])
       
   822 
       
   823 lemma fcard_funion_finter: 
       
   824   shows "fcard xs + fcard ys = fcard (xs |\<union>| ys) + fcard (xs |\<inter>| ys)"
       
   825   unfolding fcard_set funion_set finter_set
       
   826   by (rule card_Un_Int[OF finite_fset finite_fset])
       
   827 
       
   828 lemma fcard_funion_disjoint: 
       
   829   shows "xs |\<inter>| ys = {||} \<Longrightarrow> fcard (xs |\<union>| ys) = fcard xs + fcard ys"
       
   830   unfolding fcard_set funion_set 
       
   831   apply (rule card_Un_disjoint[OF finite_fset finite_fset])
       
   832   by (metis finter_set fset_simps(1))
       
   833 
       
   834 lemma fcard_delete1_less: 
       
   835   shows "x |\<in>| xs \<Longrightarrow> fcard (fdelete x xs) < fcard xs"
       
   836   unfolding fcard_set fin_set fdelete_set 
       
   837   by (rule card_Diff1_less[OF finite_fset])
       
   838 
       
   839 lemma fcard_delete2_less: 
       
   840   shows "x |\<in>| xs \<Longrightarrow> y |\<in>| xs \<Longrightarrow> fcard (fdelete y (fdelete x xs)) < fcard xs"
       
   841   unfolding fcard_set fdelete_set fin_set
       
   842   by (rule card_Diff2_less[OF finite_fset])
       
   843 
       
   844 lemma fcard_delete1_le: 
       
   845   shows "fcard (fdelete x xs) \<le> fcard xs"
       
   846   unfolding fdelete_set fcard_set
       
   847   by (rule card_Diff1_le[OF finite_fset])
       
   848 
       
   849 lemma fcard_psubset: 
       
   850   shows "ys |\<subseteq>| xs \<Longrightarrow> fcard ys < fcard xs \<Longrightarrow> ys |\<subset>| xs"
       
   851   unfolding fcard_set fsubseteq_set fsubset_set
       
   852   by (rule card_psubset[OF finite_fset])
       
   853 
       
   854 lemma fcard_fmap_le: 
       
   855   shows "fcard (fmap f xs) \<le> fcard xs"
       
   856   unfolding fcard_set fmap_set_image
       
   857   by (rule card_image_le[OF finite_fset])
       
   858 
       
   859 lemma fcard_fminus_finsert[simp]:
       
   860   assumes "a |\<in>| A" and "a |\<notin>| B"
       
   861   shows "fcard (A - finsert a B) = fcard (A - B) - 1"
       
   862   using assms 
       
   863   unfolding fin_set fcard_set fminus_set
       
   864   by (simp add: card_Diff_insert[OF finite_fset])
       
   865 
       
   866 lemma fcard_fminus_fsubset:
       
   867   assumes "B |\<subseteq>| A"
       
   868   shows "fcard (A - B) = fcard A - fcard B"
       
   869   using assms 
       
   870   unfolding fsubseteq_set fcard_set fminus_set
       
   871   by (rule card_Diff_subset[OF finite_fset])
       
   872 
       
   873 lemma fcard_fminus_subset_finter:
       
   874   shows "fcard (A - B) = fcard A - fcard (A |\<inter>| B)"
       
   875   unfolding finter_set fcard_set fminus_set
       
   876   by (rule card_Diff_subset_Int) (simp)
       
   877 
       
   878 
       
   879 section {* fconcat *}
       
   880 
       
   881 lemma fconcat_fempty:
       
   882   shows "fconcat {||} = {||}"
       
   883   by (lifting concat.simps(1))
       
   884 
       
   885 lemma fconcat_finsert:
       
   886   shows "fconcat (finsert x S) = x |\<union>| fconcat S"
       
   887   by (lifting concat.simps(2))
       
   888 
       
   889 lemma fconcat_finter:
       
   890   shows "fconcat (xs |\<union>| ys) = fconcat xs |\<union>| fconcat ys"
       
   891   by (lifting concat_append)
       
   892 
       
   893 
       
   894 section {* ffilter *}
       
   895 
       
   896 lemma subseteq_filter: 
       
   897   shows "ffilter P xs <= ffilter Q xs = (\<forall> x. x |\<in>| xs \<longrightarrow> P x \<longrightarrow> Q x)"
       
   898   by  (descending) (auto simp add: memb_def sub_list_def)
       
   899 
       
   900 lemma eq_ffilter: 
       
   901   shows "(ffilter P xs = ffilter Q xs) = (\<forall>x. x |\<in>| xs \<longrightarrow> P x = Q x)"
       
   902   by (descending) (auto simp add: memb_def)
       
   903 
       
   904 lemma subset_ffilter:
       
   905   shows "(\<And>x. x |\<in>| xs \<Longrightarrow> P x \<Longrightarrow> Q x) \<Longrightarrow> (x |\<in>| xs & \<not> P x & Q x) \<Longrightarrow> ffilter P xs < ffilter Q xs"
       
   906   unfolding less_fset_def by (auto simp add: subseteq_filter eq_ffilter)
       
   907 
       
   908 
       
   909 subsection {* ffold *}
       
   910 
       
   911 lemma ffold_nil: 
       
   912   shows "ffold f z {||} = z"
       
   913   by (descending) (simp)
       
   914 
       
   915 lemma ffold_finsert: "ffold f z (finsert a A) =
       
   916   (if rsp_fold f then if a |\<in>| A then ffold f z A else f a (ffold f z A) else z)"
       
   917   by (descending) (simp add: memb_def)
       
   918 
       
   919 lemma fin_commute_ffold:
       
   920   "\<lbrakk>rsp_fold f; h |\<in>| b\<rbrakk> \<Longrightarrow> ffold f z b = f h (ffold f z (fdelete h b))"
       
   921   by (descending) (simp add: memb_def memb_commute_ffold_list)
       
   922 
       
   923 
       
   924 subsection {* Choice in fsets *}
       
   925 
       
   926 lemma fset_choice: 
       
   927   assumes a: "\<forall>x. x |\<in>| A \<longrightarrow> (\<exists>y. P x y)"
       
   928   shows "\<exists>f. \<forall>x. x |\<in>| A \<longrightarrow> P x (f x)"
       
   929   using a
       
   930   apply(descending)
       
   931   using finite_set_choice
       
   932   by (auto simp add: memb_def Ball_def)
       
   933 
       
   934 
       
   935 section {* Induction and Cases rules for fsets *}
       
   936 
       
   937 lemma fset_exhaust [case_names fempty finsert, cases type: fset]:
       
   938   assumes fempty_case: "S = {||} \<Longrightarrow> P" 
       
   939   and     finsert_case: "\<And>x S'. S = finsert x S' \<Longrightarrow> P"
       
   940   shows "P"
       
   941   using assms by (lifting list.exhaust)
       
   942 
       
   943 lemma fset_induct [case_names fempty finsert]:
       
   944   assumes fempty_case: "P {||}"
       
   945   and     finsert_case: "\<And>x S. P S \<Longrightarrow> P (finsert x S)"
       
   946   shows "P S"
       
   947   using assms 
       
   948   by (descending) (blast intro: list.induct)
       
   949 
       
   950 lemma fset_induct_stronger [case_names fempty finsert, induct type: fset]:
       
   951   assumes fempty_case: "P {||}"
       
   952   and     finsert_case: "\<And>x S. \<lbrakk>x |\<notin>| S; P S\<rbrakk> \<Longrightarrow> P (finsert x S)"
       
   953   shows "P S"
       
   954 proof(induct S rule: fset_induct)
       
   955   case fempty
       
   956   show "P {||}" using fempty_case by simp
       
   957 next
       
   958   case (finsert x S)
       
   959   have "P S" by fact
       
   960   then show "P (finsert x S)" using finsert_case 
       
   961     by (cases "x |\<in>| S") (simp_all)
       
   962 qed
       
   963 
       
   964 lemma fcard_induct:
       
   965   assumes fempty_case: "P {||}"
       
   966   and     fcard_Suc_case: "\<And>S T. Suc (fcard S) = (fcard T) \<Longrightarrow> P S \<Longrightarrow> P T"
       
   967   shows "P S"
       
   968 proof (induct S)
       
   969   case fempty
       
   970   show "P {||}" by (rule fempty_case)
       
   971 next
       
   972   case (finsert x S)
       
   973   have h: "P S" by fact
       
   974   have "x |\<notin>| S" by fact
       
   975   then have "Suc (fcard S) = fcard (finsert x S)" 
       
   976     using fcard_suc by auto
       
   977   then show "P (finsert x S)" 
       
   978     using h fcard_Suc_case by simp
       
   979 qed
   512 
   980 
   513 lemma fset_raw_strong_cases:
   981 lemma fset_raw_strong_cases:
   514   obtains "xs = []"
   982   obtains "xs = []"
   515     | x ys where "\<not> memb x ys" and "xs \<approx> x # ys"
   983     | x ys where "\<not> memb x ys" and "xs \<approx> x # ys"
   516 proof (induct xs arbitrary: x ys)
   984 proof (induct xs arbitrary: x ys)
   543   qed
  1011   qed
   544   then show thesis using a c by blast
  1012   then show thesis using a c by blast
   545 qed
  1013 qed
   546 
  1014 
   547 
  1015 
   548 text {* alternate formulation with a different decomposition principle
  1016 lemma fset_strong_cases:
       
  1017   obtains "xs = {||}"
       
  1018     | x ys where "x |\<notin>| ys" and "xs = finsert x ys"
       
  1019   by (lifting fset_raw_strong_cases)
       
  1020 
       
  1021 
       
  1022 lemma fset_induct2:
       
  1023   "P {||} {||} \<Longrightarrow>
       
  1024   (\<And>x xs. x |\<notin>| xs \<Longrightarrow> P (finsert x xs) {||}) \<Longrightarrow>
       
  1025   (\<And>y ys. y |\<notin>| ys \<Longrightarrow> P {||} (finsert y ys)) \<Longrightarrow>
       
  1026   (\<And>x xs y ys. \<lbrakk>P xs ys; x |\<notin>| xs; y |\<notin>| ys\<rbrakk> \<Longrightarrow> P (finsert x xs) (finsert y ys)) \<Longrightarrow>
       
  1027   P xsa ysa"
       
  1028   apply (induct xsa arbitrary: ysa)
       
  1029   apply (induct_tac x rule: fset_induct_stronger)
       
  1030   apply simp_all
       
  1031   apply (induct_tac xa rule: fset_induct_stronger)
       
  1032   apply simp_all
       
  1033   done
       
  1034 
       
  1035 
       
  1036 
       
  1037 subsection {* alternate formulation with a different decomposition principle
   549   and a proof of equivalence *}
  1038   and a proof of equivalence *}
   550 
  1039 
   551 inductive
  1040 inductive
   552   list_eq2
  1041   list_eq2 ("_ \<approx>2 _")
   553 where
  1042 where
   554   "list_eq2 (a # b # xs) (b # a # xs)"
  1043   "(a # b # xs) \<approx>2 (b # a # xs)"
   555 | "list_eq2 [] []"
  1044 | "[] \<approx>2 []"
   556 | "list_eq2 xs ys \<Longrightarrow> list_eq2 ys xs"
  1045 | "xs \<approx>2 ys \<Longrightarrow>  ys \<approx>2 xs"
   557 | "list_eq2 (a # a # xs) (a # xs)"
  1046 | "(a # a # xs) \<approx>2 (a # xs)"
   558 | "list_eq2 xs ys \<Longrightarrow> list_eq2 (a # xs) (a # ys)"
  1047 | "xs \<approx>2 ys \<Longrightarrow>  (a # xs) \<approx>2 (a # ys)"
   559 | "\<lbrakk>list_eq2 xs1 xs2; list_eq2 xs2 xs3\<rbrakk> \<Longrightarrow> list_eq2 xs1 xs3"
  1048 | "\<lbrakk>xs1 \<approx>2 xs2;  xs2 \<approx>2 xs3\<rbrakk> \<Longrightarrow> xs1 \<approx>2 xs3"
   560 
  1049 
   561 lemma list_eq2_refl:
  1050 lemma list_eq2_refl:
   562   shows "list_eq2 xs xs"
  1051   shows "xs \<approx>2 xs"
   563   by (induct xs) (auto intro: list_eq2.intros)
  1052   by (induct xs) (auto intro: list_eq2.intros)
   564 
  1053 
       
  1054 lemma list_eq2_set:
       
  1055   assumes a: "xs \<approx>2 ys"
       
  1056   shows "set xs = set ys"
       
  1057 using a by (induct) (auto)
       
  1058 
       
  1059 lemma list_eq2_card:
       
  1060   assumes a: "xs \<approx>2 ys"
       
  1061   shows "card_list xs = card_list ys"
       
  1062 using a 
       
  1063 apply(induct) 
       
  1064 apply(auto simp add: card_list_def)
       
  1065 apply(metis insert_commute)
       
  1066 apply(metis list_eq2_set)
       
  1067 done
       
  1068 
       
  1069 lemma list_eq2_equiv1:
       
  1070   assumes a: "xs \<approx>2 ys"
       
  1071   shows "xs \<approx> ys"
       
  1072 using a by (induct) (auto)
       
  1073 
       
  1074 
   565 lemma cons_delete_list_eq2:
  1075 lemma cons_delete_list_eq2:
   566   shows "list_eq2 (a # (removeAll a A)) (if memb a A then A else a # A)"
  1076   shows "(a # (removeAll a A)) \<approx>2 (if memb a A then A else a # A)"
   567   apply (induct A)
  1077   apply (induct A)
   568   apply (simp add: memb_def list_eq2_refl)
  1078   apply (simp add: memb_def list_eq2_refl)
   569   apply (case_tac "memb a (aa # A)")
  1079   apply (case_tac "memb a (aa # A)")
   570   apply (simp_all only: memb_def)
  1080   apply (simp_all only: memb_def)
   571   apply (case_tac [!] "a = aa")
  1081   apply (case_tac [!] "a = aa")
   577   apply (auto simp add: list_eq2_refl memb_def)
  1087   apply (auto simp add: list_eq2_refl memb_def)
   578   done
  1088   done
   579 
  1089 
   580 lemma memb_delete_list_eq2:
  1090 lemma memb_delete_list_eq2:
   581   assumes a: "memb e r"
  1091   assumes a: "memb e r"
   582   shows "list_eq2 (e # removeAll e r) r"
  1092   shows "(e # removeAll e r) \<approx>2 r"
   583   using a cons_delete_list_eq2[of e r]
  1093   using a cons_delete_list_eq2[of e r]
   584   by simp
  1094   by simp
       
  1095 
       
  1096 (*
       
  1097 lemma list_eq2_equiv2:
       
  1098   assumes a: "xs \<approx> ys"
       
  1099   shows "xs \<approx>2 ys"
       
  1100 using a
       
  1101 apply(induct xs arbitrary: ys taking: "card o set" rule: measure_induct)
       
  1102 apply(simp)
       
  1103 apply(case_tac x)
       
  1104 apply(simp)
       
  1105 apply(auto intro: list_eq2.intros)[1]
       
  1106 apply(simp)
       
  1107 apply(case_tac "a \<in> set list")
       
  1108 apply(simp add: insert_absorb)
       
  1109 apply(drule_tac x="removeAll a ys" in spec)
       
  1110 apply(drule mp)
       
  1111 apply(simp)
       
  1112 apply(subgoal_tac "0 < card (set ys)")
       
  1113 apply(simp)
       
  1114 apply(metis length_pos_if_in_set length_remdups_card_conv set_remdups)
       
  1115 apply(simp)
       
  1116 apply(clarify)
       
  1117 apply(drule_tac x="removeAll a list" in spec)
       
  1118 apply(drule mp)
       
  1119 apply(simp)
       
  1120 oops
       
  1121 *)
   585 
  1122 
   586 lemma list_eq2_equiv:
  1123 lemma list_eq2_equiv:
   587   "(l \<approx> r) \<longleftrightarrow> (list_eq2 l r)"
  1124   "(l \<approx> r) \<longleftrightarrow> (list_eq2 l r)"
   588 proof
  1125 proof
   589   show "list_eq2 l r \<Longrightarrow> l \<approx> r" by (induct rule: list_eq2.induct) auto
  1126   show "list_eq2 l r \<Longrightarrow> l \<approx> r" by (induct rule: list_eq2.induct) auto
   590 next
  1127 next
   591   {
  1128   {
   592     fix n
  1129     fix n
   593     assume a: "card_list l = n" and b: "l \<approx> r"
  1130     assume a: "card_list l = n" and b: "l \<approx> r"
   594     have "list_eq2 l r"
  1131     have "l \<approx>2 r"
   595       using a b
  1132       using a b
   596     proof (induct n arbitrary: l r)
  1133     proof (induct n arbitrary: l r)
   597       case 0
  1134       case 0
   598       have "card_list l = 0" by fact
  1135       have "card_list l = 0" by fact
   599       then have "\<forall>x. \<not> memb x l" unfolding card_list_def memb_def by auto
  1136       then have "\<forall>x. \<not> memb x l" unfolding card_list_def memb_def by auto
   614 	unfolding memb_def by auto
  1151 	unfolding memb_def by auto
   615       have f: "card_list (removeAll a l) = m" using e d by (simp add: card_list_def memb_def)
  1152       have f: "card_list (removeAll a l) = m" using e d by (simp add: card_list_def memb_def)
   616       have g: "removeAll a l \<approx> removeAll a r" using removeAll_rsp b by simp
  1153       have g: "removeAll a l \<approx> removeAll a r" using removeAll_rsp b by simp
   617       have "list_eq2 (removeAll a l) (removeAll a r)" by (rule Suc.hyps[OF f g])
  1154       have "list_eq2 (removeAll a l) (removeAll a r)" by (rule Suc.hyps[OF f g])
   618       then have h: "list_eq2 (a # removeAll a l) (a # removeAll a r)" by (rule list_eq2.intros(5))
  1155       then have h: "list_eq2 (a # removeAll a l) (a # removeAll a r)" by (rule list_eq2.intros(5))
   619       have i: "list_eq2 l (a # removeAll a l)"
  1156       have i: "list_eq2 l (a # removeAll a l)"	
   620         by (rule list_eq2.intros(3)[OF memb_delete_list_eq2[OF e]])
  1157         by (rule list_eq2.intros(3)[OF memb_delete_list_eq2[OF e]])
   621       have "list_eq2 l (a # removeAll a r)" by (rule list_eq2.intros(6)[OF i h])
  1158       have "list_eq2 l (a # removeAll a r)" by (rule list_eq2.intros(6)[OF i h])
   622       then show ?case using list_eq2.intros(6)[OF _ memb_delete_list_eq2[OF e']] by simp
  1159       then show ?case using list_eq2.intros(6)[OF _ memb_delete_list_eq2[OF e']] by simp
   623     qed
  1160     qed
   624     }
  1161     }
   625   then show "l \<approx> r \<Longrightarrow> list_eq2 l r" by blast
  1162   then show "l \<approx> r \<Longrightarrow> list_eq2 l r" by blast
   626 qed
       
   627 
       
   628 
       
   629 section {* Lifted theorems *}
       
   630 
       
   631 
       
   632 subsection {* fin *}
       
   633 
       
   634 lemma not_fin_fnil: 
       
   635   shows "x |\<notin>| {||}"
       
   636   by (descending) (simp add: memb_def)
       
   637 
       
   638 lemma fin_set: 
       
   639   shows "x |\<in>| S \<longleftrightarrow> x \<in> fset S"
       
   640   by (descending) (simp add: memb_def)
       
   641 
       
   642 lemma fnotin_set: 
       
   643   shows "x |\<notin>| S \<longleftrightarrow> x \<notin> fset S"
       
   644   by (descending) (simp add: memb_def)
       
   645 
       
   646 lemma fset_eq_iff:
       
   647   shows "S = T \<longleftrightarrow> (\<forall>x. (x |\<in>| S) = (x |\<in>| T))"
       
   648   by (descending) (auto simp add: memb_def)
       
   649 
       
   650 lemma none_fin_fempty:
       
   651   shows "(\<forall>x. x |\<notin>| S) \<longleftrightarrow> S = {||}"
       
   652   by (descending) (simp add: memb_def)
       
   653 
       
   654 
       
   655 subsection {* finsert *}
       
   656 
       
   657 lemma fin_finsert_iff[simp]:
       
   658   shows "x |\<in>| finsert y S \<longleftrightarrow> x = y \<or> x |\<in>| S"
       
   659   by (descending) (simp add: memb_def)
       
   660 
       
   661 lemma
       
   662   shows finsertI1: "x |\<in>| finsert x S"
       
   663   and   finsertI2: "x |\<in>| S \<Longrightarrow> x |\<in>| finsert y S"
       
   664   by (descending, simp add: memb_def)+
       
   665 
       
   666 lemma finsert_absorb[simp]:
       
   667   shows "x |\<in>| S \<Longrightarrow> finsert x S = S"
       
   668   by (descending) (auto simp add: memb_def)
       
   669 
       
   670 lemma fempty_not_finsert[simp]:
       
   671   shows "{||} \<noteq> finsert x S"
       
   672   and   "finsert x S \<noteq> {||}"
       
   673   by (descending, simp)+
       
   674 
       
   675 lemma finsert_left_comm:
       
   676   shows "finsert x (finsert y S) = finsert y (finsert x S)"
       
   677   by (descending) (auto)
       
   678 
       
   679 lemma finsert_left_idem:
       
   680   shows "finsert x (finsert x S) = finsert x S"
       
   681   by (descending) (auto)
       
   682 
       
   683 lemma fsingleton_eq[simp]:
       
   684   shows "{|x|} = {|y|} \<longleftrightarrow> x = y"
       
   685   by (descending) (auto)
       
   686 
       
   687 
       
   688 (* FIXME: is this in any case a useful lemma *)
       
   689 lemma fin_mdef:
       
   690   shows "x |\<in>| F \<longleftrightarrow> x |\<notin>| (F - {|x|}) \<and> F = finsert x (F - {|x|})"
       
   691   by (descending) (auto simp add: memb_def diff_list_def)
       
   692 
       
   693 
       
   694 subsection {* fset *}
       
   695 
       
   696 lemma fset_simps[simp]:
       
   697   "fset {||} = ({} :: 'a set)"
       
   698   "fset (finsert (x :: 'a) S) = insert x (fset S)"
       
   699   by (lifting set.simps)
       
   700 
       
   701 lemma finite_fset [simp]: 
       
   702   shows "finite (fset S)"
       
   703   by (descending) (simp)
       
   704 
       
   705 lemma fset_cong:
       
   706   shows "fset S = fset T \<longleftrightarrow> S = T"
       
   707   by (descending) (simp)
       
   708 
       
   709 lemma ffilter_set [simp]: 
       
   710   shows "fset (ffilter P xs) = P \<inter> fset xs"
       
   711   by (descending) (auto simp add: mem_def)
       
   712 
       
   713 lemma fdelete_set [simp]: 
       
   714   shows "fset (fdelete x xs) = fset xs - {x}"
       
   715   by (descending) (simp)
       
   716 
       
   717 lemma finter_set [simp]: 
       
   718   shows "fset (xs |\<inter>| ys) = fset xs \<inter> fset ys"
       
   719   by (descending) (auto simp add: inter_list_def)
       
   720 
       
   721 lemma funion_set [simp]: 
       
   722   shows "fset (xs |\<union>| ys) = fset xs \<union> fset ys"
       
   723   by (lifting set_append)
       
   724 
       
   725 lemma fminus_set [simp]: 
       
   726   shows "fset (xs - ys) = fset xs - fset ys"
       
   727   by (descending) (auto simp add: diff_list_def)
       
   728 
       
   729 
       
   730 subsection {* funion *}
       
   731 
       
   732 lemmas [simp] =
       
   733   sup_bot_left[where 'a="'a fset", standard]
       
   734   sup_bot_right[where 'a="'a fset", standard]
       
   735 
       
   736 lemma funion_finsert[simp]:
       
   737   shows "finsert x S |\<union>| T = finsert x (S |\<union>| T)"
       
   738   by (lifting append.simps(2))
       
   739 
       
   740 lemma singleton_funion_left:
       
   741   shows "{|a|} |\<union>| S = finsert a S"
       
   742   by simp
       
   743 
       
   744 lemma singleton_funion_right:
       
   745   shows "S |\<union>| {|a|} = finsert a S"
       
   746   by (subst sup.commute) simp
       
   747 
       
   748 lemma fin_funion:
       
   749   shows "x |\<in>| S |\<union>| T \<longleftrightarrow> x |\<in>| S \<or> x |\<in>| T"
       
   750   by (descending) (simp add: memb_def)
       
   751 
       
   752 
       
   753 subsection {* fminus *}
       
   754 
       
   755 lemma fminus_fin: 
       
   756   shows "x |\<in>| (xs - ys) \<longleftrightarrow> x |\<in>| xs \<and> x |\<notin>| ys"
       
   757   by (descending) (simp add: diff_list_def memb_def)
       
   758 
       
   759 lemma fminus_red: 
       
   760   shows "finsert x xs - ys = (if x |\<in>| ys then xs - ys else finsert x (xs - ys))"
       
   761   by (descending) (auto simp add: diff_list_def memb_def)
       
   762 
       
   763 lemma fminus_red_fin[simp]: 
       
   764   shows "x |\<in>| ys \<Longrightarrow> finsert x xs - ys = xs - ys"
       
   765   by (simp add: fminus_red)
       
   766 
       
   767 lemma fminus_red_fnotin[simp]: 
       
   768   shows "x |\<notin>| ys \<Longrightarrow> finsert x xs - ys = finsert x (xs - ys)"
       
   769   by (simp add: fminus_red)
       
   770 
       
   771 lemma fin_fminus_fnotin: 
       
   772   shows "x |\<in>| F - S \<Longrightarrow> x |\<notin>| S"
       
   773   unfolding fin_set fminus_set
       
   774   by blast
       
   775 
       
   776 lemma fin_fnotin_fminus: 
       
   777   shows "x |\<in>| S \<Longrightarrow> x |\<notin>| F - S"
       
   778   unfolding fin_set fminus_set
       
   779   by blast
       
   780 
       
   781 
       
   782 section {* fdelete *}
       
   783 
       
   784 lemma fin_fdelete:
       
   785   shows "x |\<in>| fdelete y S \<longleftrightarrow> x |\<in>| S \<and> x \<noteq> y"
       
   786   by (descending) (simp add: memb_def)
       
   787 
       
   788 lemma fnotin_fdelete:
       
   789   shows "x |\<notin>| fdelete x S"
       
   790   by (descending) (simp add: memb_def)
       
   791 
       
   792 lemma fnotin_fdelete_ident:
       
   793   shows "x |\<notin>| S \<Longrightarrow> fdelete x S = S"
       
   794   by (descending) (simp add: memb_def)
       
   795 
       
   796 lemma fset_fdelete_cases:
       
   797   shows "S = {||} \<or> (\<exists>x. x |\<in>| S \<and> S = finsert x (fdelete x S))"
       
   798   by (descending) (auto simp add: memb_def insert_absorb)
       
   799   
       
   800 
       
   801 section {* finter *}
       
   802 
       
   803 lemma finter_empty_l:
       
   804   shows "{||} |\<inter>| S = {||}"
       
   805   by simp
       
   806 
       
   807 lemma finter_empty_r:
       
   808   shows "S |\<inter>| {||} = {||}"
       
   809   by simp
       
   810 
       
   811 lemma finter_finsert:
       
   812   shows "finsert x S |\<inter>| T = (if x |\<in>| T then finsert x (S |\<inter>| T) else S |\<inter>| T)"
       
   813   by (descending) (auto simp add: inter_list_def memb_def)
       
   814 
       
   815 lemma fin_finter:
       
   816   shows "x |\<in>| (S |\<inter>| T) \<longleftrightarrow> x |\<in>| S \<and> x |\<in>| T"
       
   817   by (descending) (simp add: inter_list_def memb_def)
       
   818 
       
   819 
       
   820 subsection {* fsubset *}
       
   821 
       
   822 lemma fsubseteq_set: 
       
   823   shows "xs |\<subseteq>| ys \<longleftrightarrow> fset xs \<subseteq> fset ys"
       
   824   by (descending) (simp add: sub_list_def)
       
   825 
       
   826 lemma fsubset_set: 
       
   827   shows "xs |\<subset>| ys \<longleftrightarrow> fset xs \<subset> fset ys"
       
   828   unfolding less_fset_def 
       
   829   by (descending) (auto simp add: sub_list_def)
       
   830 
       
   831 lemma fsubseteq_finsert:
       
   832   shows "(finsert x xs) |\<subseteq>| ys \<longleftrightarrow> x |\<in>| ys \<and> xs |\<subseteq>| ys"
       
   833   by (descending) (simp add: sub_list_def memb_def)
       
   834 
       
   835 lemma fsubset_fin: 
       
   836   shows "xs |\<subseteq>| ys = (\<forall>x. x |\<in>| xs \<longrightarrow> x |\<in>| ys)"
       
   837   by (descending) (auto simp add: sub_list_def memb_def)
       
   838 
       
   839 (* FIXME: no type ord *)
       
   840 (*
       
   841 lemma fsubset_finsert:
       
   842   shows "(finsert x xs) |\<subset>| ys \<longleftrightarrow> x |\<in>| ys \<and> xs |\<subset>| ys"
       
   843   by (descending) (simp add: sub_list_def memb_def)
       
   844 *)
       
   845 
       
   846 lemma fsubseteq_fempty:
       
   847   shows "xs |\<subseteq>| {||} \<longleftrightarrow> xs = {||}"
       
   848   by (descending) (simp add: sub_list_def)
       
   849 
       
   850 (* also problem with ord *)
       
   851 lemma not_fsubset_fnil: 
       
   852   shows "\<not> xs |\<subset>| {||}"
       
   853   by (metis fset_simps(1) fsubset_set not_psubset_empty)
       
   854 
       
   855 
       
   856 section {* fmap *}
       
   857 
       
   858 lemma fmap_simps [simp]:
       
   859    shows "fmap f {||} = {||}"
       
   860   and   "fmap f (finsert x S) = finsert (f x) (fmap f S)"
       
   861   by (descending, simp)+
       
   862 
       
   863 lemma fmap_set_image [simp]:
       
   864   shows "fset (fmap f S) = f ` (fset S)"
       
   865   by (descending) (simp)
       
   866 
       
   867 lemma inj_fmap_eq_iff:
       
   868   shows "inj f \<Longrightarrow> fmap f S = fmap f T \<longleftrightarrow> S = T"
       
   869   by (descending) (metis inj_vimage_image_eq list_eq.simps set_map)
       
   870 
       
   871 lemma fmap_funion: 
       
   872   shows "fmap f (S |\<union>| T) = fmap f S |\<union>| fmap f T"
       
   873   by (descending) (simp)
       
   874 
       
   875 
       
   876 subsection {* fcard *}
       
   877 
       
   878 lemma fcard_set: 
       
   879   shows "fcard xs = card (fset xs)"
       
   880   by (lifting card_list_def)
       
   881 
       
   882 lemma fcard_finsert_if [simp]:
       
   883   shows "fcard (finsert x S) = (if x |\<in>| S then fcard S else Suc (fcard S))"
       
   884   by (descending) (auto simp add: card_list_def memb_def insert_absorb)
       
   885 
       
   886 lemma fcard_0[simp]:
       
   887   shows "fcard S = 0 \<longleftrightarrow> S = {||}"
       
   888   by (descending) (simp add: card_list_def)
       
   889 
       
   890 lemma fcard_fempty[simp]:
       
   891   shows "fcard {||} = 0"
       
   892   by (simp add: fcard_0)
       
   893 
       
   894 lemma fcard_1:
       
   895   shows "fcard S = 1 \<longleftrightarrow> (\<exists>x. S = {|x|})"
       
   896   by (descending) (auto simp add: card_list_def card_Suc_eq)
       
   897 
       
   898 lemma fcard_gt_0:
       
   899   shows "x \<in> fset S \<Longrightarrow> 0 < fcard S"
       
   900   by (descending) (auto simp add: card_list_def card_gt_0_iff)
       
   901   
       
   902 lemma fcard_not_fin:
       
   903   shows "(x |\<notin>| S) = (fcard (finsert x S) = Suc (fcard S))"
       
   904   by (descending) (auto simp add: memb_def card_list_def insert_absorb)
       
   905 
       
   906 lemma fcard_suc: 
       
   907   shows "fcard S = Suc n \<Longrightarrow> \<exists>x T. x |\<notin>| T \<and> S = finsert x T \<and> fcard T = n"
       
   908   apply(descending)
       
   909   apply(auto simp add: card_list_def memb_def)
       
   910   apply(drule card_eq_SucD)
       
   911   apply(auto)
       
   912   apply(rule_tac x="b" in exI)
       
   913   apply(rule_tac x="removeAll b S" in exI)
       
   914   apply(auto)
       
   915   done
       
   916 
       
   917 lemma fcard_delete:
       
   918   shows "fcard (fdelete y S) = (if y |\<in>| S then fcard S - 1 else fcard S)"
       
   919   by (descending) (simp add: card_list_def memb_def)
       
   920 
       
   921 lemma fcard_suc_memb: 
       
   922   shows "fcard A = Suc n \<Longrightarrow> \<exists>a. a |\<in>| A"
       
   923   apply(descending)
       
   924   apply(simp add: card_list_def memb_def)
       
   925   apply(drule card_eq_SucD)
       
   926   apply(auto)
       
   927   done
       
   928 
       
   929 lemma fin_fcard_not_0: 
       
   930   shows "a |\<in>| A \<Longrightarrow> fcard A \<noteq> 0"
       
   931   by (descending) (auto simp add: card_list_def memb_def)
       
   932 
       
   933 lemma fcard_mono: 
       
   934   shows "xs |\<subseteq>| ys \<Longrightarrow> fcard xs \<le> fcard ys"
       
   935   unfolding fcard_set fsubseteq_set
       
   936   by (simp add: card_mono[OF finite_fset])
       
   937 
       
   938 lemma fcard_fsubset_eq: 
       
   939   shows "xs |\<subseteq>| ys \<Longrightarrow> fcard ys \<le> fcard xs \<Longrightarrow> xs = ys"
       
   940   unfolding fcard_set fsubseteq_set
       
   941   by (auto dest: card_seteq[OF finite_fset] simp add: fset_cong)
       
   942 
       
   943 lemma psubset_fcard_mono: 
       
   944   shows "xs |\<subset>| ys \<Longrightarrow> fcard xs < fcard ys"
       
   945   unfolding fcard_set fsubset_set
       
   946   by (rule psubset_card_mono[OF finite_fset])
       
   947 
       
   948 lemma fcard_funion_finter: 
       
   949   shows "fcard xs + fcard ys = fcard (xs |\<union>| ys) + fcard (xs |\<inter>| ys)"
       
   950   unfolding fcard_set funion_set finter_set
       
   951   by (rule card_Un_Int[OF finite_fset finite_fset])
       
   952 
       
   953 lemma fcard_funion_disjoint: 
       
   954   shows "xs |\<inter>| ys = {||} \<Longrightarrow> fcard (xs |\<union>| ys) = fcard xs + fcard ys"
       
   955   unfolding fcard_set funion_set 
       
   956   apply (rule card_Un_disjoint[OF finite_fset finite_fset])
       
   957   by (metis finter_set fset_simps(1))
       
   958 
       
   959 lemma fcard_delete1_less: 
       
   960   shows "x |\<in>| xs \<Longrightarrow> fcard (fdelete x xs) < fcard xs"
       
   961   unfolding fcard_set fin_set fdelete_set 
       
   962   by (rule card_Diff1_less[OF finite_fset])
       
   963 
       
   964 lemma fcard_delete2_less: 
       
   965   shows "x |\<in>| xs \<Longrightarrow> y |\<in>| xs \<Longrightarrow> fcard (fdelete y (fdelete x xs)) < fcard xs"
       
   966   unfolding fcard_set fdelete_set fin_set
       
   967   by (rule card_Diff2_less[OF finite_fset])
       
   968 
       
   969 lemma fcard_delete1_le: 
       
   970   shows "fcard (fdelete x xs) \<le> fcard xs"
       
   971   unfolding fdelete_set fcard_set
       
   972   by (rule card_Diff1_le[OF finite_fset])
       
   973 
       
   974 lemma fcard_psubset: 
       
   975   shows "ys |\<subseteq>| xs \<Longrightarrow> fcard ys < fcard xs \<Longrightarrow> ys |\<subset>| xs"
       
   976   unfolding fcard_set fsubseteq_set fsubset_set
       
   977   by (rule card_psubset[OF finite_fset])
       
   978 
       
   979 lemma fcard_fmap_le: 
       
   980   shows "fcard (fmap f xs) \<le> fcard xs"
       
   981   unfolding fcard_set fmap_set_image
       
   982   by (rule card_image_le[OF finite_fset])
       
   983 
       
   984 lemma fcard_fminus_finsert[simp]:
       
   985   assumes "a |\<in>| A" and "a |\<notin>| B"
       
   986   shows "fcard (A - finsert a B) = fcard (A - B) - 1"
       
   987   using assms 
       
   988   unfolding fin_set fcard_set fminus_set
       
   989   by (simp add: card_Diff_insert[OF finite_fset])
       
   990 
       
   991 lemma fcard_fminus_fsubset:
       
   992   assumes "B |\<subseteq>| A"
       
   993   shows "fcard (A - B) = fcard A - fcard B"
       
   994   using assms 
       
   995   unfolding fsubseteq_set fcard_set fminus_set
       
   996   by (rule card_Diff_subset[OF finite_fset])
       
   997 
       
   998 lemma fcard_fminus_subset_finter:
       
   999   shows "fcard (A - B) = fcard A - fcard (A |\<inter>| B)"
       
  1000   unfolding finter_set fcard_set fminus_set
       
  1001   by (rule card_Diff_subset_Int) (simp)
       
  1002 
       
  1003 
       
  1004 section {* fconcat *}
       
  1005 
       
  1006 lemma fconcat_fempty:
       
  1007   shows "fconcat {||} = {||}"
       
  1008   by (lifting concat.simps(1))
       
  1009 
       
  1010 lemma fconcat_finsert:
       
  1011   shows "fconcat (finsert x S) = x |\<union>| fconcat S"
       
  1012   by (lifting concat.simps(2))
       
  1013 
       
  1014 lemma fconcat_finter:
       
  1015   shows "fconcat (xs |\<union>| ys) = fconcat xs |\<union>| fconcat ys"
       
  1016   by (lifting concat_append)
       
  1017 
       
  1018 
       
  1019 section {* ffilter *}
       
  1020 
       
  1021 lemma subseteq_filter: 
       
  1022   shows "ffilter P xs <= ffilter Q xs = (\<forall> x. x |\<in>| xs \<longrightarrow> P x \<longrightarrow> Q x)"
       
  1023   by  (descending) (auto simp add: memb_def sub_list_def)
       
  1024 
       
  1025 lemma eq_ffilter: 
       
  1026   shows "(ffilter P xs = ffilter Q xs) = (\<forall>x. x |\<in>| xs \<longrightarrow> P x = Q x)"
       
  1027   by (descending) (auto simp add: memb_def)
       
  1028 
       
  1029 lemma subset_ffilter:
       
  1030   shows "(\<And>x. x |\<in>| xs \<Longrightarrow> P x \<Longrightarrow> Q x) \<Longrightarrow> (x |\<in>| xs & \<not> P x & Q x) \<Longrightarrow> ffilter P xs < ffilter Q xs"
       
  1031   unfolding less_fset_def by (auto simp add: subseteq_filter eq_ffilter)
       
  1032 
       
  1033 
       
  1034 subsection {* ffold *}
       
  1035 
       
  1036 lemma ffold_nil: 
       
  1037   shows "ffold f z {||} = z"
       
  1038   by (descending) (simp)
       
  1039 
       
  1040 lemma ffold_finsert: "ffold f z (finsert a A) =
       
  1041   (if rsp_fold f then if a |\<in>| A then ffold f z A else f a (ffold f z A) else z)"
       
  1042   by (descending) (simp add: memb_def)
       
  1043 
       
  1044 lemma fin_commute_ffold:
       
  1045   "\<lbrakk>rsp_fold f; h |\<in>| b\<rbrakk> \<Longrightarrow> ffold f z b = f h (ffold f z (fdelete h b))"
       
  1046   by (descending) (simp add: memb_def memb_commute_ffold_raw)
       
  1047 
       
  1048 
       
  1049 subsection {* Choice in fsets *}
       
  1050 
       
  1051 lemma fset_choice: 
       
  1052   assumes a: "\<forall>x. x |\<in>| A \<longrightarrow> (\<exists>y. P x y)"
       
  1053   shows "\<exists>f. \<forall>x. x |\<in>| A \<longrightarrow> P x (f x)"
       
  1054   using a
       
  1055   apply(descending)
       
  1056   using finite_set_choice
       
  1057   by (auto simp add: memb_def Ball_def)
       
  1058 
       
  1059 
       
  1060 (* FIXME: is that in any way useful *)  
       
  1061 
       
  1062 
       
  1063 
       
  1064 section {* Induction and Cases rules for fsets *}
       
  1065 
       
  1066 lemma fset_strong_cases:
       
  1067   obtains "xs = {||}"
       
  1068     | x ys where "x |\<notin>| ys" and "xs = finsert x ys"
       
  1069   by (lifting fset_raw_strong_cases)
       
  1070 
       
  1071 lemma fset_exhaust[case_names fempty finsert, cases type: fset]:
       
  1072   shows "\<lbrakk>S = {||} \<Longrightarrow> P; \<And>x S'. S = finsert x S' \<Longrightarrow> P\<rbrakk> \<Longrightarrow> P"
       
  1073   by (lifting list.exhaust)
       
  1074 
       
  1075 lemma fset_induct_weak[case_names fempty finsert]:
       
  1076   shows "\<lbrakk>P {||}; \<And>x S. P S \<Longrightarrow> P (finsert x S)\<rbrakk> \<Longrightarrow> P S"
       
  1077   by (lifting list.induct)
       
  1078 
       
  1079 lemma fset_induct[case_names fempty finsert, induct type: fset]:
       
  1080   assumes prem1: "P {||}"
       
  1081   and     prem2: "\<And>x S. \<lbrakk>x |\<notin>| S; P S\<rbrakk> \<Longrightarrow> P (finsert x S)"
       
  1082   shows "P S"
       
  1083 proof(induct S rule: fset_induct_weak)
       
  1084   case fempty
       
  1085   show "P {||}" by (rule prem1)
       
  1086 next
       
  1087   case (finsert x S)
       
  1088   have asm: "P S" by fact
       
  1089   show "P (finsert x S)"
       
  1090     by (cases "x |\<in>| S") (simp_all add: asm prem2)
       
  1091 qed
       
  1092 
       
  1093 lemma fset_induct2:
       
  1094   "P {||} {||} \<Longrightarrow>
       
  1095   (\<And>x xs. x |\<notin>| xs \<Longrightarrow> P (finsert x xs) {||}) \<Longrightarrow>
       
  1096   (\<And>y ys. y |\<notin>| ys \<Longrightarrow> P {||} (finsert y ys)) \<Longrightarrow>
       
  1097   (\<And>x xs y ys. \<lbrakk>P xs ys; x |\<notin>| xs; y |\<notin>| ys\<rbrakk> \<Longrightarrow> P (finsert x xs) (finsert y ys)) \<Longrightarrow>
       
  1098   P xsa ysa"
       
  1099   apply (induct xsa arbitrary: ysa)
       
  1100   apply (induct_tac x rule: fset_induct)
       
  1101   apply simp_all
       
  1102   apply (induct_tac xa rule: fset_induct)
       
  1103   apply simp_all
       
  1104   done
       
  1105 
       
  1106 lemma fset_fcard_induct:
       
  1107   assumes a: "P {||}"
       
  1108   and     b: "\<And>xs ys. Suc (fcard xs) = (fcard ys) \<Longrightarrow> P xs \<Longrightarrow> P ys"
       
  1109   shows "P zs"
       
  1110 proof (induct zs)
       
  1111   show "P {||}" by (rule a)
       
  1112 next
       
  1113   fix x :: 'a and zs :: "'a fset"
       
  1114   assume h: "P zs"
       
  1115   assume "x |\<notin>| zs"
       
  1116   then have H1: "Suc (fcard zs) = fcard (finsert x zs)" using fcard_suc by auto
       
  1117   then show "P (finsert x zs)" using b h by simp
       
  1118 qed
  1163 qed
  1119 
  1164 
  1120 
  1165 
  1121 (* We cannot write it as "assumes .. shows" since Isabelle changes
  1166 (* We cannot write it as "assumes .. shows" since Isabelle changes
  1122    the quantifiers to schematic variables and reintroduces them in
  1167    the quantifiers to schematic variables and reintroduces them in
  1140   and "\<And>xs ys a. \<lbrakk>xs = ys; P xs ys\<rbrakk> \<Longrightarrow> P (finsert a xs) (finsert a ys)"
  1185   and "\<And>xs ys a. \<lbrakk>xs = ys; P xs ys\<rbrakk> \<Longrightarrow> P (finsert a xs) (finsert a ys)"
  1141   and "\<And>xs1 xs2 xs3. \<lbrakk>xs1 = xs2; P xs1 xs2; xs2 = xs3; P xs2 xs3\<rbrakk> \<Longrightarrow> P xs1 xs3"
  1186   and "\<And>xs1 xs2 xs3. \<lbrakk>xs1 = xs2; P xs1 xs2; xs2 = xs3; P xs2 xs3\<rbrakk> \<Longrightarrow> P xs1 xs3"
  1142   shows "P x1 x2"
  1187   shows "P x1 x2"
  1143   using assms
  1188   using assms
  1144   by (lifting list_eq2.induct[simplified list_eq2_equiv[symmetric]])
  1189   by (lifting list_eq2.induct[simplified list_eq2_equiv[symmetric]])
  1145 
       
  1146 
       
  1147 
       
  1148 section {* lemmas transferred from Finite_Set theory *}
       
  1149 
       
  1150 text {* finiteness for finite sets holds *}
       
  1151 
       
  1152 
       
  1153 
  1190 
  1154 
  1191 
  1155 lemma list_all2_refl:
  1192 lemma list_all2_refl:
  1156   assumes q: "equivp R"
  1193   assumes q: "equivp R"
  1157   shows "(list_all2 R) r r"
  1194   shows "(list_all2 R) r r"
  1229   | dest_fsetT T = raise TYPE ("dest_fsetT: fset type expected", [T], []);
  1266   | dest_fsetT T = raise TYPE ("dest_fsetT: fset type expected", [T], []);
  1230 *}
  1267 *}
  1231 
  1268 
  1232 no_notation
  1269 no_notation
  1233   list_eq (infix "\<approx>" 50)
  1270   list_eq (infix "\<approx>" 50)
       
  1271 and list_eq2 (infix "\<approx>2" 50)
  1234 
  1272 
  1235 end
  1273 end