--- a/NEWS Wed Nov 13 15:00:17 2024 +0000
+++ b/NEWS Wed Nov 13 20:14:24 2024 +0100
@@ -127,6 +127,21 @@
formal markup by the prover. Repeated invocation of this action extends
the selection incrementally.
+* The Output dockable (and its variants used elsewhere) has been
+improved as follows:
+
+ - Its vertical scroll position is maintained more carefully, when
+ messages are printed incrementally.
+
+ - Performance of printing messages repeatedly has improved slightly,
+ with less load on the GUI thread.
+
+ - Highlighting works via mouse hovering alone, without requiring
+ C-modifier. Double click selects that area.
+
+* An active highlight area in the input buffer or output panel may be
+selected via double-click.
+
* The "Documentation" panel supports plain text files again, notably
"jedit-changes". This was broken in Isabelle2022, Isabelle2023,
Isabelle2024.
--- a/etc/build.props Wed Nov 13 15:00:17 2024 +0000
+++ b/etc/build.props Wed Nov 13 20:14:24 2024 +0100
@@ -82,6 +82,7 @@
src/Pure/GUI/gui.scala \
src/Pure/GUI/gui_thread.scala \
src/Pure/GUI/popup.scala \
+ src/Pure/GUI/rich_text.scala \
src/Pure/GUI/tree_view.scala \
src/Pure/GUI/wrap_panel.scala \
src/Pure/General/antiquote.scala \
--- a/src/HOL/Algebra/Chinese_Remainder.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/Chinese_Remainder.thy Wed Nov 13 20:14:24 2024 +0100
@@ -231,11 +231,13 @@
shows "(canonical_proj I J) ` carrier R = carrier (RDirProd (R Quot I) (R Quot J))"
unfolding RDirProd_def DirProd_def FactRing_def A_RCOSETS_def'
proof (auto simp add: monoid.defs)
- { fix I i assume "ideal I R" "i \<in> I" hence "I +> i = \<zero>\<^bsub>R Quot I\<^esub>"
- using a_rcos_zero by (simp add: FactRing_def)
- } note aux_lemma1 = this
+ have aux_lemma1: "I +> i = \<zero>\<^bsub>R Quot I\<^esub>" if "ideal I R" "i \<in> I" for I i
+ using that a_rcos_zero by (simp add: FactRing_def)
- { fix I i j assume A: "ideal I R" "i \<in> I" "j \<in> carrier R" "i \<oplus> j = \<one>"
+ have aux_lemma2: "I +> j = \<one>\<^bsub>R Quot I\<^esub>"
+ if A: "ideal I R" "i \<in> I" "j \<in> carrier R" "i \<oplus> j = \<one>"
+ for I i j
+ proof -
have "(I +> i) \<oplus>\<^bsub>R Quot I\<^esub> (I +> j) = I +> \<one>"
using ring_hom_memE(3)[OF ideal.rcos_ring_hom ideal.Icarr[OF _ A(2)] A(3)] A(1,4) by simp
moreover have "I +> i = I"
@@ -243,9 +245,9 @@
by (simp add: A(1-2) abelian_subgroup.a_rcos_const)
moreover have "I +> j \<in> carrier (R Quot I)" and "I = \<zero>\<^bsub>R Quot I\<^esub>" and "I +> \<one> = \<one>\<^bsub>R Quot I\<^esub>"
by (auto simp add: FactRing_def A_RCOSETS_def' A(3))
- ultimately have "I +> j = \<one>\<^bsub>R Quot I\<^esub>"
+ ultimately show ?thesis
using ring.ring_simprules(8)[OF ideal.quotient_is_ring[OF A(1)]] by simp
- } note aux_lemma2 = this
+ qed
interpret I: ring "R Quot I" + J: ring "R Quot J"
using assms(1-2)[THEN ideal.quotient_is_ring] by auto
@@ -418,33 +420,33 @@
case 0 show ?case
by (auto simp add: RDirProd_list_carrier FactRing_def A_RCOSETS_def')
next
- { fix S :: "'c ring" and T :: "'d ring" and f g
- assume A: "ring T" "f \<in> ring_hom R S" "g \<in> ring_hom R T" "f ` carrier R \<subseteq> f ` (a_kernel R T g)"
- have "(\<lambda>a. (f a, g a)) ` carrier R = (f ` carrier R) \<times> (g ` carrier R)"
+ have aux_lemma: "(\<lambda>a. (f a, g a)) ` carrier R = (f ` carrier R) \<times> (g ` carrier R)"
+ if A: "ring T" "f \<in> ring_hom R S" "g \<in> ring_hom R T" "f ` carrier R \<subseteq> f ` (a_kernel R T g)"
+ for S :: "'c ring" and T :: "'d ring" and f g
+ proof
+ show "(\<lambda>a. (f a, g a)) ` carrier R \<subseteq> (f ` carrier R) \<times> (g ` carrier R)"
+ by blast
+ next
+ show "(f ` carrier R) \<times> (g ` carrier R) \<subseteq> (\<lambda>a. (f a, g a)) ` carrier R"
proof
- show "(\<lambda>a. (f a, g a)) ` carrier R \<subseteq> (f ` carrier R) \<times> (g ` carrier R)"
+ fix t assume "t \<in> (f ` carrier R) \<times> (g ` carrier R)"
+ then obtain a b where a: "a \<in> carrier R" "f a = fst t" and b: "b \<in> carrier R" "g b = snd t"
+ by auto
+ obtain c where c: "c \<in> a_kernel R T g" "f c = f (a \<ominus> b)"
+ using A(4) minus_closed[OF a(1) b (1)] by auto
+ have "f (c \<oplus> b) = f (a \<ominus> b) \<oplus>\<^bsub>S\<^esub> f b"
+ using ring_hom_memE(3)[OF A(2)] b c unfolding a_kernel_def' by auto
+ hence "f (c \<oplus> b) = f a"
+ using ring_hom_memE(3)[OF A(2) minus_closed[of a b], of b] a b by algebra
+ moreover have "g (c \<oplus> b) = g b"
+ using ring_hom_memE(1,3)[OF A(3)] b(1) c ring.ring_simprules(8)[OF A(1)]
+ unfolding a_kernel_def' by auto
+ ultimately have "(\<lambda>a. (f a, g a)) (c \<oplus> b) = t" and "c \<oplus> b \<in> carrier R"
+ using a b c unfolding a_kernel_def' by auto
+ thus "t \<in> (\<lambda>a. (f a, g a)) ` carrier R"
by blast
- next
- show "(f ` carrier R) \<times> (g ` carrier R) \<subseteq> (\<lambda>a. (f a, g a)) ` carrier R"
- proof
- fix t assume "t \<in> (f ` carrier R) \<times> (g ` carrier R)"
- then obtain a b where a: "a \<in> carrier R" "f a = fst t" and b: "b \<in> carrier R" "g b = snd t"
- by auto
- obtain c where c: "c \<in> a_kernel R T g" "f c = f (a \<ominus> b)"
- using A(4) minus_closed[OF a(1) b (1)] by auto
- have "f (c \<oplus> b) = f (a \<ominus> b) \<oplus>\<^bsub>S\<^esub> f b"
- using ring_hom_memE(3)[OF A(2)] b c unfolding a_kernel_def' by auto
- hence "f (c \<oplus> b) = f a"
- using ring_hom_memE(3)[OF A(2) minus_closed[of a b], of b] a b by algebra
- moreover have "g (c \<oplus> b) = g b"
- using ring_hom_memE(1,3)[OF A(3)] b(1) c ring.ring_simprules(8)[OF A(1)]
- unfolding a_kernel_def' by auto
- ultimately have "(\<lambda>a. (f a, g a)) (c \<oplus> b) = t" and "c \<oplus> b \<in> carrier R"
- using a b c unfolding a_kernel_def' by auto
- thus "t \<in> (\<lambda>a. (f a, g a)) ` carrier R"
- by blast
- qed
- qed } note aux_lemma = this
+ qed
+ qed
let ?map_Quot = "\<lambda>I n. map (\<lambda>i. R Quot (I i)) [0..< Suc n]"
let ?DirProd = "\<lambda>I n. RDirProd_list (?map_Quot I n)"
--- a/src/HOL/Algebra/Coset.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/Coset.thy Wed Nov 13 20:14:24 2024 +0100
@@ -1914,9 +1914,10 @@
interpret Anormal: normal A "(G Mod H)" using assms by simp
show "{x \<in> carrier G. H #> x \<in> A} #> x = x <# {x \<in> carrier G. H #> x \<in> A}" if x: "x \<in> carrier G" for x
proof -
- { fix y
- assume y: "y \<in> {x \<in> carrier G. H #> x \<in> A} #> x"
- then obtain x' where x': "x' \<in> carrier G" "H #> x' \<in> A" "y = x' \<otimes> x"
+ have "y \<in> x <# {x \<in> carrier G. H #> x \<in> A}"
+ if y: "y \<in> {x \<in> carrier G. H #> x \<in> A} #> x" for y
+ proof -
+ from that obtain x' where x': "x' \<in> carrier G" "H #> x' \<in> A" "y = x' \<otimes> x"
unfolding r_coset_def by auto
from x(1) have Hx: "H #> x \<in> carrier (G Mod H)"
unfolding FactGroup_def RCOSETS_def by force
@@ -1937,11 +1938,12 @@
also have "\<dots> = y"
by (simp add: x x')
finally have "x \<otimes> (inv x \<otimes> x' \<otimes> x) = y" .
- with xcoset have "y \<in> x <# {x \<in> carrier G. H #> x \<in> A}" by auto}
- moreover
- { fix y
- assume y: "y \<in> x <# {x \<in> carrier G. H #> x \<in> A}"
- then obtain x' where x': "x' \<in> carrier G" "H #> x' \<in> A" "y = x \<otimes> x'" unfolding l_coset_def by auto
+ with xcoset show ?thesis by auto
+ qed
+ moreover have "y \<in> {x \<in> carrier G. H #> x \<in> A} #> x"
+ if y: "y \<in> x <# {x \<in> carrier G. H #> x \<in> A}" for y
+ proof -
+ from that obtain x' where x': "x' \<in> carrier G" "H #> x' \<in> A" "y = x \<otimes> x'" unfolding l_coset_def by auto
from x(1) have invx: "inv x \<in> carrier G"
by (rule inv_closed)
hence Hinvx: "H #> (inv x) \<in> carrier (G Mod H)"
@@ -1960,7 +1962,8 @@
also have "\<dots> = y"
by (simp add: x x')
finally have "x \<otimes> x' \<otimes> inv x \<otimes> x = y".
- with xcoset have "y \<in> {x \<in> carrier G. H #> x \<in> A} #> x" by auto }
+ with xcoset show ?thesis by auto
+ qed
ultimately show ?thesis
by auto
qed
--- a/src/HOL/Algebra/Embedded_Algebras.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/Embedded_Algebras.thy Wed Nov 13 20:14:24 2024 +0100
@@ -1123,14 +1123,14 @@
assumes "dimension n K E" and "dimension m K E"
shows "n = m"
proof -
- { fix n m assume n: "dimension n K E" and m: "dimension m K E"
- then obtain Vs
+ have aux_lemma: "n \<le> m" if n: "dimension n K E" and m: "dimension m K E" for n m
+ proof -
+ from that obtain Vs
where Vs: "set Vs \<subseteq> carrier R" "independent K Vs" "length Vs = n" "Span K Vs = E"
using exists_base by meson
- hence "n \<le> m"
+ then show ?thesis
using independent_length_le_dimension[OF m Vs(2)] Span_base_incl[OF Vs(1)] by auto
- } note aux_lemma = this
-
+ qed
show ?thesis
using aux_lemma[OF assms] aux_lemma[OF assms(2,1)] by simp
qed
@@ -1166,28 +1166,28 @@
assumes "dimension n K E" and "independent K Us" "set Us \<subseteq> E"
shows "\<exists>Vs. length (Vs @ Us) = n \<and> independent K (Vs @ Us) \<and> Span K (Vs @ Us) = E"
proof -
- { fix Us k assume "k \<le> n" "independent K Us" "set Us \<subseteq> E" "length Us = k"
- hence "\<exists>Vs. length (Vs @ Us) = n \<and> independent K (Vs @ Us) \<and> Span K (Vs @ Us) = E"
- proof (induct arbitrary: Us rule: inc_induct)
- case base thus ?case
- using independent_length_eq_dimension[OF assms(1) base(1-2)] by auto
- next
- case (step m)
- have "Span K Us \<subseteq> E"
- using mono_Span_subset step(4-6) exists_base[OF assms(1)] by blast
- hence "Span K Us \<subset> E"
- using independent_length_eq_dimension[OF assms(1) step(4-5)] step(2,6) assms(1) by blast
- then obtain v where v: "v \<in> E" "v \<notin> Span K Us"
- using Span_strict_incl exists_base[OF assms(1)] by blast
- hence "independent K (v # Us)"
- using space_subgroup_props(1)[OF assms(1)] li_Cons[OF _ v(2) step(4)] by auto
- then obtain Vs
- where "length (Vs @ (v # Us)) = n" "independent K (Vs @ (v # Us))" "Span K (Vs @ (v # Us)) = E"
- using step(3)[of "v # Us"] step(1-2,4-6) v by auto
- thus ?case
- by (metis append.assoc append_Cons append_Nil)
- qed } note aux_lemma = this
-
+ have aux_lemma: "\<exists>Vs. length (Vs @ Us) = n \<and> independent K (Vs @ Us) \<and> Span K (Vs @ Us) = E"
+ if "k \<le> n" "independent K Us" "set Us \<subseteq> E" "length Us = k" for Us k
+ using that
+ proof (induct arbitrary: Us rule: inc_induct)
+ case base
+ thus ?case using independent_length_eq_dimension[OF assms(1) base(1-2)] by auto
+ next
+ case (step m)
+ have "Span K Us \<subseteq> E"
+ using mono_Span_subset step(4-6) exists_base[OF assms(1)] by blast
+ hence "Span K Us \<subset> E"
+ using independent_length_eq_dimension[OF assms(1) step(4-5)] step(2,6) assms(1) by blast
+ then obtain v where v: "v \<in> E" "v \<notin> Span K Us"
+ using Span_strict_incl exists_base[OF assms(1)] by blast
+ hence "independent K (v # Us)"
+ using space_subgroup_props(1)[OF assms(1)] li_Cons[OF _ v(2) step(4)] by auto
+ then obtain Vs
+ where "length (Vs @ (v # Us)) = n" "independent K (Vs @ (v # Us))" "Span K (Vs @ (v # Us)) = E"
+ using step(3)[of "v # Us"] step(1-2,4-6) v by auto
+ thus ?case
+ by (metis append.assoc append_Cons append_Nil)
+ qed
have "length Us \<le> n"
using independent_length_le_dimension[OF assms] .
thus ?thesis
--- a/src/HOL/Algebra/Exact_Sequence.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/Exact_Sequence.thy Wed Nov 13 20:14:24 2024 +0100
@@ -38,24 +38,23 @@
assumes "exact_seq (G, F)" and "(i :: nat) < length F"
shows "exact_seq (drop i G, drop i F)"
proof-
- { fix t i assume "exact_seq t" "i < length (snd t)"
- hence "exact_seq (drop i (fst t), drop i (snd t))"
- proof (induction arbitrary: i)
- case (unity G1 G2 f) thus ?case
- by (simp add: exact_seq.unity)
+ have "exact_seq (drop i (fst t), drop i (snd t))" if "exact_seq t" "i < length (snd t)" for t i
+ using that
+ proof (induction arbitrary: i)
+ case (unity G1 G2 f) thus ?case
+ by (simp add: exact_seq.unity)
+ next
+ case (extension G K l g q H h) show ?case
+ proof (cases)
+ assume "i = 0" thus ?case
+ using exact_seq.extension[OF extension.hyps] by simp
next
- case (extension G K l g q H h) show ?case
- proof (cases)
- assume "i = 0" thus ?case
- using exact_seq.extension[OF extension.hyps] by simp
- next
- assume "i \<noteq> 0" hence "i \<ge> Suc 0" by simp
- then obtain k where "k < length (snd (G # K # l, g # q))" "i = Suc k"
- using Suc_le_D extension.prems by auto
- thus ?thesis using extension.IH by simp
- qed
- qed }
-
+ assume "i \<noteq> 0" hence "i \<ge> Suc 0" by simp
+ then obtain k where "k < length (snd (G # K # l, g # q))" "i = Suc k"
+ using Suc_le_D extension.prems by auto
+ thus ?thesis using extension.IH by simp
+ qed
+ qed
thus ?thesis using assms by auto
qed
@@ -68,18 +67,19 @@
lemma exact_seq_imp_exact_hom:
assumes "exact_seq (G1 # l,q) \<longlongrightarrow>\<^bsub>g1\<^esub> G2 \<longlongrightarrow>\<^bsub>g2\<^esub> G3"
shows "g1 ` (carrier G1) = kernel G2 G3 g2"
-proof-
- { fix t assume "exact_seq t" and "length (fst t) \<ge> 3 \<and> length (snd t) \<ge> 2"
- hence "(hd (tl (snd t))) ` (carrier (hd (tl (tl (fst t))))) =
+proof -
+ have "(hd (tl (snd t))) ` (carrier (hd (tl (tl (fst t))))) =
kernel (hd (tl (fst t))) (hd (fst t)) (hd (snd t))"
- proof (induction)
- case (unity G1 G2 f)
- then show ?case by auto
- next
- case (extension G l g q H h)
- then show ?case by auto
- qed }
- thus ?thesis using assms by fastforce
+ if "exact_seq t" and "length (fst t) \<ge> 3 \<and> length (snd t) \<ge> 2" for t
+ using that
+ proof (induction)
+ case (unity G1 G2 f)
+ then show ?case by auto
+ next
+ case (extension G l g q H h)
+ then show ?case by auto
+ qed
+ with assms show ?thesis by fastforce
qed
lemma exact_seq_imp_exact_hom_arbitrary:
@@ -103,16 +103,15 @@
assumes "exact_seq ((G # l, q)) \<longlongrightarrow>\<^bsub>g\<^esub> H"
shows "group_hom G H g"
proof-
- { fix t assume "exact_seq t"
- hence "group_hom (hd (tl (fst t))) (hd (fst t)) (hd(snd t))"
- proof (induction)
- case (unity G1 G2 f)
- then show ?case by auto
- next
- case (extension G l g q H h)
- then show ?case unfolding group_hom_def group_hom_axioms_def by auto
- qed }
- note aux_lemma = this
+ have aux_lemma: "group_hom (hd (tl (fst t))) (hd (fst t)) (hd(snd t))" if "exact_seq t" for t
+ using that
+ proof (induction)
+ case (unity G1 G2 f)
+ then show ?case by auto
+ next
+ case (extension G l g q H h)
+ then show ?case unfolding group_hom_def group_hom_axioms_def by auto
+ qed
show ?thesis using aux_lemma[OF assms]
by simp
qed
--- a/src/HOL/Algebra/FiniteProduct.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/FiniteProduct.thy Wed Nov 13 20:14:24 2024 +0100
@@ -115,8 +115,7 @@
then show ?thesis
using \<open>(A,y) \<in> foldSetD D (\<cdot>) e\<close> by auto
next
- case (2 x' A' y')
- note A' = this
+ case A': (2 x' A' y')
show ?thesis
using foldSetD.cases [OF \<open>(A,y) \<in> foldSetD D (\<cdot>) e\<close>]
proof cases
@@ -124,8 +123,7 @@
then show ?thesis
using \<open>(A,x) \<in> foldSetD D (\<cdot>) e\<close> by auto
next
- case (2 x'' A'' y'')
- note A'' = this
+ case A'': (2 x'' A'' y'')
show ?thesis
proof (cases "x' = x''")
case True
--- a/src/HOL/Algebra/Generated_Fields.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/Generated_Fields.thy Wed Nov 13 20:14:24 2024 +0100
@@ -121,56 +121,56 @@
and "I \<subseteq> K"
shows "generate_field (R\<lparr>carrier := K\<rparr>) I \<subseteq> generate_field (R\<lparr>carrier := H\<rparr>) I"
proof
- {fix J assume J_def : "subfield J R" "I \<subseteq> J"
- have "generate_field (R \<lparr> carrier := J \<rparr>) I \<subseteq> J"
- using field.mono_generate_field[of "(R\<lparr>carrier := J\<rparr>)" I J] subfield_iff(2)[OF J_def(1)]
- field.generate_field_in_carrier[of "R\<lparr>carrier := J\<rparr>"] field_axioms J_def
- by auto}
- note incl_HK = this
- {fix x have "x \<in> generate_field (R\<lparr>carrier := K\<rparr>) I \<Longrightarrow> x \<in> generate_field (R\<lparr>carrier := H\<rparr>) I"
- proof (induction rule : generate_field.induct)
- case one
- have "\<one>\<^bsub>R\<lparr>carrier := H\<rparr>\<^esub> \<otimes> \<one>\<^bsub>R\<lparr>carrier := K\<rparr>\<^esub> = \<one>\<^bsub>R\<lparr>carrier := H\<rparr>\<^esub>" by simp
- moreover have "\<one>\<^bsub>R\<lparr>carrier := H\<rparr>\<^esub> \<otimes> \<one>\<^bsub>R\<lparr>carrier := K\<rparr>\<^esub> = \<one>\<^bsub>R\<lparr>carrier := K\<rparr>\<^esub>" by simp
- ultimately show ?case using assms generate_field.one by metis
- next
- case (incl h) thus ?case using generate_field.incl by force
- next
- case (a_inv h)
- note hyp = this
- have "a_inv (R\<lparr>carrier := K\<rparr>) h = a_inv R h"
- using assms group.m_inv_consistent[of "add_monoid R" K] a_comm_group incl_HK[of K] hyp
- subring.axioms(1)[OF subfieldE(1)[OF assms(2)]]
- unfolding comm_group_def a_inv_def by auto
- moreover have "a_inv (R\<lparr>carrier := H\<rparr>) h = a_inv R h"
- using assms group.m_inv_consistent[of "add_monoid R" H] a_comm_group incl_HK[of H] hyp
- subring.axioms(1)[OF subfieldE(1)[OF assms(1)]]
- unfolding comm_group_def a_inv_def by auto
- ultimately show ?case using generate_field.a_inv a_inv.IH by fastforce
- next
- case (m_inv h)
- note hyp = this
- have h_K : "h \<in> (K - {\<zero>})" using incl_HK[OF assms(2) assms(4)] hyp by auto
- hence "m_inv (R\<lparr>carrier := K\<rparr>) h = m_inv R h"
- using field.m_inv_mult_of[OF subfield_iff(2)[OF assms(2)]]
- group.m_inv_consistent[of "mult_of R" "K - {\<zero>}"] field_mult_group units_of_inv
- subgroup_mult_of subfieldE[OF assms(2)] unfolding mult_of_def apply simp
- by (metis h_K mult_of_def mult_of_is_Units subgroup.mem_carrier units_of_carrier assms(2))
- moreover have h_H : "h \<in> (H - {\<zero>})" using incl_HK[OF assms(1) assms(3)] hyp by auto
- hence "m_inv (R\<lparr>carrier := H\<rparr>) h = m_inv R h"
- using field.m_inv_mult_of[OF subfield_iff(2)[OF assms(1)]]
- group.m_inv_consistent[of "mult_of R" "H - {\<zero>}"] field_mult_group
- subgroup_mult_of[OF assms(1)] unfolding mult_of_def apply simp
- by (metis h_H field_Units m_inv_mult_of mult_of_is_Units subgroup.mem_carrier units_of_def)
- ultimately show ?case using generate_field.m_inv m_inv.IH h_H by fastforce
- next
- case (eng_add h1 h2)
- thus ?case using incl_HK assms generate_field.eng_add by force
- next
- case (eng_mult h1 h2)
- thus ?case using generate_field.eng_mult by force
- qed}
- thus "\<And>x. x \<in> generate_field (R\<lparr>carrier := K\<rparr>) I \<Longrightarrow> x \<in> generate_field (R\<lparr>carrier := H\<rparr>) I"
+ have incl_HK: "generate_field (R \<lparr> carrier := J \<rparr>) I \<subseteq> J"
+ if J_def : "subfield J R" "I \<subseteq> J" for J
+ using field.mono_generate_field[of "(R\<lparr>carrier := J\<rparr>)" I J] subfield_iff(2)[OF J_def(1)]
+ field.generate_field_in_carrier[of "R\<lparr>carrier := J\<rparr>"] field_axioms J_def
+ by auto
+
+ fix x
+ have "x \<in> generate_field (R\<lparr>carrier := K\<rparr>) I \<Longrightarrow> x \<in> generate_field (R\<lparr>carrier := H\<rparr>) I"
+ proof (induction rule : generate_field.induct)
+ case one
+ have "\<one>\<^bsub>R\<lparr>carrier := H\<rparr>\<^esub> \<otimes> \<one>\<^bsub>R\<lparr>carrier := K\<rparr>\<^esub> = \<one>\<^bsub>R\<lparr>carrier := H\<rparr>\<^esub>" by simp
+ moreover have "\<one>\<^bsub>R\<lparr>carrier := H\<rparr>\<^esub> \<otimes> \<one>\<^bsub>R\<lparr>carrier := K\<rparr>\<^esub> = \<one>\<^bsub>R\<lparr>carrier := K\<rparr>\<^esub>" by simp
+ ultimately show ?case using assms generate_field.one by metis
+ next
+ case (incl h)
+ thus ?case using generate_field.incl by force
+ next
+ case (a_inv h)
+ have "a_inv (R\<lparr>carrier := K\<rparr>) h = a_inv R h"
+ using assms group.m_inv_consistent[of "add_monoid R" K] a_comm_group incl_HK[of K] a_inv
+ subring.axioms(1)[OF subfieldE(1)[OF assms(2)]]
+ unfolding comm_group_def a_inv_def by auto
+ moreover have "a_inv (R\<lparr>carrier := H\<rparr>) h = a_inv R h"
+ using assms group.m_inv_consistent[of "add_monoid R" H] a_comm_group incl_HK[of H] a_inv
+ subring.axioms(1)[OF subfieldE(1)[OF assms(1)]]
+ unfolding comm_group_def a_inv_def by auto
+ ultimately show ?case using generate_field.a_inv a_inv.IH by fastforce
+ next
+ case (m_inv h)
+ have h_K : "h \<in> (K - {\<zero>})" using incl_HK[OF assms(2) assms(4)] m_inv by auto
+ hence "m_inv (R\<lparr>carrier := K\<rparr>) h = m_inv R h"
+ using field.m_inv_mult_of[OF subfield_iff(2)[OF assms(2)]]
+ group.m_inv_consistent[of "mult_of R" "K - {\<zero>}"] field_mult_group units_of_inv
+ subgroup_mult_of subfieldE[OF assms(2)] unfolding mult_of_def apply simp
+ by (metis h_K mult_of_def mult_of_is_Units subgroup.mem_carrier units_of_carrier assms(2))
+ moreover have h_H : "h \<in> (H - {\<zero>})" using incl_HK[OF assms(1) assms(3)] m_inv by auto
+ hence "m_inv (R\<lparr>carrier := H\<rparr>) h = m_inv R h"
+ using field.m_inv_mult_of[OF subfield_iff(2)[OF assms(1)]]
+ group.m_inv_consistent[of "mult_of R" "H - {\<zero>}"] field_mult_group
+ subgroup_mult_of[OF assms(1)] unfolding mult_of_def apply simp
+ by (metis h_H field_Units m_inv_mult_of mult_of_is_Units subgroup.mem_carrier units_of_def)
+ ultimately show ?case using generate_field.m_inv m_inv.IH h_H by fastforce
+ next
+ case (eng_add h1 h2)
+ thus ?case using incl_HK assms generate_field.eng_add by force
+ next
+ case (eng_mult h1 h2)
+ thus ?case using generate_field.eng_mult by force
+ qed
+ thus "x \<in> generate_field (R\<lparr>carrier := K\<rparr>) I \<Longrightarrow> x \<in> generate_field (R\<lparr>carrier := H\<rparr>) I"
by auto
qed
--- a/src/HOL/Algebra/Generated_Groups.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/Generated_Groups.thy Wed Nov 13 20:14:24 2024 +0100
@@ -344,23 +344,23 @@
by (simp add: DG.rcos_sum)
also have " ... = derived G (carrier G) #> (g2 \<otimes> g1)"
proof -
- { fix g1 g2 assume g1: "g1 \<in> carrier G" and g2: "g2 \<in> carrier G"
- have "derived G (carrier G) #> (g1 \<otimes> g2) \<subseteq> derived G (carrier G) #> (g2 \<otimes> g1)"
- proof
- fix h assume "h \<in> derived G (carrier G) #> (g1 \<otimes> g2)"
- then obtain g' where h: "g' \<in> carrier G" "g' \<in> derived G (carrier G)" "h = g' \<otimes> (g1 \<otimes> g2)"
- using DG.subset unfolding r_coset_def by auto
- hence "h = g' \<otimes> (g1 \<otimes> g2) \<otimes> (inv g1 \<otimes> inv g2 \<otimes> g2 \<otimes> g1)"
- using g1 g2 by (simp add: m_assoc)
- hence "h = (g' \<otimes> (g1 \<otimes> g2 \<otimes> inv g1 \<otimes> inv g2)) \<otimes> (g2 \<otimes> g1)"
- using h(1) g1 g2 inv_closed m_assoc m_closed by presburger
- moreover have "g1 \<otimes> g2 \<otimes> inv g1 \<otimes> inv g2 \<in> derived G (carrier G)"
- using incl[of _ "derived_set G (carrier G)"] g1 g2 unfolding derived_def by blast
- hence "g' \<otimes> (g1 \<otimes> g2 \<otimes> inv g1 \<otimes> inv g2) \<in> derived G (carrier G)"
- using DG.m_closed[OF h(2)] by simp
- ultimately show "h \<in> derived G (carrier G) #> (g2 \<otimes> g1)"
- unfolding r_coset_def by blast
- qed }
+ have "derived G (carrier G) #> (g1 \<otimes> g2) \<subseteq> derived G (carrier G) #> (g2 \<otimes> g1)"
+ if g1: "g1 \<in> carrier G" and g2: "g2 \<in> carrier G" for g1 g2
+ proof
+ fix h assume "h \<in> derived G (carrier G) #> (g1 \<otimes> g2)"
+ then obtain g' where h: "g' \<in> carrier G" "g' \<in> derived G (carrier G)" "h = g' \<otimes> (g1 \<otimes> g2)"
+ using DG.subset unfolding r_coset_def by auto
+ hence "h = g' \<otimes> (g1 \<otimes> g2) \<otimes> (inv g1 \<otimes> inv g2 \<otimes> g2 \<otimes> g1)"
+ using g1 g2 by (simp add: m_assoc)
+ hence "h = (g' \<otimes> (g1 \<otimes> g2 \<otimes> inv g1 \<otimes> inv g2)) \<otimes> (g2 \<otimes> g1)"
+ using h(1) g1 g2 inv_closed m_assoc m_closed by presburger
+ moreover have "g1 \<otimes> g2 \<otimes> inv g1 \<otimes> inv g2 \<in> derived G (carrier G)"
+ using incl[of _ "derived_set G (carrier G)"] g1 g2 unfolding derived_def by blast
+ hence "g' \<otimes> (g1 \<otimes> g2 \<otimes> inv g1 \<otimes> inv g2) \<in> derived G (carrier G)"
+ using DG.m_closed[OF h(2)] by simp
+ ultimately show "h \<in> derived G (carrier G) #> (g2 \<otimes> g1)"
+ unfolding r_coset_def by blast
+ qed
thus ?thesis
using g1(1) g2(1) by auto
qed
--- a/src/HOL/Algebra/Generated_Rings.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/Generated_Rings.thy Wed Nov 13 20:14:24 2024 +0100
@@ -109,38 +109,37 @@
and "I \<subseteq> K"
shows "generate_ring (R\<lparr>carrier := K\<rparr>) I \<subseteq> generate_ring (R\<lparr>carrier := H\<rparr>) I"
proof
- {fix J assume J_def : "subring J R" "I \<subseteq> J"
- have "generate_ring (R \<lparr> carrier := J \<rparr>) I \<subseteq> J"
- using ring.mono_generate_ring[of "(R\<lparr>carrier := J\<rparr>)" I J ] subring_is_ring[OF J_def(1)]
- ring.generate_ring_in_carrier[of "R\<lparr>carrier := J\<rparr>"] ring_axioms J_def(2)
- by auto}
- note incl_HK = this
- {fix x have "x \<in> generate_ring (R\<lparr>carrier := K\<rparr>) I \<Longrightarrow> x \<in> generate_ring (R\<lparr>carrier := H\<rparr>) I"
- proof (induction rule : generate_ring.induct)
- case one
- have "\<one>\<^bsub>R\<lparr>carrier := H\<rparr>\<^esub> \<otimes> \<one>\<^bsub>R\<lparr>carrier := K\<rparr>\<^esub> = \<one>\<^bsub>R\<lparr>carrier := H\<rparr>\<^esub>" by simp
- moreover have "\<one>\<^bsub>R\<lparr>carrier := H\<rparr>\<^esub> \<otimes> \<one>\<^bsub>R\<lparr>carrier := K\<rparr>\<^esub> = \<one>\<^bsub>R\<lparr>carrier := K\<rparr>\<^esub>" by simp
- ultimately show ?case using assms generate_ring.one by metis
- next
- case (incl h) thus ?case using generate_ring.incl by force
- next
- case (a_inv h)
- note hyp = this
- have "a_inv (R\<lparr>carrier := K\<rparr>) h = a_inv R h"
- using assms group.m_inv_consistent[of "add_monoid R" K] a_comm_group incl_HK[of K] hyp
- unfolding subring_def comm_group_def a_inv_def by auto
- moreover have "a_inv (R\<lparr>carrier := H\<rparr>) h = a_inv R h"
- using assms group.m_inv_consistent[of "add_monoid R" H] a_comm_group incl_HK[of H] hyp
- unfolding subring_def comm_group_def a_inv_def by auto
- ultimately show ?case using generate_ring.a_inv a_inv.IH by fastforce
- next
- case (eng_add h1 h2)
- thus ?case using incl_HK assms generate_ring.eng_add by force
- next
- case (eng_mult h1 h2)
- thus ?case using generate_ring.eng_mult by force
- qed}
- thus "\<And>x. x \<in> generate_ring (R\<lparr>carrier := K\<rparr>) I \<Longrightarrow> x \<in> generate_ring (R\<lparr>carrier := H\<rparr>) I"
+ have incl_HK: "generate_ring (R \<lparr> carrier := J \<rparr>) I \<subseteq> J" if J_def : "subring J R" "I \<subseteq> J" for J
+ using ring.mono_generate_ring[of "(R\<lparr>carrier := J\<rparr>)" I J ] subring_is_ring[OF J_def(1)]
+ ring.generate_ring_in_carrier[of "R\<lparr>carrier := J\<rparr>"] ring_axioms J_def(2)
+ by auto
+
+ fix x
+ have "x \<in> generate_ring (R\<lparr>carrier := K\<rparr>) I \<Longrightarrow> x \<in> generate_ring (R\<lparr>carrier := H\<rparr>) I"
+ proof (induction rule : generate_ring.induct)
+ case one
+ have "\<one>\<^bsub>R\<lparr>carrier := H\<rparr>\<^esub> \<otimes> \<one>\<^bsub>R\<lparr>carrier := K\<rparr>\<^esub> = \<one>\<^bsub>R\<lparr>carrier := H\<rparr>\<^esub>" by simp
+ moreover have "\<one>\<^bsub>R\<lparr>carrier := H\<rparr>\<^esub> \<otimes> \<one>\<^bsub>R\<lparr>carrier := K\<rparr>\<^esub> = \<one>\<^bsub>R\<lparr>carrier := K\<rparr>\<^esub>" by simp
+ ultimately show ?case using assms generate_ring.one by metis
+ next
+ case (incl h) thus ?case using generate_ring.incl by force
+ next
+ case (a_inv h)
+ have "a_inv (R\<lparr>carrier := K\<rparr>) h = a_inv R h"
+ using assms group.m_inv_consistent[of "add_monoid R" K] a_comm_group incl_HK[of K] a_inv
+ unfolding subring_def comm_group_def a_inv_def by auto
+ moreover have "a_inv (R\<lparr>carrier := H\<rparr>) h = a_inv R h"
+ using assms group.m_inv_consistent[of "add_monoid R" H] a_comm_group incl_HK[of H] a_inv
+ unfolding subring_def comm_group_def a_inv_def by auto
+ ultimately show ?case using generate_ring.a_inv a_inv.IH by fastforce
+ next
+ case (eng_add h1 h2)
+ thus ?case using incl_HK assms generate_ring.eng_add by force
+ next
+ case (eng_mult h1 h2)
+ thus ?case using generate_ring.eng_mult by force
+ qed
+ thus "x \<in> generate_ring (R\<lparr>carrier := K\<rparr>) I \<Longrightarrow> x \<in> generate_ring (R\<lparr>carrier := H\<rparr>) I"
by auto
qed
--- a/src/HOL/Algebra/Ideal.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/Ideal.thy Wed Nov 13 20:14:24 2024 +0100
@@ -102,8 +102,8 @@
lemma (in ring) set_add_comm:
assumes "I \<subseteq> carrier R" "J \<subseteq> carrier R" shows "I <+> J = J <+> I"
proof -
- { fix I J assume "I \<subseteq> carrier R" "J \<subseteq> carrier R" hence "I <+> J \<subseteq> J <+> I"
- using a_comm unfolding set_add_def' by (auto, blast) }
+ have "I <+> J \<subseteq> J <+> I" if "I \<subseteq> carrier R" "J \<subseteq> carrier R" for I J
+ using that a_comm unfolding set_add_def' by (auto, blast)
thus ?thesis
using assms by auto
qed
@@ -262,35 +262,33 @@
assumes Sideals: "\<And>I. I \<in> S \<Longrightarrow> ideal I R" and notempty: "S \<noteq> {}"
shows "ideal (\<Inter>S) R"
proof -
- { fix x y J
- assume "\<forall>I\<in>S. x \<in> I" "\<forall>I\<in>S. y \<in> I" and JS: "J \<in> S"
+ have "x \<oplus> y \<in> J" if "\<forall>I\<in>S. x \<in> I" "\<forall>I\<in>S. y \<in> I" and JS: "J \<in> S" for x y J
+ proof -
interpret ideal J R by (rule Sideals[OF JS])
- have "x \<oplus> y \<in> J"
- by (simp add: JS \<open>\<forall>I\<in>S. x \<in> I\<close> \<open>\<forall>I\<in>S. y \<in> I\<close>) }
- moreover
- have "\<zero> \<in> J" if "J \<in> S" for J
- by (simp add: that Sideals additive_subgroup.zero_closed ideal.axioms(1))
- moreover
- { fix x J
- assume "\<forall>I\<in>S. x \<in> I" and JS: "J \<in> S"
+ show ?thesis by (simp add: JS \<open>\<forall>I\<in>S. x \<in> I\<close> \<open>\<forall>I\<in>S. y \<in> I\<close>)
+ qed
+ moreover have "\<zero> \<in> J" if "J \<in> S" for J
+ by (simp add: that Sideals additive_subgroup.zero_closed ideal.axioms(1))
+ moreover have "\<ominus> x \<in> J" if "\<forall>I\<in>S. x \<in> I" and JS: "J \<in> S" for x J
+ proof -
interpret ideal J R by (rule Sideals[OF JS])
- have "\<ominus> x \<in> J"
- by (simp add: JS \<open>\<forall>I\<in>S. x \<in> I\<close>) }
- moreover
- { fix x y J
- assume "\<forall>I\<in>S. x \<in> I" and ycarr: "y \<in> carrier R" and JS: "J \<in> S"
+ show ?thesis by (simp add: JS \<open>\<forall>I\<in>S. x \<in> I\<close>)
+ qed
+ moreover have "y \<otimes> x \<in> J" "x \<otimes> y \<in> J"
+ if "\<forall>I\<in>S. x \<in> I" and ycarr: "y \<in> carrier R" and JS: "J \<in> S" for x y J
+ proof -
interpret ideal J R by (rule Sideals[OF JS])
- have "y \<otimes> x \<in> J" "x \<otimes> y \<in> J"
- using I_l_closed I_r_closed JS \<open>\<forall>I\<in>S. x \<in> I\<close> ycarr by blast+ }
- moreover
- { fix x
- assume "\<forall>I\<in>S. x \<in> I"
+ show "y \<otimes> x \<in> J" "x \<otimes> y \<in> J" using I_l_closed I_r_closed JS \<open>\<forall>I\<in>S. x \<in> I\<close> ycarr by blast+
+ qed
+ moreover have "x \<in> carrier R" if "\<forall>I\<in>S. x \<in> I" for x
+ proof -
obtain I0 where I0S: "I0 \<in> S"
using notempty by blast
interpret ideal I0 R by (rule Sideals[OF I0S])
have "x \<in> I0"
by (simp add: I0S \<open>\<forall>I\<in>S. x \<in> I\<close>)
- with a_subset have "x \<in> carrier R" by fast }
+ with a_subset show ?thesis by fast
+ qed
ultimately show ?thesis
by unfold_locales (auto simp: Inter_eq simp flip: a_inv_def)
qed
@@ -308,17 +306,14 @@
by (rule ring_axioms)
show "ideal_axioms (I <+> J) R"
proof -
- { fix x i j
- assume xcarr: "x \<in> carrier R" and iI: "i \<in> I" and jJ: "j \<in> J"
- from xcarr ideal.Icarr[OF idealI iI] ideal.Icarr[OF idealJ jJ]
- have "\<exists>h\<in>I. \<exists>k\<in>J. (i \<oplus> j) \<otimes> x = h \<oplus> k"
- by (meson iI ideal.I_r_closed idealJ jJ l_distr local.idealI) }
- moreover
- { fix x i j
- assume xcarr: "x \<in> carrier R" and iI: "i \<in> I" and jJ: "j \<in> J"
- from xcarr ideal.Icarr[OF idealI iI] ideal.Icarr[OF idealJ jJ]
- have "\<exists>h\<in>I. \<exists>k\<in>J. x \<otimes> (i \<oplus> j) = h \<oplus> k"
- by (meson iI ideal.I_l_closed idealJ jJ local.idealI r_distr) }
+ have "\<exists>h\<in>I. \<exists>k\<in>J. (i \<oplus> j) \<otimes> x = h \<oplus> k"
+ if xcarr: "x \<in> carrier R" and iI: "i \<in> I" and jJ: "j \<in> J" for x i j
+ using xcarr ideal.Icarr[OF idealI iI] ideal.Icarr[OF idealJ jJ]
+ by (meson iI ideal.I_r_closed idealJ jJ l_distr local.idealI)
+ moreover have "\<exists>h\<in>I. \<exists>k\<in>J. x \<otimes> (i \<oplus> j) = h \<oplus> k"
+ if xcarr: "x \<in> carrier R" and iI: "i \<in> I" and jJ: "j \<in> J" for x i j
+ using xcarr ideal.Icarr[OF idealI iI] ideal.Icarr[OF idealJ jJ]
+ by (meson iI ideal.I_l_closed idealJ jJ local.idealI r_distr)
ultimately show "ideal_axioms (I <+> J) R"
by (intro ideal_axioms.intro) (auto simp: set_add_defs)
qed
--- a/src/HOL/Algebra/Ideal_Product.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/Ideal_Product.thy Wed Nov 13 20:14:24 2024 +0100
@@ -273,26 +273,25 @@
local.ring_axioms ring.ideal_prod_is_ideal)
qed
qed
-next
- { fix s J K assume A: "ideal J R" "ideal K R" "s \<in> I \<cdot> J"
- have "s \<in> I \<cdot> (J <+> K) \<and> s \<in> I \<cdot> (K <+> J)"
- proof -
- from \<open>s \<in> I \<cdot> J\<close> have "s \<in> I \<cdot> (J <+> K)"
- proof (induct s rule: ideal_prod.induct)
- case (prod i j)
- hence "(j \<oplus> \<zero>) \<in> J <+> K"
- using set_add_def'[of R J K]
- additive_subgroup.zero_closed[OF ideal.axioms(1), of K R] A(2) by auto
- thus ?case
- by (metis A(1) additive_subgroup.a_Hcarr ideal.axioms(1) ideal_prod.prod prod r_zero)
- next
- case (sum s1 s2) thus ?case
- by (simp add: ideal_prod.sum)
- qed
- thus ?thesis
- by (metis A(1) A(2) ideal_def ring.union_genideal sup_commute)
- qed } note aux_lemma = this
+ have aux_lemma: "s \<in> I \<cdot> (J <+> K) \<and> s \<in> I \<cdot> (K <+> J)"
+ if A: "ideal J R" "ideal K R" "s \<in> I \<cdot> J" for s J K
+ proof -
+ from \<open>s \<in> I \<cdot> J\<close> have "s \<in> I \<cdot> (J <+> K)"
+ proof (induct s rule: ideal_prod.induct)
+ case (prod i j)
+ hence "(j \<oplus> \<zero>) \<in> J <+> K"
+ using set_add_def'[of R J K]
+ additive_subgroup.zero_closed[OF ideal.axioms(1), of K R] A(2) by auto
+ thus ?case
+ by (metis A(1) additive_subgroup.a_Hcarr ideal.axioms(1) ideal_prod.prod prod r_zero)
+ next
+ case (sum s1 s2) thus ?case
+ by (simp add: ideal_prod.sum)
+ qed
+ thus ?thesis
+ by (metis A(1) A(2) ideal_def ring.union_genideal sup_commute)
+ qed
show "I \<cdot> J <+> I \<cdot> K \<subseteq> I \<cdot> (J <+> K)"
proof
fix s assume "s \<in> I \<cdot> J <+> I \<cdot> K"
@@ -308,19 +307,22 @@
assumes "ideal I R" "ideal J R"
shows "I \<cdot> J = J \<cdot> I"
proof -
- { fix I J assume A: "ideal I R" "ideal J R"
- have "I \<cdot> J \<subseteq> J \<cdot> I"
- proof
- fix s assume "s \<in> I \<cdot> J" thus "s \<in> J \<cdot> I"
- proof (induct s rule: ideal_prod.induct)
- case (prod i j) thus ?case
- using m_comm[OF ideal.Icarr[OF A(1) prod(1)] ideal.Icarr[OF A(2) prod(2)]]
- by (simp add: ideal_prod.prod)
- next
- case (sum s1 s2) thus ?case by (simp add: ideal_prod.sum)
- qed
- qed }
- thus ?thesis using assms by blast
+ have "I \<cdot> J \<subseteq> J \<cdot> I" if A: "ideal I R" "ideal J R" for I J
+ proof
+ fix s
+ assume "s \<in> I \<cdot> J"
+ thus "s \<in> J \<cdot> I"
+ proof (induct s rule: ideal_prod.induct)
+ case (prod i j)
+ thus ?case
+ using m_comm[OF ideal.Icarr[OF A(1) prod(1)] ideal.Icarr[OF A(2) prod(2)]]
+ by (simp add: ideal_prod.prod)
+ next
+ case (sum s1 s2)
+ thus ?case by (simp add: ideal_prod.sum)
+ qed
+ qed
+ with assms show ?thesis by blast
qed
text \<open>The following result would also be true for locale ring\<close>
--- a/src/HOL/Algebra/Indexed_Polynomials.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/Indexed_Polynomials.thy Wed Nov 13 20:14:24 2024 +0100
@@ -285,23 +285,22 @@
assumes "\<And>P. P \<in> carrier L \<Longrightarrow> carrier_coeff P" and "\<And>P. P \<in> carrier L \<Longrightarrow> index_free P i" and "\<zero>\<^bsub>L\<^esub> = indexed_const \<zero>"
shows "inj_on (\<lambda>Ps. indexed_eval Ps i) (carrier (poly_ring L))"
proof -
- { fix Ps
- assume "Ps \<in> carrier (poly_ring L)" and "indexed_eval Ps i = indexed_const \<zero>"
- have "Ps = []"
- proof (rule ccontr)
- assume "Ps \<noteq> []"
- then obtain P' Ps' where Ps: "Ps = P' # Ps'"
- using list.exhaust by blast
- with \<open>Ps \<in> carrier (poly_ring L)\<close>
- have "P' \<noteq> indexed_const \<zero>" and "list_all carrier_coeff Ps" and "list_all (\<lambda>P. index_free P i) Ps"
- using assms unfolding sym[OF univ_poly_carrier[of L "carrier L"]] polynomial_def
- by (simp add: list.pred_set subset_code(1))+
- then obtain m where "(indexed_eval Ps i) m \<noteq> \<zero>"
- using exists_indexed_eval_monomial'[of P' Ps'] unfolding Ps by auto
- hence "indexed_eval Ps i \<noteq> indexed_const \<zero>"
- unfolding indexed_const_def by auto
- with \<open>indexed_eval Ps i = indexed_const \<zero>\<close> show False by simp
- qed } note aux_lemma = this
+ have aux_lemma: "Ps = []"
+ if "Ps \<in> carrier (poly_ring L)" and "indexed_eval Ps i = indexed_const \<zero>" for Ps
+ proof (rule ccontr)
+ assume "\<not> ?thesis"
+ then obtain P' Ps' where Ps: "Ps = P' # Ps'"
+ using list.exhaust by blast
+ with \<open>Ps \<in> carrier (poly_ring L)\<close>
+ have "P' \<noteq> indexed_const \<zero>" and "list_all carrier_coeff Ps" and "list_all (\<lambda>P. index_free P i) Ps"
+ using assms unfolding sym[OF univ_poly_carrier[of L "carrier L"]] polynomial_def
+ by (simp add: list.pred_set subset_code(1))+
+ then obtain m where "(indexed_eval Ps i) m \<noteq> \<zero>"
+ using exists_indexed_eval_monomial'[of P' Ps'] unfolding Ps by auto
+ hence "indexed_eval Ps i \<noteq> indexed_const \<zero>"
+ unfolding indexed_const_def by auto
+ with \<open>indexed_eval Ps i = indexed_const \<zero>\<close> show False by simp
+ qed
show ?thesis
proof (rule inj_onI)
@@ -356,9 +355,9 @@
lemma (in ring) indexed_eval_index_free:
assumes "list_all (\<lambda>P. index_free P j) Ps" and "i \<noteq> j" shows "index_free (indexed_eval Ps i) j"
proof -
- { fix Ps assume "list_all (\<lambda>P. index_free P j) Ps" hence "index_free (indexed_eval_aux Ps i) j"
- using indexed_padd_index_free[OF indexed_pmult_index_free[OF _ assms(2)]]
- by (induct Ps) (auto simp add: indexed_zero_def index_free_def) }
+ have "index_free (indexed_eval_aux Ps i) j" if "list_all (\<lambda>P. index_free P j) Ps" for Ps
+ using that indexed_padd_index_free[OF indexed_pmult_index_free[OF _ assms(2)]]
+ by (induct Ps) (auto simp add: indexed_zero_def index_free_def)
thus ?thesis
using assms(1) by auto
qed
--- a/src/HOL/Algebra/IntRing.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/IntRing.thy Wed Nov 13 20:14:24 2024 +0100
@@ -54,7 +54,7 @@
show "carrier \<Z> = UNIV" by simp
\<comment> \<open>Operations\<close>
- { fix x y show "mult \<Z> x y = x * y" by simp }
+ show "mult \<Z> x y = x * y" for x y by simp
show "one \<Z> = 1" by simp
show "pow \<Z> x n = x^n" by (induct n) simp_all
qed
@@ -67,11 +67,8 @@
then interpret int: comm_monoid \<Z> .
\<comment> \<open>Operations\<close>
- { fix x y have "mult \<Z> x y = x * y" by simp }
- note mult = this
- have one: "one \<Z> = 1" by simp
show "finprod \<Z> f A = prod f A"
- by (induct A rule: infinite_finite_induct, auto)
+ by (induct A rule: infinite_finite_induct) auto
qed
interpretation int: abelian_monoid \<Z>
@@ -88,12 +85,10 @@
show "carrier \<Z> = UNIV" by simp
\<comment> \<open>Operations\<close>
- { fix x y show "add \<Z> x y = x + y" by simp }
- note add = this
- show zero: "zero \<Z> = 0"
- by simp
+ show "add \<Z> x y = x + y" for x y by simp
+ show zero: "zero \<Z> = 0" by simp
show "finsum \<Z> f A = sum f A"
- by (induct A rule: infinite_finite_induct, auto)
+ by (induct A rule: infinite_finite_induct) auto
qed
interpretation int: abelian_group \<Z>
@@ -118,17 +113,15 @@
qed auto
then interpret int: abelian_group \<Z> .
\<comment> \<open>Operations\<close>
- { fix x y have "add \<Z> x y = x + y" by simp }
- note add = this
+ have add: "add \<Z> x y = x + y" for x y by simp
have zero: "zero \<Z> = 0" by simp
- {
- fix x
+ show a_inv: "a_inv \<Z> x = - x" for x
+ proof -
have "add \<Z> (- x) x = zero \<Z>"
by (simp add: add zero)
- then show "a_inv \<Z> x = - x"
+ then show ?thesis
by (simp add: int.minus_equality)
- }
- note a_inv = this
+ qed
show "a_minus \<Z> x y = x - y"
by (simp add: int.minus_eq add a_inv)
qed (simp add: int_carrier_eq int_zero_eq int_add_eq int_finsum_eq)+
--- a/src/HOL/Algebra/Multiplicative_Group.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/Multiplicative_Group.thy Wed Nov 13 20:14:24 2024 +0100
@@ -216,37 +216,43 @@
assumes "n > 0"
shows "(\<Sum>d | d dvd n. phi' d) = n"
proof -
- { fix d assume "d dvd n" then obtain q where q: "n = d * q" ..
- have "card {a. 1 \<le> a \<and> a \<le> d \<and> coprime a d} = card {m \<in> {1 .. n}. n div gcd m n = d}"
- (is "card ?RF = card ?F")
- proof (rule card_bij_eq)
- { fix a b assume "a * n div d = b * n div d"
- hence "a * (n div d) = b * (n div d)"
- using dvd_div_mult[OF \<open>d dvd n\<close>] by (fastforce simp add: mult.commute)
- hence "a = b" using dvd_div_ge_1[OF _ \<open>d dvd n\<close>] \<open>n>0\<close>
- by (simp add: mult.commute nat_mult_eq_cancel1)
- } thus "inj_on (\<lambda>a. a*n div d) ?RF" unfolding inj_on_def by blast
- { fix a assume a: "a\<in>?RF"
- hence "a * (n div d) \<ge> 1" using \<open>n>0\<close> dvd_div_ge_1[OF _ \<open>d dvd n\<close>] by simp
- hence ge_1: "a * n div d \<ge> 1" by (simp add: \<open>d dvd n\<close> div_mult_swap)
- have le_n: "a * n div d \<le> n" using div_mult_mono a by simp
- have "gcd (a * n div d) n = n div d * gcd a d"
- by (simp add: gcd_mult_distrib_nat q ac_simps)
- hence "n div gcd (a * n div d) n = d*n div (d*(n div d))" using a by simp
- hence "a * n div d \<in> ?F"
- using ge_1 le_n by (fastforce simp add: \<open>d dvd n\<close>)
- } thus "(\<lambda>a. a*n div d) ` ?RF \<subseteq> ?F" by blast
- { fix m l assume A: "m \<in> ?F" "l \<in> ?F" "m div gcd m n = l div gcd l n"
- hence "gcd m n = gcd l n" using dvd_div_eq_2[OF assms] by fastforce
- hence "m = l" using dvd_div_eq_1[of "gcd m n" m l] A(3) by fastforce
- } thus "inj_on (\<lambda>a. a div gcd a n) ?F" unfolding inj_on_def by blast
- { fix m assume "m \<in> ?F"
- hence "m div gcd m n \<in> ?RF" using dvd_div_ge_1
- by (fastforce simp add: div_le_mono div_gcd_coprime)
- } thus "(\<lambda>a. a div gcd a n) ` ?F \<subseteq> ?RF" by blast
- qed force+
- } hence phi'_eq: "\<And>d. d dvd n \<Longrightarrow> phi' d = card {m \<in> {1 .. n}. n div gcd m n = d}"
- unfolding phi'_def by presburger
+ have "card {a. 1 \<le> a \<and> a \<le> d \<and> coprime a d} = card {m \<in> {1 .. n}. n div gcd m n = d}"
+ (is "card ?RF = card ?F")
+ if "d dvd n" for d
+ proof (rule card_bij_eq)
+ from that obtain q where q: "n = d * q" ..
+ have "a = b" if "a * n div d = b * n div d" for a b
+ proof -
+ from that have "a * (n div d) = b * (n div d)"
+ using dvd_div_mult[OF \<open>d dvd n\<close>] by (fastforce simp add: mult.commute)
+ then show ?thesis using dvd_div_ge_1[OF _ \<open>d dvd n\<close>] \<open>n>0\<close>
+ by (simp add: mult.commute nat_mult_eq_cancel1)
+ qed
+ thus "inj_on (\<lambda>a. a*n div d) ?RF" unfolding inj_on_def by blast
+ have "a * n div d \<in> ?F" if a: "a\<in>?RF" for a
+ proof -
+ from that have "a * (n div d) \<ge> 1" using \<open>n>0\<close> dvd_div_ge_1[OF _ \<open>d dvd n\<close>] by simp
+ hence ge_1: "a * n div d \<ge> 1" by (simp add: \<open>d dvd n\<close> div_mult_swap)
+ have le_n: "a * n div d \<le> n" using div_mult_mono a by simp
+ have "gcd (a * n div d) n = n div d * gcd a d"
+ by (simp add: gcd_mult_distrib_nat q ac_simps)
+ hence "n div gcd (a * n div d) n = d*n div (d*(n div d))" using a by simp
+ then show ?thesis
+ using ge_1 le_n by (fastforce simp add: \<open>d dvd n\<close>)
+ qed
+ thus "(\<lambda>a. a*n div d) ` ?RF \<subseteq> ?F" by blast
+ have "m = l" if A: "m \<in> ?F" "l \<in> ?F" "m div gcd m n = l div gcd l n" for m l
+ proof -
+ from that have "gcd m n = gcd l n" using dvd_div_eq_2[OF assms] by fastforce
+ then show ?thesis using dvd_div_eq_1[of "gcd m n" m l] A(3) by fastforce
+ qed
+ thus "inj_on (\<lambda>a. a div gcd a n) ?F" unfolding inj_on_def by blast
+ have "m div gcd m n \<in> ?RF" if "m \<in> ?F" for m
+ using that dvd_div_ge_1 by (fastforce simp add: div_le_mono div_gcd_coprime)
+ thus "(\<lambda>a. a div gcd a n) ` ?F \<subseteq> ?RF" by blast
+ qed force+
+ hence phi'_eq: "\<And>d. d dvd n \<Longrightarrow> phi' d = card {m \<in> {1 .. n}. n div gcd m n = d}"
+ unfolding phi'_def by presburger
have fin: "finite {d. d dvd n}" using dvd_nat_bounds[OF \<open>n>0\<close>] by force
have "(\<Sum>d | d dvd n. phi' d)
= card (\<Union>d \<in> {d. d dvd n}. {m \<in> {1 .. n}. n div gcd m n = d})"
@@ -419,22 +425,23 @@
proof (rule inj_onI, rule ccontr)
fix x y :: nat
assume A: "x \<in> {1 .. ord a}" "y \<in> {1 .. ord a}" "a [^] x = a [^] y" "x\<noteq>y"
- { assume "x < ord a" "y < ord a"
- hence False using ord_inj[OF assms] A unfolding inj_on_def by fastforce
- }
- moreover
- { assume "x = ord a" "y < ord a"
+ then consider "x < ord a" "y < ord a" | "x = ord a" "y < ord a" | "y = ord a" "x < ord a"
+ by force
+ then show False
+ proof cases
+ case 1
+ then show ?thesis using ord_inj[OF assms] A unfolding inj_on_def by fastforce
+ next
+ case 2
hence "a [^] y = a [^] (0::nat)" using pow_ord_eq_1 A by (simp add: a)
hence "y=0" using ord_inj[OF assms] \<open>y < ord a\<close> unfolding inj_on_def by force
- hence False using A by fastforce
- }
- moreover
- { assume "y = ord a" "x < ord a"
+ with A show ?thesis by fastforce
+ next
+ case 3
hence "a [^] x = a [^] (0::nat)" using pow_ord_eq_1 A by (simp add: a)
hence "x=0" using ord_inj[OF assms] \<open>x < ord a\<close> unfolding inj_on_def by force
- hence False using A by fastforce
- }
- ultimately show False using A by force
+ with A show ?thesis by fastforce
+ qed
qed
lemma (in group) ord_ge_1:
@@ -462,8 +469,9 @@
shows "{a[^]x | x. x \<in> (UNIV :: nat set)} = {a[^]x | x. x \<in> {0 .. ord a - 1}}" (is "?L = ?R")
proof
show "?R \<subseteq> ?L" by blast
- { fix y assume "y \<in> ?L"
- then obtain x::nat where x: "y = a[^]x" by auto
+ have "y \<in> {a[^]x | x. x \<in> {0 .. ord a - 1}}" if "y \<in> ?L" for y
+ proof -
+ from that obtain x::nat where x: "y = a[^]x" by auto
define r q where "r = x mod ord a" and "q = x div ord a"
then have "x = q * ord a + r"
by (simp add: div_mult_mod_eq)
@@ -472,8 +480,8 @@
hence "y = a[^]r" using assms by (simp add: pow_ord_eq_1)
have "r < ord a" using ord_ge_1[OF assms] by (simp add: r_def)
hence "r \<in> {0 .. ord a - 1}" by (force simp: r_def)
- hence "y \<in> {a[^]x | x. x \<in> {0 .. ord a - 1}}" using \<open>y=a[^]r\<close> by blast
- }
+ thus ?thesis using \<open>y=a[^]r\<close> by blast
+ qed
thus "?L \<subseteq> ?R" by auto
qed
@@ -598,20 +606,21 @@
assumes "a \<in> carrier G" "ord a \<noteq> 0"
shows "{a[^]x | x. x \<in> (UNIV :: nat set)} = {a[^]x | x. x \<in> {0 .. ord a - 1}}" (is "?L = ?R")
proof
- show "?R \<subseteq> ?L" by blast
- { fix y assume "y \<in> ?L"
- then obtain x::nat where x: "y = a[^]x" by auto
- define r q where "r = x mod ord a" and "q = x div ord a"
- then have "x = q * ord a + r"
- by (simp add: div_mult_mod_eq)
- hence "y = (a[^]ord a)[^]q \<otimes> a[^]r"
- using x assms by (metis mult.commute nat_pow_mult nat_pow_pow)
- hence "y = a[^]r" using assms by simp
- have "r < ord a" using assms by (simp add: r_def)
- hence "r \<in> {0 .. ord a - 1}" by (force simp: r_def)
- hence "y \<in> {a[^]x | x. x \<in> {0 .. ord a - 1}}" using \<open>y=a[^]r\<close> by blast
- }
- thus "?L \<subseteq> ?R" by auto
+ show "?R \<subseteq> ?L" by blast
+ have "y \<in> {a[^]x | x. x \<in> {0 .. ord a - 1}}" if "y \<in> ?L" for y
+ proof -
+ from that obtain x::nat where x: "y = a[^]x" by auto
+ define r q where "r = x mod ord a" and "q = x div ord a"
+ then have "x = q * ord a + r"
+ by (simp add: div_mult_mod_eq)
+ hence "y = (a[^]ord a)[^]q \<otimes> a[^]r"
+ using x assms by (metis mult.commute nat_pow_mult nat_pow_pow)
+ hence "y = a[^]r" using assms by simp
+ have "r < ord a" using assms by (simp add: r_def)
+ hence "r \<in> {0 .. ord a - 1}" by (force simp: r_def)
+ then show ?thesis using \<open>y=a[^]r\<close> by blast
+ qed
+ thus "?L \<subseteq> ?R" by auto
qed
lemma generate_pow_nat:
@@ -669,8 +678,7 @@
then show ?thesis
using \<open>ord a = 0\<close> by auto
next
- case False
- note finite_subgroup = this
+ case finite_subgroup: False
then have "generate G { a } = (([^]) a) ` {0..ord a - 1}"
using generate_pow_nat ord_elems_inf_carrier a by auto
hence "card (generate G {a}) = card {0..ord a - 1}"
@@ -952,12 +960,14 @@
have set_eq2: "{x \<in> carrier (mult_of R) . group.ord (mult_of R) x = d}
= (\<lambda> n . a[^]n) ` {n \<in> {1 .. d}. group.ord (mult_of R) (a[^]n) = d}" (is "?L = ?R")
proof
- { fix x assume x: "x \<in> (carrier (mult_of R)) \<and> group.ord (mult_of R) x = d"
- hence "x \<in> {x \<in> carrier (mult_of R). x [^] d = \<one>}"
+ have "x \<in> ?R" if x: "x \<in> (carrier (mult_of R)) \<and> group.ord (mult_of R) x = d" for x
+ proof -
+ from that have "x \<in> {x \<in> carrier (mult_of R). x [^] d = \<one>}"
by (simp add: G.pow_ord_eq_1[of x, symmetric])
then obtain n where n: "x = a[^]n \<and> n \<in> {1 .. d}" using set_eq1 by blast
- hence "x \<in> ?R" using x by fast
- } thus "?L \<subseteq> ?R" by blast
+ then show ?thesis using x by fast
+ qed
+ thus "?L \<subseteq> ?R" by blast
show "?R \<subseteq> ?L" using a by (auto simp add: carrier_mult_of[symmetric] simp del: carrier_mult_of)
qed
have "inj_on (\<lambda> n . a[^]n) {n \<in> {1 .. d}. group.ord (mult_of R) (a[^]n) = d}"
@@ -994,27 +1004,30 @@
using fin finite by (subst card_UN_disjoint) auto
also have "?U = carrier (mult_of R)"
proof
- { fix x assume x: "x \<in> carrier (mult_of R)"
- hence x': "x\<in>carrier (mult_of R)" by simp
+ have "x \<in> ?U" if x: "x \<in> carrier (mult_of R)" for x
+ proof -
+ from that have x': "x\<in>carrier (mult_of R)" by simp
then have "group.ord (mult_of R) x dvd order (mult_of R)"
using G.ord_dvd_group_order by blast
- hence "x \<in> ?U" using dvd_nat_bounds[of "order (mult_of R)" "group.ord (mult_of R) x"] x by blast
- } thus "carrier (mult_of R) \<subseteq> ?U" by blast
+ then show ?thesis
+ using dvd_nat_bounds[of "order (mult_of R)" "group.ord (mult_of R) x"] x by blast
+ qed
+ thus "carrier (mult_of R) \<subseteq> ?U" by blast
qed auto
also have "card ... = order (mult_of R)"
using order_mult_of finite' by (simp add: order_def)
finally have sum_Ns_eq: "(\<Sum>d | d dvd order (mult_of R). ?N d) = order (mult_of R)" .
- { fix d assume d: "d dvd order (mult_of R)"
- have "card {a \<in> carrier (mult_of R). group.ord (mult_of R) a = d} \<le> phi' d"
- proof cases
- assume "card {a \<in> carrier (mult_of R). group.ord (mult_of R) a = d} = 0" thus ?thesis by presburger
- next
- assume "card {a \<in> carrier (mult_of R). group.ord (mult_of R) a = d} \<noteq> 0"
- hence "\<exists>a \<in> carrier (mult_of R). group.ord (mult_of R) a = d" by (auto simp: card_eq_0_iff)
- thus ?thesis using num_elems_of_ord_eq_phi'[OF finite d] by auto
- qed
- }
+ have "card {a \<in> carrier (mult_of R). group.ord (mult_of R) a = d} \<le> phi' d"
+ if d: "d dvd order (mult_of R)" for d
+ proof (cases "card {a \<in> carrier (mult_of R). group.ord (mult_of R) a = d} = 0")
+ case True
+ thus ?thesis by presburger
+ next
+ case False
+ hence "\<exists>a \<in> carrier (mult_of R). group.ord (mult_of R) a = d" by (auto simp: card_eq_0_iff)
+ thus ?thesis using num_elems_of_ord_eq_phi'[OF finite d] by auto
+ qed
hence all_le: "\<And>i. i \<in> {d. d dvd order (mult_of R) }
\<Longrightarrow> (\<lambda>i. card {a \<in> carrier (mult_of R). group.ord (mult_of R) a = i}) i \<le> (\<lambda>i. phi' i) i" by fast
hence le: "(\<Sum>i | i dvd order (mult_of R). ?N i)
--- a/src/HOL/Algebra/Polynomial_Divisibility.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/Polynomial_Divisibility.thy Wed Nov 13 20:14:24 2024 +0100
@@ -735,27 +735,25 @@
assumes "subring K R" and "p \<in> carrier (K[X])" and "q \<in> carrier (K[X])"
shows "p \<sim>\<^bsub>K[X]\<^esub> q \<Longrightarrow> length p = length q"
proof -
- { fix p q
- assume p: "p \<in> carrier (K[X])" and q: "q \<in> carrier (K[X])" and "p \<sim>\<^bsub>K[X]\<^esub> q"
- have "length p \<le> length q"
- proof (cases "q = []")
- case True with \<open>p \<sim>\<^bsub>K[X]\<^esub> q\<close> have "p = []"
- unfolding associated_def True factor_def univ_poly_def by auto
- thus ?thesis
- using True by simp
- next
- case False
- from \<open>p \<sim>\<^bsub>K[X]\<^esub> q\<close> have "p divides\<^bsub>K [X]\<^esub> q"
- unfolding associated_def by simp
- hence "p divides\<^bsub>poly_ring R\<^esub> q"
- using carrier_polynomial[OF assms(1)]
- unfolding factor_def univ_poly_carrier univ_poly_mult by auto
- with \<open>q \<noteq> []\<close> have "degree p \<le> degree q"
- using pdivides_imp_degree_le[OF assms(1) p q] unfolding pdivides_def by simp
- with \<open>q \<noteq> []\<close> show ?thesis
- by (cases "p = []", auto simp add: Suc_leI le_diff_iff)
- qed
- } note aux_lemma = this
+ have aux_lemma: "length p \<le> length q"
+ if p: "p \<in> carrier (K[X])" and q: "q \<in> carrier (K[X])" and "p \<sim>\<^bsub>K[X]\<^esub> q" for p q
+ proof (cases "q = []")
+ case True with \<open>p \<sim>\<^bsub>K[X]\<^esub> q\<close> have "p = []"
+ unfolding associated_def True factor_def univ_poly_def by auto
+ thus ?thesis
+ using True by simp
+ next
+ case False
+ from \<open>p \<sim>\<^bsub>K[X]\<^esub> q\<close> have "p divides\<^bsub>K [X]\<^esub> q"
+ unfolding associated_def by simp
+ hence "p divides\<^bsub>poly_ring R\<^esub> q"
+ using carrier_polynomial[OF assms(1)]
+ unfolding factor_def univ_poly_carrier univ_poly_mult by auto
+ with \<open>q \<noteq> []\<close> have "degree p \<le> degree q"
+ using pdivides_imp_degree_le[OF assms(1) p q] unfolding pdivides_def by simp
+ with \<open>q \<noteq> []\<close> show ?thesis
+ by (cases "p = []", auto simp add: Suc_leI le_diff_iff)
+ qed
interpret UP: domain "K[X]"
using univ_poly_is_domain[OF assms(1)] .
@@ -896,21 +894,23 @@
interpret UP: domain "K[X]"
using univ_poly_is_domain[OF assms(1)] .
- { fix q r
- assume q: "q \<in> carrier (K[X])" and r: "r \<in> carrier (K[X])" and "[ a, b ] = q \<otimes>\<^bsub>K[X]\<^esub> r"
- hence not_zero: "q \<noteq> []" "r \<noteq> []"
+ have aux_lemma1: "degree q + degree r = 1" "q \<noteq> []" "r \<noteq> []"
+ if q: "q \<in> carrier (K[X])" and r: "r \<in> carrier (K[X])" and "[ a, b ] = q \<otimes>\<^bsub>K[X]\<^esub> r" for q r
+ proof -
+ from that have not_zero: "q \<noteq> []" "r \<noteq> []"
by (metis UP.integral_iff list.distinct(1) univ_poly_zero)+
have "degree (q \<otimes>\<^bsub>K[X]\<^esub> r) = degree q + degree r"
using not_zero poly_mult_degree_eq[OF assms(1)] q r
by (simp add: univ_poly_carrier univ_poly_mult)
- with sym[OF \<open>[ a, b ] = q \<otimes>\<^bsub>K[X]\<^esub> r\<close>] have "degree q + degree r = 1" and "q \<noteq> []" "r \<noteq> []"
+ with sym[OF \<open>[ a, b ] = q \<otimes>\<^bsub>K[X]\<^esub> r\<close>] show "degree q + degree r = 1" and "q \<noteq> []" "r \<noteq> []"
using not_zero by auto
- } note aux_lemma1 = this
+ qed
- { fix q r
- assume q: "q \<in> carrier (K[X])" "q \<noteq> []" and r: "r \<in> carrier (K[X])" "r \<noteq> []"
- and "[ a, b ] = q \<otimes>\<^bsub>K[X]\<^esub> r" and "degree q = 1" and "degree r = 0"
- hence "length q = Suc (Suc 0)" and "length r = Suc 0"
+ have aux_lemma2: "r \<in> Units (K[X])"
+ if q: "q \<in> carrier (K[X])" "q \<noteq> []" and r: "r \<in> carrier (K[X])" "r \<noteq> []"
+ and "[ a, b ] = q \<otimes>\<^bsub>K[X]\<^esub> r" and "degree q = 1" and "degree r = 0" for q r
+ proof -
+ from that have "length q = Suc (Suc 0)" and "length r = Suc 0"
by (linarith, metis add.right_neutral add_eq_if length_0_conv)
from \<open>length q = Suc (Suc 0)\<close> obtain c d where q_def: "q = [ c, d ]"
by (metis length_0_conv length_Cons list.exhaust nat.inject)
@@ -933,9 +933,9 @@
moreover have "[ c \<otimes> inv_a ] \<otimes>\<^bsub>K[X]\<^esub> r = [ \<one> ]"
using \<open>a = c \<otimes> e\<close> a inv_a c e subsetD[OF subringE(1)[OF assms(1)]]
unfolding r_def univ_poly_mult by (auto) (simp add: m_assoc m_lcomm integral_iff)+
- ultimately have "r \<in> Units (K[X])"
+ ultimately show ?thesis
using r(1) UP.m_comm[OF in_carrier r(1)] unfolding sym[OF univ_poly_one[of R K]] Units_def by auto
- } note aux_lemma2 = this
+ qed
fix q r
assume q: "q \<in> carrier (K[X])" and r: "r \<in> carrier (K[X])" and qr: "[ a, b ] = q \<otimes>\<^bsub>K[X]\<^esub> r"
@@ -1264,24 +1264,24 @@
interpret UP: domain "poly_ring R"
using univ_poly_is_domain[OF carrier_is_subring] .
- { fix p q
- assume p: "p \<in> carrier (poly_ring R)" and q: "q \<in> carrier (poly_ring R)" and pq: "p \<sim>\<^bsub>poly_ring R\<^esub> q"
- have "is_root p x \<Longrightarrow> is_root q x"
- proof -
- assume is_root: "is_root p x"
- then have "[ \<one>, \<ominus> x ] pdivides p" and "p \<noteq> []" and "x \<in> carrier R"
- using is_root_imp_pdivides[OF p] unfolding is_root_def by auto
- moreover have "[ \<one>, \<ominus> x ] \<in> carrier (poly_ring R)"
- using is_root unfolding is_root_def sym[OF univ_poly_carrier] polynomial_def by simp
- ultimately have "[ \<one>, \<ominus> x ] pdivides q"
- using UP.divides_cong_r[OF _ pq ] unfolding pdivides_def by simp
- with \<open>p \<noteq> []\<close> and \<open>x \<in> carrier R\<close> show ?thesis
- using associated_polynomials_imp_same_length[OF carrier_is_subring p q pq]
- pdivides_imp_is_root[of q x]
- by fastforce
- qed
- }
-
+ have "is_root q x"
+ if p: "p \<in> carrier (poly_ring R)"
+ and q: "q \<in> carrier (poly_ring R)"
+ and pq: "p \<sim>\<^bsub>poly_ring R\<^esub> q"
+ and is_root: "is_root p x"
+ for p q
+ proof -
+ from is_root have "[ \<one>, \<ominus> x ] pdivides p" and "p \<noteq> []" and "x \<in> carrier R"
+ using is_root_imp_pdivides[OF p] unfolding is_root_def by auto
+ moreover have "[ \<one>, \<ominus> x ] \<in> carrier (poly_ring R)"
+ using is_root unfolding is_root_def sym[OF univ_poly_carrier] polynomial_def by simp
+ ultimately have "[ \<one>, \<ominus> x ] pdivides q"
+ using UP.divides_cong_r[OF _ pq ] unfolding pdivides_def by simp
+ with \<open>p \<noteq> []\<close> and \<open>x \<in> carrier R\<close> show ?thesis
+ using associated_polynomials_imp_same_length[OF carrier_is_subring p q pq]
+ pdivides_imp_is_root[of q x]
+ by fastforce
+ qed
then show ?thesis
using assms UP.associated_sym[OF assms(3)] by blast
qed
--- a/src/HOL/Algebra/Polynomials.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/Polynomials.thy Wed Nov 13 20:14:24 2024 +0100
@@ -217,29 +217,30 @@
hence deg_eq: "degree p1 = degree p2"
using degree_def'[OF assms(1)] degree_def'[OF assms(2)] by auto
thus "p1 = p2"
- proof (cases)
- assume "p1 \<noteq> [] \<and> p2 \<noteq> []"
+ proof (cases "p1 \<noteq> [] \<and> p2 \<noteq> []")
+ case True
hence "length p1 = length p2"
using deg_eq by (simp add: Nitpick.size_list_simp(2))
thus ?thesis
using coeff_iff_length_cond[of p1 p2] coeff_eq by simp
next
- { fix p1 p2 assume A: "p1 = []" "coeff p1 = coeff p2" "polynomial K p2"
- have "p2 = []"
- proof (rule ccontr)
- assume "p2 \<noteq> []"
- hence "(coeff p2) (degree p2) \<noteq> \<zero>"
- using A(3) unfolding polynomial_def
- by (metis coeff.simps(2) list.collapse)
- moreover have "(coeff p1) ` UNIV = { \<zero> }"
- using A(1) by auto
- hence "(coeff p2) ` UNIV = { \<zero> }"
- using A(2) by simp
- ultimately show False
- by blast
- qed } note aux_lemma = this
- assume "\<not> (p1 \<noteq> [] \<and> p2 \<noteq> [])"
- hence "p1 = [] \<or> p2 = []" by simp
+ case False
+ have aux_lemma: "p2 = []"
+ if A: "p1 = []" "coeff p1 = coeff p2" "polynomial K p2"
+ for p1 p2
+ proof (rule ccontr)
+ assume "p2 \<noteq> []"
+ hence "(coeff p2) (degree p2) \<noteq> \<zero>"
+ using A(3) unfolding polynomial_def
+ by (metis coeff.simps(2) list.collapse)
+ moreover have "(coeff p1) ` UNIV = { \<zero> }"
+ using A(1) by auto
+ hence "(coeff p2) ` UNIV = { \<zero> }"
+ using A(2) by simp
+ ultimately show False
+ by blast
+ qed
+ from False have "p1 = [] \<or> p2 = []" by simp
thus ?thesis
using assms coeff_eq aux_lemma[of p1 p2] aux_lemma[of p2 p1] by auto
qed
@@ -409,20 +410,19 @@
assumes "set p1 \<subseteq> K" and "set p2 \<subseteq> K"
shows "polynomial K (poly_add p1 p2)"
proof -
- { fix p1 p2 assume A: "set p1 \<subseteq> K" "set p2 \<subseteq> K" "length p1 \<ge> length p2"
- hence "polynomial K (poly_add p1 p2)"
- proof -
- define p2' where "p2' = (replicate (length p1 - length p2) \<zero>) @ p2"
- hence "set p2' \<subseteq> K" and "length p1 = length p2'"
- using A(2-3) subringE(2)[OF K] by auto
- hence "set (map2 (\<oplus>) p1 p2') \<subseteq> K"
- using A(1) subringE(7)[OF K]
- by (induct p1) (auto, metis set_ConsD subsetD set_zip_leftD set_zip_rightD)
- thus ?thesis
- unfolding p2'_def using normalize_gives_polynomial A(3) by simp
- qed }
- thus ?thesis
- using assms by auto
+ have "polynomial K (poly_add p1 p2)"
+ if A: "set p1 \<subseteq> K" "set p2 \<subseteq> K" "length p1 \<ge> length p2" for p1 p2
+ proof -
+ define p2' where "p2' = (replicate (length p1 - length p2) \<zero>) @ p2"
+ hence "set p2' \<subseteq> K" and "length p1 = length p2'"
+ using A(2-3) subringE(2)[OF K] by auto
+ hence "set (map2 (\<oplus>) p1 p2') \<subseteq> K"
+ using A(1) subringE(7)[OF K]
+ by (induct p1) (auto, metis set_ConsD subsetD set_zip_leftD set_zip_rightD)
+ thus ?thesis
+ unfolding p2'_def using normalize_gives_polynomial A(3) by simp
+ qed
+ thus ?thesis using assms by auto
qed
lemma poly_add_closed: "\<lbrakk> polynomial K p1; polynomial K p2 \<rbrakk> \<Longrightarrow> polynomial K (poly_add p1 p2)"
@@ -432,29 +432,28 @@
assumes "polynomial K p1" "polynomial K p2" and "length p1 \<noteq> length p2"
shows "length (poly_add p1 p2) = max (length p1) (length p2)"
proof -
- { fix p1 p2 assume A: "polynomial K p1" "polynomial K p2" "length p1 > length p2"
- hence "length (poly_add p1 p2) = max (length p1) (length p2)"
- proof -
- let ?p2 = "(replicate (length p1 - length p2) \<zero>) @ p2"
- have p1: "p1 \<noteq> []" and p2: "?p2 \<noteq> []"
- using A(3) by auto
- then have "zip p1 (replicate (length p1 - length p2) \<zero> @ p2) = zip (lead_coeff p1 # tl p1) (lead_coeff (replicate (length p1 - length p2) \<zero> @ p2) # tl (replicate (length p1 - length p2) \<zero> @ p2))"
- by auto
- hence "lead_coeff (map2 (\<oplus>) p1 ?p2) = lead_coeff p1 \<oplus> lead_coeff ?p2"
- by simp
- moreover have "lead_coeff p1 \<in> carrier R"
- using p1 A(1) lead_coeff_in_carrier[OF K, of "hd p1" "tl p1"] by auto
- ultimately have "lead_coeff (map2 (\<oplus>) p1 ?p2) = lead_coeff p1"
- using A(3) by auto
- moreover have "lead_coeff p1 \<noteq> \<zero>"
- using p1 A(1) unfolding polynomial_def by simp
- ultimately have "length (normalize (map2 (\<oplus>) p1 ?p2)) = length p1"
- using normalize_length_eq by auto
- thus ?thesis
- using A(3) by auto
- qed }
- thus ?thesis
- using assms by auto
+ have "length (poly_add p1 p2) = max (length p1) (length p2)"
+ if A: "polynomial K p1" "polynomial K p2" "length p1 > length p2" for p1 p2
+ proof -
+ let ?p2 = "(replicate (length p1 - length p2) \<zero>) @ p2"
+ have p1: "p1 \<noteq> []" and p2: "?p2 \<noteq> []"
+ using A(3) by auto
+ then have "zip p1 (replicate (length p1 - length p2) \<zero> @ p2) =
+ zip (lead_coeff p1 # tl p1) (lead_coeff (replicate (length p1 - length p2) \<zero> @ p2) # tl (replicate (length p1 - length p2) \<zero> @ p2))"
+ by auto
+ hence "lead_coeff (map2 (\<oplus>) p1 ?p2) = lead_coeff p1 \<oplus> lead_coeff ?p2"
+ by simp
+ moreover have "lead_coeff p1 \<in> carrier R"
+ using p1 A(1) lead_coeff_in_carrier[OF K, of "hd p1" "tl p1"] by auto
+ ultimately have "lead_coeff (map2 (\<oplus>) p1 ?p2) = lead_coeff p1"
+ using A(3) by auto
+ moreover have "lead_coeff p1 \<noteq> \<zero>"
+ using p1 A(1) unfolding polynomial_def by simp
+ ultimately have "length (normalize (map2 (\<oplus>) p1 ?p2)) = length p1"
+ using normalize_length_eq by auto
+ thus ?thesis using A(3) by auto
+ qed
+ thus ?thesis using assms by auto
qed
lemma poly_add_degree_eq:
@@ -471,10 +470,10 @@
lemma poly_add_length_le: "length (poly_add p1 p2) \<le> max (length p1) (length p2)"
proof -
- { fix p1 p2 :: "'a list" assume A: "length p1 \<ge> length p2"
- let ?p2 = "(replicate (length p1 - length p2) \<zero>) @ p2"
- have "length (poly_add p1 p2) \<le> max (length p1) (length p2)"
- using normalize_length_le[of "map2 (\<oplus>) p1 ?p2"] A by auto }
+ have "length (poly_add p1 p2) \<le> max (length p1) (length p2)"
+ if "length p1 \<ge> length p2" for p1 p2 :: "'a list"
+ using normalize_length_le[of "map2 (\<oplus>) p1 ((replicate (length p1 - length p2) \<zero>) @ p2)"] that
+ by auto
thus ?thesis
by (metis le_cases max.commute poly_add.simps)
qed
@@ -582,57 +581,58 @@
assumes "set p1 \<subseteq> carrier R" "set p2 \<subseteq> carrier R"
shows "poly_add p1 p2 = poly_add (normalize p1) p2"
proof -
- { fix n p1 p2 assume "set p1 \<subseteq> carrier R" "set p2 \<subseteq> carrier R"
- hence "poly_add p1 p2 = poly_add ((replicate n \<zero>) @ p1) p2"
- proof (induction n)
- case 0 thus ?case by simp
- next
- { fix p1 p2 :: "'a list"
- assume in_carrier: "set p1 \<subseteq> carrier R" "set p2 \<subseteq> carrier R"
- have "poly_add p1 p2 = poly_add (\<zero> # p1) p2"
- proof -
- have "length p1 \<ge> length p2 \<Longrightarrow> ?thesis"
- proof -
- assume A: "length p1 \<ge> length p2"
- let ?p2 = "\<lambda>n. (replicate n \<zero>) @ p2"
- have "poly_add p1 p2 = normalize (map2 (\<oplus>) (\<zero> # p1) (\<zero> # ?p2 (length p1 - length p2)))"
- using A by simp
- also have " ... = normalize (map2 (\<oplus>) (\<zero> # p1) (?p2 (length (\<zero> # p1) - length p2)))"
- by (simp add: A Suc_diff_le)
- also have " ... = poly_add (\<zero> # p1) p2"
- using A by simp
- finally show ?thesis .
- qed
+ have aux_lemma: "poly_add p1 p2 = poly_add ((replicate n \<zero>) @ p1) p2"
+ if "set p1 \<subseteq> carrier R" "set p2 \<subseteq> carrier R"
+ for n p1 p2
+ using that
+ proof (induction n)
+ case 0
+ thus ?case by simp
+ next
+ case (Suc n)
+ have aux_lemma: "poly_add p1 p2 = poly_add (\<zero> # p1) p2"
+ if in_carrier: "set p1 \<subseteq> carrier R" "set p2 \<subseteq> carrier R"
+ for p1 p2
+ proof -
+ have "length p1 \<ge> length p2 \<Longrightarrow> ?thesis"
+ proof -
+ assume A: "length p1 \<ge> length p2"
+ let ?p2 = "\<lambda>n. (replicate n \<zero>) @ p2"
+ have "poly_add p1 p2 = normalize (map2 (\<oplus>) (\<zero> # p1) (\<zero> # ?p2 (length p1 - length p2)))"
+ using A by simp
+ also have " ... = normalize (map2 (\<oplus>) (\<zero> # p1) (?p2 (length (\<zero> # p1) - length p2)))"
+ by (simp add: A Suc_diff_le)
+ also have " ... = poly_add (\<zero> # p1) p2"
+ using A by simp
+ finally show ?thesis .
+ qed
+ moreover have "length p2 > length p1 \<Longrightarrow> ?thesis"
+ proof -
+ assume A: "length p2 > length p1"
+ let ?f = "\<lambda>n p. (replicate n \<zero>) @ p"
+ have "poly_add p1 p2 = poly_add p2 p1"
+ using A by simp
+ also have " ... = normalize (map2 (\<oplus>) p2 (?f (length p2 - length p1) p1))"
+ using A by simp
+ also have " ... = normalize (map2 (\<oplus>) p2 (?f (length p2 - Suc (length p1)) (\<zero> # p1)))"
+ by (metis A Suc_diff_Suc append_Cons replicate_Suc replicate_app_Cons_same)
+ also have " ... = poly_add p2 (\<zero> # p1)"
+ using A by simp
+ also have " ... = poly_add (\<zero> # p1) p2"
+ using poly_add_comm[of p2 "\<zero> # p1"] in_carrier by auto
+ finally show ?thesis .
+ qed
+ ultimately show ?thesis by auto
+ qed
- moreover have "length p2 > length p1 \<Longrightarrow> ?thesis"
- proof -
- assume A: "length p2 > length p1"
- let ?f = "\<lambda>n p. (replicate n \<zero>) @ p"
- have "poly_add p1 p2 = poly_add p2 p1"
- using A by simp
- also have " ... = normalize (map2 (\<oplus>) p2 (?f (length p2 - length p1) p1))"
- using A by simp
- also have " ... = normalize (map2 (\<oplus>) p2 (?f (length p2 - Suc (length p1)) (\<zero> # p1)))"
- by (metis A Suc_diff_Suc append_Cons replicate_Suc replicate_app_Cons_same)
- also have " ... = poly_add p2 (\<zero> # p1)"
- using A by simp
- also have " ... = poly_add (\<zero> # p1) p2"
- using poly_add_comm[of p2 "\<zero> # p1"] in_carrier by auto
- finally show ?thesis .
- qed
-
- ultimately show ?thesis by auto
- qed } note aux_lemma = this
-
- case (Suc n)
- hence in_carrier: "set (replicate n \<zero> @ p1) \<subseteq> carrier R"
- by auto
- have "poly_add p1 p2 = poly_add (replicate n \<zero> @ p1) p2"
- using Suc by simp
- also have " ... = poly_add (replicate (Suc n) \<zero> @ p1) p2"
- using aux_lemma[OF in_carrier Suc(3)] by simp
- finally show ?case .
- qed } note aux_lemma = this
+ from Suc have in_carrier: "set (replicate n \<zero> @ p1) \<subseteq> carrier R"
+ by auto
+ have "poly_add p1 p2 = poly_add (replicate n \<zero> @ p1) p2"
+ using Suc by simp
+ also have " ... = poly_add (replicate (Suc n) \<zero> @ p1) p2"
+ using aux_lemma[OF in_carrier Suc(3)] by simp
+ finally show ?case .
+ qed
have "poly_add p1 p2 =
poly_add ((replicate (length p1 - length (normalize p1)) \<zero>) @ normalize p1) p2"
@@ -935,29 +935,29 @@
assumes "set p1 \<subseteq> carrier R" "set p2 \<subseteq> carrier R"
shows "poly_mult p1 p2 = poly_mult ((replicate n \<zero>) @ p1) p2"
proof -
- { fix p1 p2 assume A: "set p1 \<subseteq> carrier R" "set p2 \<subseteq> carrier R"
- hence "poly_mult p1 p2 = poly_mult (\<zero> # p1) p2"
- proof -
- let ?a_p2 = "(map ((\<otimes>) \<zero>) p2) @ (replicate (length p1) \<zero>)"
- have "?a_p2 = replicate (length p2 + length p1) \<zero>"
- using A(2) by (induction p2) (auto)
- hence "poly_mult (\<zero> # p1) p2 = poly_add (replicate (length p2 + length p1) \<zero>) (poly_mult p1 p2)"
- by simp
- also have " ... = poly_add (normalize (replicate (length p2 + length p1) \<zero>)) (poly_mult p1 p2)"
- using poly_add_normalize(1)[of "replicate (length p2 + length p1) \<zero>" "poly_mult p1 p2"]
- poly_mult_in_carrier[OF A] by force
- also have " ... = poly_mult p1 p2"
- using poly_add_zero(2)[OF _ poly_mult_is_polynomial[OF _ A]] carrier_is_subring
- normalize_replicate_zero[of "length p2 + length p1" "[]"] by simp
- finally show ?thesis by auto
- qed } note aux_lemma = this
-
+ have aux_lemma: "poly_mult p1 p2 = poly_mult (\<zero> # p1) p2"
+ if A: "set p1 \<subseteq> carrier R" "set p2 \<subseteq> carrier R" for p1 p2
+ proof -
+ let ?a_p2 = "(map ((\<otimes>) \<zero>) p2) @ (replicate (length p1) \<zero>)"
+ have "?a_p2 = replicate (length p2 + length p1) \<zero>"
+ using A(2) by (induction p2) (auto)
+ hence "poly_mult (\<zero> # p1) p2 = poly_add (replicate (length p2 + length p1) \<zero>) (poly_mult p1 p2)"
+ by simp
+ also have " ... = poly_add (normalize (replicate (length p2 + length p1) \<zero>)) (poly_mult p1 p2)"
+ using poly_add_normalize(1)[of "replicate (length p2 + length p1) \<zero>" "poly_mult p1 p2"]
+ poly_mult_in_carrier[OF A] by force
+ also have " ... = poly_mult p1 p2"
+ using poly_add_zero(2)[OF _ poly_mult_is_polynomial[OF _ A]] carrier_is_subring
+ normalize_replicate_zero[of "length p2 + length p1" "[]"] by simp
+ finally show ?thesis by auto
+ qed
from assms show ?thesis
proof (induction n)
- case 0 thus ?case by simp
+ case 0
+ thus ?case by simp
next
- case (Suc n) thus ?case
- using aux_lemma[of "replicate n \<zero> @ p1" p2] by force
+ case (Suc n)
+ thus ?case using aux_lemma[of "replicate n \<zero> @ p1" p2] by force
qed
qed
@@ -1896,14 +1896,15 @@
assumes "set p \<subseteq> carrier R" "set q \<subseteq> carrier R" and "a \<in> carrier R"
shows "eval (poly_add p q) a = (eval p a) \<oplus> (eval q a)"
proof -
- { fix p q assume A: "set p \<subseteq> carrier R" "set q \<subseteq> carrier R" "length p \<ge> length q"
- hence "eval (poly_add p ((replicate (length p - length q) \<zero>) @ q)) a =
+ have aux_lemma: "eval (poly_add p q) a = (eval p a) \<oplus> (eval q a)"
+ if A: "set p \<subseteq> carrier R" "set q \<subseteq> carrier R" "length p \<ge> length q" for p q
+ proof -
+ from that have "eval (poly_add p ((replicate (length p - length q) \<zero>) @ q)) a =
(eval p a) \<oplus> (eval ((replicate (length p - length q) \<zero>) @ q) a)"
using eval_poly_add_aux[OF A(1) _ _ assms(3), of "(replicate (length p - length q) \<zero>) @ q"] by force
- hence "eval (poly_add p q) a = (eval p a) \<oplus> (eval q a)"
- using eval_replicate[OF A(2) assms(3)] A(3) by auto }
- note aux_lemma = this
-
+ then show "eval (poly_add p q) a = (eval p a) \<oplus> (eval q a)"
+ using eval_replicate[OF A(2) assms(3)] A(3) by auto
+ qed
have ?thesis if "length q \<ge> length p"
using assms(1-2)[THEN eval_in_carrier[OF _ assms(3)]] poly_add_comm[OF assms(1-2)]
aux_lemma[OF assms(2,1) that]
@@ -1978,8 +1979,12 @@
case Nil thus ?case
using eval_in_carrier[OF assms(2-3)] by simp
next
- { fix n b assume b: "b \<in> carrier R"
- hence "set (map ((\<otimes>) b) q) \<subseteq> carrier R" and "set (replicate n \<zero>) \<subseteq> carrier R"
+ case (Cons b p)
+
+ have aux_lemma: "eval ((map ((\<otimes>) b) q) @ (replicate n \<zero>)) a = (eval (monom b n) a) \<otimes> (eval q a)"
+ if b: "b \<in> carrier R" for n b
+ proof -
+ from that have "set (map ((\<otimes>) b) q) \<subseteq> carrier R" and "set (replicate n \<zero>) \<subseteq> carrier R"
using assms(2) by (induct q) (auto)
hence "eval ((map ((\<otimes>) b) q) @ (replicate n \<zero>)) a = (eval ((map ((\<otimes>) b) q)) a) \<otimes> (a [^] n) \<oplus> \<zero>"
using eval_append[OF _ _ assms(3), of "map ((\<otimes>) b) q" "replicate n \<zero>"]
@@ -1990,12 +1995,11 @@
by simp
also have " ... = (b \<otimes> (a [^] n)) \<otimes> (eval q a)"
using eval_in_carrier[OF assms(2-3)] b assms(3) m_assoc m_comm by auto
- finally have "eval ((map ((\<otimes>) b) q) @ (replicate n \<zero>)) a = (eval (monom b n) a) \<otimes> (eval q a)"
- using eval_monom[OF b assms(3)] by simp }
- note aux_lemma = this
+ finally show ?thesis
+ using eval_monom[OF b assms(3)] by simp
+ qed
- case (Cons b p)
- hence in_carrier:
+ from Cons have in_carrier:
"eval (monom b (length p)) a \<in> carrier R" "eval p a \<in> carrier R" "eval q a \<in> carrier R" "b \<in> carrier R"
using eval_in_carrier monom_in_carrier assms by auto
have set_map: "set ((map ((\<otimes>) b) q) @ (replicate (length p) \<zero>)) \<subseteq> carrier R"
@@ -2183,43 +2187,52 @@
interpret UP: domain "K[X]"
using univ_poly_is_domain[OF assms(1)] .
- { fix l assume "set l \<subseteq> K"
- hence "poly_of_const a \<in> carrier (K[X])" if "a \<in> set l" for a
+ have aux_lemma1: "set (?map_norm l) \<subseteq> carrier (K[X])" if "set l \<subseteq> K" for l
+ proof -
+ from that have "poly_of_const a \<in> carrier (K[X])" if "a \<in> set l" for a
using that normalize_gives_polynomial[of "[ a ]" K]
unfolding univ_poly_carrier poly_of_const_def by auto
- hence "set (?map_norm l) \<subseteq> carrier (K[X])"
- by auto }
- note aux_lemma1 = this
+ then show ?thesis by auto
+ qed
- { fix q l assume set_l: "set l \<subseteq> K" and q: "q \<in> carrier (K[X])"
- from set_l have "UP.eval (?map_norm l) q = UP.eval (?map_norm ((replicate n \<zero>) @ l)) q" for n
- proof (induct n, simp)
- case (Suc n)
- from \<open>set l \<subseteq> K\<close> have set_replicate: "set ((replicate n \<zero>) @ l) \<subseteq> K"
- using subringE(2)[OF assms(1)] by (induct n) (auto)
- have step: "UP.eval (?map_norm l') q = UP.eval (?map_norm (\<zero> # l')) q" if "set l' \<subseteq> K" for l'
- using UP.eval_in_carrier[OF aux_lemma1[OF that]] q unfolding poly_of_const_def
- by (simp, simp add: sym[OF univ_poly_zero[of R K]])
- have "UP.eval (?map_norm l) q = UP.eval (?map_norm ((replicate n \<zero>) @ l)) q"
- using Suc by simp
- also have " ... = UP.eval (map poly_of_const ((replicate (Suc n) \<zero>) @ l)) q"
- using step[OF set_replicate] by simp
- finally show ?case .
- qed }
- note aux_lemma2 = this
+ have aux_lemma2: "UP.eval (?map_norm l) q = UP.eval (?map_norm ((replicate n \<zero>) @ l)) q"
+ if set_l: "set l \<subseteq> K" and q: "q \<in> carrier (K[X])"
+ for n q l
+ using set_l
+ proof (induct n)
+ case 0
+ then show ?case by simp
+ next
+ case (Suc n)
+ from \<open>set l \<subseteq> K\<close> have set_replicate: "set ((replicate n \<zero>) @ l) \<subseteq> K"
+ using subringE(2)[OF assms(1)] by (induct n) (auto)
+ have step: "UP.eval (?map_norm l') q = UP.eval (?map_norm (\<zero> # l')) q" if "set l' \<subseteq> K" for l'
+ using UP.eval_in_carrier[OF aux_lemma1[OF that]] q unfolding poly_of_const_def
+ by (simp, simp add: sym[OF univ_poly_zero[of R K]])
+ have "UP.eval (?map_norm l) q = UP.eval (?map_norm ((replicate n \<zero>) @ l)) q"
+ using Suc by simp
+ also have " ... = UP.eval (map poly_of_const ((replicate (Suc n) \<zero>) @ l)) q"
+ using step[OF set_replicate] by simp
+ finally show ?case .
+ qed
- { fix q l assume "set l \<subseteq> K" and q: "q \<in> carrier (K[X])"
+ have aux_lemma3: "UP.eval (?map_norm l) q = UP.eval (?map_norm (normalize l)) q"
+ if "set l \<subseteq> K" and q: "q \<in> carrier (K[X])" for q l
+ proof -
from \<open>set l \<subseteq> K\<close> have set_norm: "set (normalize l) \<subseteq> K"
by (induct l) (auto)
- have "UP.eval (?map_norm l) q = UP.eval (?map_norm (normalize l)) q"
+ show ?thesis
using aux_lemma2[OF set_norm q, of "length l - length (local.normalize l)"]
- unfolding sym[OF normalize_trick[of l]] .. }
- note aux_lemma3 = this
+ unfolding sym[OF normalize_trick[of l]] ..
+ qed
from \<open>p \<in> carrier (K[X])\<close> show ?thesis
proof (induct "length p" arbitrary: p rule: less_induct)
case less thus ?case
- proof (cases p, simp add: univ_poly_zero)
+ proof (cases p)
+ case Nil
+ then show ?thesis by (simp add: univ_poly_zero)
+ next
case (Cons a l)
hence a: "a \<in> carrier R - { \<zero> }" and set_l: "set l \<subseteq> carrier R" "set l \<subseteq> K"
using less(2) subringE(1)[OF assms(1)] unfolding sym[OF univ_poly_carrier] polynomial_def by auto
--- a/src/HOL/Algebra/Ring_Divisibility.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/Ring_Divisibility.thy Wed Nov 13 20:14:24 2024 +0100
@@ -518,22 +518,22 @@
assumes "C \<noteq> {}" "subset.chain { I. ideal I R } C"
shows "\<Union>C \<in> C"
proof -
- { fix S assume "finite S" "S \<subseteq> \<Union>C"
- hence "\<exists>I. I \<in> C \<and> S \<subseteq> I"
- proof (induct S)
- case empty thus ?case
- using assms(1) by blast
- next
- case (insert s S)
- then obtain I where I: "I \<in> C" "S \<subseteq> I"
- by blast
- moreover obtain I' where I': "I' \<in> C" "s \<in> I'"
- using insert(4) by blast
- ultimately have "I \<subseteq> I' \<or> I' \<subseteq> I"
- using assms unfolding pred_on.chain_def by blast
- thus ?case
- using I I' by blast
- qed } note aux_lemma = this
+ have aux_lemma: "\<exists>I. I \<in> C \<and> S \<subseteq> I" if "finite S" "S \<subseteq> \<Union>C" for S
+ using that
+ proof (induct S)
+ case empty
+ thus ?case using assms(1) by blast
+ next
+ case (insert s S)
+ then obtain I where I: "I \<in> C" "S \<subseteq> I"
+ by blast
+ moreover obtain I' where I': "I' \<in> C" "s \<in> I'"
+ using insert(4) by blast
+ ultimately have "I \<subseteq> I' \<or> I' \<subseteq> I"
+ using assms unfolding pred_on.chain_def by blast
+ thus ?case
+ using I I' by blast
+ qed
obtain S where S: "finite S" "S \<subseteq> carrier R" "\<Union>C = Idl S"
using finetely_gen[OF chain_Union_is_ideal[OF assms(2)]] assms(1) by auto
@@ -805,27 +805,27 @@
assumes "a \<in> carrier R" "b \<in> carrier R" "d \<in> carrier R"
shows "PIdl d = PIdl a <+>\<^bsub>R\<^esub> PIdl b \<longleftrightarrow> d gcdof a b"
proof -
- { fix a b d
- assume in_carrier: "a \<in> carrier R" "b \<in> carrier R" "d \<in> carrier R"
- and ideal_eq: "PIdl d = PIdl a <+>\<^bsub>R\<^esub> PIdl b"
- have "d gcdof a b"
- proof (auto simp add: isgcd_def)
- have "a \<in> PIdl d" and "b \<in> PIdl d"
- using in_carrier(1-2)[THEN cgenideal_ideal] additive_subgroup.zero_closed[OF ideal.axioms(1)]
- in_carrier(1-2)[THEN cgenideal_self] in_carrier(1-2)
- unfolding ideal_eq set_add_def' by force+
- thus "d divides a" and "d divides b"
- using in_carrier(1,2)[THEN to_contain_is_to_divide[OF in_carrier(3)]]
- cgenideal_minimal[OF cgenideal_ideal[OF in_carrier(3)]] by simp+
- next
- fix c assume c: "c \<in> carrier R" "c divides a" "c divides b"
- hence "PIdl a \<subseteq> PIdl c" and "PIdl b \<subseteq> PIdl c"
- using to_contain_is_to_divide in_carrier by auto
- hence "PIdl a <+>\<^bsub>R\<^esub> PIdl b \<subseteq> PIdl c"
- by (metis Un_subset_iff c(1) in_carrier(1-2) cgenideal_ideal genideal_minimal union_genideal)
- thus "c divides d"
- using ideal_eq to_contain_is_to_divide[OF c(1) in_carrier(3)] by simp
- qed } note aux_lemma = this
+ have aux_lemma: "d gcdof a b"
+ if in_carrier: "a \<in> carrier R" "b \<in> carrier R" "d \<in> carrier R"
+ and ideal_eq: "PIdl d = PIdl a <+>\<^bsub>R\<^esub> PIdl b"
+ for a b d
+ proof (auto simp add: isgcd_def)
+ have "a \<in> PIdl d" and "b \<in> PIdl d"
+ using in_carrier(1-2)[THEN cgenideal_ideal] additive_subgroup.zero_closed[OF ideal.axioms(1)]
+ in_carrier(1-2)[THEN cgenideal_self] in_carrier(1-2)
+ unfolding ideal_eq set_add_def' by force+
+ thus "d divides a" and "d divides b"
+ using in_carrier(1,2)[THEN to_contain_is_to_divide[OF in_carrier(3)]]
+ cgenideal_minimal[OF cgenideal_ideal[OF in_carrier(3)]] by simp+
+ next
+ fix c assume c: "c \<in> carrier R" "c divides a" "c divides b"
+ hence "PIdl a \<subseteq> PIdl c" and "PIdl b \<subseteq> PIdl c"
+ using to_contain_is_to_divide in_carrier by auto
+ hence "PIdl a <+>\<^bsub>R\<^esub> PIdl b \<subseteq> PIdl c"
+ by (metis Un_subset_iff c(1) in_carrier(1-2) cgenideal_ideal genideal_minimal union_genideal)
+ thus "c divides d"
+ using ideal_eq to_contain_is_to_divide[OF c(1) in_carrier(3)] by simp
+ qed
have "PIdl d = PIdl a <+>\<^bsub>R\<^esub> PIdl b \<Longrightarrow> d gcdof a b"
using aux_lemma assms by simp
--- a/src/HOL/Algebra/SndIsomorphismGrp.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/SndIsomorphismGrp.thy Wed Nov 13 20:14:24 2024 +0100
@@ -119,15 +119,14 @@
have "group ((G\<lparr>carrier := H <#> S\<rparr>) Mod H)"
by (simp add: H_contained_in_set_mult normal.factorgroup_is_group normal_axioms
normal_restrict_supergroup normal_set_mult_subgroup)
- moreover
- { fix g
- assume g: "g \<in> S"
- with g have "g \<in> H <#> S"
+ moreover have "H #> g \<in> carrier ((G\<lparr>carrier := H <#> S\<rparr>) Mod H)" if g: "g \<in> S" for g
+ proof -
+ from g that have "g \<in> H <#> S"
using S_contained_in_set_mult by blast
- hence "H #> g \<in> carrier ((G\<lparr>carrier := H <#> S\<rparr>) Mod H)"
- unfolding FactGroup_def RCOSETS_def r_coset_def by auto }
- moreover
- have "\<And>x y. \<lbrakk>x \<in> S; y \<in> S\<rbrakk> \<Longrightarrow> H #> x \<otimes> y = H #> x <#> (H #> y)"
+ thus "H #> g \<in> carrier ((G\<lparr>carrier := H <#> S\<rparr>) Mod H)"
+ unfolding FactGroup_def RCOSETS_def r_coset_def by auto
+ qed
+ moreover have "\<And>x y. \<lbrakk>x \<in> S; y \<in> S\<rbrakk> \<Longrightarrow> H #> x \<otimes> y = H #> x <#> (H #> y)"
using normal.rcos_sum normal_axioms subgroup.mem_carrier subgrpS by fastforce
ultimately show ?thesis
by (auto simp: group_hom_def group_hom_axioms_def hom_def)
--- a/src/HOL/Algebra/Sym_Groups.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/Sym_Groups.thy Wed Nov 13 20:14:24 2024 +0100
@@ -207,19 +207,22 @@
shows "\<exists>a b A' p'. a \<noteq> b \<and> A = (insert a (insert b A')) \<and>
swapidseq_ext A' n p' \<and> p = (transpose a b) \<circ> p'"
proof -
- { fix A n k and p :: "'a \<Rightarrow> 'a"
- assume "swapidseq_ext A n p" "n = Suc k"
- hence "\<exists>a b A' p'. a \<noteq> b \<and> A = (insert a (insert b A')) \<and>
- swapidseq_ext A' k p' \<and> p = (transpose a b) \<circ> p'"
- proof (induction, simp)
- case single thus ?case
- by (metis Un_insert_right insert_iff insert_is_Un swapidseq_ext.single)
- next
- case comp thus ?case
- by blast
- qed }
- thus ?thesis
- using assms by simp
+ have "\<exists>a b A' p'. a \<noteq> b \<and> A = (insert a (insert b A')) \<and>
+ swapidseq_ext A' k p' \<and> p = (transpose a b) \<circ> p'"
+ if "swapidseq_ext A n p" "n = Suc k"
+ for A n k and p :: "'a \<Rightarrow> 'a"
+ using that
+ proof (induction)
+ case empty
+ thus ?case by simp
+ next
+ case single
+ thus ?case by (metis Un_insert_right insert_iff insert_is_Un swapidseq_ext.single)
+ next
+ case comp
+ thus ?case by blast
+ qed
+ thus ?thesis using assms by simp
qed
lemma swapidseq_ext_backwards':
@@ -369,61 +372,61 @@
proof
show "generate (alt_group n) (three_cycles n) \<subseteq> carrier (alt_group n)"
using A.generate_subgroup_incl[OF three_cycles_incl A.subgroup_self] .
- next
show "carrier (alt_group n) \<subseteq> generate (alt_group n) (three_cycles n)"
proof
- { fix q :: "nat \<Rightarrow> nat" and a b c
- assume "a \<noteq> b" "b \<noteq> c" "{ a, b, c } \<subseteq> {1..n}"
- have "cycle_of_list [a, b, c] \<in> generate (alt_group n) (three_cycles n)"
- proof (cases)
- assume "c = a"
- hence "cycle_of_list [ a, b, c ] = id"
- by (simp add: swap_commute)
- thus "cycle_of_list [ a, b, c ] \<in> generate (alt_group n) (three_cycles n)"
- using one[of "alt_group n"] unfolding alt_group_one by simp
- next
- assume "c \<noteq> a"
- have "distinct [a, b, c]"
- using \<open>a \<noteq> b\<close> and \<open>b \<noteq> c\<close> and \<open>c \<noteq> a\<close> by auto
- with \<open>{ a, b, c } \<subseteq> {1..n}\<close>
- show "cycle_of_list [ a, b, c ] \<in> generate (alt_group n) (three_cycles n)"
- by (intro incl, fastforce)
- qed } note aux_lemma1 = this
+ have aux_lemma1: "cycle_of_list [a, b, c] \<in> generate (alt_group n) (three_cycles n)"
+ if "a \<noteq> b" "b \<noteq> c" "{ a, b, c } \<subseteq> {1..n}"
+ for q :: "nat \<Rightarrow> nat" and a b c
+ proof (cases)
+ assume "c = a"
+ hence "cycle_of_list [ a, b, c ] = id"
+ by (simp add: swap_commute)
+ thus "cycle_of_list [ a, b, c ] \<in> generate (alt_group n) (three_cycles n)"
+ using one[of "alt_group n"] unfolding alt_group_one by simp
+ next
+ assume "c \<noteq> a"
+ have "distinct [a, b, c]"
+ using \<open>a \<noteq> b\<close> and \<open>b \<noteq> c\<close> and \<open>c \<noteq> a\<close> by auto
+ with \<open>{ a, b, c } \<subseteq> {1..n}\<close>
+ show "cycle_of_list [ a, b, c ] \<in> generate (alt_group n) (three_cycles n)"
+ by (intro incl) fastforce
+ qed
- { fix S :: "nat set" and q :: "nat \<Rightarrow> nat"
- assume seq: "swapidseq_ext S (Suc (Suc 0)) q" and S: "S \<subseteq> {1..n}"
- have "q \<in> generate (alt_group n) (three_cycles n)"
- proof -
- obtain a b q' where ab: "a \<noteq> b" "a \<in> S" "b \<in> S"
- and q': "swapidseq_ext S (Suc 0) q'" "q = (transpose a b) \<circ> q'"
- using swapidseq_ext_backwards'[OF seq] by auto
- obtain c d where cd: "c \<noteq> d" "c \<in> S" "d \<in> S"
- and q: "q = (transpose a b) \<circ> (Fun.swap c d id)"
- using swapidseq_ext_backwards'[OF q'(1)]
- swapidseq_ext_zero_imp_id
- unfolding q'(2)
- by fastforce
+ have aux_lemma2: "q \<in> generate (alt_group n) (three_cycles n)"
+ if seq: "swapidseq_ext S (Suc (Suc 0)) q" and S: "S \<subseteq> {1..n}"
+ for S :: "nat set" and q :: "nat \<Rightarrow> nat"
+ proof -
+ obtain a b q' where ab: "a \<noteq> b" "a \<in> S" "b \<in> S"
+ and q': "swapidseq_ext S (Suc 0) q'" "q = (transpose a b) \<circ> q'"
+ using swapidseq_ext_backwards'[OF seq] by auto
+ obtain c d where cd: "c \<noteq> d" "c \<in> S" "d \<in> S"
+ and q: "q = (transpose a b) \<circ> (Fun.swap c d id)"
+ using swapidseq_ext_backwards'[OF q'(1)]
+ swapidseq_ext_zero_imp_id
+ unfolding q'(2)
+ by fastforce
- consider (eq) "b = c" | (ineq) "b \<noteq> c" by auto
- thus ?thesis
- proof cases
- case eq then have "q = cycle_of_list [ a, b, d ]"
- unfolding q by simp
- moreover have "{ a, b, d } \<subseteq> {1..n}"
- using ab cd S by blast
- ultimately show ?thesis
- using aux_lemma1[OF ab(1)] cd(1) eq by simp
- next
- case ineq
- hence "q = cycle_of_list [ a, b, c ] \<circ> cycle_of_list [ b, c, d ]"
- unfolding q by (simp add: swap_nilpotent o_assoc)
- moreover have "{ a, b, c } \<subseteq> {1..n}" and "{ b, c, d } \<subseteq> {1..n}"
- using ab cd S by blast+
- ultimately show ?thesis
- using eng[OF aux_lemma1[OF ab(1) ineq] aux_lemma1[OF ineq cd(1)]]
- unfolding alt_group_mult by simp
- qed
- qed } note aux_lemma2 = this
+ consider (eq) "b = c" | (ineq) "b \<noteq> c" by auto
+ thus ?thesis
+ proof cases
+ case eq
+ then have "q = cycle_of_list [ a, b, d ]"
+ unfolding q by simp
+ moreover have "{ a, b, d } \<subseteq> {1..n}"
+ using ab cd S by blast
+ ultimately show ?thesis
+ using aux_lemma1[OF ab(1)] cd(1) eq by simp
+ next
+ case ineq
+ hence "q = cycle_of_list [ a, b, c ] \<circ> cycle_of_list [ b, c, d ]"
+ unfolding q by (simp add: swap_nilpotent o_assoc)
+ moreover have "{ a, b, c } \<subseteq> {1..n}" and "{ b, c, d } \<subseteq> {1..n}"
+ using ab cd S by blast+
+ ultimately show ?thesis
+ using eng[OF aux_lemma1[OF ab(1) ineq] aux_lemma1[OF ineq cd(1)]]
+ unfolding alt_group_mult by simp
+ qed
+ qed
fix p assume "p \<in> carrier (alt_group n)" then have p: "p permutes {1..n}" "evenperm p"
unfolding alt_group_carrier by auto
@@ -464,66 +467,67 @@
show "derived (alt_group n) (carrier (alt_group n)) \<subseteq> carrier (alt_group n)"
using group.derived_in_carrier[OF alt_group_is_group] by simp
next
- { fix p assume "p \<in> three_cycles n" have "p \<in> derived (alt_group n) (carrier (alt_group n))"
- proof -
- obtain cs where cs: "p = cycle_of_list cs" "cycle cs" "length cs = 3" "set cs \<subseteq> {1..n}"
- using \<open>p \<in> three_cycles n\<close> by auto
- then obtain a b c where cs_def: "cs = [ a, b, c ]"
- using stupid_lemma[OF cs(3)] by blast
- have "card (set cs) = 3"
- using cs(2-3)
- by (simp add: distinct_card)
+ have aux_lemma: "p \<in> derived (alt_group n) (carrier (alt_group n))"
+ if "p \<in> three_cycles n" for p
+ proof -
+ obtain cs where cs: "p = cycle_of_list cs" "cycle cs" "length cs = 3" "set cs \<subseteq> {1..n}"
+ using \<open>p \<in> three_cycles n\<close> by auto
+ then obtain a b c where cs_def: "cs = [ a, b, c ]"
+ using stupid_lemma[OF cs(3)] by blast
+ have "card (set cs) = 3"
+ using cs(2-3)
+ by (simp add: distinct_card)
- have "set cs \<noteq> {1..n}"
- using assms cs(3) unfolding sym[OF distinct_card[OF cs(2)]] by auto
- then obtain d where d: "d \<notin> set cs" "d \<in> {1..n}"
- using cs(4) by blast
+ have "set cs \<noteq> {1..n}"
+ using assms cs(3) unfolding sym[OF distinct_card[OF cs(2)]] by auto
+ then obtain d where d: "d \<notin> set cs" "d \<in> {1..n}"
+ using cs(4) by blast
- hence "cycle (d # cs)" and "length (d # cs) = 4" and "card {1..n} = n"
- using cs(2-3) by auto
- hence "set (d # cs) \<noteq> {1..n}"
- using assms unfolding sym[OF distinct_card[OF \<open>cycle (d # cs)\<close>]]
- by (metis Suc_n_not_le_n eval_nat_numeral(3))
- then obtain e where e: "e \<notin> set (d # cs)" "e \<in> {1..n}"
- using d cs(4) by (metis insert_subset list.simps(15) subsetI subset_antisym)
+ hence "cycle (d # cs)" and "length (d # cs) = 4" and "card {1..n} = n"
+ using cs(2-3) by auto
+ hence "set (d # cs) \<noteq> {1..n}"
+ using assms unfolding sym[OF distinct_card[OF \<open>cycle (d # cs)\<close>]]
+ by (metis Suc_n_not_le_n eval_nat_numeral(3))
+ then obtain e where e: "e \<notin> set (d # cs)" "e \<in> {1..n}"
+ using d cs(4) by (metis insert_subset list.simps(15) subsetI subset_antisym)
- define q where "q = (Fun.swap d e id) \<circ> (Fun.swap b c id)"
- hence "bij q"
- by (simp add: bij_comp)
- moreover have "q b = c" and "q c = b"
- using d(1) e(1) unfolding q_def cs_def by simp+
- moreover have "q a = a"
- using d(1) e(1) cs(2) unfolding q_def cs_def by auto
- ultimately have "q \<circ> p \<circ> (inv' q) = cycle_of_list [ a, c, b ]"
- using conjugation_of_cycle[OF cs(2), of q]
- unfolding sym[OF cs(1)] unfolding cs_def by simp
- also have " ... = p \<circ> p"
- using cs(2) unfolding cs(1) cs_def
- by (simp add: comp_swap swap_commute transpose_comp_triple)
- finally have "q \<circ> p \<circ> (inv' q) = p \<circ> p" .
- moreover have "bij p"
- unfolding cs(1) cs_def by (simp add: bij_comp)
- ultimately have p: "q \<circ> p \<circ> (inv' q) \<circ> (inv' p) = p"
- by (simp add: bijection.intro bijection.inv_comp_right comp_assoc)
+ define q where "q = (Fun.swap d e id) \<circ> (Fun.swap b c id)"
+ hence "bij q"
+ by (simp add: bij_comp)
+ moreover have "q b = c" and "q c = b"
+ using d(1) e(1) unfolding q_def cs_def by simp+
+ moreover have "q a = a"
+ using d(1) e(1) cs(2) unfolding q_def cs_def by auto
+ ultimately have "q \<circ> p \<circ> (inv' q) = cycle_of_list [ a, c, b ]"
+ using conjugation_of_cycle[OF cs(2), of q]
+ unfolding sym[OF cs(1)] unfolding cs_def by simp
+ also have " ... = p \<circ> p"
+ using cs(2) unfolding cs(1) cs_def
+ by (simp add: comp_swap swap_commute transpose_comp_triple)
+ finally have "q \<circ> p \<circ> (inv' q) = p \<circ> p" .
+ moreover have "bij p"
+ unfolding cs(1) cs_def by (simp add: bij_comp)
+ ultimately have p: "q \<circ> p \<circ> (inv' q) \<circ> (inv' p) = p"
+ by (simp add: bijection.intro bijection.inv_comp_right comp_assoc)
- have "swapidseq (Suc (Suc 0)) q"
- using comp_Suc[OF comp_Suc[OF id], of b c d e] e(1) cs(2) unfolding q_def cs_def by auto
- hence "evenperm q"
- using even_Suc_Suc_iff evenperm_unique by blast
- moreover have "q permutes { d, e, b, c }"
- unfolding q_def by (simp add: permutes_compose permutes_swap_id)
- hence "q permutes {1..n}"
- using cs(4) d(2) e(2) permutes_subset unfolding cs_def by fastforce
- ultimately have "q \<in> carrier (alt_group n)"
- unfolding alt_group_carrier by simp
- moreover have "p \<in> carrier (alt_group n)"
- using \<open>p \<in> three_cycles n\<close> three_cycles_incl by blast
- ultimately have "p \<in> derived_set (alt_group n) (carrier (alt_group n))"
- using p alt_group_inv_equality unfolding alt_group_mult
- by (metis (no_types, lifting) UN_iff singletonI)
- thus "p \<in> derived (alt_group n) (carrier (alt_group n))"
- unfolding derived_def by (rule incl)
- qed } note aux_lemma = this
+ have "swapidseq (Suc (Suc 0)) q"
+ using comp_Suc[OF comp_Suc[OF id], of b c d e] e(1) cs(2) unfolding q_def cs_def by auto
+ hence "evenperm q"
+ using even_Suc_Suc_iff evenperm_unique by blast
+ moreover have "q permutes { d, e, b, c }"
+ unfolding q_def by (simp add: permutes_compose permutes_swap_id)
+ hence "q permutes {1..n}"
+ using cs(4) d(2) e(2) permutes_subset unfolding cs_def by fastforce
+ ultimately have "q \<in> carrier (alt_group n)"
+ unfolding alt_group_carrier by simp
+ moreover have "p \<in> carrier (alt_group n)"
+ using \<open>p \<in> three_cycles n\<close> three_cycles_incl by blast
+ ultimately have "p \<in> derived_set (alt_group n) (carrier (alt_group n))"
+ using p alt_group_inv_equality unfolding alt_group_mult
+ by (metis (no_types, lifting) UN_iff singletonI)
+ thus "p \<in> derived (alt_group n) (carrier (alt_group n))"
+ unfolding derived_def by (rule incl)
+ qed
interpret A: group "alt_group n"
using alt_group_is_group .
--- a/src/HOL/Algebra/UnivPoly.thy Wed Nov 13 15:00:17 2024 +0000
+++ b/src/HOL/Algebra/UnivPoly.thy Wed Nov 13 20:14:24 2024 +0100
@@ -408,20 +408,16 @@
assumes R1: "p \<in> carrier P" and R2: "q \<in> carrier P" shows "p \<otimes>\<^bsub>P\<^esub> q = q \<otimes>\<^bsub>P\<^esub> p"
proof (rule up_eqI)
fix n
- {
- fix k and a b :: "nat=>'a"
- assume R: "a \<in> UNIV \<rightarrow> carrier R" "b \<in> UNIV \<rightarrow> carrier R"
- then have "k <= n ==>
- (\<Oplus>i \<in> {..k}. a i \<otimes> b (n-i)) = (\<Oplus>i \<in> {..k}. a (k-i) \<otimes> b (i+n-k))"
- (is "_ \<Longrightarrow> ?eq k")
- proof (induct k)
- case 0 then show ?case by (simp add: Pi_def)
- next
- case (Suc k) then show ?case
- by (subst (2) finsum_Suc2) (simp add: Pi_def a_comm)+
- qed
- }
- note l = this
+ have l: "(\<Oplus>i \<in> {..k}. a i \<otimes> b (n-i)) = (\<Oplus>i \<in> {..k}. a (k-i) \<otimes> b (i+n-k))" (is "?eq k")
+ if "a \<in> UNIV \<rightarrow> carrier R" "b \<in> UNIV \<rightarrow> carrier R" and "k <= n"
+ for k and a b :: "nat=>'a"
+ using that
+ proof (induct k)
+ case 0 then show ?case by (simp add: Pi_def)
+ next
+ case (Suc k) then show ?case
+ by (subst (2) finsum_Suc2) (simp add: Pi_def a_comm)+
+ qed
from R1 R2 show "coeff P (p \<otimes>\<^bsub>P\<^esub> q) n = coeff P (q \<otimes>\<^bsub>P\<^esub> p) n"
unfolding coeff_mult [OF R1 R2, of n]
unfolding coeff_mult [OF R2 R1, of n]
--- a/src/Pure/Admin/component_jedit.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Pure/Admin/component_jedit.scala Wed Nov 13 20:14:24 2024 +0100
@@ -471,6 +471,8 @@
/* settings */
+ // see also https://docs.oracle.com/en/java/javase/21/troubleshoot/java-2d-properties.html
+
component_dir.write_settings("""
JEDIT_HOME="$COMPONENT/""" + jedit_patched + """"
JEDIT_JARS=""" + quote(File.read_dir(jars_dir).map("$JEDIT_HOME/jars/" + _).mkString(":")) + """
@@ -480,7 +482,7 @@
JEDIT_SETTINGS="$ISABELLE_HOME_USER/jedit"
JEDIT_OPTIONS="-reuseview -nobackground -nosplash -log=9"
JEDIT_JAVA_OPTIONS="-Xms512m -Xmx4g -Xss16m"
-JEDIT_JAVA_SYSTEM_OPTIONS="-Duser.language=en -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true -Dapple.laf.useScreenMenuBar=true -Dapple.awt.application.name=Isabelle"
+JEDIT_JAVA_SYSTEM_OPTIONS="-Dsun.java2d.metal=false -Duser.language=en -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true -Dapple.laf.useScreenMenuBar=true -Dapple.awt.application.name=Isabelle"
ISABELLE_DOCS="$ISABELLE_DOCS:$JEDIT_HOME/doc"
""")
--- a/src/Pure/Build/build.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Pure/Build/build.scala Wed Nov 13 20:14:24 2024 +0100
@@ -764,7 +764,7 @@
val doc_blobs = Document.Blobs.make(blobs)
- Document.State.init.snippet(command, doc_blobs)
+ Document.State.init.snippet(List(command), doc_blobs)
}
}
--- a/src/Pure/Build/build_job.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Pure/Build/build_job.scala Wed Nov 13 20:14:24 2024 +0100
@@ -300,7 +300,7 @@
def export_text(name: String, text: String, compress: Boolean = true): Unit =
export_(name, List(XML.Text(text)), compress = compress)
- for (command <- snapshot.snippet_command) {
+ for (command <- snapshot.snippet_commands) {
export_text(Export.DOCUMENT_ID, command.id.toString, compress = false)
}
--- a/src/Pure/GUI/font_metric.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Pure/GUI/font_metric.scala Wed Nov 13 20:14:24 2024 +0100
@@ -54,9 +54,4 @@
string_width(s1) / unit
}
def average: Double = average_width / unit
-
- def pretty_margin(margin: Int, limit: Int = -1): Int = {
- val m = (margin * average).toInt
- (if (limit < 0) m else m min limit) max 20
- }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Pure/GUI/rich_text.scala Wed Nov 13 20:14:24 2024 +0100
@@ -0,0 +1,103 @@
+/* Title: Pure/GUI/rich_text.scala
+ Author: Makarius
+
+Support for rendering of rich text, based on individual messages (XML.Elem).
+*/
+
+package isabelle
+
+
+import java.lang.ref.WeakReference
+
+import javax.swing.JComponent
+
+import scala.collection.mutable
+
+
+object Rich_Text {
+ /* margin */
+
+ def make_margin(metric: Font_Metric, margin: Int, limit: Int = -1): Int = {
+ val m = (margin * metric.average).toInt
+ (if (limit < 0) m else m min limit) max 20
+ }
+
+ def component_margin(metric: Font_Metric, component: JComponent): Int =
+ make_margin(metric, (component.getWidth.toDouble / metric.average_width).toInt)
+
+
+ /* format */
+
+ sealed case class Formatted(id: Document_ID.Generic, body: XML.Body) {
+ lazy val text: String = XML.content(body)
+ lazy val markups: Command.Markups = Command.Markups.init(Markup_Tree.from_XML(body))
+ def command(results: Command.Results): Command =
+ Command.unparsed(text, id = id, results = results, markups = markups)
+ }
+
+ def format(
+ msgs: List[XML.Elem],
+ margin: Double,
+ metric: Font_Metric,
+ cache: Cache = Cache.none
+ ): List[Formatted] = {
+ val result = new mutable.ListBuffer[Formatted]
+ for (msg <- msgs) {
+ if (result.nonEmpty) result += Formatted(Document_ID.make(), Pretty.Separator)
+ result += cache.format(msg, margin, metric)
+ Exn.Interrupt.expose()
+ }
+ result.toList
+ }
+
+ def formatted_lines(formatted: List[Formatted]): Int =
+ if (formatted.isEmpty) 0
+ else {
+ 1 + formatted.iterator.map(form =>
+ XML.traverse_text(form.body, 0, (n, s) => n + Library.count_newlines(s))).sum
+ }
+
+ def formatted_margin(metric: Font_Metric, formatted: List[Formatted]): Double =
+ split_lines(formatted.map(_.text).mkString)
+ .foldLeft(0.0) { case (m, line) => m max metric(line) }
+
+
+ /* cache */
+
+ object Cache {
+ def make(
+ compress: Compress.Cache = Compress.Cache.make(),
+ max_string: Int = isabelle.Cache.default_max_string,
+ initial_size: Int = isabelle.Cache.default_initial_size): Cache =
+ new Cache(compress, initial_size, max_string)
+
+ val none: Cache = make(max_string = 0)
+
+ sealed case class Args(msg: XML.Elem, margin: Double, metric: Font_Metric)
+ }
+
+ class Cache(compress: Compress.Cache, max_string: Int, initial_size: Int)
+ extends Term.Cache(compress, max_string, initial_size) {
+ cache =>
+
+ def format(msg: XML.Elem, margin: Double, metric: Font_Metric): Formatted = {
+ def run: Formatted =
+ Formatted(Protocol_Message.get_serial(msg),
+ cache.body(Pretty.formatted(List(msg), margin = margin, metric = metric)))
+
+ if (cache.table == null) run
+ else {
+ val x = Cache.Args(msg, margin, metric)
+ cache.table.get(x) match {
+ case ref: WeakReference[Any] => ref.get.asInstanceOf[Formatted]
+ case null =>
+ val y = run
+ cache.table.synchronized {
+ if (cache.table.get(x) == null) cache.table.put(x, new WeakReference[Any](y))
+ }
+ y
+ }
+ }
+ }
+ }
+}
--- a/src/Pure/General/cache.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Pure/General/cache.scala Wed Nov 13 20:14:24 2024 +0100
@@ -26,9 +26,9 @@
class Cache(max_string: Int, initial_size: Int) {
val no_cache: Boolean = max_string == 0
- private val table: JMap[Any, WeakReference[Any]] =
+ protected val table: JMap[Any, WeakReference[Any]] =
if (max_string == 0) null
- else Collections.synchronizedMap(new WeakHashMap[Any, WeakReference[Any]](initial_size))
+ else Collections.synchronizedMap(new WeakHashMap[Any, WeakReference[Any]](initial_size))
override def toString: String =
if (no_cache) "Cache.none" else "Cache(size = " + table.size + ")"
@@ -56,6 +56,7 @@
else if (x == "true") "true"
else if (x == "false") "false"
else if (x == "0.0") "0.0"
+ else if (Symbol.is_static_spaces(x)) Symbol.spaces(x.length)
else if (Library.is_small_int(x)) Library.signed_string_of_int(Integer.parseInt(x))
else {
lookup(x) match {
--- a/src/Pure/General/symbol.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Pure/General/symbol.scala Wed Nov 13 20:14:24 2024 +0100
@@ -25,11 +25,18 @@
val space_char = ' '
val space = " "
- private val static_spaces = space * 4000
+ private val static_spaces_length = 4000
+ private val static_spaces = space * static_spaces_length
+
+ def is_static_spaces(s: String): Boolean = {
+ val n = s.length
+ n == 0 || n <= static_spaces_length && s(0) == space_char && s.forall(_ == space_char)
+ }
def spaces(n: Int): String = {
require(n >= 0, "negative spaces")
- if (n < static_spaces.length) static_spaces.substring(0, n)
+ if (n == 0) ""
+ else if (n < static_spaces_length) static_spaces.substring(0, n)
else space * n
}
--- a/src/Pure/PIDE/command.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Pure/PIDE/command.scala Wed Nov 13 20:14:24 2024 +0100
@@ -333,10 +333,8 @@
case XML.Elem(Markup(name, props), body) =>
props match {
case Markup.Serial(i) =>
- val markup_message =
- cache.elem(Protocol.make_message(body, name, props = props))
- val message_markup =
- cache.elem(XML.elem(Markup(name, props.filter(p => p._1 == Markup.SERIAL))))
+ val markup_message = cache.elem(Protocol.make_message(body, name, props = props))
+ val message_markup = cache.elem(XML.elem(Markup(name, Markup.Serial(i))))
var st = add_result(i -> markup_message)
if (Protocol.is_inlined(message)) {
@@ -382,14 +380,10 @@
results: Results = Results.empty,
markups: Markups = Markups.empty
): Command = {
- val (source1, span1) = Command_Span.unparsed(source, theory = theory).compact_source
- new Command(id, node_name, blobs_info, span1, source1, results, markups)
+ val span = Command_Span.unparsed(source, theory = theory)
+ new Command(id, node_name, blobs_info, span, source, results, markups)
}
- def rich_text(body: XML.Body = Nil, results: Results = Results.empty): Command =
- unparsed(XML.content(body), id = Document_ID.make(), results = results,
- markups = Markups.init(Markup_Tree.from_XML(body)))
-
/* edits and perspective */
@@ -484,8 +478,8 @@
def is_ignored: Boolean = span.kind == Command_Span.Ignored_Span
def is_undefined: Boolean = id == Document_ID.none
- val is_unparsed: Boolean = span.content.exists(_.is_unparsed)
- val is_unfinished: Boolean = span.content.exists(_.is_unfinished)
+ lazy val is_unparsed: Boolean = span.content.exists(_.is_unparsed)
+ lazy val is_unfinished: Boolean = span.content.exists(_.is_unfinished)
def potentially_initialized: Boolean = span.name == Thy_Header.THEORY
@@ -512,9 +506,9 @@
/* source chunks */
- val chunk: Symbol.Text_Chunk = Symbol.Text_Chunk(source)
+ lazy val chunk: Symbol.Text_Chunk = Symbol.Text_Chunk(source)
- val chunks: Map[Symbol.Text_Chunk.Name, Symbol.Text_Chunk] =
+ lazy val chunks: Map[Symbol.Text_Chunk.Name, Symbol.Text_Chunk] =
((Symbol.Text_Chunk.Default -> chunk) ::
(for (case Exn.Res(blob) <- blobs; (_, file) <- blob.content)
yield blob.chunk_file -> file)).toMap
@@ -522,7 +516,7 @@
def length: Int = source.length
def range: Text.Range = chunk.range
- val core_range: Text.Range =
+ lazy val core_range: Text.Range =
Text.Range(0,
span.content.reverseIterator.takeWhile(_.is_ignored).foldLeft(length)(_ - _.source.length))
@@ -606,8 +600,8 @@
/* accumulated results */
- val init_state: Command.State =
+ lazy val init_state: Command.State =
Command.State(this, results = init_results, markups = init_markups)
- val empty_state: Command.State = Command.State(this)
+ lazy val empty_state: Command.State = Command.State(this)
}
--- a/src/Pure/PIDE/document.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Pure/PIDE/document.scala Wed Nov 13 20:14:24 2024 +0100
@@ -568,7 +568,7 @@
val version: Version,
val node_name: Node.Name,
pending_edits: Pending_Edits,
- val snippet_command: Option[Command]
+ val snippet_commands: List[Command]
) {
override def toString: String =
"Snapshot(node = " + node_name.node + ", version = " + version.id +
@@ -576,7 +576,7 @@
def switch(name: Node.Name): Snapshot =
if (name == node_name) this
- else new Snapshot(state, version, name, pending_edits, None)
+ else new Snapshot(state, version, name, pending_edits, Nil)
/* nodes */
@@ -628,27 +628,51 @@
/* command as add-on snippet */
- def snippet(command: Command, doc_blobs: Blobs): Snapshot = {
- val node_name = command.node_name
+ def snippet(commands: List[Command], doc_blobs: Blobs): Snapshot = {
+ require(commands.nonEmpty, "no snippet commands")
+
+ val node_name = commands.head.node_name
+ val node_commands = Linear_Set.from(commands)
- val blobs = for (a <- command.blobs_names; b <- doc_blobs.get(a)) yield a -> b
+ require(commands.forall(command => command.node_name == node_name),
+ "incoherent snippet node names")
+
+ val blobs =
+ for {
+ command <- commands
+ a <- command.blobs_names
+ b <- doc_blobs.get(a)
+ } yield a -> b
val nodes0 = version.nodes
- val nodes1 = nodes0 + (node_name -> nodes0(node_name).update_commands(Linear_Set(command)))
+ val nodes1 = nodes0 + (node_name -> nodes0(node_name).update_commands(node_commands))
val nodes2 = blobs.foldLeft(nodes1) { case (ns, (a, b)) => ns + (a -> Node.init_blob(b)) }
val version1 = Version.make(nodes2)
+ val text_edits: List[Text.Edit] = {
+ var offset = 0
+ val result = new mutable.ListBuffer[Text.Edit]
+ for (command <- commands) {
+ result += Text.Edit.insert(offset, command.source)
+ offset += command.source.length
+ }
+ result.toList
+ }
+
val edits: List[Edit_Text] =
- List(node_name -> Node.Edits(List(Text.Edit.insert(0, command.source)))) :::
+ List(node_name -> Node.Edits(text_edits)) :::
blobs.map({ case (a, b) => a -> Node.Blob(b) })
- val state0 = state.define_command(command)
+ val assign_update: Assign_Update =
+ commands.map(command => command.id -> List(Document_ID.make()))
+
+ val state0 = commands.foldLeft(state)(_.define_command(_))
val state1 =
state0.continue_history(Future.value(version), edits, Future.value(version1))
.define_version(version1, state0.the_assignment(version))
- .assign(version1.id, Nil, List(command.id -> List(Document_ID.make())))._2
+ .assign(version1.id, Nil, assign_update)._2
- state1.snapshot(node_name = node_name, snippet_command = Some(command))
+ state1.snapshot(node_name = node_name, snippet_commands = commands)
}
@@ -1030,7 +1054,7 @@
Command.unparsed(command.source, theory = true, id = id, node_name = node_name,
blobs_info = command.blobs_info, results = st.results, markups = st.markups)
val state1 = copy(theories = theories - id)
- (state1.snippet(command1, doc_blobs), state1)
+ (state1.snippet(List(command1), doc_blobs), state1)
}
def assign(
@@ -1254,7 +1278,7 @@
def snapshot(
node_name: Node.Name = Node.Name.empty,
pending_edits: Pending_Edits = Pending_Edits.empty,
- snippet_command: Option[Command] = None
+ snippet_commands: List[Command] = Nil
): Snapshot = {
val stable = recent_stable
val version = stable.version.get_finished
@@ -1265,10 +1289,10 @@
case (name, Node.Edits(es)) <- change.rev_edits
} yield (name -> es)).foldLeft(pending_edits)(_ + _)
- new Snapshot(this, version, node_name, pending_edits1, snippet_command)
+ new Snapshot(this, version, node_name, pending_edits1, snippet_commands)
}
- def snippet(command: Command, doc_blobs: Blobs): Snapshot =
- snapshot().snippet(command, doc_blobs)
+ def snippet(commands: List[Command], doc_blobs: Blobs): Snapshot =
+ snapshot().snippet(commands, doc_blobs)
}
}
--- a/src/Pure/PIDE/protocol_message.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Pure/PIDE/protocol_message.scala Wed Nov 13 20:14:24 2024 +0100
@@ -34,6 +34,16 @@
}
+ /* message serial */
+
+ def get_serial(msg: XML.Elem): Long =
+ Markup.Serial.get(msg.markup.properties)
+
+ def provide_serial(msg: XML.Elem): XML.Elem =
+ if (get_serial(msg) != 0L) msg
+ else msg.copy(markup = msg.markup.update_properties(Markup.Serial(Document_ID.make())))
+
+
/* inlined reports */
val report_elements: Markup.Elements = Markup.Elements(Markup.REPORT)
--- a/src/Pure/PIDE/xml.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Pure/PIDE/xml.scala Wed Nov 13 20:14:24 2024 +0100
@@ -177,14 +177,6 @@
def text_length(body: Body): Int = traverse_text(body, 0, (n, s) => n + s.length)
def symbol_length(body: Body): Int = traverse_text(body, 0, (n, s) => n + Symbol.length(s))
- def content_is_empty(body: Body): Boolean =
- traverse_text(body, true, (b, s) => b && s.isEmpty)
-
- def content_lines(body: Body): Int = {
- val n = traverse_text(body, 0, (n, s) => n + Library.count_newlines(s))
- if (n == 0 && content_is_empty(body)) 0 else n + 1
- }
-
def content(body: Body): String =
Library.string_builder(hint = text_length(body)) { text =>
traverse_text(body, (), (_, s) => text.append(s))
--- a/src/Tools/jEdit/src/jedit_lib.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Tools/jEdit/src/jedit_lib.scala Wed Nov 13 20:14:24 2024 +0100
@@ -12,10 +12,11 @@
import java.io.{File => JFile}
import java.awt.{Component, Container, GraphicsEnvironment, Point, Rectangle, Dimension, Toolkit}
import java.awt.event.{InputEvent, KeyEvent, KeyListener}
-import javax.swing.{Icon, ImageIcon, JWindow, SwingUtilities}
+import javax.swing.{Icon, ImageIcon, JScrollBar, JWindow, SwingUtilities}
import scala.util.parsing.input.CharSequenceReader
import scala.jdk.CollectionConverters._
+import scala.annotation.tailrec
import org.gjt.sp.jedit.{jEdit, Buffer, View, GUIUtilities, Debug, EditPane}
import org.gjt.sp.jedit.io.{FileVFS, VFSManager}
@@ -92,12 +93,6 @@
def buffer_file(buffer: Buffer): Option[JFile] = check_file(buffer_name(buffer))
- def buffer_undo_in_progress[A](buffer: JEditBuffer, body: => A): A = {
- val undo_in_progress = buffer.isUndoInProgress
- def set(b: Boolean): Unit = Untyped.set[Boolean](buffer, "undoInProgress", b)
- try { set(true); body } finally { set(undo_in_progress) }
- }
-
/* main jEdit components */
@@ -141,12 +136,50 @@
}
- /* get text */
+ /* buffer text */
def get_text(buffer: JEditBuffer, range: Text.Range): Option[String] =
try { Some(buffer.getText(range.start, range.length)) }
catch { case _: ArrayIndexOutOfBoundsException => None }
+ def set_text(buffer: JEditBuffer, text: List[String]): Int = {
+ val old = buffer.isUndoInProgress
+ def set(b: Boolean): Unit = Untyped.set[Boolean](buffer, "undoInProgress", b)
+
+ val length = buffer.getLength
+ var offset = 0
+
+ @tailrec def drop_common_prefix(list: List[String]): List[String] =
+ list match {
+ case s :: rest
+ if offset + s.length <= length &&
+ CharSequence.compare(buffer.getSegment(offset, s.length), s) == 0 =>
+ offset += s.length
+ drop_common_prefix(rest)
+ case _ => list
+ }
+
+ def insert(list: List[String]): Unit =
+ for (s <- list) {
+ buffer.insert(offset, s)
+ offset += s.length
+ }
+
+ try {
+ set(true)
+ buffer.beginCompoundEdit()
+ val rest = drop_common_prefix(text)
+ val update_start = offset
+ if (offset < length) buffer.remove(offset, length - offset)
+ insert(rest)
+ update_start
+ }
+ finally {
+ buffer.endCompoundEdit()
+ set(old)
+ }
+ }
+
/* point range */
@@ -230,10 +263,43 @@
}
+ /* scrolling */
+
+ def vertical_scrollbar(text_area: TextArea): JScrollBar =
+ Untyped.get[JScrollBar](text_area, "vertical")
+
+ def horizontal_scrollbar(text_area: TextArea): JScrollBar =
+ Untyped.get[JScrollBar](text_area, "horizontal")
+
+ def scrollbar_at_end(scrollbar: JScrollBar): Boolean =
+ scrollbar.getValue > 0 &&
+ scrollbar.getValue + scrollbar.getVisibleAmount == scrollbar.getMaximum
+
+ def scrollbar_bottom(text_area: TextArea): Boolean =
+ scrollbar_at_end(vertical_scrollbar(text_area))
+
+ def scrollbar_start(text_area: TextArea): Int =
+ text_area.getBuffer.getLineStartOffset(vertical_scrollbar(text_area).getValue)
+
+ def bottom_line_offset(buffer: JEditBuffer): Int =
+ buffer.getLineStartOffset(buffer.getLineOfOffset(buffer.getLength))
+
+ def scroll_to_caret(text_area: TextArea): Unit = {
+ val caret_line = text_area.getCaretLine()
+ val display_manager = text_area.getDisplayManager
+ if (!display_manager.isLineVisible(caret_line)) {
+ display_manager.expandFold(caret_line, true)
+ }
+ text_area.scrollToCaret(true)
+ }
+
+
/* graphics range */
def font_metric(painter: TextAreaPainter): Font_Metric =
- new Font_Metric(font = painter.getFont, context = painter.getFontRenderContext)
+ new Font_Metric(
+ font = painter.getFont,
+ context = painter.getFontRenderContext)
case class Gfx_Range(x: Int, y: Int, length: Int)
--- a/src/Tools/jEdit/src/jedit_rendering.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Tools/jEdit/src/jedit_rendering.scala Wed Nov 13 20:14:24 2024 +0100
@@ -25,10 +25,16 @@
def apply(snapshot: Document.Snapshot, model: Document_Model, options: Options): JEdit_Rendering =
new JEdit_Rendering(snapshot, model, options)
- def apply(snapshot: Document.Snapshot, rich_text: Command): JEdit_Rendering = {
- val snippet = snapshot.snippet(rich_text, Document.Blobs.empty)
+ def apply(
+ snapshot: Document.Snapshot,
+ rich_texts: List[Rich_Text.Formatted],
+ results: Command.Results
+ ): JEdit_Rendering = {
+ val snapshot1 =
+ if (rich_texts.isEmpty) snapshot
+ else snapshot.snippet(rich_texts.map(_.command(results)), Document.Blobs.empty)
val model = File_Model.init(PIDE.session)
- apply(snippet, model, PIDE.options.value)
+ apply(snapshot1, model, PIDE.options.value)
}
--- a/src/Tools/jEdit/src/main_plugin.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Tools/jEdit/src/main_plugin.scala Wed Nov 13 20:14:24 2024 +0100
@@ -53,6 +53,7 @@
def options: JEdit_Options = plugin.options
def resources: JEdit_Resources = plugin.resources
def session: Session = plugin.session
+ def cache: Rich_Text.Cache = session.cache.asInstanceOf[Rich_Text.Cache]
object editor extends JEdit_Editor
}
@@ -76,7 +77,12 @@
/* session */
private var _session: Session = null
- private def init_session(): Unit = _session = new Session(options.value, resources)
+ private def init_session(): Unit = {
+ _session =
+ new Session(options.value, resources) {
+ override val cache: Term.Cache = Rich_Text.Cache.make()
+ }
+ }
def session: Session = _session
--- a/src/Tools/jEdit/src/pretty_text_area.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Tools/jEdit/src/pretty_text_area.scala Wed Nov 13 20:14:24 2024 +0100
@@ -41,7 +41,7 @@
private var current_base_snapshot = Document.Snapshot.init
private var current_base_results = Command.Results.empty
private var current_rendering: JEdit_Rendering =
- JEdit_Rendering(current_base_snapshot, Command.rich_text())
+ JEdit_Rendering(current_base_snapshot, Nil, Command.Results.empty)
private var future_refresh: Option[Future[Unit]] = None
private val rich_text_area =
@@ -88,31 +88,51 @@
if (getWidth > 0) {
val metric = JEdit_Lib.font_metric(getPainter)
- val margin = metric.pretty_margin((getPainter.getWidth.toDouble / metric.average_width).toInt)
-
+ val margin = Rich_Text.component_margin(metric, getPainter)
+ val output = current_output
val snapshot = current_base_snapshot
val results = current_base_results
- val formatted =
- Pretty.formatted(Pretty.separate(current_output), margin = margin, metric = metric)
future_refresh.foreach(_.cancel())
future_refresh =
Some(Future.fork {
- val (text, rendering) =
+ val (rich_texts, rendering) =
try {
- val rich_text = Command.rich_text(body = formatted, results = results)
- (rich_text.source, JEdit_Rendering(snapshot, rich_text))
+ val rich_texts = Rich_Text.format(output, margin, metric, cache = PIDE.cache)
+ val rendering = JEdit_Rendering(snapshot, rich_texts, results)
+ (rich_texts, rendering)
}
- catch { case exn: Throwable => Log.log(Log.ERROR, this, exn); throw exn }
- Exn.Interrupt.expose()
+ catch {
+ case exn: Throwable if !Exn.is_interrupt(exn) =>
+ Log.log(Log.ERROR, this, exn)
+ throw exn
+ }
GUI_Thread.later {
- current_rendering = rendering
- JEdit_Lib.buffer_edit(getBuffer) {
- rich_text_area.active_reset()
- getBuffer.setFoldHandler(new Fold_Handling.Document_Fold_Handler(rendering))
- JEdit_Lib.buffer_undo_in_progress(getBuffer, setText(text))
- setCaretPosition(0)
+ val current_metric = JEdit_Lib.font_metric(getPainter)
+ val current_margin = Rich_Text.component_margin(current_metric, getPainter)
+ if (metric == current_metric &&
+ margin == current_margin &&
+ output == current_output &&
+ snapshot == current_base_snapshot &&
+ results == current_base_results
+ ) {
+ current_rendering = rendering
+
+ val scroll_bottom = JEdit_Lib.scrollbar_bottom(pretty_text_area)
+ val scroll_start = JEdit_Lib.scrollbar_start(pretty_text_area)
+ val update_start =
+ JEdit_Lib.buffer_edit(getBuffer) {
+ rich_text_area.active_reset()
+ getBuffer.setFoldHandler(new Fold_Handling.Document_Fold_Handler(rendering))
+ JEdit_Lib.set_text(getBuffer, rich_texts.map(_.text))
+ }
+
+ setCaretPosition(
+ if (scroll_bottom) JEdit_Lib.bottom_line_offset(getBuffer)
+ else if (scroll_start < update_start) scroll_start
+ else 0)
+ JEdit_Lib.scroll_to_caret(pretty_text_area)
}
}
})
@@ -134,7 +154,7 @@
current_base_snapshot = base_snapshot
current_base_results = base_results
- current_output = output
+ current_output = output.map(Protocol_Message.provide_serial)
refresh()
}
--- a/src/Tools/jEdit/src/pretty_tooltip.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Tools/jEdit/src/pretty_tooltip.scala Wed Nov 13 20:14:24 2024 +0100
@@ -248,17 +248,15 @@
val geometry = JEdit_Lib.window_geometry(pretty_tooltip, painter)
val metric = JEdit_Lib.font_metric(painter)
val margin =
- metric.pretty_margin(rendering.tooltip_margin,
+ Rich_Text.make_margin(metric, rendering.tooltip_margin,
limit = ((w_max - geometry.deco_width) / metric.average_width).toInt)
- val formatted = Pretty.formatted(Pretty.separate(output), margin = margin, metric = metric)
- val lines = XML.content_lines(formatted)
+ val formatted = Rich_Text.format(output, margin, metric, cache = PIDE.cache)
+ val lines = Rich_Text.formatted_lines(formatted)
val h = painter.getLineHeight * lines + geometry.deco_height
val margin1 =
- if (h <= h_max) {
- split_lines(XML.content(formatted)).foldLeft(0.0) { case (m, line) => m max metric(line) }
- }
+ if (h <= h_max) Rich_Text.formatted_margin(metric, formatted)
else margin.toDouble
val w = (metric.unit * (margin1 + 1)).round.toInt + geometry.deco_width
--- a/src/Tools/jEdit/src/rich_text_area.scala Wed Nov 13 15:00:17 2024 +0000
+++ b/src/Tools/jEdit/src/rich_text_area.scala Wed Nov 13 20:14:24 2024 +0100
@@ -23,7 +23,7 @@
import org.gjt.sp.util.Log
import org.gjt.sp.jedit.View
import org.gjt.sp.jedit.syntax.{Chunk => JEditChunk, SyntaxStyle}
-import org.gjt.sp.jedit.textarea.{TextAreaExtension, TextAreaPainter, TextArea}
+import org.gjt.sp.jedit.textarea.{TextAreaExtension, TextAreaPainter, TextArea, Selection}
class Rich_Text_Area(
@@ -218,24 +218,38 @@
private val mouse_listener = new MouseAdapter {
override def mouseClicked(e: MouseEvent): Unit = {
robust_body(()) {
- hyperlink_area.info match {
- case Some(Text.Info(range, link)) =>
- if (!link.external) {
- try { text_area.moveCaretPosition(range.start) }
- catch {
- case _: ArrayIndexOutOfBoundsException =>
- case _: IllegalArgumentException =>
+ val clicks = e.getClickCount
+ if (clicks == 1) {
+ hyperlink_area.info match {
+ case Some(Text.Info(range, link)) =>
+ if (!link.external) {
+ try { text_area.moveCaretPosition(range.start) }
+ catch {
+ case _: ArrayIndexOutOfBoundsException =>
+ case _: IllegalArgumentException =>
+ }
+ text_area.requestFocus()
}
- text_area.requestFocus()
- }
- link.follow(view)
- case None =>
+ link.follow(view)
+ e.consume()
+ case None =>
+ }
+ active_area.text_info match {
+ case Some((text, Text.Info(_, markup))) =>
+ Active.action(view, text, markup)
+ close_action()
+ e.consume()
+ case None =>
+ }
}
- active_area.text_info match {
- case Some((text, Text.Info(_, markup))) =>
- Active.action(view, text, markup)
- close_action()
- case None =>
+ else if (clicks == 2) {
+ highlight_area.info match {
+ case Some(Text.Info(r, _)) =>
+ text_area.selectNone()
+ text_area.addToSelection(new Selection.Range(r.start, r.stop))
+ e.consume()
+ case None =>
+ }
}
}
}