[STATEMENT]
lemma Hermite_Lindemann_aux4:
  fixes \<beta> :: "complex \<Rightarrow> complex"
  assumes [intro]: "finite X"
  assumes alg1: "\<And>x. x \<in> X \<Longrightarrow> algebraic x"
  assumes alg2: "\<And>x. x \<in> X \<Longrightarrow> algebraic (\<beta> x)"
  assumes nz:   "\<And>x. x \<in> X \<Longrightarrow> \<beta> x \<noteq> 0"
  assumes sum0: "(\<Sum>x\<in>X. \<beta> x * exp x) = 0"
  shows   "X = {}"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. X = {}
[PROOF STEP]
proof (rule ccontr)
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
assume X: "X \<noteq> {}"
[PROOF STATE]
proof (state)
this:
X \<noteq> {}

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
note [intro!] = finite_PiE
[PROOF STATE]
proof (state)
this:
\<lbrakk>finite ?S; \<And>i. i \<in> ?S \<Longrightarrow> finite (?T i)\<rbrakk> \<Longrightarrow> finite (Pi\<^sub>E ?S ?T)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
text \<open>
    We now take more or less the same approach as before, except that now we find a polynomial
    that has all of the conjugates of the coefficients \<open>\<beta>\<close> as roots. Note that this is a slight
    deviation from Baker's proof, who picks one polynomial for each \<open>\<beta>\<close> independently. I did it
    this way because, as Bernard~\cite{bernard} observed, it makes the proof a bit easier.
  \<close>
[PROOF STATE]
proof (state)
this:
\<lbrakk>finite ?S; \<And>i. i \<in> ?S \<Longrightarrow> finite (?T i)\<rbrakk> \<Longrightarrow> finite (Pi\<^sub>E ?S ?T)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
define P :: "int poly" where "P = \<Prod>((min_int_poly \<circ> \<beta>) ` X)"
[PROOF STATE]
proof (state)
this:
P = \<Prod>((min_int_poly \<circ> \<beta>) ` X)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
define Roots :: "complex set" where "Roots = {x. ipoly P x = 0}"
[PROOF STATE]
proof (state)
this:
Roots = {x. ipoly P x = 0}

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "0 \<notin> Roots"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. 0 \<notin> Roots
[PROOF STEP]
using \<open>finite X\<close> alg2 nz
[PROOF STATE]
proof (prove)
using this:
finite X
?x \<in> X \<Longrightarrow> algebraic (\<beta> ?x)
?x \<in> X \<Longrightarrow> \<beta> ?x \<noteq> 0

goal (1 subgoal):
 1. 0 \<notin> Roots
[PROOF STEP]
by (auto simp: Roots_def P_def poly_prod)
[PROOF STATE]
proof (state)
this:
0 \<notin> Roots

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have [simp]: "P \<noteq> 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. P \<noteq> 0
[PROOF STEP]
using \<open>finite X\<close>
[PROOF STATE]
proof (prove)
using this:
finite X

goal (1 subgoal):
 1. P \<noteq> 0
[PROOF STEP]
by (auto simp: P_def)
[PROOF STATE]
proof (state)
this:
P \<noteq> 0

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have [intro]: "finite Roots"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. finite Roots
[PROOF STEP]
unfolding Roots_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. finite {x. ipoly P x = 0}
[PROOF STEP]
by (intro poly_roots_finite) auto
[PROOF STATE]
proof (state)
this:
finite Roots

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "\<beta> ` X \<subseteq> Roots"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<beta> ` X \<subseteq> Roots
[PROOF STEP]
proof safe
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>x xa. xa \<in> X \<Longrightarrow> \<beta> xa \<in> Roots
[PROOF STEP]
fix x
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>x xa. xa \<in> X \<Longrightarrow> \<beta> xa \<in> Roots
[PROOF STEP]
assume "x \<in> X"
[PROOF STATE]
proof (state)
this:
x \<in> X

goal (1 subgoal):
 1. \<And>x xa. xa \<in> X \<Longrightarrow> \<beta> xa \<in> Roots
[PROOF STEP]
hence "ipoly (min_int_poly (\<beta> x)) (\<beta> x) = 0"
[PROOF STATE]
proof (prove)
using this:
x \<in> X

goal (1 subgoal):
 1. ipoly (min_int_poly (\<beta> x)) (\<beta> x) = 0
[PROOF STEP]
by (intro ipoly_min_int_poly alg2)
[PROOF STATE]
proof (state)
this:
ipoly (min_int_poly (\<beta> x)) (\<beta> x) = 0

goal (1 subgoal):
 1. \<And>x xa. xa \<in> X \<Longrightarrow> \<beta> xa \<in> Roots
[PROOF STEP]
thus "\<beta> x \<in> Roots"
[PROOF STATE]
proof (prove)
using this:
ipoly (min_int_poly (\<beta> x)) (\<beta> x) = 0

goal (1 subgoal):
 1. \<beta> x \<in> Roots
[PROOF STEP]
using \<open>finite X\<close> \<open>x \<in> X\<close>
[PROOF STATE]
proof (prove)
using this:
ipoly (min_int_poly (\<beta> x)) (\<beta> x) = 0
finite X
x \<in> X

goal (1 subgoal):
 1. \<beta> x \<in> Roots
[PROOF STEP]
by (auto simp: Roots_def P_def of_int_poly_hom.hom_prod poly_prod)
[PROOF STATE]
proof (state)
this:
\<beta> x \<in> Roots

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<beta> ` X \<subseteq> Roots

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "squarefree (of_int_poly P :: complex poly)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. squarefree (Ring_Hom_Poly.of_int_poly P)
[PROOF STEP]
unfolding P_def of_int_poly_hom.hom_prod o_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. squarefree (prod Ring_Hom_Poly.of_int_poly ((\<lambda>x. min_int_poly (\<beta> x)) ` X))
[PROOF STEP]
proof (rule squarefree_prod_coprime; safe)
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<And>a b x xa. \<lbrakk>min_int_poly (\<beta> x) \<noteq> min_int_poly (\<beta> xa); x \<in> X; xa \<in> X\<rbrakk> \<Longrightarrow> algebraic_semidom_class.coprime (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> x))) (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> xa)))
 2. \<And>a x. x \<in> X \<Longrightarrow> squarefree (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> x)))
[PROOF STEP]
fix x
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<And>a b x xa. \<lbrakk>min_int_poly (\<beta> x) \<noteq> min_int_poly (\<beta> xa); x \<in> X; xa \<in> X\<rbrakk> \<Longrightarrow> algebraic_semidom_class.coprime (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> x))) (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> xa)))
 2. \<And>a x. x \<in> X \<Longrightarrow> squarefree (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> x)))
[PROOF STEP]
assume "x \<in> X"
[PROOF STATE]
proof (state)
this:
x \<in> X

goal (2 subgoals):
 1. \<And>a b x xa. \<lbrakk>min_int_poly (\<beta> x) \<noteq> min_int_poly (\<beta> xa); x \<in> X; xa \<in> X\<rbrakk> \<Longrightarrow> algebraic_semidom_class.coprime (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> x))) (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> xa)))
 2. \<And>a x. x \<in> X \<Longrightarrow> squarefree (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> x)))
[PROOF STEP]
thus "squarefree (of_int_poly (min_int_poly (\<beta> x)) :: complex poly)"
[PROOF STATE]
proof (prove)
using this:
x \<in> X

goal (1 subgoal):
 1. squarefree (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> x)))
[PROOF STEP]
by (intro squarefree_of_int_polyI) auto
[PROOF STATE]
proof (state)
this:
squarefree (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> x)))

goal (1 subgoal):
 1. \<And>a b x xa. \<lbrakk>min_int_poly (\<beta> x) \<noteq> min_int_poly (\<beta> xa); x \<in> X; xa \<in> X\<rbrakk> \<Longrightarrow> algebraic_semidom_class.coprime (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> x))) (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> xa)))
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>a b x xa. \<lbrakk>min_int_poly (\<beta> x) \<noteq> min_int_poly (\<beta> xa); x \<in> X; xa \<in> X\<rbrakk> \<Longrightarrow> algebraic_semidom_class.coprime (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> x))) (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> xa)))
[PROOF STEP]
fix x y
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>a b x xa. \<lbrakk>min_int_poly (\<beta> x) \<noteq> min_int_poly (\<beta> xa); x \<in> X; xa \<in> X\<rbrakk> \<Longrightarrow> algebraic_semidom_class.coprime (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> x))) (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> xa)))
[PROOF STEP]
assume xy: "x \<in> X" "y \<in> X" "min_int_poly (\<beta> x) \<noteq> min_int_poly (\<beta> y)"
[PROOF STATE]
proof (state)
this:
x \<in> X
y \<in> X
min_int_poly (\<beta> x) \<noteq> min_int_poly (\<beta> y)

goal (1 subgoal):
 1. \<And>a b x xa. \<lbrakk>min_int_poly (\<beta> x) \<noteq> min_int_poly (\<beta> xa); x \<in> X; xa \<in> X\<rbrakk> \<Longrightarrow> algebraic_semidom_class.coprime (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> x))) (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> xa)))
[PROOF STEP]
thus "Rings.coprime (of_int_poly (min_int_poly (\<beta> x)))
            (of_int_poly (min_int_poly (\<beta> y)) :: complex poly)"
[PROOF STATE]
proof (prove)
using this:
x \<in> X
y \<in> X
min_int_poly (\<beta> x) \<noteq> min_int_poly (\<beta> y)

goal (1 subgoal):
 1. algebraic_semidom_class.coprime (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> x))) (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> y)))
[PROOF STEP]
by (intro coprime_of_int_polyI[OF primes_coprime]) auto
[PROOF STATE]
proof (state)
this:
algebraic_semidom_class.coprime (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> x))) (Ring_Hom_Poly.of_int_poly (min_int_poly (\<beta> y)))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
squarefree (Ring_Hom_Poly.of_int_poly P)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
define n where "n = card Roots"
[PROOF STATE]
proof (state)
this:
n = card Roots

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
define m where "m = card X"
[PROOF STATE]
proof (state)
this:
m = card X

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "Roots \<noteq> {}"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. Roots \<noteq> {}
[PROOF STEP]
using \<open>\<beta> ` X \<subseteq> Roots\<close> \<open>X \<noteq> {}\<close>
[PROOF STATE]
proof (prove)
using this:
\<beta> ` X \<subseteq> Roots
X \<noteq> {}

goal (1 subgoal):
 1. Roots \<noteq> {}
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
Roots \<noteq> {}

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
hence "n > 0" "m > 0"
[PROOF STATE]
proof (prove)
using this:
Roots \<noteq> {}

goal (1 subgoal):
 1. 0 < n &&& 0 < m
[PROOF STEP]
using \<open>finite Roots\<close> \<open>finite X\<close> \<open>X \<noteq> {}\<close>
[PROOF STATE]
proof (prove)
using this:
Roots \<noteq> {}
finite Roots
finite X
X \<noteq> {}

goal (1 subgoal):
 1. 0 < n &&& 0 < m
[PROOF STEP]
by (auto simp: n_def m_def)
[PROOF STATE]
proof (state)
this:
0 < n
0 < m

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have fin1 [simp]: "finite (X \<rightarrow>\<^sub>E Roots)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. finite (X \<rightarrow>\<^sub>E Roots)
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
finite (X \<rightarrow>\<^sub>E Roots)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have [simp]: "card (X \<rightarrow>\<^sub>E Roots) = n ^ m"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. card (X \<rightarrow>\<^sub>E Roots) = n ^ m
[PROOF STEP]
by (subst card_PiE) (auto simp: m_def n_def)
[PROOF STATE]
proof (state)
this:
card (X \<rightarrow>\<^sub>E Roots) = n ^ m

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
text \<open>
    We again find a bijection between the roots and the natural numbers less than \<open>n\<close>:
  \<close>
[PROOF STATE]
proof (state)
this:
card (X \<rightarrow>\<^sub>E Roots) = n ^ m

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
obtain Root where Root: "bij_betw Root {..<n} Roots"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<And>Root. bij_betw Root {..<n} Roots \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
using ex_bij_betw_nat_finite[OF \<open>finite Roots\<close>]
[PROOF STATE]
proof (prove)
using this:
\<exists>h. bij_betw h {0..<card Roots} Roots

