src/HOL/Finite_Set.thy
changeset 42875 d1aad0957eb2
parent 42873 da1253ff1764
child 43866 8a50dc70cbff
equal deleted inserted replaced
42874:f115492c7c8d 42875:d1aad0957eb2
   576     assume "x = a" with insertI show ?case by auto
   576     assume "x = a" with insertI show ?case by auto
   577   next
   577   next
   578     assume "x \<noteq> a"
   578     assume "x \<noteq> a"
   579     then obtain y' where y: "y = f a y'" and y': "fold_graph f z (A - {a}) y'"
   579     then obtain y' where y: "y = f a y'" and y': "fold_graph f z (A - {a}) y'"
   580       using insertI by auto
   580       using insertI by auto
   581     have 1: "f x y = f a (f x y')"
   581     have "f x y = f a (f x y')"
   582       unfolding y by (rule fun_left_comm)
   582       unfolding y by (rule fun_left_comm)
   583     have 2: "fold_graph f z (insert x A - {a}) (f x y')"
   583     moreover have "fold_graph f z (insert x A - {a}) (f x y')"
   584       using y' and `x \<noteq> a` and `x \<notin> A`
   584       using y' and `x \<noteq> a` and `x \<notin> A`
   585       by (simp add: insert_Diff_if fold_graph.insertI)
   585       by (simp add: insert_Diff_if fold_graph.insertI)
   586     from 1 2 show ?case by fast
   586     ultimately show ?case by fast
   587   qed
   587   qed
   588 qed simp
   588 qed simp
   589 
   589 
   590 lemma fold_graph_insertE:
   590 lemma fold_graph_insertE:
   591   assumes "fold_graph f z (insert x A) v" and "x \<notin> A"
   591   assumes "fold_graph f z (insert x A) v" and "x \<notin> A"
   624 by (unfold fold_def) blast
   624 by (unfold fold_def) blast
   625 
   625 
   626 text{* The various recursion equations for @{const fold}: *}
   626 text{* The various recursion equations for @{const fold}: *}
   627 
   627 
   628 lemma fold_insert [simp]:
   628 lemma fold_insert [simp]:
   629   "finite A ==> x \<notin> A ==> fold f z (insert x A) = f x (fold f z A)"
   629   assumes "finite A" and "x \<notin> A"
   630 apply (rule fold_equality)
   630   shows "fold f z (insert x A) = f x (fold f z A)"
   631 apply (erule fold_graph.insertI)
   631 proof (rule fold_equality)
   632 apply (erule fold_graph_fold)
   632   from `finite A` have "fold_graph f z A (fold f z A)" by (rule fold_graph_fold)
   633 done
   633   with `x \<notin> A`show "fold_graph f z (insert x A) (f x (fold f z A))" by (rule fold_graph.insertI)
       
   634 qed
   634 
   635 
   635 lemma fold_fun_comm:
   636 lemma fold_fun_comm:
   636   "finite A \<Longrightarrow> f x (fold f z A) = fold f (f x z) A"
   637   "finite A \<Longrightarrow> f x (fold f z A) = fold f (f x z) A"
   637 proof (induct rule: finite_induct)
   638 proof (induct rule: finite_induct)
   638   case empty then show ?case by simp
   639   case empty then show ?case by simp
   644 lemma fold_insert2:
   645 lemma fold_insert2:
   645   "finite A \<Longrightarrow> x \<notin> A \<Longrightarrow> fold f z (insert x A) = fold f (f x z) A"
   646   "finite A \<Longrightarrow> x \<notin> A \<Longrightarrow> fold f z (insert x A) = fold f (f x z) A"
   646 by (simp add: fold_fun_comm)
   647 by (simp add: fold_fun_comm)
   647 
   648 
   648 lemma fold_rec:
   649 lemma fold_rec:
   649 assumes "finite A" and "x \<in> A"
   650   assumes "finite A" and "x \<in> A"
   650 shows "fold f z A = f x (fold f z (A - {x}))"
   651   shows "fold f z A = f x (fold f z (A - {x}))"
   651 proof -
   652 proof -
   652   have A: "A = insert x (A - {x})" using `x \<in> A` by blast
   653   have A: "A = insert x (A - {x})" using `x \<in> A` by blast
   653   then have "fold f z A = fold f z (insert x (A - {x}))" by simp
   654   then have "fold f z A = fold f z (insert x (A - {x}))" by simp
   654   also have "\<dots> = f x (fold f z (A - {x}))"
   655   also have "\<dots> = f x (fold f z (A - {x}))"
   655     by (rule fold_insert) (simp add: `finite A`)+
   656     by (rule fold_insert) (simp add: `finite A`)+
   813 
   814 
   814 
   815 
   815 subsection {* The derived combinator @{text fold_image} *}
   816 subsection {* The derived combinator @{text fold_image} *}
   816 
   817 
   817 definition fold_image :: "('b \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a set \<Rightarrow> 'b"
   818 definition fold_image :: "('b \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> 'b \<Rightarrow> 'a set \<Rightarrow> 'b"
   818 where "fold_image f g = fold (%x y. f (g x) y)"
   819   where "fold_image f g = fold (\<lambda>x y. f (g x) y)"
   819 
   820 
   820 lemma fold_image_empty[simp]: "fold_image f g z {} = z"
   821 lemma fold_image_empty[simp]: "fold_image f g z {} = z"
   821 by(simp add:fold_image_def)
   822   by (simp add:fold_image_def)
   822 
   823 
   823 context ab_semigroup_mult
   824 context ab_semigroup_mult
   824 begin
   825 begin
   825 
   826 
   826 lemma fold_image_insert[simp]:
   827 lemma fold_image_insert[simp]:
   827 assumes "finite A" and "a \<notin> A"
   828   assumes "finite A" and "a \<notin> A"
   828 shows "fold_image times g z (insert a A) = g a * (fold_image times g z A)"
   829   shows "fold_image times g z (insert a A) = g a * (fold_image times g z A)"
   829 proof -
   830 proof -
   830   interpret I: comp_fun_commute "%x y. (g x) * y" proof
   831   interpret comp_fun_commute "%x y. (g x) * y" proof
   831   qed (simp add: fun_eq_iff mult_ac)
   832   qed (simp add: fun_eq_iff mult_ac)
   832   show ?thesis using assms by (simp add: fold_image_def)
   833   show ?thesis using assms by (simp add: fold_image_def)
   833 qed
   834 qed
   834 
   835 
   835 (*
       
   836 lemma fold_commute:
       
   837   "finite A ==> (!!z. x * (fold times g z A) = fold times g (x * z) A)"
       
   838   apply (induct set: finite)
       
   839    apply simp
       
   840   apply (simp add: mult_left_commute [of x])
       
   841   done
       
   842 
       
   843 lemma fold_nest_Un_Int:
       
   844   "finite A ==> finite B
       
   845     ==> fold times g (fold times g z B) A = fold times g (fold times g z (A Int B)) (A Un B)"
       
   846   apply (induct set: finite)
       
   847    apply simp
       
   848   apply (simp add: fold_commute Int_insert_left insert_absorb)
       
   849   done
       
   850 
       
   851 lemma fold_nest_Un_disjoint:
       
   852   "finite A ==> finite B ==> A Int B = {}
       
   853     ==> fold times g z (A Un B) = fold times g (fold times g z B) A"
       
   854   by (simp add: fold_nest_Un_Int)
       
   855 *)
       
   856 
       
   857 lemma fold_image_reindex:
   836 lemma fold_image_reindex:
   858 assumes fin: "finite A"
   837   assumes "finite A"
   859 shows "inj_on h A \<Longrightarrow> fold_image times g z (h`A) = fold_image times (g\<circ>h) z A"
   838   shows "inj_on h A \<Longrightarrow> fold_image times g z (h ` A) = fold_image times (g \<circ> h) z A"
   860 using fin by induct auto
   839   using assms by induct auto
   861 
       
   862 (*
       
   863 text{*
       
   864   Fusion theorem, as described in Graham Hutton's paper,
       
   865   A Tutorial on the Universality and Expressiveness of Fold,
       
   866   JFP 9:4 (355-372), 1999.
       
   867 *}
       
   868 
       
   869 lemma fold_fusion:
       
   870   assumes "ab_semigroup_mult g"
       
   871   assumes fin: "finite A"
       
   872     and hyp: "\<And>x y. h (g x y) = times x (h y)"
       
   873   shows "h (fold g j w A) = fold times j (h w) A"
       
   874 proof -
       
   875   class_interpret ab_semigroup_mult [g] by fact
       
   876   show ?thesis using fin hyp by (induct set: finite) simp_all
       
   877 qed
       
   878 *)
       
   879 
   840 
   880 lemma fold_image_cong:
   841 lemma fold_image_cong:
   881   "finite A \<Longrightarrow>
   842   assumes "finite A" and g_h: "\<And>x. x\<in>A \<Longrightarrow> g x = h x"
   882   (!!x. x:A ==> g x = h x) ==> fold_image times g z A = fold_image times h z A"
   843   shows "fold_image times g z A = fold_image times h z A"
   883 apply (subgoal_tac "ALL C. C <= A --> (ALL x:C. g x = h x) --> fold_image times g z C = fold_image times h z C")
   844 proof -
   884  apply simp
   845   from `finite A`
   885 apply (erule finite_induct, simp)
   846   have "\<And>C. C <= A --> (ALL x:C. g x = h x) --> fold_image times g z C = fold_image times h z C"
   886 apply (simp add: subset_insert_iff, clarify)
   847   proof (induct arbitrary: C)
   887 apply (subgoal_tac "finite C")
   848     case empty then show ?case by simp
   888  prefer 2 apply (blast dest: finite_subset [COMP swap_prems_rl])
   849   next
   889 apply (subgoal_tac "C = insert x (C - {x})")
   850     case (insert x F) then show ?case apply -
   890  prefer 2 apply blast
   851     apply (simp add: subset_insert_iff, clarify)
   891 apply (erule ssubst)
   852     apply (subgoal_tac "finite C")
   892 apply (drule spec)
   853       prefer 2 apply (blast dest: finite_subset [COMP swap_prems_rl])
   893 apply (erule (1) notE impE)
   854     apply (subgoal_tac "C = insert x (C - {x})")
   894 apply (simp add: Ball_def del: insert_Diff_single)
   855       prefer 2 apply blast
   895 done
   856     apply (erule ssubst)
       
   857     apply (simp add: Ball_def del: insert_Diff_single)
       
   858     done
       
   859   qed
       
   860   with g_h show ?thesis by simp
       
   861 qed
   896 
   862 
   897 end
   863 end
   898 
   864 
   899 context comm_monoid_mult
   865 context comm_monoid_mult
   900 begin
   866 begin