equal
deleted
inserted
replaced
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) |