goal (1 subgoal):
 1. (\<And>Root. bij_betw Root {..<n} Roots \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
unfolding n_def atLeast0LessThan
[PROOF STATE]
proof (prove)
using this:
\<exists>h. bij_betw h {..<card Roots} Roots

goal (1 subgoal):
 1. (\<And>Root. bij_betw Root {..<card Roots} Roots \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
by metis
[PROOF STATE]
proof (state)
this:
bij_betw Root {..<n} Roots

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
define unRoot :: "complex \<Rightarrow> nat" where "unRoot = inv_into {..<n} Root"
[PROOF STATE]
proof (state)
this:
unRoot = inv_into {..<n} Root

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have unRoot: "bij_betw unRoot Roots {..<n}"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bij_betw unRoot Roots {..<n}
[PROOF STEP]
unfolding unRoot_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bij_betw (inv_into {..<n} Root) Roots {..<n}
[PROOF STEP]
by (intro bij_betw_inv_into Root)
[PROOF STATE]
proof (state)
this:
bij_betw unRoot Roots {..<n}

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have unRoot_Root [simp]: "unRoot (Root i) = i" if "i < n" for i
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. unRoot (Root i) = i
[PROOF STEP]
unfolding unRoot_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. inv_into {..<n} Root (Root i) = i
[PROOF STEP]
using Root that
[PROOF STATE]
proof (prove)
using this:
bij_betw Root {..<n} Roots
i < n

goal (1 subgoal):
 1. inv_into {..<n} Root (Root i) = i
[PROOF STEP]
by (subst inv_into_f_f) (auto simp: bij_betw_def)
[PROOF STATE]
proof (state)
this:
?i < n \<Longrightarrow> unRoot (Root ?i) = ?i

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have Root_unRoot [simp]: "Root (unRoot x) = x" if "x \<in> Roots" for x
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. Root (unRoot x) = x
[PROOF STEP]
unfolding unRoot_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. Root (inv_into {..<n} Root x) = x
[PROOF STEP]
using Root that
[PROOF STATE]
proof (prove)
using this:
bij_betw Root {..<n} Roots
x \<in> Roots

goal (1 subgoal):
 1. Root (inv_into {..<n} Root x) = x
[PROOF STEP]
by (subst f_inv_into_f) (auto simp: bij_betw_def)
[PROOF STATE]
proof (state)
this:
?x \<in> Roots \<Longrightarrow> Root (unRoot ?x) = ?x

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have [simp, intro]: "Root i \<in> Roots" if "i < n" for i
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. Root i \<in> Roots
[PROOF STEP]
using Root that
[PROOF STATE]
proof (prove)
using this:
bij_betw Root {..<n} Roots
i < n

goal (1 subgoal):
 1. Root i \<in> Roots
[PROOF STEP]
by (auto simp: bij_betw_def)
[PROOF STATE]
proof (state)
this:
?i < n \<Longrightarrow> Root ?i \<in> Roots

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have [simp, intro]: "unRoot x < n" if "x \<in> Roots" for x
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. unRoot x < n
[PROOF STEP]
using unRoot that
[PROOF STATE]
proof (prove)
using this:
bij_betw unRoot Roots {..<n}
x \<in> Roots

goal (1 subgoal):
 1. unRoot x < n
[PROOF STEP]
by (auto simp: bij_betw_def)
[PROOF STATE]
proof (state)
this:
?x \<in> Roots \<Longrightarrow> unRoot ?x < n

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
text \<open>
    And we again define the set of multisets and tuples that we will get in the expanded product.
  \<close>
[PROOF STATE]
proof (state)
this:
?x \<in> Roots \<Longrightarrow> unRoot ?x < n

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
define Roots_ms :: "complex multiset set" where
    "Roots_ms = {Y. set_mset Y \<subseteq> X \<and> size Y = n ^ m}"
[PROOF STATE]
proof (state)
this:
Roots_ms = {Y. set_mset Y \<subseteq> X \<and> size Y = n ^ m}

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have [intro]: "finite Roots_ms"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. finite Roots_ms
[PROOF STEP]
unfolding Roots_ms_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. finite {Y. set_mset Y \<subseteq> X \<and> size Y = n ^ m}
[PROOF STEP]
by (rule finite_multisets_of_size) auto
[PROOF STATE]
proof (state)
this:
finite Roots_ms

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
define tuples :: "complex multiset \<Rightarrow> ((complex \<Rightarrow> complex) \<Rightarrow> complex) set"
    where "tuples = (\<lambda>Y. {f\<in>(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. image_mset f (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y})"
[PROOF STATE]
proof (state)
this:
tuples = (\<lambda>Y. {f \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. image_mset f (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y})

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have [intro]: "finite (tuples Y)" for Y
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. finite (tuples Y)
[PROOF STEP]
unfolding tuples_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. finite {f \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. image_mset f (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y}
[PROOF STEP]
by (rule finite_subset[of _ "(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X"]) auto
[PROOF STATE]
proof (state)
this:
finite (tuples ?Y)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
text \<open>
    We will also need to convert permutations over the natural and over the roots again.
  \<close>
[PROOF STATE]
proof (state)
this:
finite (tuples ?Y)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
define convert_perm :: "(nat \<Rightarrow> nat) \<Rightarrow> (complex \<Rightarrow> complex)" where
    "convert_perm = (\<lambda>\<sigma> x. if x \<in> Roots then Root (\<sigma> (unRoot x)) else x)"
[PROOF STATE]
proof (state)
this:
convert_perm = (\<lambda>\<sigma> x. if x \<in> Roots then Root (\<sigma> (unRoot x)) else x)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have bij_convert: "bij_betw convert_perm {\<sigma>. \<sigma> permutes {..<n}} {\<sigma>. \<sigma> permutes Roots}"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bij_betw convert_perm {\<sigma>. \<sigma> permutes {..<n}} {\<sigma>. \<sigma> permutes Roots}
[PROOF STEP]
using bij_betw_permutations[OF Root]
[PROOF STATE]
proof (prove)
using this:
bij_betw (\<lambda>\<pi> x. if x \<in> Roots then Root (\<pi> (inv_into {..<n} Root x)) else x) {\<pi>. \<pi> permutes {..<n}} {\<pi>. \<pi> permutes Roots}

goal (1 subgoal):
 1. bij_betw convert_perm {\<sigma>. \<sigma> permutes {..<n}} {\<sigma>. \<sigma> permutes Roots}
[PROOF STEP]
unfolding convert_perm_def unRoot_def
[PROOF STATE]
proof (prove)
using this:
bij_betw (\<lambda>\<pi> x. if x \<in> Roots then Root (\<pi> (inv_into {..<n} Root x)) else x) {\<pi>. \<pi> permutes {..<n}} {\<pi>. \<pi> permutes Roots}

goal (1 subgoal):
 1. bij_betw (\<lambda>\<sigma> x. if x \<in> Roots then Root (\<sigma> (inv_into {..<n} Root x)) else x) {\<sigma>. \<sigma> permutes {..<n}} {\<sigma>. \<sigma> permutes Roots}
[PROOF STEP]
.
[PROOF STATE]
proof (state)
this:
bij_betw convert_perm {\<sigma>. \<sigma> permutes {..<n}} {\<sigma>. \<sigma> permutes Roots}

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have permutes_convert_perm [intro]: "convert_perm \<sigma> permutes Roots" if "\<sigma> permutes {..<n}" for \<sigma>
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. convert_perm \<sigma> permutes Roots
[PROOF STEP]
using that bij_convert
[PROOF STATE]
proof (prove)
using this:
\<sigma> permutes {..<n}
bij_betw convert_perm {\<sigma>. \<sigma> permutes {..<n}} {\<sigma>. \<sigma> permutes Roots}

goal (1 subgoal):
 1. convert_perm \<sigma> permutes Roots
[PROOF STEP]
unfolding bij_betw_def
[PROOF STATE]
proof (prove)
using this:
\<sigma> permutes {..<n}
inj_on convert_perm {\<sigma>. \<sigma> permutes {..<n}} \<and> convert_perm ` {\<sigma>. \<sigma> permutes {..<n}} = {\<sigma>. \<sigma> permutes Roots}

goal (1 subgoal):
 1. convert_perm \<sigma> permutes Roots
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
?\<sigma> permutes {..<n} \<Longrightarrow> convert_perm ?\<sigma> permutes Roots

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
text \<open>
    We also need a small lemma showing that our tuples are stable under permutation of the roots.
  \<close>
[PROOF STATE]
proof (state)
this:
?\<sigma> permutes {..<n} \<Longrightarrow> convert_perm ?\<sigma> permutes Roots

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have bij_betw_compose_perm:
    "bij_betw (\<lambda>f. restrict (\<lambda>g. f (restrict (\<pi> \<circ> g) X)) (X \<rightarrow>\<^sub>E Roots)) (tuples Y) (tuples Y)"
    if \<pi>: "\<pi> permutes Roots" and "Y \<in> Roots_ms" for \<pi> Y
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. bij_betw (\<lambda>f. \<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (tuples Y) (tuples Y)
[PROOF STEP]
proof (rule bij_betwI)
[PROOF STATE]
proof (state)
goal (4 subgoals):
 1. (\<lambda>f. \<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) \<in> tuples Y \<rightarrow> tuples Y
 2. ?g \<in> tuples Y \<rightarrow> tuples Y
 3. \<And>x. x \<in> tuples Y \<Longrightarrow> ?g (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi> \<circ> g) X)) = x
 4. \<And>y. y \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. ?g y (restrict (\<pi> \<circ> g) X)) = y
[PROOF STEP]
have *: "(\<lambda>f. restrict (\<lambda>g. f (restrict (\<pi> \<circ> g) X)) (X \<rightarrow>\<^sub>E Roots)) \<in> tuples Y \<rightarrow> tuples Y"
      if \<pi>: "\<pi> permutes Roots" for \<pi>
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<lambda>f. \<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) \<in> tuples Y \<rightarrow> tuples Y
[PROOF STEP]
proof
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi> \<circ> g) X)) \<in> tuples Y
[PROOF STEP]
fix f
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi> \<circ> g) X)) \<in> tuples Y
[PROOF STEP]
assume f: "f \<in> tuples Y"
[PROOF STATE]
proof (state)
this:
f \<in> tuples Y

goal (1 subgoal):
 1. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi> \<circ> g) X)) \<in> tuples Y
[PROOF STEP]
hence f': "f \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X"
[PROOF STATE]
proof (prove)
using this:
f \<in> tuples Y

goal (1 subgoal):
 1. f \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X
[PROOF STEP]
by (auto simp: tuples_def)
[PROOF STATE]
proof (state)
this:
f \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X

goal (1 subgoal):
 1. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi> \<circ> g) X)) \<in> tuples Y
[PROOF STEP]
define f' where "f' = (\<lambda>g. f (restrict (\<pi> \<circ> g) X))"
[PROOF STATE]
proof (state)
this:
f' = (\<lambda>g. f (restrict (\<pi> \<circ> g) X))

goal (1 subgoal):
 1. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi> \<circ> g) X)) \<in> tuples Y
[PROOF STEP]
have "f' \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow> X"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. f' \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow> X
[PROOF STEP]
unfolding f'_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<lambda>g. f (restrict (\<pi> \<circ> g) X)) \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow> X
[PROOF STEP]
using f' bij_betw_apply[OF bij_betw_compose_left_perm_PiE[OF \<pi>, of X]]
[PROOF STATE]
proof (prove)
using this:
f \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X
?a \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> restrict (\<pi> \<circ> ?a) X \<in> X \<rightarrow>\<^sub>E Roots

goal (1 subgoal):
 1. (\<lambda>g. f (restrict (\<pi> \<circ> g) X)) \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow> X
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
f' \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow> X

goal (1 subgoal):
 1. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi> \<circ> g) X)) \<in> tuples Y
[PROOF STEP]
hence "restrict f' (X \<rightarrow>\<^sub>E Roots) \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X"
[PROOF STATE]
proof (prove)
using this:
f' \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow> X

goal (1 subgoal):
 1. restrict f' (X \<rightarrow>\<^sub>E Roots) \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X
[PROOF STEP]
by simp
[PROOF STATE]
proof (state)
this:
restrict f' (X \<rightarrow>\<^sub>E Roots) \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X

goal (1 subgoal):
 1. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi> \<circ> g) X)) \<in> tuples Y
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
restrict f' (X \<rightarrow>\<^sub>E Roots) \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X

goal (1 subgoal):
 1. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi> \<circ> g) X)) \<in> tuples Y
[PROOF STEP]
have "image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y
[PROOF STEP]
have "image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) =
              image_mset f' (mset_set (X \<rightarrow>\<^sub>E Roots))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = image_mset f' (mset_set (X \<rightarrow>\<^sub>E Roots))
[PROOF STEP]
by (intro image_mset_cong) auto
[PROOF STATE]
proof (state)
this:
image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = image_mset f' (mset_set (X \<rightarrow>\<^sub>E Roots))

goal (1 subgoal):
 1. image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = image_mset f' (mset_set (X \<rightarrow>\<^sub>E Roots))

goal (1 subgoal):
 1. image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y
[PROOF STEP]
have "\<dots> = image_mset f (image_mset (\<lambda>g. restrict (\<pi> \<circ> g) X) (mset_set (X \<rightarrow>\<^sub>E Roots)))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. image_mset f' (mset_set (X \<rightarrow>\<^sub>E Roots)) = image_mset f {#restrict (\<pi> \<circ> g) X. g \<in># mset_set (X \<rightarrow>\<^sub>E Roots)#}
[PROOF STEP]
unfolding f'_def o_def multiset.map_comp
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. {#f (\<lambda>x\<in>X. \<pi> (g x)). g \<in># mset_set (X \<rightarrow>\<^sub>E Roots)#} = {#f (\<lambda>xa\<in>X. \<pi> (x xa)). x \<in># mset_set (X \<rightarrow>\<^sub>E Roots)#}
[PROOF STEP]
by (simp add: o_def)
[PROOF STATE]
proof (state)
this:
image_mset f' (mset_set (X \<rightarrow>\<^sub>E Roots)) = image_mset f {#restrict (\<pi> \<circ> g) X. g \<in># mset_set (X \<rightarrow>\<^sub>E Roots)#}

goal (1 subgoal):
 1. image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
image_mset f' (mset_set (X \<rightarrow>\<^sub>E Roots)) = image_mset f {#restrict (\<pi> \<circ> g) X. g \<in># mset_set (X \<rightarrow>\<^sub>E Roots)#}

goal (1 subgoal):
 1. image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y
[PROOF STEP]
have "image_mset (\<lambda>g. restrict (\<pi> \<circ> g) X) (mset_set (X \<rightarrow>\<^sub>E Roots)) =
                   mset_set (X \<rightarrow>\<^sub>E Roots)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. {#restrict (\<pi> \<circ> g) X. g \<in># mset_set (X \<rightarrow>\<^sub>E Roots)#} = mset_set (X \<rightarrow>\<^sub>E Roots)
[PROOF STEP]
by (intro bij_betw_image_mset_set bij_betw_compose_left_perm_PiE \<pi>)
[PROOF STATE]
proof (state)
this:
{#restrict (\<pi> \<circ> g) X. g \<in># mset_set (X \<rightarrow>\<^sub>E Roots)#} = mset_set (X \<rightarrow>\<^sub>E Roots)

goal (1 subgoal):
 1. image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
{#restrict (\<pi> \<circ> g) X. g \<in># mset_set (X \<rightarrow>\<^sub>E Roots)#} = mset_set (X \<rightarrow>\<^sub>E Roots)

goal (1 subgoal):
 1. image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y
[PROOF STEP]
have "image_mset f \<dots> = Y"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. image_mset f (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y
[PROOF STEP]
using f
[PROOF STATE]
proof (prove)
using this:
f \<in> tuples Y

goal (1 subgoal):
 1. image_mset f (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y
[PROOF STEP]
by (simp add: tuples_def)
[PROOF STATE]
proof (state)
this:
image_mset f (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y

goal (1 subgoal):
 1. image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y
[PROOF STEP]
finally
[PROOF STATE]
proof (chain)
picking this:
image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y

goal (1 subgoal):
 1. image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y
[PROOF STEP]
.
[PROOF STATE]
proof (state)
this:
image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y

goal (1 subgoal):
 1. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi> \<circ> g) X)) \<in> tuples Y
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
restrict f' (X \<rightarrow>\<^sub>E Roots) \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X
image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y
[PROOF STEP]
show "restrict f' (X \<rightarrow>\<^sub>E Roots) \<in> tuples Y"
[PROOF STATE]
proof (prove)
using this:
restrict f' (X \<rightarrow>\<^sub>E Roots) \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X
image_mset (restrict f' (X \<rightarrow>\<^sub>E Roots)) (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y

goal (1 subgoal):
 1. restrict f' (X \<rightarrow>\<^sub>E Roots) \<in> tuples Y
[PROOF STEP]
by (auto simp: tuples_def)
[PROOF STATE]
proof (state)
this:
restrict f' (X \<rightarrow>\<^sub>E Roots) \<in> tuples Y

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
?\<pi> permutes Roots \<Longrightarrow> (\<lambda>f. \<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (?\<pi> \<circ> g) X)) \<in> tuples Y \<rightarrow> tuples Y

goal (4 subgoals):
 1. (\<lambda>f. \<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) \<in> tuples Y \<rightarrow> tuples Y
 2. ?g \<in> tuples Y \<rightarrow> tuples Y
 3. \<And>x. x \<in> tuples Y \<Longrightarrow> ?g (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi> \<circ> g) X)) = x
 4. \<And>y. y \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. ?g y (restrict (\<pi> \<circ> g) X)) = y
[PROOF STEP]
show "(\<lambda>f. restrict (\<lambda>g. f (restrict (\<pi> \<circ> g) X)) (X \<rightarrow>\<^sub>E Roots)) \<in> tuples Y \<rightarrow> tuples Y"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<lambda>f. \<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) \<in> tuples Y \<rightarrow> tuples Y
[PROOF STEP]
by (intro * \<pi>)
[PROOF STATE]
proof (state)
this:
(\<lambda>f. \<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) \<in> tuples Y \<rightarrow> tuples Y

goal (3 subgoals):
 1. ?g \<in> tuples Y \<rightarrow> tuples Y
 2. \<And>x. x \<in> tuples Y \<Longrightarrow> ?g (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi> \<circ> g) X)) = x
 3. \<And>y. y \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. ?g y (restrict (\<pi> \<circ> g) X)) = y
[PROOF STEP]
show "(\<lambda>f. restrict (\<lambda>g. f (restrict (inv_into UNIV \<pi> \<circ> g) X)) (X \<rightarrow>\<^sub>E Roots)) \<in> tuples Y \<rightarrow> tuples Y"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<lambda>f. \<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (inv \<pi> \<circ> g) X)) \<in> tuples Y \<rightarrow> tuples Y
[PROOF STEP]
by (intro * permutes_inv \<pi>)
[PROOF STATE]
proof (state)
this:
(\<lambda>f. \<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (inv \<pi> \<circ> g) X)) \<in> tuples Y \<rightarrow> tuples Y

goal (2 subgoals):
 1. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) = x
 2. \<And>y. y \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. y (restrict (inv \<pi> \<circ> g) X)) (restrict (\<pi> \<circ> g) X)) = y
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) = x
 2. \<And>y. y \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. y (restrict (inv \<pi> \<circ> g) X)) (restrict (\<pi> \<circ> g) X)) = y
[PROOF STEP]
have *: "(\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X))
                (restrict (inv_into UNIV \<pi> \<circ> g) X)) = f" (is "?lhs = _")
      if f: "f \<in> tuples Y" and \<pi>: "\<pi> permutes Roots" for f \<pi>
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) = f
[PROOF STEP]
proof
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>x. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) x = f x
[PROOF STEP]
fix g
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>x. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) x = f x
[PROOF STEP]
show "?lhs g = f g"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) g = f g
[PROOF STEP]
proof (cases "g \<in> X \<rightarrow>\<^sub>E Roots")
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. g \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) g = f g
 2. g \<notin> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) g = f g
[PROOF STEP]
case True
[PROOF STATE]
proof (state)
this:
g \<in> X \<rightarrow>\<^sub>E Roots

goal (2 subgoals):
 1. g \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) g = f g
 2. g \<notin> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) g = f g
[PROOF STEP]
have "restrict (\<pi> \<circ> restrict (inv_into UNIV \<pi> \<circ> g) X) X = g"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. restrict (\<pi> \<circ> restrict (inv \<pi> \<circ> g) X) X = g
[PROOF STEP]
using True
[PROOF STATE]
proof (prove)
using this:
g \<in> X \<rightarrow>\<^sub>E Roots

goal (1 subgoal):
 1. restrict (\<pi> \<circ> restrict (inv \<pi> \<circ> g) X) X = g
[PROOF STEP]
by (intro ext) (auto simp: permutes_inverses[OF \<pi>])
[PROOF STATE]
proof (state)
this:
restrict (\<pi> \<circ> restrict (inv \<pi> \<circ> g) X) X = g

goal (2 subgoals):
 1. g \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) g = f g
 2. g \<notin> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) g = f g
[PROOF STEP]
thus ?thesis
[PROOF STATE]
proof (prove)
using this:
restrict (\<pi> \<circ> restrict (inv \<pi> \<circ> g) X) X = g

goal (1 subgoal):
 1. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) g = f g
[PROOF STEP]
using True
[PROOF STATE]
proof (prove)
using this:
restrict (\<pi> \<circ> restrict (inv \<pi> \<circ> g) X) X = g
g \<in> X \<rightarrow>\<^sub>E Roots

goal (1 subgoal):
 1. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) g = f g
[PROOF STEP]
by (auto simp: permutes_in_image[OF permutes_inv[OF \<pi>]])
[PROOF STATE]
proof (state)
this:
(\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) g = f g

goal (1 subgoal):
 1. g \<notin> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) g = f g
[PROOF STEP]
qed (use f in \<open>auto simp: tuples_def\<close>)
[PROOF STATE]
proof (state)
this:
(\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) g = f g

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<lbrakk>?f \<in> tuples Y; ?\<pi> permutes Roots\<rbrakk> \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. ?f (restrict (?\<pi> \<circ> g) X)) (restrict (inv ?\<pi> \<circ> g) X)) = ?f

goal (2 subgoals):
 1. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) = x
 2. \<And>y. y \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. y (restrict (inv \<pi> \<circ> g) X)) (restrict (\<pi> \<circ> g) X)) = y
[PROOF STEP]
show "(\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X))
                (restrict (inv_into UNIV \<pi> \<circ> g) X)) = f" if "f \<in> tuples Y" for f
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) = f
[PROOF STEP]
using *[OF that \<pi>]
[PROOF STATE]
proof (prove)
using this:
(\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) = f

goal (1 subgoal):
 1. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) = f
[PROOF STEP]
.
[PROOF STATE]
proof (state)
this:
?f \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. ?f (restrict (\<pi> \<circ> g) X)) (restrict (inv \<pi> \<circ> g) X)) = ?f

goal (1 subgoal):
 1. \<And>y. y \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. y (restrict (inv \<pi> \<circ> g) X)) (restrict (\<pi> \<circ> g) X)) = y
[PROOF STEP]
show "(\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (inv_into UNIV \<pi> \<circ> g) X))
                (restrict (\<pi> \<circ> g) X)) = f" if "f \<in> tuples Y" for f
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (inv \<pi> \<circ> g) X)) (restrict (\<pi> \<circ> g) X)) = f
[PROOF STEP]
using *[OF that permutes_inv[OF \<pi>]] permutes_inv_inv[OF \<pi>]
[PROOF STATE]
proof (prove)
using this:
(\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (inv \<pi> \<circ> g) X)) (restrict (inv (inv \<pi>) \<circ> g) X)) = f
inv (inv \<pi>) = \<pi>

goal (1 subgoal):
 1. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (inv \<pi> \<circ> g) X)) (restrict (\<pi> \<circ> g) X)) = f
[PROOF STEP]
by simp
[PROOF STATE]
proof (state)
this:
?f \<in> tuples Y \<Longrightarrow> (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. (\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. ?f (restrict (inv \<pi> \<circ> g) X)) (restrict (\<pi> \<circ> g) X)) = ?f

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<lbrakk>?\<pi> permutes Roots; ?Y \<in> Roots_ms\<rbrakk> \<Longrightarrow> bij_betw (\<lambda>f. \<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (?\<pi> \<circ> g) X)) (tuples ?Y) (tuples ?Y)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
text \<open>
    We show that the coefficients in the expanded new sum are rational -- again using the
    fundamental theorem of symmetric polynomials.
  \<close>
[PROOF STATE]
proof (state)
this:
\<lbrakk>?\<pi> permutes Roots; ?Y \<in> Roots_ms\<rbrakk> \<Longrightarrow> bij_betw (\<lambda>f. \<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. f (restrict (?\<pi> \<circ> g) X)) (tuples ?Y) (tuples ?Y)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
define \<beta>' :: "complex multiset \<Rightarrow> complex"
    where "\<beta>' = (\<lambda>Y. \<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g))"
[PROOF STATE]
proof (state)
this:
\<beta>' = (\<lambda>Y. \<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g))

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "\<beta>' Y \<in> \<rat>" if Y: "Y \<in> Roots_ms" for Y
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<beta>' Y \<in> \<rat>
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<beta>' Y \<in> \<rat>
[PROOF STEP]
define Q :: "complex mpoly"
      where "Q = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f g))))"
[PROOF STATE]
proof (state)
this:
Q = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f g))))

goal (1 subgoal):
 1. \<beta>' Y \<in> \<rat>
[PROOF STEP]
have "insertion Root Q \<in> \<rat>"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. insertion Root Q \<in> \<rat>
[PROOF STEP]
proof (rule symmetric_poly_of_roots_in_subring)
[PROOF STATE]
proof (state)
goal (10 subgoals):
 1. ring_closed \<rat>
 2. \<forall>m. MPoly_Type.coeff Q m \<in> \<rat>
 3. ring_homomorphism (\<lambda>a. a)
 4. finite ?A
 5. symmetric_mpoly ?A Q
 6. vars Q \<subseteq> ?A
 7. ?cinv * ?c = 1
 8. ?cinv \<in> \<rat>
 9. ?p = Polynomial.smult ?c (\<Prod>i\<in>?A. [:- Root i, 1:])
 10. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
show "ring_closed (\<rat> :: complex set)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. ring_closed \<rat>
[PROOF STEP]
by standard auto
[PROOF STATE]
proof (state)
this:
ring_closed \<rat>

goal (9 subgoals):
 1. \<forall>m. MPoly_Type.coeff Q m \<in> \<rat>
 2. ring_homomorphism (\<lambda>a. a)
 3. finite ?A
 4. symmetric_mpoly ?A Q
 5. vars Q \<subseteq> ?A
 6. ?cinv * ?c = 1
 7. ?cinv \<in> \<rat>
 8. ?p = Polynomial.smult ?c (\<Prod>i\<in>?A. [:- Root i, 1:])
 9. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
ring_closed \<rat>
[PROOF STEP]
interpret ring_closed "\<rat> :: complex set"
[PROOF STATE]
proof (prove)
using this:
ring_closed \<rat>

goal (1 subgoal):
 1. ring_closed \<rat>
[PROOF STEP]
.
[PROOF STATE]
proof (state)
goal (9 subgoals):
 1. \<forall>m. MPoly_Type.coeff Q m \<in> \<rat>
 2. ring_homomorphism (\<lambda>a. a)
 3. finite ?A
 4. symmetric_mpoly ?A Q
 5. vars Q \<subseteq> ?A
 6. ?cinv * ?c = 1
 7. ?cinv \<in> \<rat>
 8. ?p = Polynomial.smult ?c (\<Prod>i\<in>?A. [:- Root i, 1:])
 9. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
show "\<forall>m. coeff Q m \<in> \<rat>"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>m. MPoly_Type.coeff Q m \<in> \<rat>
[PROOF STEP]
by (auto simp: Q_def coeff_Var when_def intro!: sum_in_Rats coeff_prod_closed)
[PROOF STATE]
proof (state)
this:
\<forall>m. MPoly_Type.coeff Q m \<in> \<rat>

goal (8 subgoals):
 1. ring_homomorphism (\<lambda>a. a)
 2. finite ?A
 3. symmetric_mpoly ?A Q
 4. vars Q \<subseteq> ?A
 5. ?cinv * ?c = 1
 6. ?cinv \<in> \<rat>
 7. ?p = Polynomial.smult ?c (\<Prod>i\<in>?A. [:- Root i, 1:])
 8. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (8 subgoals):
 1. ring_homomorphism (\<lambda>a. a)
 2. finite ?A
 3. symmetric_mpoly ?A Q
 4. vars Q \<subseteq> ?A
 5. ?cinv * ?c = 1
 6. ?cinv \<in> \<rat>
 7. ?p = Polynomial.smult ?c (\<Prod>i\<in>?A. [:- Root i, 1:])
 8. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
show "symmetric_mpoly {..<n} Q"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. symmetric_mpoly {..<n} Q
[PROOF STEP]
unfolding symmetric_mpoly_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<forall>\<pi>. \<pi> permutes {..<n} \<longrightarrow> mpoly_map_vars \<pi> Q = Q
[PROOF STEP]
proof safe
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>\<pi>. \<pi> permutes {..<n} \<Longrightarrow> mpoly_map_vars \<pi> Q = Q
[PROOF STEP]
fix \<pi>
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>\<pi>. \<pi> permutes {..<n} \<Longrightarrow> mpoly_map_vars \<pi> Q = Q
[PROOF STEP]
assume \<pi>: "\<pi> permutes {..<n}"
[PROOF STATE]
proof (state)
this:
\<pi> permutes {..<n}

goal (1 subgoal):
 1. \<And>\<pi>. \<pi> permutes {..<n} \<Longrightarrow> mpoly_map_vars \<pi> Q = Q
[PROOF STEP]
define \<pi>' where "\<pi>' = convert_perm (inv_into UNIV \<pi>)"
[PROOF STATE]
proof (state)
this:
\<pi>' = convert_perm (inv \<pi>)

goal (1 subgoal):
 1. \<And>\<pi>. \<pi> permutes {..<n} \<Longrightarrow> mpoly_map_vars \<pi> Q = Q
[PROOF STEP]
have \<pi>': "\<pi>' permutes Roots"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<pi>' permutes Roots
[PROOF STEP]
unfolding \<pi>'_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. convert_perm (inv \<pi>) permutes Roots
[PROOF STEP]
by (intro permutes_convert_perm permutes_inv \<pi>)
[PROOF STATE]
proof (state)
this:
\<pi>' permutes Roots

goal (1 subgoal):
 1. \<And>\<pi>. \<pi> permutes {..<n} \<Longrightarrow> mpoly_map_vars \<pi> Q = Q
[PROOF STEP]
have "mpoly_map_vars \<pi> Q = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g)))))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. mpoly_map_vars \<pi> Q = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g)))))
[PROOF STEP]
unfolding Q_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. mpoly_map_vars \<pi> (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f g)))) = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g)))))
[PROOF STEP]
by (simp add: permutes_bij[OF \<pi>])
[PROOF STATE]
proof (state)
this:
mpoly_map_vars \<pi> Q = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g)))))

goal (1 subgoal):
 1. \<And>\<pi>. \<pi> permutes {..<n} \<Longrightarrow> mpoly_map_vars \<pi> Q = Q
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
mpoly_map_vars \<pi> Q = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g)))))

goal (1 subgoal):
 1. \<And>\<pi>. \<pi> permutes {..<n} \<Longrightarrow> mpoly_map_vars \<pi> Q = Q
[PROOF STEP]
have "\<dots> = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g))))) = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))))
[PROOF STEP]
proof (rule sum.cong, goal_cases)
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. tuples Y = tuples Y
 2. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (x g))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (x (restrict (\<pi>' \<circ> g) X)))))
[PROOF STEP]
case (2 f)
[PROOF STATE]
proof (state)
this:
f \<in> tuples Y

goal (2 subgoals):
 1. tuples Y = tuples Y
 2. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (x g))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (x (restrict (\<pi>' \<circ> g) X)))))
[PROOF STEP]
have f: "f \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. f \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X
[PROOF STEP]
using 2
[PROOF STATE]
proof (prove)
using this:
f \<in> tuples Y

goal (1 subgoal):
 1. f \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X
[PROOF STEP]
by (auto simp: tuples_def)
[PROOF STATE]
proof (state)
this:
f \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X

goal (2 subgoals):
 1. tuples Y = tuples Y
 2. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (x g))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (x (restrict (\<pi>' \<circ> g) X)))))
[PROOF STEP]
have "(\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g))))) =
                (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X))))))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X))))))
[PROOF STEP]
using \<pi>'
[PROOF STATE]
proof (prove)
using this:
\<pi>' permutes Roots

goal (1 subgoal):
 1. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X))))))
[PROOF STEP]
by (intro prod.reindex_bij_betw [symmetric] bij_betw_compose_left_perm_PiE)
[PROOF STATE]
proof (state)
this:
(\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X))))))

goal (2 subgoals):
 1. tuples Y = tuples Y
 2. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (x g))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (x (restrict (\<pi>' \<circ> g) X)))))
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X))))))

goal (2 subgoals):
 1. tuples Y = tuples Y
 2. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (x g))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (x (restrict (\<pi>' \<circ> g) X)))))
[PROOF STEP]
have "\<dots> = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X)))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))))
[PROOF STEP]
proof (intro prod.cong refl arg_cong[of _ _ Var])
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>x. x \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> \<pi> (unRoot (restrict (\<pi>' \<circ> x) X (f (restrict (\<pi>' \<circ> x) X)))) = unRoot (x (f (restrict (\<pi>' \<circ> x) X)))
[PROOF STEP]
fix g
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>x. x \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> \<pi> (unRoot (restrict (\<pi>' \<circ> x) X (f (restrict (\<pi>' \<circ> x) X)))) = unRoot (x (f (restrict (\<pi>' \<circ> x) X)))
[PROOF STEP]
assume g: "g \<in> X \<rightarrow>\<^sub>E Roots"
[PROOF STATE]
proof (state)
this:
g \<in> X \<rightarrow>\<^sub>E Roots

goal (1 subgoal):
 1. \<And>x. x \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> \<pi> (unRoot (restrict (\<pi>' \<circ> x) X (f (restrict (\<pi>' \<circ> x) X)))) = unRoot (x (f (restrict (\<pi>' \<circ> x) X)))
[PROOF STEP]
have "restrict (\<pi>' \<circ> g) X \<in> X \<rightarrow>\<^sub>E Roots"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. restrict (\<pi>' \<circ> g) X \<in> X \<rightarrow>\<^sub>E Roots
[PROOF STEP]
using bij_betw_compose_left_perm_PiE[OF \<pi>', of X] g
[PROOF STATE]
proof (prove)
using this:
bij_betw (\<lambda>f. restrict (\<pi>' \<circ> f) X) (X \<rightarrow>\<^sub>E Roots) (X \<rightarrow>\<^sub>E Roots)
g \<in> X \<rightarrow>\<^sub>E Roots

goal (1 subgoal):
 1. restrict (\<pi>' \<circ> g) X \<in> X \<rightarrow>\<^sub>E Roots
[PROOF STEP]
unfolding bij_betw_def
[PROOF STATE]
proof (prove)
using this:
inj_on (\<lambda>f. restrict (\<pi>' \<circ> f) X) (X \<rightarrow>\<^sub>E Roots) \<and> (\<lambda>f. restrict (\<pi>' \<circ> f) X) ` (X \<rightarrow>\<^sub>E Roots) = X \<rightarrow>\<^sub>E Roots
g \<in> X \<rightarrow>\<^sub>E Roots

goal (1 subgoal):
 1. restrict (\<pi>' \<circ> g) X \<in> X \<rightarrow>\<^sub>E Roots
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
restrict (\<pi>' \<circ> g) X \<in> X \<rightarrow>\<^sub>E Roots

goal (1 subgoal):
 1. \<And>x. x \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> \<pi> (unRoot (restrict (\<pi>' \<circ> x) X (f (restrict (\<pi>' \<circ> x) X)))) = unRoot (x (f (restrict (\<pi>' \<circ> x) X)))
[PROOF STEP]
hence *: "f (restrict (\<pi>' \<circ> g) X) \<in> X"
[PROOF STATE]
proof (prove)
using this:
restrict (\<pi>' \<circ> g) X \<in> X \<rightarrow>\<^sub>E Roots

goal (1 subgoal):
 1. f (restrict (\<pi>' \<circ> g) X) \<in> X
[PROOF STEP]
by (rule PiE_mem[OF f])
[PROOF STATE]
proof (state)
this:
f (restrict (\<pi>' \<circ> g) X) \<in> X

goal (1 subgoal):
 1. \<And>x. x \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> \<pi> (unRoot (restrict (\<pi>' \<circ> x) X (f (restrict (\<pi>' \<circ> x) X)))) = unRoot (x (f (restrict (\<pi>' \<circ> x) X)))
[PROOF STEP]
hence **: "g (f (restrict (\<pi>' \<circ> g) X)) \<in> Roots"
[PROOF STATE]
proof (prove)
using this:
f (restrict (\<pi>' \<circ> g) X) \<in> X

goal (1 subgoal):
 1. g (f (restrict (\<pi>' \<circ> g) X)) \<in> Roots
[PROOF STEP]
by (rule PiE_mem[OF g])
[PROOF STATE]
proof (state)
this:
g (f (restrict (\<pi>' \<circ> g) X)) \<in> Roots

goal (1 subgoal):
 1. \<And>x. x \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> \<pi> (unRoot (restrict (\<pi>' \<circ> x) X (f (restrict (\<pi>' \<circ> x) X)))) = unRoot (x (f (restrict (\<pi>' \<circ> x) X)))
[PROOF STEP]
have "unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X))) =
                   unRoot (Root (inv_into UNIV \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X))))))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X))) = unRoot (Root (inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X))))))
[PROOF STEP]
using * **
[PROOF STATE]
proof (prove)
using this:
f (restrict (\<pi>' \<circ> g) X) \<in> X
g (f (restrict (\<pi>' \<circ> g) X)) \<in> Roots

goal (1 subgoal):
 1. unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X))) = unRoot (Root (inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X))))))
[PROOF STEP]
by (subst \<pi>'_def) (auto simp: convert_perm_def)
[PROOF STATE]
proof (state)
this:
unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X))) = unRoot (Root (inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X))))))

goal (1 subgoal):
 1. \<And>x. x \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> \<pi> (unRoot (restrict (\<pi>' \<circ> x) X (f (restrict (\<pi>' \<circ> x) X)))) = unRoot (x (f (restrict (\<pi>' \<circ> x) X)))
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X))) = unRoot (Root (inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X))))))

goal (1 subgoal):
 1. \<And>x. x \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> \<pi> (unRoot (restrict (\<pi>' \<circ> x) X (f (restrict (\<pi>' \<circ> x) X)))) = unRoot (x (f (restrict (\<pi>' \<circ> x) X)))
[PROOF STEP]
have "inv_into UNIV \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))) \<in> {..<n}"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))) \<in> {..<n}
[PROOF STEP]
using **
[PROOF STATE]
proof (prove)
using this:
g (f (restrict (\<pi>' \<circ> g) X)) \<in> Roots

goal (1 subgoal):
 1. inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))) \<in> {..<n}
[PROOF STEP]
by (subst permutes_in_image[OF permutes_inv[OF \<pi>]]) auto
[PROOF STATE]
proof (state)
this:
inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))) \<in> {..<n}

