Skip to content

Commit

Permalink
feat(RingTheory/Congruence): add the CompleteLattice instance (#8313)
Browse files Browse the repository at this point in the history
The code is copied from `GroupTheory/Congruence.lean`, and then modified to fix the errors.

I haven't copied the full contents of `GroupTheory/Congruencee`, only the results about the lattice structure.

This replaces leanprover-community/mathlib3#18588
  • Loading branch information
eric-wieser committed Dec 16, 2023
1 parent 1f95ef7 commit eb4573a
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 5 deletions.
4 changes: 4 additions & 0 deletions Mathlib/GroupTheory/Congruence.lean
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,10 @@ theorem coe_sInf (S : Set (Con M)) :
#align con.Inf_def Con.coe_sInf
#align add_con.Inf_def AddCon.coe_sInf

@[to_additive (attr := simp, norm_cast)]
theorem coe_iInf {ι : Sort*} (f : ι → Con M) : ⇑(iInf f) = ⨅ i, ⇑(f i) := by
rw [iInf, coe_sInf, ← Set.range_comp, sInf_range, Function.comp]

@[to_additive]
instance : PartialOrder (Con M) where
le_refl _ _ _ := id
Expand Down
178 changes: 173 additions & 5 deletions Mathlib/RingTheory/Congruence.lean
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ Most of the time you likely want to use the `Ideal.Quotient` API that is built o
## TODO
* Use this for `RingQuot` too.
* Copy across more API from `Con` and `AddCon` in `GroupTheory/Congruence.lean`, such as:
* The `CompleteLattice` structure.
* The `conGen_eq` lemma, stating that
`ringConGen r = sInf {s : RingCon M | ∀ x y, r x y → s x y}`.
* Copy across more API from `Con` and `AddCon` in `GroupTheory/Congruence.lean`.
-/


Expand Down Expand Up @@ -118,9 +115,16 @@ instance : Inhabited (RingCon R) :=
⟨ringConGen EmptyRelation⟩

@[simp]
theorem rel_mk {s : Con R} {h a b} : RingCon.mk s h a b ↔ @Setoid.r _ s.toSetoid a b :=
theorem rel_mk {s : Con R} {h a b} : RingCon.mk s h a b ↔ s a b :=
Iff.rfl

/-- The map sending a congruence relation to its underlying binary relation is injective. -/
theorem ext' {c d : RingCon R} (H : ⇑c = ⇑d) : c = d := FunLike.coe_injective H

/-- Extensionality rule for congruence relations. -/
theorem ext {c d : RingCon R} (H : ∀ x y, c x y ↔ d x y) : c = d :=
ext' <| by ext; apply H

end Basic

section Quotient
Expand Down Expand Up @@ -415,4 +419,168 @@ def mk' [NonAssocSemiring R] (c : RingCon R) : R →+* c.Quotient

end Quotient

/-! ### Lattice structure
The API in this section is copied from `Mathlib/GroupTheory/Congruence.lean`
-/


section Lattice

variable [Add R] [Mul R]

/-- For congruence relations `c, d` on a type `M` with multiplication and addition, `c ≤ d` iff
`∀ x y ∈ M`, `x` is related to `y` by `d` if `x` is related to `y` by `c`. -/
instance : LE (RingCon R) where
le c d := ∀ ⦃x y⦄, c x y → d x y

/-- Definition of `≤` for congruence relations. -/
theorem le_def {c d : RingCon R} : c ≤ d ↔ ∀ {x y}, c x y → d x y :=
Iff.rfl

/-- The infimum of a set of congruence relations on a given type with multiplication and
addition. -/
instance : InfSet (RingCon R) where
sInf S :=
{ r := fun x y => ∀ c : RingCon R, c ∈ S → c x y
iseqv :=
fun x c _hc => c.refl x, fun h c hc => c.symm <| h c hc, fun h1 h2 c hc =>
c.trans (h1 c hc) <| h2 c hc⟩
add' := fun h1 h2 c hc => c.add (h1 c hc) <| h2 c hc
mul' := fun h1 h2 c hc => c.mul (h1 c hc) <| h2 c hc }

/-- The infimum of a set of congruence relations is the same as the infimum of the set's image
under the map to the underlying equivalence relation. -/
theorem sInf_toSetoid (S : Set (RingCon R)) : (sInf S).toSetoid = sInf ((·.toSetoid) '' S) :=
Setoid.ext' fun x y =>
fun h r ⟨c, hS, hr⟩ => by rw [← hr]; exact h c hS, fun h c hS => h c.toSetoid ⟨c, hS, rfl⟩⟩

/-- The infimum of a set of congruence relations is the same as the infimum of the set's image
under the map to the underlying binary relation. -/
@[simp, norm_cast]
theorem coe_sInf (S : Set (RingCon R)) : ⇑(sInf S) = sInf ((⇑) '' S) := by
ext; simp only [sInf_image, iInf_apply, iInf_Prop_eq]; rfl

@[simp, norm_cast]
theorem coe_iInf {ι : Sort*} (f : ι → RingCon R) : ⇑(iInf f) = ⨅ i, ⇑(f i) := by
rw [iInf, coe_sInf, ← Set.range_comp, sInf_range, Function.comp]

instance : PartialOrder (RingCon R) where
le_refl _c _ _ := id
le_trans _c1 _c2 _c3 h1 h2 _x _y h := h2 <| h1 h
le_antisymm _c _d hc hd := ext fun _x _y => ⟨fun h => hc h, fun h => hd h⟩

/-- The complete lattice of congruence relations on a given type with multiplication and
addition. -/
instance : CompleteLattice (RingCon R) where
__ := completeLatticeOfInf (RingCon R) fun s =>
fun r hr x y h => (h : ∀ r ∈ s, (r : RingCon R) x y) r hr,
fun _r hr _x _y h _r' hr' => hr hr' h⟩
inf c d :=
{ toSetoid := c.toSetoid ⊓ d.toSetoid
mul' := fun h1 h2 => ⟨c.mul h1.1 h2.1, d.mul h1.2 h2.2
add' := fun h1 h2 => ⟨c.add h1.1 h2.1, d.add h1.2 h2.2⟩ }
inf_le_left _ _ := fun _ _ h => h.1
inf_le_right _ _ := fun _ _ h => h.2
le_inf _ _ _ hb hc := fun _ _ h => ⟨hb h, hc h⟩
top :=
{ (⊤ : Setoid R) with
mul' := fun _ _ => trivial
add' := fun _ _ => trivial }
le_top _ := fun _ _ _h => trivial
bot :=
{ (⊥ : Setoid R) with
mul' := congr_arg₂ _
add' := congr_arg₂ _ }
bot_le c := fun x _y h => h ▸ c.refl x

@[simp, norm_cast]
theorem coe_top : ⇑(⊤ : RingCon R) = ⊤ := rfl

/-- The infimum of two congruence relations equals the infimum of the underlying binary
operations. -/
@[simp, norm_cast]
theorem coe_inf {c d : RingCon R} : ⇑(c ⊓ d) = ⇑c ⊓ ⇑d := rfl

/-- Definition of the infimum of two congruence relations. -/
theorem inf_iff_and {c d : RingCon R} {x y} : (c ⊓ d) x y ↔ c x y ∧ d x y :=
Iff.rfl

/-- The inductively defined smallest congruence relation containing a binary relation `r` equals
the infimum of the set of congruence relations containing `r`. -/
theorem ringConGen_eq (r : R → R → Prop) :
ringConGen r = sInf {s : RingCon R | ∀ x y, r x y → s x y} :=
le_antisymm
(fun _x _y H =>
RingConGen.Rel.recOn H (fun _ _ h _ hs => hs _ _ h) (RingCon.refl _)
(fun _ => RingCon.symm _) (fun _ _ => RingCon.trans _)
(fun _ _ h1 h2 c hc => c.add (h1 c hc) <| h2 c hc)
(fun _ _ h1 h2 c hc => c.mul (h1 c hc) <| h2 c hc))
(sInf_le fun _ _ => RingConGen.Rel.of _ _)

/-- The smallest congruence relation containing a binary relation `r` is contained in any
congruence relation containing `r`. -/
theorem ringConGen_le {r : R → R → Prop} {c : RingCon R}
(h : ∀ x y, r x y → c x y) : ringConGen r ≤ c := by
rw [ringConGen_eq]; exact sInf_le h

/-- Given binary relations `r, s` with `r` contained in `s`, the smallest congruence relation
containing `s` contains the smallest congruence relation containing `r`. -/
theorem ringConGen_mono {r s : R → R → Prop} (h : ∀ x y, r x y → s x y) :
ringConGen r ≤ ringConGen s :=
ringConGen_le fun x y hr => RingConGen.Rel.of _ _ <| h x y hr

/-- Congruence relations equal the smallest congruence relation in which they are contained. -/
theorem ringConGen_of_ringCon (c : RingCon R) : ringConGen c = c :=
le_antisymm (by rw [ringConGen_eq]; exact sInf_le fun _ _ => id) RingConGen.Rel.of

/-- The map sending a binary relation to the smallest congruence relation in which it is
contained is idempotent. -/
theorem ringConGen_idem (r : R → R → Prop) : ringConGen (ringConGen r) = ringConGen r :=
ringConGen_of_ringCon _

/-- The supremum of congruence relations `c, d` equals the smallest congruence relation containing
the binary relation '`x` is related to `y` by `c` or `d`'. -/
theorem sup_eq_ringConGen (c d : RingCon R) : c ⊔ d = ringConGen fun x y => c x y ∨ d x y := by
rw [ringConGen_eq]
apply congr_arg sInf
simp only [le_def, or_imp, ← forall_and]

/-- The supremum of two congruence relations equals the smallest congruence relation containing
the supremum of the underlying binary operations. -/
theorem sup_def {c d : RingCon R} : c ⊔ d = ringConGen (⇑c ⊔ ⇑d) := by
rw [sup_eq_ringConGen]; rfl

/-- The supremum of a set of congruence relations `S` equals the smallest congruence relation
containing the binary relation 'there exists `c ∈ S` such that `x` is related to `y` by
`c`'. -/
theorem sSup_eq_ringConGen (S : Set (RingCon R)) :
sSup S = ringConGen fun x y => ∃ c : RingCon R, c ∈ S ∧ c x y := by
rw [ringConGen_eq]
apply congr_arg sInf
ext
exact ⟨fun h _ _ ⟨r, hr⟩ => h hr.1 hr.2, fun h r hS _ _ hr => h _ _ ⟨r, hS, hr⟩⟩

/-- The supremum of a set of congruence relations is the same as the smallest congruence relation
containing the supremum of the set's image under the map to the underlying binary relation. -/
theorem sSup_def {S : Set (RingCon R)} :
sSup S = ringConGen (sSup (@Set.image (RingCon R) (R → R → Prop) (⇑) S)) := by
rw [sSup_eq_ringConGen, sSup_image]
congr with (x y)
simp only [sSup_image, iSup_apply, iSup_Prop_eq, exists_prop, rel_eq_coe]

variable (R)

/-- There is a Galois insertion of congruence relations on a type with multiplication and addition
`R` into binary relations on `R`. -/
protected def gi : @GaloisInsertion (R → R → Prop) (RingCon R) _ _ ringConGen (⇑) where
choice r _h := ringConGen r
gc _r c :=
fun H _ _ h => H <| RingConGen.Rel.of _ _ h, fun H =>
ringConGen_of_ringCon c ▸ ringConGen_mono H⟩
le_l_u x := (ringConGen_of_ringCon x).symm ▸ le_refl x
choice_eq _ _ := rfl

end Lattice

end RingCon

0 comments on commit eb4573a

Please sign in to comment.