src/HOL/Library/Multiset_Permutations.thy
changeset 67399 eab6ce8368fa
parent 65366 10ca63a18e56
child 68406 6beb45f6cf67
equal deleted inserted replaced
67398:5eb932e604a2 67399:eab6ce8368fa
    83   unfolding permutations_of_multiset_def by simp
    83   unfolding permutations_of_multiset_def by simp
    84 
    84 
    85 lemma permutations_of_multiset_nonempty: 
    85 lemma permutations_of_multiset_nonempty: 
    86   assumes nonempty: "A \<noteq> {#}"
    86   assumes nonempty: "A \<noteq> {#}"
    87   shows   "permutations_of_multiset A = 
    87   shows   "permutations_of_multiset A = 
    88              (\<Union>x\<in>set_mset A. (op # x) ` permutations_of_multiset (A - {#x#}))" (is "_ = ?rhs")
    88              (\<Union>x\<in>set_mset A. ((#) x) ` permutations_of_multiset (A - {#x#}))" (is "_ = ?rhs")
    89 proof safe
    89 proof safe
    90   fix xs assume "xs \<in> permutations_of_multiset A"
    90   fix xs assume "xs \<in> permutations_of_multiset A"
    91   hence mset_xs: "mset xs = A" by (simp add: permutations_of_multiset_def)
    91   hence mset_xs: "mset xs = A" by (simp add: permutations_of_multiset_def)
    92   hence "xs \<noteq> []" by (auto simp: nonempty)
    92   hence "xs \<noteq> []" by (auto simp: nonempty)
    93   then obtain x xs' where xs: "xs = x # xs'" by (cases xs) simp_all
    93   then obtain x xs' where xs: "xs = x # xs'" by (cases xs) simp_all
   184 lemma card_permutations_of_multiset_aux:
   184 lemma card_permutations_of_multiset_aux:
   185   "card (permutations_of_multiset A) * (\<Prod>x\<in>set_mset A. fact (count A x)) = fact (size A)"
   185   "card (permutations_of_multiset A) * (\<Prod>x\<in>set_mset A. fact (count A x)) = fact (size A)"
   186 proof (induction A rule: multiset_remove_induct)
   186 proof (induction A rule: multiset_remove_induct)
   187   case (remove A)
   187   case (remove A)
   188   have "card (permutations_of_multiset A) = 
   188   have "card (permutations_of_multiset A) = 
   189           card (\<Union>x\<in>set_mset A. op # x ` permutations_of_multiset (A - {#x#}))"
   189           card (\<Union>x\<in>set_mset A. (#) x ` permutations_of_multiset (A - {#x#}))"
   190     by (simp add: permutations_of_multiset_nonempty remove.hyps)
   190     by (simp add: permutations_of_multiset_nonempty remove.hyps)
   191   also have "\<dots> = (\<Sum>x\<in>set_mset A. card (permutations_of_multiset (A - {#x#})))"
   191   also have "\<dots> = (\<Sum>x\<in>set_mset A. card (permutations_of_multiset (A - {#x#})))"
   192     by (subst card_UN_disjoint) (auto simp: card_image)
   192     by (subst card_UN_disjoint) (auto simp: card_image)
   193   also have "\<dots> * (\<Prod>x\<in>set_mset A. fact (count A x)) = 
   193   also have "\<dots> * (\<Prod>x\<in>set_mset A. fact (count A x)) = 
   194                (\<Sum>x\<in>set_mset A. card (permutations_of_multiset (A - {#x#})) * 
   194                (\<Sum>x\<in>set_mset A. card (permutations_of_multiset (A - {#x#})) * 
   351 
   351 
   352 declare length_remove1 [termination_simp] 
   352 declare length_remove1 [termination_simp] 
   353 
   353 
   354 fun permutations_of_list_impl where
   354 fun permutations_of_list_impl where
   355   "permutations_of_list_impl xs = (if xs = [] then [[]] else
   355   "permutations_of_list_impl xs = (if xs = [] then [[]] else
   356      List.bind (remdups xs) (\<lambda>x. map (op # x) (permutations_of_list_impl (remove1 x xs))))"
   356      List.bind (remdups xs) (\<lambda>x. map ((#) x) (permutations_of_list_impl (remove1 x xs))))"
   357 
   357 
   358 fun permutations_of_list_impl_aux where
   358 fun permutations_of_list_impl_aux where
   359   "permutations_of_list_impl_aux acc xs = (if xs = [] then [acc] else
   359   "permutations_of_list_impl_aux acc xs = (if xs = [] then [acc] else
   360      List.bind (remdups xs) (\<lambda>x. permutations_of_list_impl_aux (x#acc) (remove1 x xs)))"
   360      List.bind (remdups xs) (\<lambda>x. permutations_of_list_impl_aux (x#acc) (remove1 x xs)))"
   361 
   361 
   366   "permutations_of_list_impl [] = [[]]"
   366   "permutations_of_list_impl [] = [[]]"
   367   by (simp add: permutations_of_list_impl.simps)
   367   by (simp add: permutations_of_list_impl.simps)
   368 
   368 
   369 lemma permutations_of_list_impl_nonempty:
   369 lemma permutations_of_list_impl_nonempty:
   370   "xs \<noteq> [] \<Longrightarrow> permutations_of_list_impl xs = 
   370   "xs \<noteq> [] \<Longrightarrow> permutations_of_list_impl xs = 
   371      List.bind (remdups xs) (\<lambda>x. map (op # x) (permutations_of_list_impl (remove1 x xs)))"
   371      List.bind (remdups xs) (\<lambda>x. map ((#) x) (permutations_of_list_impl (remove1 x xs)))"
   372   by (subst permutations_of_list_impl.simps) simp_all
   372   by (subst permutations_of_list_impl.simps) simp_all
   373 
   373 
   374 lemma set_permutations_of_list_impl:
   374 lemma set_permutations_of_list_impl:
   375   "set (permutations_of_list_impl xs) = permutations_of_multiset (mset xs)"
   375   "set (permutations_of_list_impl xs) = permutations_of_multiset (mset xs)"
   376   by (induction xs rule: permutations_of_list_impl.induct)
   376   by (induction xs rule: permutations_of_list_impl.induct)