{-# OPTIONS --safe #-}
module Cubical.Algebra.CommRing.LocalRing where
open import Cubical.Foundations.Prelude
open import Cubical.Foundations.Function using (_∘_)
open import Cubical.Foundations.Structure using (⟨_⟩)
open import Cubical.Foundations.Powerset using (_∈_; ℙ)
open import Cubical.Foundations.HLevels
open import Cubical.Foundations.Univalence using (hPropExt)
open import Cubical.Data.Nat using (ℕ)
open import Cubical.Data.FinData using (FinVec; Fin; ¬Fin0; zero; suc; one)
open import Cubical.Data.Sigma using (∃-syntax; _×_)
open import Cubical.Data.Sum as ⊎ using (_⊎_)
open import Cubical.Data.Empty as ⊥ using (isProp⊥)
open import Cubical.Relation.Nullary using (¬_)
open import Cubical.HITs.PropositionalTruncation as ∥_∥₁ using (isPropPropTrunc; ∣_∣₁; ∥_∥₁)
open import Cubical.Algebra.CommRing
open import Cubical.Algebra.CommRing.FGIdeal using (generatedIdeal; linearCombination)
open import Cubical.Algebra.CommRing.Ideal using (module CommIdeal)
open import Cubical.Algebra.Ring.BigOps using (module Sum)
open import Cubical.Tactics.CommRingSolver
private
variable
ℓ : Level
module _ (R : CommRing ℓ) where
open Sum (CommRing→Ring R) using (∑)
isLocal : Type ℓ
isLocal =
{n : ℕ} →
(xs : FinVec ⟨ R ⟩ n) →
∑ xs ∈ R ˣ →
∃[ i ∈ Fin n ] (xs i ∈ R ˣ)
isPropIsLocal : isProp isLocal
isPropIsLocal = isPropImplicitΠ λ _ → isPropΠ2 λ _ _ → isPropPropTrunc
module Consequences (local : isLocal) where
open CommRingStr (snd R)
open Units R
1≢0 : ¬ (1r ≡ 0r)
1≢0 1≡0 = ∥_∥₁.rec isProp⊥ (¬Fin0 ∘ fst) (local xs 0∈Rˣ)
where
xs : FinVec ⟨ R ⟩ 0
xs ()
0∈Rˣ : 0r ∈ R ˣ
0∈Rˣ = subst (_∈ (R ˣ)) 1≡0 RˣContainsOne
invertibleInBinarySum :
{x y : ⟨ R ⟩} →
x + y ∈ R ˣ →
∥ (x ∈ R ˣ) ⊎ (y ∈ R ˣ) ∥₁
invertibleInBinarySum {x = x} {y = y} x+yInv =
∥_∥₁.map Σ→⊎ (local {n = 2} xy (subst (_∈ R ˣ) ∑xy≡x+y x+yInv))
where
xy : FinVec ⟨ R ⟩ 2
xy zero = x
xy one = y
∑xy≡x+y : x + y ≡ x + (y + 0r)
∑xy≡x+y = solve! R
Σ→⊎ : Σ[ i ∈ Fin 2 ] xy i ∈ R ˣ → (x ∈ R ˣ) ⊎ (y ∈ R ˣ)
Σ→⊎ (zero , xInv) = ⊎.inl xInv
Σ→⊎ (one , yInv) = ⊎.inr yInv
onLinearCombinations :
{n : ℕ} →
(α xs : FinVec ⟨ R ⟩ n) →
1r ≡ linearCombination R α xs →
∃[ i ∈ Fin n ] xs i ∈ R ˣ
onLinearCombinations {n = n} α xs 1≡αxs = αxsHasInv→xsHasInv αxsHasInvertible
where
αxs : FinVec ⟨ R ⟩ n
αxs i = α i · xs i
αxsHasInvertible : ∃[ i ∈ Fin n ] αxs i ∈ R ˣ
αxsHasInvertible = local αxs (subst (_∈ R ˣ) 1≡αxs RˣContainsOne)
αxsHasInv→xsHasInv : ∃[ i ∈ Fin n ] αxs i ∈ R ˣ → ∃[ i ∈ Fin n ] xs i ∈ R ˣ
αxsHasInv→xsHasInv =
∥_∥₁.rec
isPropPropTrunc
λ{(i , αxsi∈Rˣ) → ∣ i , snd (RˣMultDistributing (α i) (xs i) αxsi∈Rˣ) ∣₁}
onFGIdeals :
{n : ℕ} →
(xs : FinVec ⟨ R ⟩ n) →
1r ∈ fst (generatedIdeal R xs) →
∃[ i ∈ Fin n ] xs i ∈ R ˣ
onFGIdeals xs =
∥_∥₁.rec
isPropPropTrunc
λ{(α , 1≡αxs) → onLinearCombinations α xs 1≡αxs}
private
nonInvertibles : ℙ ⟨ R ⟩
nonInvertibles = λ x → (¬ (x ∈ R ˣ)) , isProp→ isProp⊥
open CommIdeal.isCommIdeal
nonInvertiblesFormIdeal : CommIdeal.isCommIdeal R nonInvertibles
+Closed nonInvertiblesFormIdeal {x = x} {y = y} xNonInv yNonInv x+yInv =
∥_∥₁.rec isProp⊥ (⊎.rec xNonInv yNonInv) (invertibleInBinarySum x+yInv)
contains0 nonInvertiblesFormIdeal (x , 0x≡1) =
1≢0 (sym 0x≡1 ∙ solve! R)
·Closed nonInvertiblesFormIdeal {x = x} r xNonInv rxInv =
xNonInv (snd (RˣMultDistributing r x rxInv))
module Characterizations where
module BinSum where
open CommRingStr (snd R)
BinSum : Type ℓ
BinSum = (x y : ⟨ R ⟩) → (x + y ∈ R ˣ) → ∥ (x ∈ R ˣ) ⊎ (y ∈ R ˣ) ∥₁
Alternative : Type ℓ
Alternative = (¬ 1r ≡ 0r) × BinSum
isPropAlternative : isProp Alternative
isPropAlternative =
isProp×
(isProp→ isProp⊥)
(isPropΠ3 (λ _ _ _ → isPropPropTrunc))
isLocal→Alternative : isLocal → Alternative
isLocal→Alternative local =
1≢0
, λ x y → invertibleInBinarySum
where
open Consequences local
module _ ((1≢0 , binSum) : Alternative) where
alternative→isLocal : isLocal
alternative→isLocal {n = ℕ.zero} xs (0⁻¹ , 00⁻¹≡1) =
⊥.rec (1≢0 (sym 00⁻¹≡1 ∙ 0x≡0 0⁻¹))
where
0x≡0 : (x : ⟨ R ⟩) → 0r · x ≡ 0r
0x≡0 _ = solve! R
alternative→isLocal {n = ℕ.suc n} xxs x+∑xsInv =
∥_∥₁.rec
isPropPropTrunc
(⊎.rec
(λ xInv → ∣ zero , xInv ∣₁)
( ∥_∥₁.map (λ{(i , xsiInv) → (suc i) , xsiInv})
∘ alternative→isLocal xs))
(binSum x (∑ xs) x+∑xsInv)
where
x : ⟨ R ⟩
x = xxs zero
xs : FinVec ⟨ R ⟩ n
xs = xxs ∘ suc
path : isLocal ≡ Alternative
path =
hPropExt
isPropIsLocal
isPropAlternative
isLocal→Alternative
alternative→isLocal
module OneMinus where
open CommRingStr (snd R)
OneMinus : Type ℓ
OneMinus = (x : ⟨ R ⟩) → ∥ (x ∈ R ˣ) ⊎ (1r - x ∈ R ˣ) ∥₁
Alternative : Type ℓ
Alternative = (¬ 1r ≡ 0r) × OneMinus
isPropAlternative : isProp Alternative
isPropAlternative =
isProp×
(isProp→ isProp⊥)
(isPropΠ (λ _ → isPropPropTrunc))
private
binSum→OneMinus : BinSum.BinSum → OneMinus
binSum→OneMinus binSum x =
binSum x (1r - x) (subst (_∈ R ˣ) (solve! R) RˣContainsOne)
where open Units R
oneMinus→BinSum : OneMinus → BinSum.BinSum
oneMinus→BinSum oneMinus x y (s⁻¹ , ss⁻¹≡1) =
∥_∥₁.map
(⊎.map
(fst ∘ RˣMultDistributing x s⁻¹)
(fst ∘ RˣMultDistributing y s⁻¹ ∘ subst (_∈ R ˣ) 1-xs⁻¹≡ys⁻¹))
(oneMinus (x · s⁻¹))
where
1-xs⁻¹≡ys⁻¹ : 1r - x · s⁻¹ ≡ y · s⁻¹
1-xs⁻¹≡ys⁻¹ =
(1r - x · s⁻¹) ≡⟨ cong (_- _) (sym ss⁻¹≡1) ⟩
((x + y) · s⁻¹ - x · s⁻¹) ≡⟨ solve! R ⟩
(y · s⁻¹) ∎
open Units R
pathFromBinSum : BinSum.Alternative ≡ Alternative
pathFromBinSum =
hPropExt
BinSum.isPropAlternative
isPropAlternative
(λ{ (1≢0 , binSum) → 1≢0 , binSum→OneMinus binSum})
(λ{ (1≢0 , oneMinus) → 1≢0 , oneMinus→BinSum oneMinus})
path : isLocal ≡ Alternative
path = BinSum.path ∙ pathFromBinSum