goal (1 subgoal):
 1. \<And>x. x \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> \<pi> (unRoot (restrict (\<pi>' \<circ> x) X (f (restrict (\<pi>' \<circ> x) X)))) = unRoot (x (f (restrict (\<pi>' \<circ> x) X)))
[PROOF STEP]
hence "unRoot (Root (inv_into UNIV \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))))) =
                   inv_into UNIV \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X))))"
[PROOF STATE]
proof (prove)
using this:
inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))) \<in> {..<n}

goal (1 subgoal):
 1. unRoot (Root (inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))))) = inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X))))
[PROOF STEP]
by (intro unRoot_Root) auto
[PROOF STATE]
proof (state)
this:
unRoot (Root (inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))))) = inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X))))

goal (1 subgoal):
 1. \<And>x. x \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> \<pi> (unRoot (restrict (\<pi>' \<circ> x) X (f (restrict (\<pi>' \<circ> x) X)))) = unRoot (x (f (restrict (\<pi>' \<circ> x) X)))
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
unRoot (Root (inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))))) = inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X))))

goal (1 subgoal):
 1. \<And>x. x \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> \<pi> (unRoot (restrict (\<pi>' \<circ> x) X (f (restrict (\<pi>' \<circ> x) X)))) = unRoot (x (f (restrict (\<pi>' \<circ> x) X)))
[PROOF STEP]
have "\<pi> \<dots> = unRoot (g (f (restrict (\<pi>' \<circ> g) X)))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<pi> (inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X))))) = unRoot (g (f (restrict (\<pi>' \<circ> g) X)))
[PROOF STEP]
by (rule permutes_inverses[OF \<pi>])
[PROOF STATE]
proof (state)
this:
\<pi> (inv \<pi> (unRoot (g (f (restrict (\<pi>' \<circ> g) X))))) = unRoot (g (f (restrict (\<pi>' \<circ> g) X)))

goal (1 subgoal):
 1. \<And>x. x \<in> X \<rightarrow>\<^sub>E Roots \<Longrightarrow> \<pi> (unRoot (restrict (\<pi>' \<circ> x) X (f (restrict (\<pi>' \<circ> x) X)))) = unRoot (x (f (restrict (\<pi>' \<circ> x) X)))
[PROOF STEP]
finally
[PROOF STATE]
proof (chain)
picking this:
\<pi> (unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X)))) = unRoot (g (f (restrict (\<pi>' \<circ> g) X)))
[PROOF STEP]
show "\<pi> (unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X)))) =
                          unRoot (g (f (restrict (\<pi>' \<circ> g) X)))"
[PROOF STATE]
proof (prove)
using this:
\<pi> (unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X)))) = unRoot (g (f (restrict (\<pi>' \<circ> g) X)))

goal (1 subgoal):
 1. \<pi> (unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X)))) = unRoot (g (f (restrict (\<pi>' \<circ> g) X)))
[PROOF STEP]
.
[PROOF STATE]
proof (state)
this:
\<pi> (unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X)))) = unRoot (g (f (restrict (\<pi>' \<circ> g) X)))

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
(\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (restrict (\<pi>' \<circ> g) X (f (restrict (\<pi>' \<circ> g) X)))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))))

goal (2 subgoals):
 1. tuples Y = tuples Y
 2. \<And>x. x \<in> tuples Y \<Longrightarrow> (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (x g))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (x (restrict (\<pi>' \<circ> g) X)))))
[PROOF STEP]
finally
[PROOF STATE]
proof (chain)
picking this:
(\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))))
[PROOF STEP]
show ?case
[PROOF STATE]
proof (prove)
using this:
(\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))))

goal (1 subgoal):
 1. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))))
[PROOF STEP]
.
[PROOF STATE]
proof (state)
this:
(\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g))))) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))))

