Zulip Chat Archive

Stream: Is there code for X?

Topic: Zsqrtd and adjoin


Suzuka Yu (Apr 08 2025 at 03:37):

Greetings! I wonder wether we have (or plan to build) certain connection between Zsqrtd and Algebra.adjoin? For instance, ℤ√d is isomorphic to Algebra.adjoin ℤ {(d : ℂ) ^ (1 / 2 : ℂ)}

Suzuka Yu (Apr 08 2025 at 03:39):

@loogle Zsqrtd, Algebra.adjoin

loogle (Apr 08 2025 at 03:39):

:shrug: nothing found

Kevin Buzzard (Apr 08 2025 at 05:31):

I doubt that's true if d is a square.

Suzuka Yu (Apr 08 2025 at 06:12):

Sorry but why it is not? I thought that when d is a square, (d : ℂ) ^ (1 / 2 : ℂ) would be an actual integer so Algebra.adjoin ℤ {(d : ℂ) ^ (1 / 2 : ℂ)} would be ⊥ : Subalgebra ℤ ℂ, which is basically , whereas ℤ√d should also be

Johan Commelin (Apr 08 2025 at 06:15):

docs#Zsqrtd

Johan Commelin (Apr 08 2025 at 06:16):

It looks like Zsqrtd always has rank 2. So it will be Z×Z\Z \times \Z when dd is a square.

Suzuka Yu (Apr 08 2025 at 06:21):

ahh, sorry I didn't think of that. Thanks for the correction! But when d is square free, would it be true?

Kevin Buzzard (Apr 08 2025 at 06:40):

Can you formalise your question?

Kevin Buzzard (Apr 08 2025 at 06:42):

And the answer to your revised question is still no because 1 is squarefree. The condition you want is "not a square"

Suzuka Yu (Apr 08 2025 at 06:53):

Sure! Thanks for reminding me, I'll exclude the situation where d is unit

import Mathlib

open Zsqrtd

variable {d : } (hd : Squarefree d) (hunit : ¬ IsUnit d) -- or (hnon : Nonsquare d.natAbs)?

example : d ≃+* Algebra.adjoin  {(d : ) ^ (1 / 2 : )} := by
  sorry

Kevin Buzzard (Apr 08 2025 at 07:03):

"squarefree" isn't the opposite of "not a square". For example 12 is not a square and it's not squarefree either, and the theorem is true for 12. The theorem can also be true for units, for example -1, which is a unit but is not a square. The correct condition is nothing to do with units or squarefree or absolute values, the correct condition is "not a square".

Kevin Buzzard (Apr 08 2025 at 07:10):

Under this assumption you should prove that the min poly of d^{1/2} is X^2-d (using the not-a-square assumption to rule out linear factors) and then prove that both rings are isomorphic to Z[X]/(X^2-d).

Suzuka Yu (Apr 08 2025 at 09:54):

(sincerely apologize, feels like I'm making silly mistake all the time :pensive:

I've corrected my condition, and managed to calculate the minimal polynomial (min_polyz). Proving Algebra.adjoin is isomorphic to Z[X]/(X^2-d) is straightforward using minpoly.equivAdjoin, but is there an easy way to construct the other isomorphism? (Zsqrtd is isomorphic to Z[X]/(X^2-d))

import Mathlib

open Zsqrtd Polynomial PowerBasis Algebra

variable {d : } (hnon :  x : , d  x * x)

local notation "polyz" => X ^ 2 - C d
local notation: max "√[" i "]" =>  ((i : ) ^ ((1 / 2) : ))

private theorem polyz_natDegree : natDegree polyz = 2 := natDegree_X_pow_sub_C
private theorem polyz_Monic : Monic polyz := by monicity!

theorem integralz : IsIntegral  [d] := by
  refine polyz, polyz_Monic, ?_⟩⟩
  · simp only [algebraMap_int_eq, one_div, eq_intCast, eval₂_sub, eval₂_X_pow,
    Complex.cpow_ofNat_inv_pow]
    show d - eval₂ (Int.castRingHom ) ((d : ) ^ (2⁻¹ : )) (C d) = 0
    rw [eval₂_C, eq_intCast, sub_self]

private theorem min_polyz_dvd : minpoly  [d]  X ^ 2 - C d := by
  refine minpoly.isIntegrallyClosed_dvd integralz ?_
  simp only [one_div, eq_intCast, map_sub, map_pow, aeval_X, Complex.cpow_ofNat_inv_pow,
    map_intCast, sub_self]

private theorem min_polyz_natDegree_le : (minpoly  [d]).natDegree  2 := by
  rw [ @polyz_natDegree d]
  exact natDegree_le_of_dvd min_polyz_dvd (X_pow_sub_C_ne_zero (Nat.zero_lt_two) d)

include hnon

theorem min_polyz_natDegree : (minpoly  [d]).natDegree = 2 := by
  refine le_antisymm min_polyz_natDegree_le ?_
  rw [minpoly.two_le_natDegree_iff (@integralz d)]
  rintro x, hx : (algebraMap  ) x = [d]
  have := hnon x
  apply_fun (· ^ 2) at hx
  simp only [algebraMap_int_eq, eq_intCast, one_div, Complex.cpow_ofNat_inv_pow] at hx
  norm_cast at hx
  rw [ hx, sq] at this
  exact False.elim <| this rfl

theorem min_polyz : minpoly  [d] = polyz := by
  refine (eq_of_monic_of_dvd_of_natDegree_le (minpoly.monic integralz)
    polyz_Monic min_polyz_dvd ?_).symm
  rw [polyz_natDegree, min_polyz_natDegree hnon]

noncomputable def equiv₁ :
    AdjoinRoot (minpoly  [d]) ≃ₐ[] Algebra.adjoin  {[d]} :=
  minpoly.equivAdjoin integralz

def equiv₂ : d ≃ₐ[] AdjoinRoot polyz := sorry

Suzuka Yu (Apr 08 2025 at 10:37):

Or should I try directly build the isomorphism via power basis on Algebra.adjoin?

Junyan Xu (Apr 08 2025 at 10:51):

Maybe you can try to use IsAdjoinRoot.aequiv

Suzuka Yu (Apr 08 2025 at 11:14):

Thanks for the advice! I'll look into it

Edison Xie (Apr 08 2025 at 13:28):

would this be better after we refactor Zsqrtd? @Kevin Buzzard

Kevin Buzzard (Apr 08 2025 at 13:48):

Zsqrtd is a model for Z[X]/(X2d)\Z[X]/(X^2-d) even for d a square. My proposal was to replace it by R[X]/(X2aXb)R[X]/(X^2-aX-b) for a general commutative ring R and elements a,b in R.


Last updated: May 02 2025 at 03:31 UTC