Theory pAdic_Product
theory pAdic_Product
imports
FLS_Prime_Equiv_Depth
"HOL-Computational_Algebra.Fraction_Field"
"HOL-Analysis.Elementary_Metric_Spaces"
begin
section ‹p-Adic fields as equivalence classes of sequences of formal Laurent series›
subsection ‹Preliminaries›
lemma inj_on_vimage_image_eq:
"(f -` (f ` B)) ∩ A = B" if "inj_on f A" and "B ⊆ A"
using that unfolding inj_on_def by fast
subsection ‹The type definition as a quotient›
quotient_type (overloaded) 'a p_adic_prod
= "'a::nontrivial_factorial_idom fls_pseq" / globally_p_equal
by (simp, rule p_equality_depth_fls_pseq.globally_p_equal_equivp)
lemmas rep_p_adic_prod_inverse = Quotient3_abs_rep[OF Quotient3_p_adic_prod]
and p_adic_prod_lift_globally_p_equal = Quotient3_rel_abs[OF Quotient3_p_adic_prod]
and globally_p_equal_fls_pseq_equals_rsp = equals_rsp[OF Quotient3_p_adic_prod]
and p_adic_prod_eq_iff
= Quotient3_rel_rep[OF Quotient3_p_adic_prod, symmetric]
and globally_p_equal_fls_pseq_rep_p_adic_prod_refl
= Quotient3_rep_reflp[OF Quotient3_p_adic_prod]
and globally_p_equal_fls_pseq_rep_abs_p_adic_prod
= rep_abs_rsp[OF Quotient3_p_adic_prod] rep_abs_rsp_left[OF Quotient3_p_adic_prod]
lemma p_adic_prod_globally_p_equal_self:
"(rep_p_adic_prod (abs_p_adic_prod r)) ≃⇩∀⇩p r"
using Quotient3_rep_abs[OF Quotient3_p_adic_prod]
p_equality_depth_fls_pseq.globally_p_equal_refl
by auto
lemma rep_p_adic_prod_p_equal_self: "rep_p_adic_prod (abs_p_adic_prod r) ≃⇩p r"
for p :: "'a::nontrivial_factorial_idom prime" and r :: "'a fls_pseq"
using p_adic_prod_globally_p_equal_self p_equality_depth_fls_pseq.globally_p_equalD by auto
lemma rep_p_adic_prod_set_inverse: "abs_p_adic_prod ` (rep_p_adic_prod ` A) = A"
proof
show "abs_p_adic_prod ` rep_p_adic_prod ` A ⊆ A"
proof
fix x assume "x ∈ abs_p_adic_prod ` rep_p_adic_prod ` A"
from this obtain a where "a ∈ A" "x = abs_p_adic_prod (rep_p_adic_prod a)" by fast
thus "x ∈ A" using rep_p_adic_prod_inverse by metis
qed
show "A ⊆ abs_p_adic_prod ` rep_p_adic_prod ` A"
proof
fix a assume "a ∈ A"
thus "a ∈ abs_p_adic_prod ` rep_p_adic_prod ` A"
using rep_p_adic_prod_inverse[of a] by force
qed
qed
lemma p_adic_prod_cases [case_names abs_p_adic_prod, cases type: p_adic_prod]:
C if "⋀X. x = abs_p_adic_prod X ⟹ C"
by (metis that rep_p_adic_prod_inverse)
lemmas two_p_adic_prod_cases = p_adic_prod_cases[case_product p_adic_prod_cases]
and three_p_adic_prod_cases =
p_adic_prod_cases[case_product p_adic_prod_cases[case_product p_adic_prod_cases]]
lemma p_adic_prod_reduced_cases [case_names abs_p_adic_prod]:
fixes x :: "'a::nontrivial_euclidean_ring_cancel p_adic_prod"
obtains X where "x = abs_p_adic_prod X" and "∀p. (X p) pmod p = X p"
proof (cases x)
case (abs_p_adic_prod X)
define Y where "Y ≡ (λp. (X p) pmod p)"
with abs_p_adic_prod have "x = abs_p_adic_prod Y"
using fls_pseq_globally_reduced p_adic_prod_lift_globally_p_equal by blast
moreover from Y_def have "∀p. (Y p) pmod p = Y p" by fastforce
ultimately show ?thesis using that by blast
qed
lemma p_adic_prod_unique_rep:
"∃!X. x = abs_p_adic_prod X ∧ (∀p. (X p) pmod p = X p)"
for x :: "'a::nontrivial_euclidean_ring_cancel p_adic_prod"
proof (intro ex_ex1I, safe)
obtain X where "x = abs_p_adic_prod X ∧ (∀p. (X p) pmod p = X p)"
using p_adic_prod_reduced_cases by meson
thus "∃X. x = abs_p_adic_prod X ∧ (∀p. X p pmod p = X p)" by fast
next
fix X X' :: "'a fls_pseq"
assume "∀p. X p pmod p = X p"
and "∀p. X' p pmod p = X' p"
and "abs_p_adic_prod X = abs_p_adic_prod X'"
thus "X = X'" using p_adic_prod.abs_eq_iff[of X X'] fls_pmod_cong by fastforce
qed
abbreviation
"reduced_rep_p_adic_prod x ≡
(THE X. x = abs_p_adic_prod X ∧ (∀p. (X p) pmod p = X p))"
lemma reduced_rep_p_adic_prod_is_rep:
"x = abs_p_adic_prod (reduced_rep_p_adic_prod x)"
for x :: "'a::nontrivial_euclidean_ring_cancel p_adic_prod"
using theI'[OF p_adic_prod_unique_rep] by fast
lemma reduced_rep_p_adic_prod_is_reduced:
"(reduced_rep_p_adic_prod x p) pmod p = reduced_rep_p_adic_prod x p"
for p :: "'a::nontrivial_euclidean_ring_cancel prime" and X :: "'a p_adic_prod"
using theI'[OF p_adic_prod_unique_rep] by fast
lemma abs_p_adic_prod_inverse:
"reduced_rep_p_adic_prod (abs_p_adic_prod X) = X" if "∀p. (X p) pmod p = X p"
for X :: "'a::nontrivial_euclidean_ring_cancel fls_pseq"
by (intro the1_equality p_adic_prod_unique_rep, simp add: that)
lemma p_adic_prod_seq_cases [case_names abs_p_adic_prod]:
C if "⋀F. X = (λn. abs_p_adic_prod (F n)) ⟹ C"
proof-
define F where "F ≡ λn. rep_p_adic_prod (X n)"
hence "X = (λn. abs_p_adic_prod (F n))"
using rep_p_adic_prod_inverse by metis
with that show C by auto
qed
lemma p_adic_prod_seq_reduced_cases [case_names abs_p_adic_prod]:
fixes X :: "nat ⇒ 'a::nontrivial_euclidean_ring_cancel p_adic_prod"
obtains F
where "X = (λn. abs_p_adic_prod (F n))"
and "∀(n::nat) (p::'a prime). (F n p) pmod p = F n p"
proof-
define F where "F ≡ λn. reduced_rep_p_adic_prod (X n)"
from F_def have "X = (λn. abs_p_adic_prod (F n))"
using reduced_rep_p_adic_prod_is_rep by blast
moreover from F_def have "∀(n::nat) (p::'a prime). (F n p) pmod p = F n p"
using reduced_rep_p_adic_prod_is_reduced by blast
ultimately show thesis using that by simp
qed
subsection ‹Algebraic instantiations›
text ‹The product of p-adic fields form a ring.›
instantiation p_adic_prod :: (nontrivial_factorial_idom) comm_ring_1
begin
lift_definition zero_p_adic_prod :: "'a p_adic_prod" is "0::'a fls_pseq" .
lift_definition one_p_adic_prod :: "'a p_adic_prod" is "1::'a fls_pseq" .
lift_definition plus_p_adic_prod ::
"'a p_adic_prod ⇒ 'a p_adic_prod ⇒ 'a p_adic_prod"
is "λX Y. X + Y"
using p_equality_depth_fls_pseq.globally_p_equal_add by force
lift_definition uminus_p_adic_prod :: "'a p_adic_prod ⇒ 'a p_adic_prod"
is "λX. - X"
using p_equality_depth_fls_pseq.globally_p_equal_uminus by auto
lift_definition minus_p_adic_prod ::
"'a p_adic_prod ⇒ 'a p_adic_prod ⇒ 'a p_adic_prod"
is "λX Y. X - Y"
using p_equality_depth_fls_pseq.globally_p_equal_minus by force
lift_definition times_p_adic_prod ::
"'a p_adic_prod ⇒ 'a p_adic_prod ⇒ 'a p_adic_prod"
is "λX Y. X * Y"
using p_equality_depth_fls_pseq.globally_p_equal_mult by fastforce
instance
proof
fix a b c :: "'a p_adic_prod"
show "a + b + c = a + (b + c)" by transfer (simp add: add.assoc)
show "a + b = b + a" by transfer (simp add: add.commute)
show "1 * a = a" by transfer simp
show "0 + a = a" by transfer simp
show "- a + a = 0" by transfer simp
show "a - b = a + - b" by transfer simp
show "a * b * c = a * (b * c)" by transfer (simp add: mult.assoc)
show "(a + b) * c = a * c + b * c" by transfer (simp add: distrib_right)
show "a * b = b * a" by transfer (simp add: mult.commute)
have "¬ (0::'a fls_pseq) ≃⇩∀⇩p (1::'a fls_pseq)"
using p_equality_depth_fls_pseq.globally_p_equalD p_equal_fls_sym fls_1_not_p_equal_0
by fastforce
thus "(0::'a p_adic_prod) ≠ (1::'a p_adic_prod)" by transfer simp
qed
end
lemma pow_p_adic_prod_abs_eq:
"(abs_p_adic_prod X) ^ n = abs_p_adic_prod (X ^ n)"
for X :: "'a::nontrivial_factorial_idom fls_pseq"
proof (induct n)
case 0
have "(abs_p_adic_prod X) ^ 0 = (1 :: 'a p_adic_prod)" by auto
moreover have "abs_p_adic_prod (X ^ 0) = (1 :: 'a p_adic_prod)"
using one_p_adic_prod.abs_eq by simp
ultimately show ?case by presburger
next
case (Suc n) thus "(abs_p_adic_prod X) ^ Suc n = abs_p_adic_prod (X ^ Suc n)"
using times_p_adic_prod.abs_eq by auto
qed
text ‹We can create inverses at the nonzero places.›
instantiation p_adic_prod ::
(nontrivial_factorial_unique_euclidean_bezout) "{divide_trivial, inverse}"
begin
lift_definition divide_p_adic_prod ::
"'a p_adic_prod ⇒ 'a p_adic_prod ⇒ 'a p_adic_prod"
is "λX Y. X * (Y¯⇧∀⇧p)"
proof-
fix X X' Y Y' :: "'a fls_pseq"
assume "X ≃⇩∀⇩p X'" and "Y ≃⇩∀⇩p Y'"
thus
"X * (Y¯⇧∀⇧p) ≃⇩∀⇩p
X' * (Y'¯⇧∀⇧p)"
using globally_pinverse_cong[of Y Y'] p_equality_depth_fls_pseq.globally_p_equal_mult[of X X']
by fastforce
qed
lift_definition inverse_p_adic_prod :: "'a p_adic_prod ⇒ 'a p_adic_prod"
is global_pinverse_fls_pseq
by (rule globally_pinverse_cong)
instance
proof
show "⋀a::'a p_adic_prod. a div 0 = 0" by transfer (simp flip: zero_fun_def)
show "⋀a::'a p_adic_prod. a div 1 = a" by transfer (simp flip: one_fun_def)
show "⋀a::'a p_adic_prod. 0 div a = 0" by transfer (simp flip: zero_fun_def)
qed
end
subsection ‹Equivalence and depth relative to a prime›
overloading
p_equal_p_adic_prod ≡
"p_equal :: 'a::nontrivial_factorial_idom prime ⇒ 'a p_adic_prod ⇒
'a p_adic_prod ⇒ bool"
p_restrict_p_adic_prod ≡
"p_restrict :: 'a p_adic_prod ⇒
('a prime ⇒ bool) ⇒ 'a p_adic_prod"
p_depth_p_adic_prod ≡ "p_depth :: 'a prime ⇒ 'a p_adic_prod ⇒ int"
global_unfrmzr_pows_p_adic_prod ≡
"global_unfrmzr_pows :: ('a prime ⇒ int) ⇒ 'a p_adic_prod"
begin
lift_definition p_equal_p_adic_prod ::
"'a::nontrivial_factorial_idom prime ⇒
'a p_adic_prod ⇒ 'a p_adic_prod ⇒ bool"
is p_equal
by (
simp only: globally_p_equal_fls_pseq_def,
rule p_equality_depth_fls_pseq.globally_p_equal_transfer_equals_rsp, simp_all
)
lift_definition p_restrict_p_adic_prod ::
"'a::nontrivial_factorial_idom p_adic_prod ⇒
('a prime ⇒ bool) ⇒ 'a p_adic_prod"
is "λX P p. if P p then X p else 0"
using p_equality_depth_fls_pseq.globally_p_equalD by fastforce
lift_definition p_depth_p_adic_prod ::
"'a::nontrivial_factorial_idom prime ⇒ 'a p_adic_prod ⇒ int"
is p_depth
by (
simp only: globally_p_equal_fls_pseq_def,
rule p_equality_depth_fls_pseq.globally_p_equal_p_depth
)
lift_definition global_unfrmzr_pows_p_adic_prod ::
"('a::nontrivial_factorial_idom prime ⇒ int) ⇒ 'a p_adic_prod"
is global_unfrmzr_pows .
end
lemma p_equal_p_adic_prod_abs_eq0: "(abs_p_adic_prod X ≃⇩p 0) = (X ≃⇩p 0)"
for p :: "'a::nontrivial_factorial_idom prime" and X :: "'a fls_pseq"
using p_equal_p_adic_prod.abs_eq[of p X "0::'a fls_pseq"]
by (simp add: zero_p_adic_prod.abs_eq)
lemma p_equal_p_adic_prod_abs_eq1: "(abs_p_adic_prod X ≃⇩p 1) = (X ≃⇩p 1)"
for p :: "'a::nontrivial_factorial_idom prime" and X :: "'a fls_pseq"
using p_equal_p_adic_prod.abs_eq[of p X "1::'a fls_pseq"]
by (simp add: one_p_adic_prod.abs_eq)
global_interpretation p_equality_p_adic_prod:
p_equality_no_zero_divisors_1
"p_equal :: 'a::nontrivial_factorial_idom prime ⇒
'a p_adic_prod ⇒ 'a p_adic_prod ⇒ bool"
proof
fix p :: "'a prime"
define E :: "'a p_adic_prod ⇒ 'a p_adic_prod ⇒ bool"
where "E ≡ p_equal p"
show "equivp E"
unfolding E_def p_equal_p_adic_prod_def
proof-
define F :: "'a fls_pseq ⇒ 'a fls_pseq ⇒ bool"
and G :: "'a p_adic_prod ⇒ 'a p_adic_prod ⇒ bool"
where "F ≡ p_equal p"
and
"G ≡
map_fun id (map_fun rep_p_adic_prod (map_fun rep_p_adic_prod id)) p_equal p"
hence "G = (λx y. F (rep_p_adic_prod x) (rep_p_adic_prod y))" by force
with F_def show "equivp G" using equivp_transfer p_equality_depth_fls_pseq.equivp by fast
qed
show "∃x::'a p_adic_prod. x ¬≃⇩p 0"
by (transfer, rule p_equality_depth_fls_pseq.nontrivial)
fix x y :: "'a p_adic_prod"
show "(x ≃⇩p y) = (x - y ≃⇩p 0)"
and "y ≃⇩p 0 ⟹ x * y ≃⇩p 0"
by (
transfer, rule p_equality_depth_fls_pseq.conv_0,
transfer, rule p_equality_depth_fls_pseq.mult_0_right
)
assume "x ¬≃⇩p 0" and "y ¬≃⇩p 0"
thus "x * y ¬≃⇩p 0"
using p_depth_fls.no_zero_divisors[of p]
by (cases x, cases y)
(auto simp add: p_equal_p_adic_prod_abs_eq0 times_p_adic_prod.abs_eq)
qed
overloading
globally_p_equal_p_adic_prod ≡
"globally_p_equal ::
'a::nontrivial_factorial_idom p_adic_prod ⇒ 'a p_adic_prod ⇒ bool"
begin
definition globally_p_equal_p_adic_prod ::
"'a::nontrivial_factorial_idom p_adic_prod ⇒ 'a p_adic_prod ⇒ bool"
where globally_p_equal_p_adic_prod_def[simp]:
"globally_p_equal_p_adic_prod = p_equality_p_adic_prod.globally_p_equal"
end