src/HOL/Quotient_Examples/FSet.thy
changeset 41070 36cec0e3491f
parent 40962 069cd1c1f39b
child 41071 7204024077a8
equal deleted inserted replaced
41069:6fabc0414055 41070:36cec0e3491f
   956   by (auto simp add: Ball_def)
   956   by (auto simp add: Ball_def)
   957 
   957 
   958 
   958 
   959 section {* Induction and Cases rules for fsets *}
   959 section {* Induction and Cases rules for fsets *}
   960 
   960 
   961 lemma fset_exhaust [case_names empty_fset insert_fset, cases type: fset]:
   961 lemma fset_exhaust [case_names empty insert, cases type: fset]:
   962   assumes empty_fset_case: "S = {||} \<Longrightarrow> P" 
   962   assumes empty_fset_case: "S = {||} \<Longrightarrow> P" 
   963   and     insert_fset_case: "\<And>x S'. S = insert_fset x S' \<Longrightarrow> P"
   963   and     insert_fset_case: "\<And>x S'. S = insert_fset x S' \<Longrightarrow> P"
   964   shows "P"
   964   shows "P"
   965   using assms by (lifting list.exhaust)
   965   using assms by (lifting list.exhaust)
   966 
   966 
   967 lemma fset_induct [case_names empty_fset insert_fset]:
   967 lemma fset_induct [case_names empty insert]:
   968   assumes empty_fset_case: "P {||}"
   968   assumes empty_fset_case: "P {||}"
   969   and     insert_fset_case: "\<And>x S. P S \<Longrightarrow> P (insert_fset x S)"
   969   and     insert_fset_case: "\<And>x S. P S \<Longrightarrow> P (insert_fset x S)"
   970   shows "P S"
   970   shows "P S"
   971   using assms 
   971   using assms 
   972   by (descending) (blast intro: list.induct)
   972   by (descending) (blast intro: list.induct)
   973 
   973 
   974 lemma fset_induct_stronger [case_names empty_fset insert_fset, induct type: fset]:
   974 lemma fset_induct_stronger [case_names empty insert, induct type: fset]:
   975   assumes empty_fset_case: "P {||}"
   975   assumes empty_fset_case: "P {||}"
   976   and     insert_fset_case: "\<And>x S. \<lbrakk>x |\<notin>| S; P S\<rbrakk> \<Longrightarrow> P (insert_fset x S)"
   976   and     insert_fset_case: "\<And>x S. \<lbrakk>x |\<notin>| S; P S\<rbrakk> \<Longrightarrow> P (insert_fset x S)"
   977   shows "P S"
   977   shows "P S"
   978 proof(induct S rule: fset_induct)
   978 proof(induct S rule: fset_induct)
   979   case empty_fset
   979   case empty
   980   show "P {||}" using empty_fset_case by simp
   980   show "P {||}" using empty_fset_case by simp
   981 next
   981 next
   982   case (insert_fset x S)
   982   case (insert x S)
   983   have "P S" by fact
   983   have "P S" by fact
   984   then show "P (insert_fset x S)" using insert_fset_case 
   984   then show "P (insert_fset x S)" using insert_fset_case 
   985     by (cases "x |\<in>| S") (simp_all)
   985     by (cases "x |\<in>| S") (simp_all)
   986 qed
   986 qed
   987 
   987 
   988 lemma fset_card_induct:
   988 lemma fset_card_induct:
   989   assumes empty_fset_case: "P {||}"
   989   assumes empty_fset_case: "P {||}"
   990   and     card_fset_Suc_case: "\<And>S T. Suc (card_fset S) = (card_fset T) \<Longrightarrow> P S \<Longrightarrow> P T"
   990   and     card_fset_Suc_case: "\<And>S T. Suc (card_fset S) = (card_fset T) \<Longrightarrow> P S \<Longrightarrow> P T"
   991   shows "P S"
   991   shows "P S"
   992 proof (induct S)
   992 proof (induct S)
   993   case empty_fset
   993   case empty
   994   show "P {||}" by (rule empty_fset_case)
   994   show "P {||}" by (rule empty_fset_case)
   995 next
   995 next
   996   case (insert_fset x S)
   996   case (insert x S)
   997   have h: "P S" by fact
   997   have h: "P S" by fact
   998   have "x |\<notin>| S" by fact
   998   have "x |\<notin>| S" by fact
   999   then have "Suc (card_fset S) = card_fset (insert_fset x S)" 
   999   then have "Suc (card_fset S) = card_fset (insert_fset x S)" 
  1000     using card_fset_Suc by auto
  1000     using card_fset_Suc by auto
  1001   then show "P (insert_fset x S)" 
  1001   then show "P (insert_fset x S)" 
  1056   apply simp_all
  1056   apply simp_all
  1057   apply (induct_tac xa rule: fset_induct_stronger)
  1057   apply (induct_tac xa rule: fset_induct_stronger)
  1058   apply simp_all
  1058   apply simp_all
  1059   done
  1059   done
  1060 
  1060 
  1061 
  1061 text {* Extensionality *}
       
  1062 
       
  1063 lemma fset_eqI:
       
  1064   assumes "\<And>x. x \<in> fset A \<longleftrightarrow> x \<in> fset B"
       
  1065   shows "A = B"
       
  1066 using assms proof (induct A arbitrary: B)
       
  1067   case empty then show ?case
       
  1068     by (auto simp add: in_fset none_in_empty_fset [symmetric] sym)
       
  1069 next
       
  1070   case (insert x A)
       
  1071   from insert.prems insert.hyps(1) have "\<And>z. z \<in> fset A \<longleftrightarrow> z \<in> fset (B - {|x|})"
       
  1072     by (auto simp add: in_fset)
       
  1073   then have "A = B - {|x|}" by (rule insert.hyps(2))
       
  1074   moreover with insert.prems [symmetric, of x] have "x |\<in>| B" by (simp add: in_fset)
       
  1075   ultimately show ?case by (metis in_fset_mdef)
       
  1076 qed
  1062 
  1077 
  1063 subsection {* alternate formulation with a different decomposition principle
  1078 subsection {* alternate formulation with a different decomposition principle
  1064   and a proof of equivalence *}
  1079   and a proof of equivalence *}
  1065 
  1080 
  1066 inductive
  1081 inductive