goal (1 subgoal):
 1. tuples Y = tuples Y
[PROOF STEP]
qed simp_all
[PROOF STATE]
proof (state)
this:
(\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g))))) = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))))

goal (1 subgoal):
 1. \<And>\<pi>. \<pi> permutes {..<n} \<Longrightarrow> mpoly_map_vars \<pi> Q = Q
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (\<pi> (unRoot (g (f g))))) = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f (restrict (\<pi>' \<circ> g) X)))))

goal (1 subgoal):
 1. \<And>\<pi>. \<pi> permutes {..<n} \<Longrightarrow> mpoly_map_vars \<pi> Q = Q
[PROOF STEP]
have "\<dots> = (\<Sum>x\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g ((\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi>' \<circ> g) X)) g))))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f (restrict (\<pi>' \<circ> g) X))))) = (\<Sum>x\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g ((\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi>' \<circ> g) X)) g))))
[PROOF STEP]
by (intro sum.cong prod.cong refl) auto
[PROOF STATE]
proof (state)
this:
(\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f (restrict (\<pi>' \<circ> g) X))))) = (\<Sum>x\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g ((\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi>' \<circ> g) X)) g))))

goal (1 subgoal):
 1. \<And>\<pi>. \<pi> permutes {..<n} \<Longrightarrow> mpoly_map_vars \<pi> Q = Q
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f (restrict (\<pi>' \<circ> g) X))))) = (\<Sum>x\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g ((\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi>' \<circ> g) X)) g))))

goal (1 subgoal):
 1. \<And>\<pi>. \<pi> permutes {..<n} \<Longrightarrow> mpoly_map_vars \<pi> Q = Q
