# HG changeset patch # User paulson # Date 1529618772 -3600 # Node ID f839ce4af873343accf5428d0a78d4aaf8c7d27b # Parent f090b313fdc891ed592a7a99c8dea4f91abb4e25# Parent f75a7d2be8c55a6ea508e8bb678a2c6a12b02945 merged diff -r f090b313fdc8 -r f839ce4af873 src/HOL/Algebra/Divisibility.thy --- a/src/HOL/Algebra/Divisibility.thy Thu Jun 21 12:39:52 2018 +0200 +++ b/src/HOL/Algebra/Divisibility.thy Thu Jun 21 23:06:12 2018 +0100 @@ -659,9 +659,7 @@ and aa': "a \ a'" "a \ carrier G" "a' \ carrier G" shows "irreducible G a'" using assms - apply (elim irreducibleE, intro irreducibleI) - apply simp_all - apply (metis assms(2) assms(3) assoc_unit_l) + apply (auto simp: irreducible_def assoc_unit_l) apply (metis aa' associated_sym properfactor_cong_r) done @@ -757,12 +755,11 @@ using assms by (blast elim: primeE) lemma (in monoid_cancel) prime_cong [trans]: - assumes pprime: "prime G p" + assumes "prime G p" and pp': "p \ p'" "p \ carrier G" "p' \ carrier G" shows "prime G p'" - using pprime - apply (elim primeE, intro primeI) - apply (metis assms(2) assms(3) assoc_unit_l) + using assms + apply (auto simp: prime_def assoc_unit_l) apply (metis pp' associated_sym divides_cong_l) done @@ -1015,14 +1012,13 @@ and ascarr: "set as \ carrier G" shows "foldr (\) as \ = foldr (\) bs \" using prm ascarr - apply (induct, simp, clarsimp simp add: m_ac, clarsimp) -proof clarsimp - fix xs ys zs - assume "xs <~~> ys" "set xs \ carrier G" - then have "set ys \ carrier G" by (rule perm_closed) - moreover assume "set ys \ carrier G \ foldr (\) ys \ = foldr (\) zs \" - ultimately show "foldr (\) ys \ = foldr (\) zs \" by simp -qed +proof induction + case (swap y x l) then show ?case + by (simp add: m_lcomm) +next + case (trans xs ys zs) then show ?case + using perm_closed by auto +qed auto lemma (in comm_monoid_cancel) multlist_ee_cong: assumes "essentially_equal G fs fs'" @@ -1673,23 +1669,17 @@ from surjE[OF surj_mset] obtain Cs' where Cs: "Cs = mset Cs'" by blast have "\cs. (\c \ set cs. P c) \ mset (map (assocs G) cs) = Cs" - using elems - unfolding Cs - apply (induct Cs', simp) - proof (clarsimp simp del: mset_map) - fix a Cs' cs - assume ih: "\X. X = a \ X \ set Cs' \ \x. P x \ X = assocs G x" - and csP: "\x\set cs. P x" - and mset: "mset (map (assocs G) cs) = mset Cs'" - from ih obtain c where cP: "P c" and a: "a = assocs G c" - by auto - from cP csP have tP: "\x\set (c#cs). P x" + using elems unfolding Cs + proof (induction Cs') + case (Cons a Cs') + then obtain c cs where csP: "\x\set cs. P x" and mset: "mset (map (assocs G) cs) = mset Cs'" + and cP: "P c" and a: "a = assocs G c" + by force + then have tP: "\x\set (c#cs). P x" by simp - from mset a have "mset (map (assocs G) (c#cs)) = add_mset a (mset Cs')" - by simp - with tP show "\cs. (\x\set cs. P x) \ mset (map (assocs G) cs) = add_mset a (mset Cs')" - by fast - qed + show ?case + using tP mset a by fastforce + qed auto then show ?thesis by (simp add: fmset_def) qed @@ -1851,15 +1841,11 @@ and "set as \ carrier G" and "set bs \ carrier G" shows "properfactor G a b" - apply (rule properfactorI) - apply (rule fmsubset_divides[of as bs], fact+) -proof - assume "b divides a" - then have "fmset G bs \# fmset G as" - by (rule divides_fmsubset) fact+ - with asubb have "fmset G as = fmset G bs" - by (rule subset_mset.antisym) - with anb show False .. +proof (rule properfactorI) + show "a divides b" + using assms asubb fmsubset_divides by blast + show "\ b divides a" + by (meson anb assms asubb factorial_monoid.divides_fmsubset factorial_monoid_axioms subset_mset.antisym) qed lemma (in factorial_monoid) properfactor_fmset: @@ -1879,8 +1865,7 @@ subsection \Irreducible Elements are Prime\ lemma (in factorial_monoid) irreducible_prime: - assumes pirr: "irreducible G p" - and pcarr: "p \ carrier G" + assumes pirr: "irreducible G p" and pcarr: "p \ carrier G" shows "prime G p" using pirr proof (elim irreducibleE, intro primeI) @@ -1892,32 +1877,19 @@ "\b. b \ carrier G \ properfactor G b p \ b \ Units G" from pdvdab obtain c where ccarr: "c \ carrier G" and abpc: "a \ b = p \ c" by (rule dividesE) - - from wfactors_exist [OF acarr] obtain as where ascarr: "set as \ carrier G" and afs: "wfactors G as a" - by blast - - from wfactors_exist [OF bcarr] + using wfactors_exist [OF acarr] by blast obtain bs where bscarr: "set bs \ carrier G" and bfs: "wfactors G bs b" - by auto - - from wfactors_exist [OF ccarr] + using wfactors_exist [OF bcarr] by blast obtain cs where cscarr: "set cs \ carrier G" and cfs: "wfactors G cs c" - by auto - + using wfactors_exist [OF ccarr] by blast note carr[simp] = pcarr acarr bcarr ccarr ascarr bscarr cscarr - - from afs and bfs have abfs: "wfactors G (as @ bs) (a \ b)" - by (rule wfactors_mult) fact+ - - from pirr cfs have pcfs: "wfactors G (p # cs) (p \ c)" - by (rule wfactors_mult_single) fact+ - with abpc have abfs': "wfactors G (p # cs) (a \ b)" - by simp - - from abfs' abfs have "essentially_equal G (p # cs) (as @ bs)" + from pirr cfs abpc have "wfactors G (p # cs) (a \ b)" + by (simp add: wfactors_mult_single) + moreover have "wfactors G (as @ bs) (a \ b)" + by (rule wfactors_mult [OF afs bfs]) fact+ + ultimately have "essentially_equal G (p # cs) (as @ bs)" by (rule wfactors_unique) simp+ - then obtain ds where "p # cs <~~> ds" and dsassoc: "ds [\] (as @ bs)" by (fast elim: essentially_equalE) then have "p \ set ds" @@ -1926,138 +1898,69 @@ unfolding list_all2_conv_all_nth set_conv_nth by force then consider "p' \ set as" | "p' \ set bs" by auto then show "p divides a \ p divides b" - proof cases - case 1 - with ascarr have [simp]: "p' \ carrier G" by fast - - note pp' - also from afs - have "p' divides a" by (rule wfactors_dividesI) fact+ - finally have "p divides a" by simp - then show ?thesis .. - next - case 2 - with bscarr have [simp]: "p' \ carrier G" by fast - - note pp' - also from bfs - have "p' divides b" by (rule wfactors_dividesI) fact+ - finally have "p divides b" by simp - then show ?thesis .. - qed + using afs bfs divides_cong_l pp' wfactors_dividesI + by (meson acarr ascarr bcarr bscarr pcarr) qed \ \A version using @{const factors}, more complicated\ lemma (in factorial_monoid) factors_irreducible_prime: - assumes pirr: "irreducible G p" - and pcarr: "p \ carrier G" + assumes pirr: "irreducible G p" and pcarr: "p \ carrier G" shows "prime G p" - using pirr - apply (elim irreducibleE, intro primeI) - apply assumption -proof - - fix a b - assume acarr: "a \ carrier G" - and bcarr: "b \ carrier G" - and pdvdab: "p divides (a \ b)" - assume irreduc[rule_format]: "\b. b \ carrier G \ properfactor G b p \ b \ Units G" - from pdvdab obtain c where ccarr: "c \ carrier G" and abpc: "a \ b = p \ c" - by (rule dividesE) - note [simp] = pcarr acarr bcarr ccarr - - show "p divides a \ p divides b" - proof (cases "a \ Units G") - case aunit: True - - note pdvdab - also have "a \ b = b \ a" by (simp add: m_comm) - also from aunit have bab: "b \ a \ b" - by (intro associatedI2[of "a"], simp+) - finally have "p divides b" by simp - then show ?thesis .. - next - case anunit: False - show ?thesis - proof (cases "b \ Units G") - case bunit: True - note pdvdab - also from bunit - have baa: "a \ b \ a" - by (intro associatedI2[of "b"], simp+) - finally have "p divides a" by simp +proof (rule primeI) + show "p \ Units G" + by (meson irreducibleE pirr) + have irreduc: "\b. \b \ carrier G; properfactor G b p\ \ b \ Units G" + using pirr by (auto simp: irreducible_def) + show "p divides a \ p divides b" + if acarr: "a \ carrier G" and bcarr: "b \ carrier G" and pdvdab: "p divides (a \ b)" for a b + proof - + from pdvdab obtain c where ccarr: "c \ carrier G" and abpc: "a \ b = p \ c" + by (rule dividesE) + note [simp] = pcarr acarr bcarr ccarr + + show "p divides a \ p divides b" + proof (cases "a \ Units G") + case True + then have "p divides b" + by (metis acarr associatedI2' associated_def bcarr divides_trans m_comm pcarr pdvdab) then show ?thesis .. next - case bnunit: False - have cnunit: "c \ Units G" - proof - assume cunit: "c \ Units G" - from bnunit have "properfactor G a (a \ b)" - by (intro properfactorI3[of _ _ b], simp+) - also note abpc - also from cunit have "p \ c \ p" - by (intro associatedI2[of c], simp+) - finally have "properfactor G a p" by simp - with acarr have "a \ Units G" by (fast intro: irreduc) - with anunit show False .. - qed - - have abnunit: "a \ b \ Units G" - proof clarsimp - assume "a \ b \ Units G" - then have "a \ Units G" by (rule unit_factor) fact+ - with anunit show False .. - qed - - from factors_exist [OF acarr anunit] - obtain as where ascarr: "set as \ carrier G" and afac: "factors G as a" - by blast - - from factors_exist [OF bcarr bnunit] - obtain bs where bscarr: "set bs \ carrier G" and bfac: "factors G bs b" - by blast - - from factors_exist [OF ccarr cnunit] - obtain cs where cscarr: "set cs \ carrier G" and cfac: "factors G cs c" - by auto - - note [simp] = ascarr bscarr cscarr - - from afac and bfac have abfac: "factors G (as @ bs) (a \ b)" - by (rule factors_mult) fact+ - - from pirr cfac have pcfac: "factors G (p # cs) (p \ c)" - by (rule factors_mult_single) fact+ - with abpc have abfac': "factors G (p # cs) (a \ b)" - by simp - - from abfac' abfac have "essentially_equal G (p # cs) (as @ bs)" - by (rule factors_unique) (fact | simp)+ - then obtain ds where "p # cs <~~> ds" and dsassoc: "ds [\] (as @ bs)" - by (fast elim: essentially_equalE) - then have "p \ set ds" - by (simp add: perm_set_eq[symmetric]) - with dsassoc obtain p' where "p' \ set (as@bs)" and pp': "p \ p'" - unfolding list_all2_conv_all_nth set_conv_nth by force - then consider "p' \ set as" | "p' \ set bs" by auto - then show "p divides a \ p divides b" - proof cases - case 1 - with ascarr have [simp]: "p' \ carrier G" by fast - - note pp' - also from afac 1 have "p' divides a" by (rule factors_dividesI) fact+ - finally have "p divides a" by simp + case anunit: False + show ?thesis + proof (cases "b \ Units G") + case True + then have "p divides a" + by (meson acarr bcarr divides_unit irreducible_prime pcarr pdvdab pirr prime_def) then show ?thesis .. next - case 2 - with bscarr have [simp]: "p' \ carrier G" by fast - - note pp' - also from bfac - have "p' divides b" by (rule factors_dividesI) fact+ - finally have "p divides b" by simp - then show ?thesis .. + case bnunit: False + then have cnunit: "c \ Units G" + by (metis abpc acarr anunit bcarr ccarr irreducible_prodE irreducible_prod_rI pcarr pirr) + then have abnunit: "a \ b \ Units G" + using acarr anunit bcarr unit_factor by blast + obtain as where ascarr: "set as \ carrier G" and afac: "factors G as a" + using factors_exist [OF acarr anunit] by blast + obtain bs where bscarr: "set bs \ carrier G" and bfac: "factors G bs b" + using factors_exist [OF bcarr bnunit] by blast + obtain cs where cscarr: "set cs \ carrier G" and cfac: "factors G cs c" + using factors_exist [OF ccarr cnunit] by auto + note [simp] = ascarr bscarr cscarr + from pirr cfac abpc have abfac': "factors G (p # cs) (a \ b)" + by (simp add: factors_mult_single) + from afac and bfac have "factors G (as @ bs) (a \ b)" + by (rule factors_mult) fact+ + with abfac' have "essentially_equal G (p # cs) (as @ bs)" + using abnunit factors_unique by auto + then obtain ds where "p # cs <~~> ds" and dsassoc: "ds [\] (as @ bs)" + by (fast elim: essentially_equalE) + then have "p \ set ds" + by (simp add: perm_set_eq[symmetric]) + with dsassoc obtain p' where "p' \ set (as@bs)" and pp': "p \ p'" + unfolding list_all2_conv_all_nth set_conv_nth by force + then consider "p' \ set as" | "p' \ set bs" by auto + then show "p divides a \ p divides b" + by (meson afac bfac divides_cong_l factors_dividesI pp' ascarr bscarr pcarr) qed qed qed @@ -2597,73 +2500,47 @@ qed lemma (in gcd_condition_monoid) primeness_condition: "primeness_condition_monoid G" - apply unfold_locales - apply (rule primeI) - apply (elim irreducibleE, assumption) proof - - fix p a b - assume pcarr: "p \ carrier G" and acarr: "a \ carrier G" and bcarr: "b \ carrier G" - and pirr: "irreducible G p" - and pdvdab: "p divides a \ b" - from pirr have pnunit: "p \ Units G" - and r[rule_format]: "\b. b \ carrier G \ properfactor G b p \ b \ Units G" - by (fast elim: irreducibleE)+ - - show "p divides a \ p divides b" - proof (rule ccontr, clarsimp) - assume npdvda: "\ p divides a" - with pcarr acarr have "\ \ somegcd G p a" - apply (intro gcdI, simp, simp, simp) - apply (fast intro: unit_divides) - apply (fast intro: unit_divides) - apply (clarsimp simp add: Unit_eq_dividesone[symmetric]) - apply (rule r, rule, assumption) - apply (rule properfactorI, assumption) - proof - fix y - assume ycarr: "y \ carrier G" - assume "p divides y" - also assume "y divides a" - finally have "p divides a" - by (simp add: pcarr ycarr acarr) - with npdvda show False .. - qed simp_all - with pcarr acarr have pa: "somegcd G p a \ \" - by (fast intro: associated_sym[of "\"] gcd_closed) - - assume npdvdb: "\ p divides b" - with pcarr bcarr have "\ \ somegcd G p b" - apply (intro gcdI, simp, simp, simp) - apply (fast intro: unit_divides) - apply (fast intro: unit_divides) - apply (clarsimp simp add: Unit_eq_dividesone[symmetric]) - apply (rule r, rule, assumption) - apply (rule properfactorI, assumption) - proof - fix y - assume ycarr: "y \ carrier G" - assume "p divides y" - also assume "y divides b" - finally have "p divides b" by (simp add: pcarr ycarr bcarr) - with npdvdb - show "False" .. - qed simp_all - with pcarr bcarr have pb: "somegcd G p b \ \" - by (fast intro: associated_sym[of "\"] gcd_closed) - - from pcarr acarr bcarr pdvdab have "p gcdof p (a \ b)" - by (fast intro: isgcd_divides_l) - with pcarr acarr bcarr have "p \ somegcd G p (a \ b)" - by (fast intro: gcdI2) - also from pa pb pcarr acarr bcarr have "somegcd G p (a \ b) \ \" - by (rule relprime_mult) - finally have "p \ \" - by (simp add: pcarr acarr bcarr) - with pcarr have "p \ Units G" - by (fast intro: assoc_unit_l) - with pnunit show False .. + have *: "p divides a \ p divides b" + if pcarr[simp]: "p \ carrier G" and acarr[simp]: "a \ carrier G" and bcarr[simp]: "b \ carrier G" + and pirr: "irreducible G p" and pdvdab: "p divides a \ b" + for p a b + proof - + from pirr have pnunit: "p \ Units G" + and r: "\b. \b \ carrier G; properfactor G b p\ \ b \ Units G" + by (fast elim: irreducibleE)+ + show "p divides a \ p divides b" + proof (rule ccontr, clarsimp) + assume npdvda: "\ p divides a" and npdvdb: "\ p divides b" + have "\ \ somegcd G p a" + proof (intro gcdI unit_divides) + show "\y. \y \ carrier G; y divides p; y divides a\ \ y \ Units G" + by (meson divides_trans npdvda pcarr properfactorI r) + qed auto + with pcarr acarr have pa: "somegcd G p a \ \" + by (fast intro: associated_sym[of "\"] gcd_closed) + have "\ \ somegcd G p b" + proof (intro gcdI unit_divides) + show "\y. \y \ carrier G; y divides p; y divides b\ \ y \ Units G" + by (meson divides_trans npdvdb pcarr properfactorI r) + qed auto + with pcarr bcarr have pb: "somegcd G p b \ \" + by (fast intro: associated_sym[of "\"] gcd_closed) + have "p \ somegcd G p (a \ b)" + using pdvdab by (simp add: gcdI2 isgcd_divides_l) + also from pa pb pcarr acarr bcarr have "somegcd G p (a \ b) \ \" + by (rule relprime_mult) + finally have "p \ \" + by simp + with pcarr have "p \ Units G" + by (fast intro: assoc_unit_l) + with pnunit show False .. + qed qed -qed + show ?thesis + by unfold_locales (metis * primeI irreducibleE) +qed + sublocale gcd_condition_monoid \ primeness_condition_monoid by (rule primeness_condition) @@ -2675,63 +2552,45 @@ assumes acarr: "a \ carrier G" shows "\as. set as \ carrier G \ wfactors G as a" proof - - have r[rule_format]: "a \ carrier G \ (\as. set as \ carrier G \ wfactors G as a)" - proof (rule wf_induct[OF division_wellfounded]) - fix x - assume ih: "\y. (y, x) \ {(x, y). x \ carrier G \ y \ carrier G \ properfactor G x y} - \ y \ carrier G \ (\as. set as \ carrier G \ wfactors G as y)" - - show "x \ carrier G \ (\as. set as \ carrier G \ wfactors G as x)" - apply clarify - apply (cases "x \ Units G") - apply (rule exI[of _ "[]"], simp) - apply (cases "irreducible G x") - apply (rule exI[of _ "[x]"], simp add: wfactors_def) - proof - - assume xcarr: "x \ carrier G" - and xnunit: "x \ Units G" - and xnirr: "\ irreducible G x" - then have "\y. y \ carrier G \ properfactor G y x \ y \ Units G" - apply - - apply (rule ccontr) - apply simp - apply (subgoal_tac "irreducible G x", simp) - apply (rule irreducibleI, simp, simp) - done - then obtain y where ycarr: "y \ carrier G" and ynunit: "y \ Units G" - and pfyx: "properfactor G y x" - by blast - - have ih': "\y. \y \ carrier G; properfactor G y x\ - \ \as. set as \ carrier G \ wfactors G as y" - by (rule ih[rule_format, simplified]) (simp add: xcarr)+ - - from ih' [OF ycarr pfyx] - obtain ys where yscarr: "set ys \ carrier G" and yfs: "wfactors G ys y" - by blast - - from pfyx have "y divides x" and nyx: "\ y \ x" - by (fast elim: properfactorE2)+ - then obtain z where zcarr: "z \ carrier G" and x: "x = y \ z" - by blast - - from zcarr ycarr have "properfactor G z x" - apply (subst x) - apply (intro properfactorI3[of _ _ y]) - apply (simp add: m_comm) - apply (simp add: ynunit)+ - done - from ih' [OF zcarr this] - obtain zs where zscarr: "set zs \ carrier G" and zfs: "wfactors G zs z" - by blast - from yscarr zscarr have xscarr: "set (ys@zs) \ carrier G" - by simp - from yfs zfs ycarr zcarr yscarr zscarr have "wfactors G (ys@zs) (y\z)" - by (rule wfactors_mult) - then have "wfactors G (ys@zs) x" - by (simp add: x) - with xscarr show "\xs. set xs \ carrier G \ wfactors G xs x" - by fast + have r: "a \ carrier G \ (\as. set as \ carrier G \ wfactors G as a)" + using division_wellfounded + proof (induction rule: wf_induct_rule) + case (less x) + then have xcarr: "x \ carrier G" + by auto + show ?case + proof (cases "x \ Units G") + case True + then show ?thesis + by (metis bot.extremum list.set(1) unit_wfactors) + next + case xnunit: False + show ?thesis + proof (cases "irreducible G x") + case True + then show ?thesis + by (rule_tac x="[x]" in exI) (simp add: wfactors_def xcarr) + next + case False + then obtain y where ycarr: "y \ carrier G" and ynunit: "y \ Units G" and pfyx: "properfactor G y x" + by (meson irreducible_def xnunit) + obtain ys where yscarr: "set ys \ carrier G" and yfs: "wfactors G ys y" + using less ycarr pfyx by blast + then obtain z where zcarr: "z \ carrier G" and x: "x = y \ z" + by (meson dividesE pfyx properfactorE2) + from zcarr ycarr have "properfactor G z x" + using m_comm properfactorI3 x ynunit by blast + with less zcarr obtain zs where zscarr: "set zs \ carrier G" and zfs: "wfactors G zs z" + by blast + from yscarr zscarr have xscarr: "set (ys@zs) \ carrier G" + by simp + have "wfactors G (ys@zs) (y\z)" + using xscarr ycarr yfs zcarr zfs by auto + then have "wfactors G (ys@zs) x" + by (simp add: x) + with xscarr show "\xs. set xs \ carrier G \ wfactors G xs x" + by fast + qed qed qed from acarr show ?thesis by (rule r) @@ -2741,64 +2600,33 @@ subsubsection \Primeness condition\ lemma (in comm_monoid_cancel) multlist_prime_pos: - assumes carr: "a \ carrier G" "set as \ carrier G" - and aprime: "prime G a" - and "a divides (foldr (\) as \)" - shows "\i carrier G \ a divides (foldr (\) as \) - \ (\i. i < length as \ a divides (as!i))" - apply (induct as) - apply clarsimp defer 1 - apply clarsimp defer 1 - proof - - assume "a divides \" - with carr have "a \ Units G" - by (fast intro: divides_unit[of a \]) - with aprime show False - by (elim primeE, simp) - next - fix aa as - assume ih[rule_format]: "a divides foldr (\) as \ \ (\i carrier G" "set as \ carrier G" - and "a divides aa \ foldr (\) as \" - with carr aprime have "a divides aa \ a divides foldr (\) as \" - by (intro prime_divides) simp+ - then show "\i) as \" - from ih [OF this] obtain i where "a divides as ! i" and len: "i < length as" by auto - then have p1: "a divides (aa#as) ! (Suc i)" by simp - from len have "Suc i < Suc (length as)" by simp - with p1 show ?thesis by force - qed - qed - from assms show ?thesis - by (intro r) auto + assumes aprime: "prime G a" and carr: "a \ carrier G" + and as: "set as \ carrier G" "a divides (foldr (\) as \)" + shows "\i carrier G" "set as \ carrier G" and "a divides x \ foldr (\) as \" + by (auto simp: ) + with carr aprime have "a divides x \ a divides foldr (\) as \" + by (intro prime_divides) simp+ + then show ?case + using Cons.IH Cons.prems(1) by force qed + lemma (in primeness_condition_monoid) wfactors_unique__hlp_induct: "\a as'. a \ carrier G \ set as \ carrier G \ set as' \ carrier G \ wfactors G as a \ wfactors G as' a \ essentially_equal G as as'" proof (induct as) case Nil show ?case - proof auto - fix a as' - assume a: "a \ carrier G" - assume "wfactors G [] a" - then obtain "\ \ a" by (auto elim: wfactorsE) - with a have "a \ Units G" by (auto intro: assoc_unit_r) - moreover assume "wfactors G as' a" - moreover assume "set as' \ carrier G" - ultimately have "as' = []" by (rule unit_wfactors_empty) - then show "essentially_equal G [] as'" by simp - qed + apply (clarsimp simp: wfactors_def) + by (metis Units_one_closed assoc_unit_r list_update_nonempty unit_wfactors_empty unitfactor_ee wfactorsI) next case (Cons ah as) then show ?case