[PROOF STEP]
have "\<dots> = Q"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>x\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g ((\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi>' \<circ> g) X)) g)))) = Q
[PROOF STEP]
unfolding Q_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>x\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g ((\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi>' \<circ> g) X)) g)))) = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f g))))
[PROOF STEP]
by (rule sum.reindex_bij_betw[OF bij_betw_compose_perm]) (use \<pi>' Y in simp_all)
[PROOF STATE]
proof (state)
this:
(\<Sum>x\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g ((\<lambda>g\<in>X \<rightarrow>\<^sub>E Roots. x (restrict (\<pi>' \<circ> g) X)) g)))) = Q

goal (1 subgoal):
 1. \<And>\<pi>. \<pi> permutes {..<n} \<Longrightarrow> mpoly_map_vars \<pi> Q = Q
[PROOF STEP]
finally
[PROOF STATE]
proof (chain)
picking this:
mpoly_map_vars \<pi> Q = Q
[PROOF STEP]
show "mpoly_map_vars \<pi> Q = Q"
[PROOF STATE]
proof (prove)
using this:
mpoly_map_vars \<pi> Q = Q

goal (1 subgoal):
 1. mpoly_map_vars \<pi> Q = Q
[PROOF STEP]
.
[PROOF STATE]
proof (state)
this:
mpoly_map_vars \<pi> Q = Q

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
symmetric_mpoly {..<n} Q

goal (7 subgoals):
 1. ring_homomorphism (\<lambda>a. a)
 2. finite {..<n}
 3. vars Q \<subseteq> {..<n}
 4. ?cinv * ?c = 1
 5. ?cinv \<in> \<rat>
 6. ?p = Polynomial.smult ?c (\<Prod>i<n. [:- Root i, 1:])
 7. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (7 subgoals):
 1. ring_homomorphism (\<lambda>a. a)
 2. finite {..<n}
 3. vars Q \<subseteq> {..<n}
 4. ?cinv * ?c = 1
 5. ?cinv \<in> \<rat>
 6. ?p = Polynomial.smult ?c (\<Prod>i<n. [:- Root i, 1:])
 7. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
show "vars Q \<subseteq> {..<n}"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. vars Q \<subseteq> {..<n}
[PROOF STEP]
unfolding Q_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. vars (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Var (unRoot (g (f g)))) \<subseteq> {..<n}
[PROOF STEP]
by (intro order.trans[OF vars_sum] UN_least order.trans[OF vars_prod])
           (auto simp: vars_Var tuples_def)
[PROOF STATE]
proof (state)
this:
vars Q \<subseteq> {..<n}

goal (6 subgoals):
 1. ring_homomorphism (\<lambda>a. a)
 2. finite {..<n}
 3. ?cinv * ?c = 1
 4. ?cinv \<in> \<rat>
 5. ?p = Polynomial.smult ?c (\<Prod>i<n. [:- Root i, 1:])
 6. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (6 subgoals):
 1. ring_homomorphism (\<lambda>a. a)
 2. finite {..<n}
 3. ?cinv * ?c = 1
 4. ?cinv \<in> \<rat>
 5. ?p = Polynomial.smult ?c (\<Prod>i<n. [:- Root i, 1:])
 6. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
define lc where "lc = Polynomial.lead_coeff P"
[PROOF STATE]
proof (state)
this:
lc = Polynomial.lead_coeff P

goal (6 subgoals):
 1. ring_homomorphism (\<lambda>a. a)
 2. finite {..<n}
 3. ?cinv * ?c = 1
 4. ?cinv \<in> \<rat>
 5. ?p = Polynomial.smult ?c (\<Prod>i<n. [:- Root i, 1:])
 6. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
have "lc \<noteq> 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. lc \<noteq> 0
[PROOF STEP]
unfolding lc_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. Polynomial.lead_coeff P \<noteq> 0
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
lc \<noteq> 0

goal (6 subgoals):
 1. ring_homomorphism (\<lambda>a. a)
 2. finite {..<n}
 3. ?cinv * ?c = 1
 4. ?cinv \<in> \<rat>
 5. ?p = Polynomial.smult ?c (\<Prod>i<n. [:- Root i, 1:])
 6. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
thus "inverse (of_int lc) * (of_int lc :: complex) = 1" and "inverse (of_int lc) \<in> \<rat>"
[PROOF STATE]
proof (prove)
using this:
lc \<noteq> 0

goal (1 subgoal):
 1. inverse (of_int lc) * of_int lc = 1 &&& inverse (of_int lc) \<in> \<rat>
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
inverse (of_int lc) * of_int lc = 1
inverse (of_int lc) \<in> \<rat>

goal (4 subgoals):
 1. ring_homomorphism (\<lambda>a. a)
 2. finite {..<n}
 3. ?p = Polynomial.smult (of_int (Polynomial.lead_coeff P)) (\<Prod>i<n. [:- Root i, 1:])
 4. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
have "rsquarefree (of_int_poly P :: complex poly)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. rsquarefree (Ring_Hom_Poly.of_int_poly P)
[PROOF STEP]
using \<open>squarefree (of_int_poly P :: complex poly)\<close>
[PROOF STATE]
proof (prove)
using this:
squarefree (Ring_Hom_Poly.of_int_poly P)

goal (1 subgoal):
 1. rsquarefree (Ring_Hom_Poly.of_int_poly P)
[PROOF STEP]
by (intro squarefree_imp_rsquarefree)
[PROOF STATE]
proof (state)
this:
rsquarefree (Ring_Hom_Poly.of_int_poly P)

goal (4 subgoals):
 1. ring_homomorphism (\<lambda>a. a)
 2. finite {..<n}
 3. ?p = Polynomial.smult (of_int (Polynomial.lead_coeff P)) (\<Prod>i<n. [:- Root i, 1:])
 4. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
hence "of_int_poly P = Polynomial.smult (of_int lc) (\<Prod>x\<in>Roots. [:-x, 1:])"
[PROOF STATE]
proof (prove)
using this:
rsquarefree (Ring_Hom_Poly.of_int_poly P)

goal (1 subgoal):
 1. Ring_Hom_Poly.of_int_poly P = Polynomial.smult (of_int lc) (\<Prod>x\<in>Roots. [:- x, 1:])
[PROOF STEP]
unfolding lc_def of_int_hom.hom_lead_coeff[symmetric] Roots_def
[PROOF STATE]
proof (prove)
using this:
rsquarefree (Ring_Hom_Poly.of_int_poly P)

goal (1 subgoal):
 1. Ring_Hom_Poly.of_int_poly P = Polynomial.smult (Polynomial.lead_coeff (Ring_Hom_Poly.of_int_poly P)) (\<Prod>x\<in>{x. ipoly P x = 0}. [:- x, 1:])
[PROOF STEP]
by (rule complex_poly_decompose_rsquarefree [symmetric])
[PROOF STATE]
proof (state)
this:
Ring_Hom_Poly.of_int_poly P = Polynomial.smult (of_int lc) (\<Prod>x\<in>Roots. [:- x, 1:])

goal (4 subgoals):
 1. ring_homomorphism (\<lambda>a. a)
 2. finite {..<n}
 3. ?p = Polynomial.smult (of_int (Polynomial.lead_coeff P)) (\<Prod>i<n. [:- Root i, 1:])
 4. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
Ring_Hom_Poly.of_int_poly P = Polynomial.smult (of_int lc) (\<Prod>x\<in>Roots. [:- x, 1:])

goal (4 subgoals):
 1. ring_homomorphism (\<lambda>a. a)
 2. finite {..<n}
 3. ?p = Polynomial.smult (of_int (Polynomial.lead_coeff P)) (\<Prod>i<n. [:- Root i, 1:])
 4. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
have "(\<Prod>x\<in>Roots. [:-x, 1:]) = (\<Prod>i<n. [:-Root i, 1:])"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Prod>x\<in>Roots. [:- x, 1:]) = (\<Prod>i<n. [:- Root i, 1:])
[PROOF STEP]
by (rule prod.reindex_bij_betw[OF Root, symmetric])
[PROOF STATE]
proof (state)
this:
(\<Prod>x\<in>Roots. [:- x, 1:]) = (\<Prod>i<n. [:- Root i, 1:])

goal (4 subgoals):
 1. ring_homomorphism (\<lambda>a. a)
 2. finite {..<n}
 3. ?p = Polynomial.smult (of_int (Polynomial.lead_coeff P)) (\<Prod>i<n. [:- Root i, 1:])
 4. \<forall>i. poly.coeff ?p i \<in> \<rat>
[PROOF STEP]
finally
[PROOF STATE]
proof (chain)
picking this:
Ring_Hom_Poly.of_int_poly P = Polynomial.smult (of_int lc) (\<Prod>i<n. [:- Root i, 1:])
[PROOF STEP]
show "of_int_poly P = Polynomial.smult (of_int lc) (\<Prod>i<n. [:- Root i, 1:])"
[PROOF STATE]
proof (prove)
using this:
Ring_Hom_Poly.of_int_poly P = Polynomial.smult (of_int lc) (\<Prod>i<n. [:- Root i, 1:])

goal (1 subgoal):
 1. Ring_Hom_Poly.of_int_poly P = Polynomial.smult (of_int lc) (\<Prod>i<n. [:- Root i, 1:])
[PROOF STEP]
.
[PROOF STATE]
proof (state)
this:
Ring_Hom_Poly.of_int_poly P = Polynomial.smult (of_int lc) (\<Prod>i<n. [:- Root i, 1:])

goal (3 subgoals):
 1. ring_homomorphism (\<lambda>a. a)
 2. finite {..<n}
 3. \<forall>i. poly.coeff (Ring_Hom_Poly.of_int_poly P) i \<in> \<rat>
[PROOF STEP]
qed auto
[PROOF STATE]
proof (state)
this:
insertion Root Q \<in> \<rat>

goal (1 subgoal):
 1. \<beta>' Y \<in> \<rat>
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
insertion Root Q \<in> \<rat>

goal (1 subgoal):
 1. \<beta>' Y \<in> \<rat>
[PROOF STEP]
have "insertion Root Q = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Root (unRoot (g (f g))))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. insertion Root Q = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Root (unRoot (g (f g))))
[PROOF STEP]
by (simp add: Q_def insertion_sum insertion_prod)
[PROOF STATE]
proof (state)
this:
insertion Root Q = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Root (unRoot (g (f g))))

goal (1 subgoal):
 1. \<beta>' Y \<in> \<rat>
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
insertion Root Q = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Root (unRoot (g (f g))))

goal (1 subgoal):
 1. \<beta>' Y \<in> \<rat>
[PROOF STEP]
have "\<dots> = \<beta>' Y"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Root (unRoot (g (f g)))) = \<beta>' Y
[PROOF STEP]
unfolding \<beta>'_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Root (unRoot (g (f g)))) = (\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g))
[PROOF STEP]
by (intro sum.cong prod.cong refl Root_unRoot) (auto simp: tuples_def)
[PROOF STATE]
proof (state)
this:
(\<Sum>f\<in>tuples Y. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. Root (unRoot (g (f g)))) = \<beta>' Y

goal (1 subgoal):
 1. \<beta>' Y \<in> \<rat>
[PROOF STEP]
finally
[PROOF STATE]
proof (chain)
picking this:
\<beta>' Y \<in> \<rat>
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
\<beta>' Y \<in> \<rat>

goal (1 subgoal):
 1. \<beta>' Y \<in> \<rat>
[PROOF STEP]
.
[PROOF STATE]
proof (state)
this:
\<beta>' Y \<in> \<rat>

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
?Y \<in> Roots_ms \<Longrightarrow> \<beta>' ?Y \<in> \<rat>

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
hence "\<forall>Y\<in>Roots_ms. \<exists>x. \<beta>' Y = of_rat x"
[PROOF STATE]
proof (prove)
using this:
?Y \<in> Roots_ms \<Longrightarrow> \<beta>' ?Y \<in> \<rat>

goal (1 subgoal):
 1. \<forall>Y\<in>Roots_ms. \<exists>x. \<beta>' Y = of_rat x
[PROOF STEP]
by (auto elim!: Rats_cases)
[PROOF STATE]
proof (state)
this:
\<forall>Y\<in>Roots_ms. \<exists>x. \<beta>' Y = of_rat x

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<forall>Y\<in>Roots_ms. \<exists>x. \<beta>' Y = of_rat x
[PROOF STEP]
obtain \<beta>'' :: "complex multiset \<Rightarrow> rat"
    where \<beta>'': "\<And>Y. Y \<in> Roots_ms \<Longrightarrow> \<beta>' Y = of_rat (\<beta>'' Y)"
[PROOF STATE]
proof (prove)
using this:
\<forall>Y\<in>Roots_ms. \<exists>x. \<beta>' Y = of_rat x

goal (1 subgoal):
 1. (\<And>\<beta>''. (\<And>Y. Y \<in> Roots_ms \<Longrightarrow> \<beta>' Y = of_rat (\<beta>'' Y)) \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
by metis
[PROOF STATE]
proof (state)
this:
?Y \<in> Roots_ms \<Longrightarrow> \<beta>' ?Y = of_rat (\<beta>'' ?Y)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
text \<open>
    We again collect all the terms that happen to have equal exponents and call their
    coefficients \<open>\<beta>''\<close>:
  \<close>
[PROOF STATE]
proof (state)
this:
?Y \<in> Roots_ms \<Longrightarrow> \<beta>' ?Y = of_rat (\<beta>'' ?Y)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
define \<beta>''' :: "complex \<Rightarrow> rat" where "\<beta>''' = (\<lambda>\<alpha>. \<Sum>Y\<in>Roots_ms. (\<beta>'' Y when \<Sum>\<^sub>#Y = \<alpha>))"
[PROOF STATE]
proof (state)
this:
\<beta>''' = (\<lambda>\<alpha>. \<Sum>Y\<in>Roots_ms. \<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have supp_\<beta>''': "{x. \<beta>''' x \<noteq> 0} \<subseteq> sum_mset ` Roots_ms"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. {x. \<beta>''' x \<noteq> 0} \<subseteq> \<Sum>\<^sub># ` Roots_ms
[PROOF STEP]
by (auto simp: \<beta>'''_def when_def elim!: sum.not_neutral_contains_not_neutral split: if_splits)
[PROOF STATE]
proof (state)
this:
{x. \<beta>''' x \<noteq> 0} \<subseteq> \<Sum>\<^sub># ` Roots_ms

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
text \<open>
    We again start with the sum that we now to be zero and multiply it with all the sums that can
    be obtained with different choices for the roots.
  \<close>
[PROOF STATE]
proof (state)
this:
{x. \<beta>''' x \<noteq> 0} \<subseteq> \<Sum>\<^sub># ` Roots_ms

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "0 = (\<Sum>x\<in>X. \<beta> x * exp x)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. 0 = (\<Sum>x\<in>X. \<beta> x * exp x)
[PROOF STEP]
using sum0
[PROOF STATE]
proof (prove)
using this:
(\<Sum>x\<in>X. \<beta> x * exp x) = 0

goal (1 subgoal):
 1. 0 = (\<Sum>x\<in>X. \<beta> x * exp x)
[PROOF STEP]
..
[PROOF STATE]
proof (state)
this:
0 = (\<Sum>x\<in>X. \<beta> x * exp x)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
0 = (\<Sum>x\<in>X. \<beta> x * exp x)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "\<dots> = (\<Sum>x\<in>X. restrict \<beta> X x * exp x)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>x\<in>X. \<beta> x * exp x) = (\<Sum>x\<in>X. restrict \<beta> X x * exp x)
[PROOF STEP]
by (intro sum.cong) auto
[PROOF STATE]
proof (state)
this:
(\<Sum>x\<in>X. \<beta> x * exp x) = (\<Sum>x\<in>X. restrict \<beta> X x * exp x)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Sum>x\<in>X. \<beta> x * exp x) = (\<Sum>x\<in>X. restrict \<beta> X x * exp x)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "\<dots> dvd (\<Prod>f \<in> X \<rightarrow>\<^sub>E Roots. \<Sum>x\<in>X. f x * exp x)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>x\<in>X. restrict \<beta> X x * exp x) dvd (\<Prod>f\<in>X \<rightarrow>\<^sub>E Roots. \<Sum>x\<in>X. f x * exp x)
[PROOF STEP]
by (rule dvd_prodI) (use \<open>\<beta> ` X \<subseteq> Roots\<close> in \<open>auto simp: id_def\<close>)
[PROOF STATE]
proof (state)
this:
(\<Sum>x\<in>X. restrict \<beta> X x * exp x) dvd (\<Prod>f\<in>X \<rightarrow>\<^sub>E Roots. \<Sum>x\<in>X. f x * exp x)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Sum>x\<in>X. restrict \<beta> X x * exp x) dvd (\<Prod>f\<in>X \<rightarrow>\<^sub>E Roots. \<Sum>x\<in>X. f x * exp x)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "\<dots> = (\<Sum>f\<in>(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g) * exp (f g))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Prod>f\<in>X \<rightarrow>\<^sub>E Roots. \<Sum>x\<in>X. f x * exp x) = (\<Sum>f\<in>(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g) * exp (f g))
[PROOF STEP]
by (rule prod_sum_PiE) auto
[PROOF STATE]
proof (state)
this:
(\<Prod>f\<in>X \<rightarrow>\<^sub>E Roots. \<Sum>x\<in>X. f x * exp x) = (\<Sum>f\<in>(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g) * exp (f g))

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Prod>f\<in>X \<rightarrow>\<^sub>E Roots. \<Sum>x\<in>X. f x * exp x) = (\<Sum>f\<in>(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g) * exp (f g))

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "\<dots> = (\<Sum>f\<in>(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (\<Sum>g\<in>X \<rightarrow>\<^sub>E Roots. f g))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>f\<in>(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g) * exp (f g)) = (\<Sum>f\<in>(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (sum f (X \<rightarrow>\<^sub>E Roots)))
[PROOF STEP]
by (simp add: prod.distrib exp_sum)
[PROOF STATE]
proof (state)
this:
(\<Sum>f\<in>(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g) * exp (f g)) = (\<Sum>f\<in>(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (sum f (X \<rightarrow>\<^sub>E Roots)))

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Sum>f\<in>(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. \<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g) * exp (f g)) = (\<Sum>f\<in>(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (sum f (X \<rightarrow>\<^sub>E Roots)))

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "\<dots> = (\<Sum>(Y,f)\<in>Sigma Roots_ms tuples.
                    (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (\<Sum>g\<in>X \<rightarrow>\<^sub>E Roots. f g))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>f\<in>(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (sum f (X \<rightarrow>\<^sub>E Roots))) = (\<Sum>(Y, f)\<in>Sigma Roots_ms tuples. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (sum f (X \<rightarrow>\<^sub>E Roots)))
[PROOF STEP]
by (intro sum.reindex_bij_witness[of _ snd "\<lambda>f. (image_mset f (mset_set (X \<rightarrow>\<^sub>E Roots)), f)"])
       (auto simp: Roots_ms_def tuples_def)
[PROOF STATE]
proof (state)
this:
(\<Sum>f\<in>(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (sum f (X \<rightarrow>\<^sub>E Roots))) = (\<Sum>(Y, f)\<in>Sigma Roots_ms tuples. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (sum f (X \<rightarrow>\<^sub>E Roots)))

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Sum>f\<in>(X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (sum f (X \<rightarrow>\<^sub>E Roots))) = (\<Sum>(Y, f)\<in>Sigma Roots_ms tuples. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (sum f (X \<rightarrow>\<^sub>E Roots)))

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "\<dots> = (\<Sum>(Y,f)\<in>Sigma Roots_ms tuples. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (\<Sum>\<^sub>#Y))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>(Y, f)\<in>Sigma Roots_ms tuples. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (sum f (X \<rightarrow>\<^sub>E Roots))) = (\<Sum>(Y, f)\<in>Sigma Roots_ms tuples. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (\<Sum>\<^sub># Y))
[PROOF STEP]
by (intro sum.cong) (auto simp: tuples_def sum_unfold_sum_mset)
[PROOF STATE]
proof (state)
this:
(\<Sum>(Y, f)\<in>Sigma Roots_ms tuples. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (sum f (X \<rightarrow>\<^sub>E Roots))) = (\<Sum>(Y, f)\<in>Sigma Roots_ms tuples. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (\<Sum>\<^sub># Y))

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Sum>(Y, f)\<in>Sigma Roots_ms tuples. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (sum f (X \<rightarrow>\<^sub>E Roots))) = (\<Sum>(Y, f)\<in>Sigma Roots_ms tuples. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (\<Sum>\<^sub># Y))

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "\<dots> = (\<Sum>Y\<in>Roots_ms. \<beta>' Y * exp (\<Sum>\<^sub>#Y))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>(Y, f)\<in>Sigma Roots_ms tuples. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (\<Sum>\<^sub># Y)) = (\<Sum>Y\<in>Roots_ms. \<beta>' Y * exp (\<Sum>\<^sub># Y))
[PROOF STEP]
unfolding \<beta>'_def sum_distrib_right
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>(Y, f)\<in>Sigma Roots_ms tuples. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (\<Sum>\<^sub># Y)) = (\<Sum>Y\<in>Roots_ms. \<Sum>n\<in>tuples Y. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (n g)) * exp (\<Sum>\<^sub># Y))
[PROOF STEP]
by (rule sum.Sigma [symmetric]) auto
[PROOF STATE]
proof (state)
this:
(\<Sum>(Y, f)\<in>Sigma Roots_ms tuples. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (\<Sum>\<^sub># Y)) = (\<Sum>Y\<in>Roots_ms. \<beta>' Y * exp (\<Sum>\<^sub># Y))

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Sum>(Y, f)\<in>Sigma Roots_ms tuples. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f g)) * exp (\<Sum>\<^sub># Y)) = (\<Sum>Y\<in>Roots_ms. \<beta>' Y * exp (\<Sum>\<^sub># Y))

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "\<dots> = (\<Sum>Y\<in>Roots_ms. of_rat (\<beta>'' Y) * exp (\<Sum>\<^sub>#Y))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>Y\<in>Roots_ms. \<beta>' Y * exp (\<Sum>\<^sub># Y)) = (\<Sum>Y\<in>Roots_ms. of_rat (\<beta>'' Y) * exp (\<Sum>\<^sub># Y))
[PROOF STEP]
by (intro sum.cong) (auto simp: \<beta>'')
[PROOF STATE]
proof (state)
this:
(\<Sum>Y\<in>Roots_ms. \<beta>' Y * exp (\<Sum>\<^sub># Y)) = (\<Sum>Y\<in>Roots_ms. of_rat (\<beta>'' Y) * exp (\<Sum>\<^sub># Y))

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Sum>Y\<in>Roots_ms. \<beta>' Y * exp (\<Sum>\<^sub># Y)) = (\<Sum>Y\<in>Roots_ms. of_rat (\<beta>'' Y) * exp (\<Sum>\<^sub># Y))

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "\<dots> = (\<Sum>Y\<in>Roots_ms. Sum_any (\<lambda>\<alpha>. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>Y\<in>Roots_ms. of_rat (\<beta>'' Y) * exp (\<Sum>\<^sub># Y)) = (\<Sum>Y\<in>Roots_ms. \<Sum>\<alpha>. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>)
[PROOF STEP]
proof (rule sum.cong, goal_cases)
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. Roots_ms = Roots_ms
 2. \<And>x. x \<in> Roots_ms \<Longrightarrow> of_rat (\<beta>'' x) * exp (\<Sum>\<^sub># x) = (\<Sum>\<alpha>. of_rat (\<beta>'' x when \<Sum>\<^sub># x = \<alpha>) * exp \<alpha>)
[PROOF STEP]
case (2 Y)
[PROOF STATE]
proof (state)
this:
Y \<in> Roots_ms

goal (2 subgoals):
 1. Roots_ms = Roots_ms
 2. \<And>x. x \<in> Roots_ms \<Longrightarrow> of_rat (\<beta>'' x) * exp (\<Sum>\<^sub># x) = (\<Sum>\<alpha>. of_rat (\<beta>'' x when \<Sum>\<^sub># x = \<alpha>) * exp \<alpha>)
[PROOF STEP]
have "Sum_any (\<lambda>\<alpha>. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>) =
          (\<Sum>\<alpha>\<in>{\<Sum>\<^sub># Y}. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>\<alpha>. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>) = (\<Sum>\<alpha>\<in>{\<Sum>\<^sub># Y}. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>)
[PROOF STEP]
by (intro Sum_any.expand_superset) auto
[PROOF STATE]
proof (state)
this:
(\<Sum>\<alpha>. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>) = (\<Sum>\<alpha>\<in>{\<Sum>\<^sub># Y}. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>)

goal (2 subgoals):
 1. Roots_ms = Roots_ms
 2. \<And>x. x \<in> Roots_ms \<Longrightarrow> of_rat (\<beta>'' x) * exp (\<Sum>\<^sub># x) = (\<Sum>\<alpha>. of_rat (\<beta>'' x when \<Sum>\<^sub># x = \<alpha>) * exp \<alpha>)
[PROOF STEP]
thus ?case
[PROOF STATE]
proof (prove)
using this:
(\<Sum>\<alpha>. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>) = (\<Sum>\<alpha>\<in>{\<Sum>\<^sub># Y}. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>)

goal (1 subgoal):
 1. of_rat (\<beta>'' Y) * exp (\<Sum>\<^sub># Y) = (\<Sum>\<alpha>. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>)
[PROOF STEP]
by simp
[PROOF STATE]
proof (state)
this:
of_rat (\<beta>'' Y) * exp (\<Sum>\<^sub># Y) = (\<Sum>\<alpha>. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>)

goal (1 subgoal):
 1. Roots_ms = Roots_ms
[PROOF STEP]
qed auto
[PROOF STATE]
proof (state)
this:
(\<Sum>Y\<in>Roots_ms. of_rat (\<beta>'' Y) * exp (\<Sum>\<^sub># Y)) = (\<Sum>Y\<in>Roots_ms. \<Sum>\<alpha>. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Sum>Y\<in>Roots_ms. of_rat (\<beta>'' Y) * exp (\<Sum>\<^sub># Y)) = (\<Sum>Y\<in>Roots_ms. \<Sum>\<alpha>. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "\<dots> = Sum_any (\<lambda>\<alpha>. of_rat (\<beta>''' \<alpha>) * exp \<alpha>)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>Y\<in>Roots_ms. \<Sum>\<alpha>. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>) = (\<Sum>\<alpha>. of_rat (\<beta>''' \<alpha>) * exp \<alpha>)
[PROOF STEP]
unfolding \<beta>'''_def of_rat_sum sum_distrib_right
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>Y\<in>Roots_ms. \<Sum>\<alpha>. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>) = (\<Sum>\<alpha>. \<Sum>n\<in>Roots_ms. of_rat (\<beta>'' n when \<Sum>\<^sub># n = \<alpha>) * exp \<alpha>)
[PROOF STEP]
by (subst Sum_any_sum_swap) auto
[PROOF STATE]
proof (state)
this:
(\<Sum>Y\<in>Roots_ms. \<Sum>\<alpha>. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>) = (\<Sum>\<alpha>. of_rat (\<beta>''' \<alpha>) * exp \<alpha>)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Sum>Y\<in>Roots_ms. \<Sum>\<alpha>. of_rat (\<beta>'' Y when \<Sum>\<^sub># Y = \<alpha>) * exp \<alpha>) = (\<Sum>\<alpha>. of_rat (\<beta>''' \<alpha>) * exp \<alpha>)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "\<dots> = (\<Sum>\<alpha> | \<beta>''' \<alpha> \<noteq> 0. of_rat (\<beta>''' \<alpha>) * exp \<alpha>)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>\<alpha>. of_rat (\<beta>''' \<alpha>) * exp \<alpha>) = (\<Sum>\<alpha> | \<beta>''' \<alpha> \<noteq> 0. of_rat (\<beta>''' \<alpha>) * exp \<alpha>)
[PROOF STEP]
by (intro Sum_any.expand_superset finite_subset[OF supp_\<beta>''']) auto
[PROOF STATE]
proof (state)
this:
(\<Sum>\<alpha>. of_rat (\<beta>''' \<alpha>) * exp \<alpha>) = (\<Sum>\<alpha> | \<beta>''' \<alpha> \<noteq> 0. of_rat (\<beta>''' \<alpha>) * exp \<alpha>)

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
finally
[PROOF STATE]
proof (chain)
picking this:
0 dvd (\<Sum>\<alpha> | \<beta>''' \<alpha> \<noteq> 0. of_rat (\<beta>''' \<alpha>) * exp \<alpha>)
[PROOF STEP]
have "(\<Sum>\<alpha> | \<beta>''' \<alpha> \<noteq> 0. of_rat (\<beta>''' \<alpha>) * exp \<alpha>) = 0"
[PROOF STATE]
proof (prove)
using this:
0 dvd (\<Sum>\<alpha> | \<beta>''' \<alpha> \<noteq> 0. of_rat (\<beta>''' \<alpha>) * exp \<alpha>)

goal (1 subgoal):
 1. (\<Sum>\<alpha> | \<beta>''' \<alpha> \<noteq> 0. of_rat (\<beta>''' \<alpha>) * exp \<alpha>) = 0
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
(\<Sum>\<alpha> | \<beta>''' \<alpha> \<noteq> 0. of_rat (\<beta>''' \<alpha>) * exp \<alpha>) = 0

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
text \<open>
    We are now in the situation of our previous version of the theorem and can apply it to find
    that all the coefficients are zero.
  \<close>
[PROOF STATE]
proof (state)
this:
(\<Sum>\<alpha> | \<beta>''' \<alpha> \<noteq> 0. of_rat (\<beta>''' \<alpha>) * exp \<alpha>) = 0

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "{\<alpha>. \<beta>''' \<alpha> \<noteq> 0} = {}"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} = {}
[PROOF STEP]
proof (rule Hermite_Lindemann_aux3)
[PROOF STATE]
proof (state)
goal (4 subgoals):
 1. finite {\<alpha>. \<beta>''' \<alpha> \<noteq> 0}
 2. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> ?\<beta> x \<noteq> 0
 3. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> algebraic x
 4. (\<Sum>x\<in>{\<alpha>. \<beta>''' \<alpha> \<noteq> 0}. of_rat (?\<beta> x) * exp x) = 0
[PROOF STEP]
show "finite {\<alpha>. \<beta>''' \<alpha> \<noteq> 0}"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. finite {\<alpha>. \<beta>''' \<alpha> \<noteq> 0}
[PROOF STEP]
by (rule finite_subset[OF supp_\<beta>''']) auto
[PROOF STATE]
proof (state)
this:
finite {\<alpha>. \<beta>''' \<alpha> \<noteq> 0}

goal (3 subgoals):
 1. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> ?\<beta> x \<noteq> 0
 2. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> algebraic x
 3. (\<Sum>x\<in>{\<alpha>. \<beta>''' \<alpha> \<noteq> 0}. of_rat (?\<beta> x) * exp x) = 0
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (3 subgoals):
 1. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> ?\<beta> x \<noteq> 0
 2. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> algebraic x
 3. (\<Sum>x\<in>{\<alpha>. \<beta>''' \<alpha> \<noteq> 0}. of_rat (?\<beta> x) * exp x) = 0
[PROOF STEP]
show "(\<Sum>\<alpha> | \<beta>''' \<alpha> \<noteq> 0. of_rat (\<beta>''' \<alpha>) * exp \<alpha>) = 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>\<alpha> | \<beta>''' \<alpha> \<noteq> 0. of_rat (\<beta>''' \<alpha>) * exp \<alpha>) = 0
[PROOF STEP]
by fact
[PROOF STATE]
proof (state)
this:
(\<Sum>\<alpha> | \<beta>''' \<alpha> \<noteq> 0. of_rat (\<beta>''' \<alpha>) * exp \<alpha>) = 0

goal (2 subgoals):
 1. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> \<beta>''' x \<noteq> 0
 2. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> algebraic x
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> \<beta>''' x \<noteq> 0
 2. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> algebraic x
[PROOF STEP]
fix \<alpha>
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> \<beta>''' x \<noteq> 0
 2. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> algebraic x
[PROOF STEP]
assume \<alpha>: "\<alpha> \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0}"
[PROOF STATE]
proof (state)
this:
\<alpha> \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0}

goal (2 subgoals):
 1. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> \<beta>''' x \<noteq> 0
 2. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> algebraic x
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<alpha> \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0}
[PROOF STEP]
obtain Y where Y: "Y \<in> Roots_ms" "\<alpha> = sum_mset Y"
[PROOF STATE]
proof (prove)
using this:
\<alpha> \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0}

goal (1 subgoal):
 1. (\<And>Y. \<lbrakk>Y \<in> Roots_ms; \<alpha> = \<Sum>\<^sub># Y\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
using supp_\<beta>'''
[PROOF STATE]
proof (prove)
using this:
\<alpha> \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0}
{x. \<beta>''' x \<noteq> 0} \<subseteq> \<Sum>\<^sub># ` Roots_ms

goal (1 subgoal):
 1. (\<And>Y. \<lbrakk>Y \<in> Roots_ms; \<alpha> = \<Sum>\<^sub># Y\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
Y \<in> Roots_ms
\<alpha> = \<Sum>\<^sub># Y

goal (2 subgoals):
 1. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> \<beta>''' x \<noteq> 0
 2. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> algebraic x
[PROOF STEP]
thus "algebraic \<alpha>"
[PROOF STATE]
proof (prove)
using this:
Y \<in> Roots_ms
\<alpha> = \<Sum>\<^sub># Y

goal (1 subgoal):
 1. algebraic \<alpha>
[PROOF STEP]
using alg1
[PROOF STATE]
proof (prove)
using this:
Y \<in> Roots_ms
\<alpha> = \<Sum>\<^sub># Y
?x \<in> X \<Longrightarrow> algebraic ?x

goal (1 subgoal):
 1. algebraic \<alpha>
[PROOF STEP]
by (auto simp: Roots_ms_def)
[PROOF STATE]
proof (state)
this:
algebraic \<alpha>

goal (1 subgoal):
 1. \<And>x. x \<in> {\<alpha>. \<beta>''' \<alpha> \<noteq> 0} \<Longrightarrow> \<beta>''' x \<noteq> 0
[PROOF STEP]
qed auto
[PROOF STATE]
proof (state)
this:
{\<alpha>. \<beta>''' \<alpha> \<noteq> 0} = {}

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
text \<open>
    However, similarly to before, we can show that the coefficient corresponding to the
    term with the lexicographically greatest exponent (which is obtained by picking the
    term with the lexicographically greatest term in each of the factors of our big product)
    is non-zero.
  \<close>
[PROOF STATE]
proof (state)
this:
{\<alpha>. \<beta>''' \<alpha> \<noteq> 0} = {}

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
moreover
[PROOF STATE]
proof (state)
this:
{\<alpha>. \<beta>''' \<alpha> \<noteq> 0} = {}

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
have "\<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
define \<alpha>_max where "\<alpha>_max = complex_lex.Max X"
[PROOF STATE]
proof (state)
this:
\<alpha>_max = complex_lex.Max X

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
have [simp]: "\<alpha>_max \<in> X"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<alpha>_max \<in> X
[PROOF STEP]
unfolding \<alpha>_max_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. complex_lex.Max X \<in> X
[PROOF STEP]
using \<open>X \<noteq> {}\<close>
[PROOF STATE]
proof (prove)
using this:
X \<noteq> {}

goal (1 subgoal):
 1. complex_lex.Max X \<in> X
[PROOF STEP]
by (intro complex_lex.Max_in) auto
[PROOF STATE]
proof (state)
this:
\<alpha>_max \<in> X

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
define Y_max :: "complex multiset" where "Y_max = replicate_mset (n ^ m) \<alpha>_max"
[PROOF STATE]
proof (state)
this:
Y_max = replicate_mset (n ^ m) \<alpha>_max

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
define f_max where "f_max = restrict (\<lambda>_. \<alpha>_max) (X \<rightarrow>\<^sub>E Roots)"
[PROOF STATE]
proof (state)
this:
f_max = (\<lambda>_\<in>X \<rightarrow>\<^sub>E Roots. \<alpha>_max)

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
have [simp]: "Y_max \<in> Roots_ms"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. Y_max \<in> Roots_ms
[PROOF STEP]
by (auto simp: Y_max_def Roots_ms_def)
[PROOF STATE]
proof (state)
this:
Y_max \<in> Roots_ms

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
have "tuples Y_max = {f_max}"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. tuples Y_max = {f_max}
[PROOF STEP]
proof safe
[PROOF STATE]
proof (state)
goal (2 subgoals):
 1. \<And>x. \<lbrakk>x \<in> tuples Y_max; x \<notin> {}\<rbrakk> \<Longrightarrow> x = f_max
 2. \<And>x. f_max \<in> tuples Y_max
[PROOF STEP]
have "image_mset (\<lambda>_\<in>X \<rightarrow>\<^sub>E Roots. \<alpha>_max) (mset_set (X \<rightarrow>\<^sub>E Roots)) =
            image_mset (\<lambda>_. \<alpha>_max) (mset_set (X \<rightarrow>\<^sub>E Roots))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. image_mset (\<lambda>_\<in>X \<rightarrow>\<^sub>E Roots. \<alpha>_max) (mset_set (X \<rightarrow>\<^sub>E Roots)) = {#\<alpha>_max. _ \<in># mset_set (X \<rightarrow>\<^sub>E Roots)#}
[PROOF STEP]
by (intro image_mset_cong) auto
[PROOF STATE]
proof (state)
this:
image_mset (\<lambda>_\<in>X \<rightarrow>\<^sub>E Roots. \<alpha>_max) (mset_set (X \<rightarrow>\<^sub>E Roots)) = {#\<alpha>_max. _ \<in># mset_set (X \<rightarrow>\<^sub>E Roots)#}

goal (2 subgoals):
 1. \<And>x. \<lbrakk>x \<in> tuples Y_max; x \<notin> {}\<rbrakk> \<Longrightarrow> x = f_max
 2. \<And>x. f_max \<in> tuples Y_max
[PROOF STEP]
thus "f_max \<in> tuples Y_max"
[PROOF STATE]
proof (prove)
using this:
image_mset (\<lambda>_\<in>X \<rightarrow>\<^sub>E Roots. \<alpha>_max) (mset_set (X \<rightarrow>\<^sub>E Roots)) = {#\<alpha>_max. _ \<in># mset_set (X \<rightarrow>\<^sub>E Roots)#}

goal (1 subgoal):
 1. f_max \<in> tuples Y_max
[PROOF STEP]
by (auto simp: f_max_def tuples_def Y_max_def image_mset_const_eq)
[PROOF STATE]
proof (state)
this:
f_max \<in> tuples Y_max

goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> tuples Y_max; x \<notin> {}\<rbrakk> \<Longrightarrow> x = f_max
[PROOF STEP]
next
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> tuples Y_max; x \<notin> {}\<rbrakk> \<Longrightarrow> x = f_max
[PROOF STEP]
fix f
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> tuples Y_max; x \<notin> {}\<rbrakk> \<Longrightarrow> x = f_max
[PROOF STEP]
assume "f \<in> tuples Y_max"
[PROOF STATE]
proof (state)
this:
f \<in> tuples Y_max

goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> tuples Y_max; x \<notin> {}\<rbrakk> \<Longrightarrow> x = f_max
[PROOF STEP]
hence f: "f \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X" "image_mset f (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y_max"
[PROOF STATE]
proof (prove)
using this:
f \<in> tuples Y_max

goal (1 subgoal):
 1. f \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X &&& image_mset f (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y_max
[PROOF STEP]
by (auto simp: tuples_def)
[PROOF STATE]
proof (state)
this:
f \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X
image_mset f (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y_max

goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> tuples Y_max; x \<notin> {}\<rbrakk> \<Longrightarrow> x = f_max
[PROOF STEP]
hence "\<forall>g \<in># mset_set (X \<rightarrow>\<^sub>E Roots). f g = \<alpha>_max"
[PROOF STATE]
proof (prove)
using this:
f \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X
image_mset f (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y_max

goal (1 subgoal):
 1. \<forall>g\<in>#mset_set (X \<rightarrow>\<^sub>E Roots). f g = \<alpha>_max
[PROOF STEP]
by (intro image_mset_eq_replicate_msetD[where n = "n ^ m"]) (auto simp: Y_max_def)
[PROOF STATE]
proof (state)
this:
\<forall>g\<in>#mset_set (X \<rightarrow>\<^sub>E Roots). f g = \<alpha>_max

goal (1 subgoal):
 1. \<And>x. \<lbrakk>x \<in> tuples Y_max; x \<notin> {}\<rbrakk> \<Longrightarrow> x = f_max
[PROOF STEP]
thus "f = f_max"
[PROOF STATE]
proof (prove)
using this:
\<forall>g\<in>#mset_set (X \<rightarrow>\<^sub>E Roots). f g = \<alpha>_max

goal (1 subgoal):
 1. f = f_max
[PROOF STEP]
using f
[PROOF STATE]
proof (prove)
using this:
\<forall>g\<in>#mset_set (X \<rightarrow>\<^sub>E Roots). f g = \<alpha>_max
f \<in> (X \<rightarrow>\<^sub>E Roots) \<rightarrow>\<^sub>E X
image_mset f (mset_set (X \<rightarrow>\<^sub>E Roots)) = Y_max

goal (1 subgoal):
 1. f = f_max
[PROOF STEP]
by (auto simp: Y_max_def fun_eq_iff f_max_def)
[PROOF STATE]
proof (state)
this:
f = f_max

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
tuples Y_max = {f_max}

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
have "\<beta>''' (of_nat (n ^ m) * \<alpha>_max) = (\<Sum>Y\<in>Roots_ms. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<beta>''' (of_nat (n ^ m) * \<alpha>_max) = (\<Sum>Y\<in>Roots_ms. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max)
[PROOF STEP]
unfolding \<beta>'''_def Roots_ms_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>Y | set_mset Y \<subseteq> X \<and> size Y = n ^ m. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max) = (\<Sum>Y | set_mset Y \<subseteq> X \<and> size Y = n ^ m. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max)
[PROOF STEP]
..
[PROOF STATE]
proof (state)
this:
\<beta>''' (of_nat (n ^ m) * \<alpha>_max) = (\<Sum>Y\<in>Roots_ms. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max)

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
\<beta>''' (of_nat (n ^ m) * \<alpha>_max) = (\<Sum>Y\<in>Roots_ms. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max)

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
have "\<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max" if "Y \<in> Roots_ms" "Y \<noteq> Y_max" for Y
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
proof -
[PROOF STATE]
proof (state)
goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
have "\<not>set_mset Y \<subseteq> {\<alpha>_max}"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<not> set_mset Y \<subseteq> {\<alpha>_max}
[PROOF STEP]
using set_mset_subset_singletonD[of Y "\<alpha>_max"] that
[PROOF STATE]
proof (prove)
using this:
set_mset Y \<subseteq> {\<alpha>_max} \<Longrightarrow> Y = replicate_mset (size Y) \<alpha>_max
Y \<in> Roots_ms
Y \<noteq> Y_max

goal (1 subgoal):
 1. \<not> set_mset Y \<subseteq> {\<alpha>_max}
[PROOF STEP]
by (auto simp: Roots_ms_def Y_max_def split: if_splits)
[PROOF STATE]
proof (state)
this:
\<not> set_mset Y \<subseteq> {\<alpha>_max}

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
then
[PROOF STATE]
proof (chain)
picking this:
\<not> set_mset Y \<subseteq> {\<alpha>_max}
[PROOF STEP]
obtain y where y: "y \<in># Y" "y \<noteq> \<alpha>_max"
[PROOF STATE]
proof (prove)
using this:
\<not> set_mset Y \<subseteq> {\<alpha>_max}

goal (1 subgoal):
 1. (\<And>y. \<lbrakk>y \<in># Y; y \<noteq> \<alpha>_max\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
y \<in># Y
y \<noteq> \<alpha>_max

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
have "y \<in> X" "set_mset (Y - {#y#}) \<subseteq> X"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. y \<in> X &&& set_mset (Y - {#y#}) \<subseteq> X
[PROOF STEP]
using y that
[PROOF STATE]
proof (prove)
using this:
y \<in># Y
y \<noteq> \<alpha>_max
Y \<in> Roots_ms
Y \<noteq> Y_max

goal (1 subgoal):
 1. y \<in> X &&& set_mset (Y - {#y#}) \<subseteq> X
[PROOF STEP]
by (auto simp: Roots_ms_def dest: in_diffD)
[PROOF STATE]
proof (state)
this:
y \<in> X
set_mset (Y - {#y#}) \<subseteq> X

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
hence "y \<le>\<^sub>\<complex> \<alpha>_max"
[PROOF STATE]
proof (prove)
using this:
y \<in> X
set_mset (Y - {#y#}) \<subseteq> X

goal (1 subgoal):
 1. y \<le>\<^sub>\<complex> \<alpha>_max
[PROOF STEP]
using y
[PROOF STATE]
proof (prove)
using this:
y \<in> X
set_mset (Y - {#y#}) \<subseteq> X
y \<in># Y
y \<noteq> \<alpha>_max

goal (1 subgoal):
 1. y \<le>\<^sub>\<complex> \<alpha>_max
[PROOF STEP]
unfolding \<alpha>_max_def
[PROOF STATE]
proof (prove)
using this:
y \<in> X
set_mset (Y - {#y#}) \<subseteq> X
y \<in># Y
y \<noteq> complex_lex.Max X

goal (1 subgoal):
 1. y \<le>\<^sub>\<complex> complex_lex.Max X
[PROOF STEP]
by (intro complex_lex.Max_ge) auto
[PROOF STATE]
proof (state)
this:
y \<le>\<^sub>\<complex> \<alpha>_max

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
with y
[PROOF STATE]
proof (chain)
picking this:
y \<in># Y
y \<noteq> \<alpha>_max
y \<le>\<^sub>\<complex> \<alpha>_max
[PROOF STEP]
have "y <\<^sub>\<complex> \<alpha>_max"
[PROOF STATE]
proof (prove)
using this:
y \<in># Y
y \<noteq> \<alpha>_max
y \<le>\<^sub>\<complex> \<alpha>_max

goal (1 subgoal):
 1. y <\<^sub>\<complex> \<alpha>_max
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
y <\<^sub>\<complex> \<alpha>_max

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
have *: "Y = {#y#} + (Y - {#y#})"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. Y = {#y#} + (Y - {#y#})
[PROOF STEP]
using y
[PROOF STATE]
proof (prove)
using this:
y \<in># Y
y \<noteq> \<alpha>_max

goal (1 subgoal):
 1. Y = {#y#} + (Y - {#y#})
[PROOF STEP]
by simp
[PROOF STATE]
proof (state)
this:
Y = {#y#} + (Y - {#y#})

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
have "sum_mset Y = y + sum_mset (Y - {#y#})"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<Sum>\<^sub># Y = y + \<Sum>\<^sub># (Y - {#y#})
[PROOF STEP]
by (subst *) auto
[PROOF STATE]
proof (state)
this:
\<Sum>\<^sub># Y = y + \<Sum>\<^sub># (Y - {#y#})

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
\<Sum>\<^sub># Y = y + \<Sum>\<^sub># (Y - {#y#})

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
have "\<dots> <\<^sub>\<complex> \<alpha>_max + sum_mset (Y - {#y#})"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. y + \<Sum>\<^sub># (Y - {#y#}) <\<^sub>\<complex> \<alpha>_max + \<Sum>\<^sub># (Y - {#y#})
[PROOF STEP]
by (intro complex_lex.add_strict_right_mono) fact
[PROOF STATE]
proof (state)
this:
y + \<Sum>\<^sub># (Y - {#y#}) <\<^sub>\<complex> \<alpha>_max + \<Sum>\<^sub># (Y - {#y#})

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
y + \<Sum>\<^sub># (Y - {#y#}) <\<^sub>\<complex> \<alpha>_max + \<Sum>\<^sub># (Y - {#y#})

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
have "\<dots> \<le>\<^sub>\<complex> \<alpha>_max + sum_mset (replicate_mset (n ^ m - 1) \<alpha>_max)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<alpha>_max + \<Sum>\<^sub># (Y - {#y#}) \<le>\<^sub>\<complex> \<alpha>_max + \<Sum>\<^sub># (replicate_mset (n ^ m - 1) \<alpha>_max)
[PROOF STEP]
unfolding \<alpha>_max_def
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. complex_lex.Max X + \<Sum>\<^sub># (Y - {#y#}) \<le>\<^sub>\<complex> complex_lex.Max X + \<Sum>\<^sub># (replicate_mset (n ^ m - 1) (complex_lex.Max X))
[PROOF STEP]
using that y \<open>set_mset (Y - {#y#}) \<subseteq> X\<close>
[PROOF STATE]
proof (prove)
using this:
Y \<in> Roots_ms
Y \<noteq> Y_max
y \<in># Y
y \<noteq> \<alpha>_max
set_mset (Y - {#y#}) \<subseteq> X

goal (1 subgoal):
 1. complex_lex.Max X + \<Sum>\<^sub># (Y - {#y#}) \<le>\<^sub>\<complex> complex_lex.Max X + \<Sum>\<^sub># (replicate_mset (n ^ m - 1) (complex_lex.Max X))
[PROOF STEP]
by (intro complex_lex.add_left_mono sum_mset_mono_complex_lex
                  rel_mset_replicate_mset_right complex_lex.Max_ge)
           (auto simp: Roots_ms_def size_Diff_singleton)
[PROOF STATE]
proof (state)
this:
\<alpha>_max + \<Sum>\<^sub># (Y - {#y#}) \<le>\<^sub>\<complex> \<alpha>_max + \<Sum>\<^sub># (replicate_mset (n ^ m - 1) \<alpha>_max)

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
\<alpha>_max + \<Sum>\<^sub># (Y - {#y#}) \<le>\<^sub>\<complex> \<alpha>_max + \<Sum>\<^sub># (replicate_mset (n ^ m - 1) \<alpha>_max)

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
have "\<dots> = of_nat (Suc (n ^ m - 1)) * \<alpha>_max"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<alpha>_max + \<Sum>\<^sub># (replicate_mset (n ^ m - 1) \<alpha>_max) = of_nat (Suc (n ^ m - 1)) * \<alpha>_max
[PROOF STEP]
by (simp add: algebra_simps)
[PROOF STATE]
proof (state)
this:
\<alpha>_max + \<Sum>\<^sub># (replicate_mset (n ^ m - 1) \<alpha>_max) = of_nat (Suc (n ^ m - 1)) * \<alpha>_max

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
\<alpha>_max + \<Sum>\<^sub># (replicate_mset (n ^ m - 1) \<alpha>_max) = of_nat (Suc (n ^ m - 1)) * \<alpha>_max

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
have "Suc (n ^ m - 1) = n ^ m"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. Suc (n ^ m - 1) = n ^ m
[PROOF STEP]
using \<open>n > 0\<close>
[PROOF STATE]
proof (prove)
using this:
0 < n

goal (1 subgoal):
 1. Suc (n ^ m - 1) = n ^ m
[PROOF STEP]
by simp
[PROOF STATE]
proof (state)
this:
Suc (n ^ m - 1) = n ^ m

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
finally
[PROOF STATE]
proof (chain)
picking this:
\<Sum>\<^sub># Y <\<^sub>\<complex> of_nat (n ^ m) * \<alpha>_max
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
\<Sum>\<^sub># Y <\<^sub>\<complex> of_nat (n ^ m) * \<alpha>_max

goal (1 subgoal):
 1. \<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max
[PROOF STEP]
by simp
[PROOF STATE]
proof (state)
this:
\<Sum>\<^sub># Y \<noteq> of_nat n ^ m * \<alpha>_max

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<lbrakk>?Y \<in> Roots_ms; ?Y \<noteq> Y_max\<rbrakk> \<Longrightarrow> \<Sum>\<^sub># ?Y \<noteq> of_nat n ^ m * \<alpha>_max

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
hence "(\<Sum>Y\<in>Roots_ms. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max) = (\<Sum>Y\<in>{Y_max}. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max)"
[PROOF STATE]
proof (prove)
using this:
\<lbrakk>?Y \<in> Roots_ms; ?Y \<noteq> Y_max\<rbrakk> \<Longrightarrow> \<Sum>\<^sub># ?Y \<noteq> of_nat n ^ m * \<alpha>_max

goal (1 subgoal):
 1. (\<Sum>Y\<in>Roots_ms. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max) = (\<Sum>Y\<in>{Y_max}. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max)
[PROOF STEP]
by (intro sum.mono_neutral_right ballI) auto
[PROOF STATE]
proof (state)
this:
(\<Sum>Y\<in>Roots_ms. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max) = (\<Sum>Y\<in>{Y_max}. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max)

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Sum>Y\<in>Roots_ms. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max) = (\<Sum>Y\<in>{Y_max}. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max)

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
have "\<dots> = \<beta>'' Y_max"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Sum>Y\<in>{Y_max}. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max) = \<beta>'' Y_max
[PROOF STEP]
by (auto simp: when_def Y_max_def)
[PROOF STATE]
proof (state)
this:
(\<Sum>Y\<in>{Y_max}. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max) = \<beta>'' Y_max

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Sum>Y\<in>{Y_max}. \<beta>'' Y when \<Sum>\<^sub># Y = of_nat (n ^ m) * \<alpha>_max) = \<beta>'' Y_max

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
have "of_rat \<dots> = \<beta>' Y_max"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. of_rat (\<beta>'' Y_max) = \<beta>' Y_max
[PROOF STEP]
using \<beta>''[of Y_max]
[PROOF STATE]
proof (prove)
using this:
Y_max \<in> Roots_ms \<Longrightarrow> \<beta>' Y_max = of_rat (\<beta>'' Y_max)

goal (1 subgoal):
 1. of_rat (\<beta>'' Y_max) = \<beta>' Y_max
[PROOF STEP]
by auto
[PROOF STATE]
proof (state)
this:
of_rat (\<beta>'' Y_max) = \<beta>' Y_max

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
of_rat (\<beta>'' Y_max) = \<beta>' Y_max

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
have "\<dots> = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f_max g))"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. \<beta>' Y_max = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f_max g))
[PROOF STEP]
by (auto simp: \<beta>'_def \<open>tuples Y_max = {f_max}\<close>)
[PROOF STATE]
proof (state)
this:
\<beta>' Y_max = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f_max g))

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
\<beta>' Y_max = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f_max g))

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
have "\<dots> = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g \<alpha>_max)"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f_max g)) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g \<alpha>_max)
[PROOF STEP]
by (intro prod.cong) (auto simp: f_max_def)
[PROOF STATE]
proof (state)
this:
(\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f_max g)) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g \<alpha>_max)

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
also
[PROOF STATE]
proof (state)
this:
(\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g (f_max g)) = (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g \<alpha>_max)

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
have "\<dots> \<noteq> 0"
[PROOF STATE]
proof (prove)
goal (1 subgoal):
 1. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g \<alpha>_max) \<noteq> 0
[PROOF STEP]
using \<open>0 \<notin> Roots\<close> \<open>\<alpha>_max \<in> X\<close>
[PROOF STATE]
proof (prove)
using this:
0 \<notin> Roots
\<alpha>_max \<in> X

goal (1 subgoal):
 1. (\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g \<alpha>_max) \<noteq> 0
[PROOF STEP]
by (intro prod_nonzeroI) (metis PiE_mem)
[PROOF STATE]
proof (state)
this:
(\<Prod>g\<in>X \<rightarrow>\<^sub>E Roots. g \<alpha>_max) \<noteq> 0

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
finally
[PROOF STATE]
proof (chain)
picking this:
of_rat (\<beta>''' (of_nat (n ^ m) * \<alpha>_max)) \<noteq> 0
[PROOF STEP]
show ?thesis
[PROOF STATE]
proof (prove)
using this:
of_rat (\<beta>''' (of_nat (n ^ m) * \<alpha>_max)) \<noteq> 0

goal (1 subgoal):
 1. \<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
\<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0

goal:
No subgoals!
[PROOF STEP]
qed
[PROOF STATE]
proof (state)
this:
\<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0

goal (1 subgoal):
 1. X \<noteq> {} \<Longrightarrow> False
[PROOF STEP]
ultimately
[PROOF STATE]
proof (chain)
picking this:
{\<alpha>. \<beta>''' \<alpha> \<noteq> 0} = {}
\<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0
[PROOF STEP]
show False
[PROOF STATE]
proof (prove)
using this:
{\<alpha>. \<beta>''' \<alpha> \<noteq> 0} = {}
\<exists>\<alpha>. \<beta>''' \<alpha> \<noteq> 0

goal (1 subgoal):
 1. False
[PROOF STEP]
by blast
[PROOF STATE]
proof (state)
this:
False

goal:
No subgoals!
[PROOF STEP]
qed