Skip to content

Commit 8402dea

Browse files
author
Will Bradley
committed
Complete most of Chapter2.Section3
1 parent ef731b4 commit 8402dea

File tree

1 file changed

+271
-11
lines changed

1 file changed

+271
-11
lines changed
Lines changed: 271 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,289 @@
11
import LogicFormalization.Chapter2.Section1.Arity
22
import Mathlib.Data.Set.Defs
3+
import Mathlib.Data.Set.Operations
34
import Mathlib.Logic.Basic
5+
import Mathlib.Algebra.Group.Hom.Defs
6+
import Mathlib.Data.Set.Image
47

58
universe u v
69

7-
inductive Language (ρ: Type u) (ϝ: Type v) [Arity ρ] [Arity ϝ]
8-
| relation: ρ → Language ρ ϝ
9-
| function: ρ → Language ρ ϝ
10+
structure Language where
11+
/-- The relational symbols. -/
12+
ρ: Type u
13+
/-- The functional symbols. -/
14+
ϝ: Type v
15+
[instArityRel: Arity ρ]
16+
[instArityFun: Arity ϝ]
1017

1118
namespace Language
1219

13-
-- TODO: examples
20+
-- TODO: automate basically all this for Gr as well as Ab, O, Ring, etc.
21+
namespace Gr
22+
23+
inductive ρ
24+
deriving Repr, DecidableEq
25+
26+
instance: Arity ρ :=
27+
⟨(nomatch ·)⟩
28+
29+
inductive ϝ where
30+
| one | inv | mul
31+
deriving Repr, DecidableEq
32+
33+
instance: Arity ϝ where
34+
arity
35+
| .one => 0
36+
| .inv => 1
37+
| .mul => 2
38+
39+
/-! These instances make it possible to write e.g. `f 0` for
40+
`f: Fin (arity Language.Gr.ϝ.inv) → G` (the `0` is a `Fin`). -/
41+
instance: NeZero (arity Language.Gr.ϝ.inv) :=
42+
by decide⟩
43+
44+
instance: NeZero (arity Language.Gr.ϝ.mul) :=
45+
by decide⟩
46+
47+
end Gr
48+
49+
@[reducible]
50+
def Gr := Language.mk Gr.ρ Gr.ϝ
1451

1552
end Language
1653

54+
instance (L: Language): Arity L.ρ := L.instArityRel
55+
instance (L: Language): Arity L.ϝ := L.instArityFun
56+
1757
universe w
1858

19-
structure Structure (ρ: Type u) (ϝ: Type v) [Arity ρ] [Arity ϝ] where
20-
A: Type w
21-
nonempty: Nonempty A
22-
interpRel: (R: ρ) → Set (Fin (arity R) → A)
23-
interpFun: (F: ϝ) → (Fin (arity F) → A) → A
59+
structure Structure (L: Language) (A: Type u) [Nonempty A] where
60+
/-- The interpretation `R^𝒜` of the relational symbol `R` in `𝒜`. -/
61+
interpRel: (R: L.ρ) → Set (Fin (arity R) → A)
62+
/-- The interpretation `F^𝒜` of the functional symbol `F` in `𝒜`.
63+
See also `interpConst`. -/
64+
interpFun: (F: L.ϝ) → (Fin (arity F) → A) → A
2465

2566
namespace Structure
26-
variable {ρ: Type u} {ϝ: Type v} [Arity ρ] [Arity ϝ]
67+
variable {L: Language}
68+
variable {A: Type u} [Nonempty A] {B: Type v} [Nonempty B]
2769

28-
def interpConst (𝒜: Structure ρ ϝ) {c: ϝ} (h: arity c = 0) :=
70+
@[inherit_doc]
71+
scoped notation:max R "^" 𝒜 => Structure.interpRel 𝒜 R
72+
73+
@[inherit_doc]
74+
scoped notation:max F "^" 𝒜 => Structure.interpFun 𝒜 F
75+
76+
/-- We identify the interpretation `h^𝒜` for
77+
constant symbol `c`, `h: arity c = 0`, with the value in `A`. -/
78+
def interpConst (𝒜: Structure L A) {c: L.ϝ} (h: arity c = 0) :=
2979
𝒜.interpFun c fun f => (h ▸ f).elim0
80+
81+
@[inherit_doc]
82+
scoped notation:max h "^" 𝒜 => Structure.interpConst 𝒜 h
83+
84+
def Gr {G: Type*} [Nonempty G] [Group G] : Structure Language.Gr G where
85+
interpRel := (nomatch ·)
86+
interpFun
87+
| .one, _ => 1
88+
| .inv, f => (f 0)⁻¹
89+
| .mul, f => (f 0) * (f 1)
90+
91+
section Substructure
92+
93+
/-- `Substructure A ℬ h` is the substructure in `ℬ` with underlying set `A`. -/
94+
@[reducible, simp]
95+
def Substructure (A: Set B) [Nonempty A] (ℬ: Structure L B)
96+
(h: ∀ F (a: Fin (arity F) → A), interpFun ℬ F (a ↑·) ∈ A) : Structure L A where
97+
interpRel R := { a | (R^ℬ) (a ↑·) }
98+
interpFun F a := ⟨(F^ℬ) (a ↑·), h ..⟩
99+
100+
variable {A: Set B} [Nonempty A]
101+
/-- `IsSubstructure 𝒜 ℬ`, written `A ⊆ B`, means `A` is a substructure of `B`. -/
102+
structure IsSubstructure (𝒜: Structure L A) (ℬ: Structure L B): Prop where
103+
h₁: ∀ F (a: Fin (arity F) → A), interpFun ℬ F (a ↑·) ∈ A
104+
h₂: 𝒜 = Substructure A ℬ h₁
105+
106+
@[inherit_doc]
107+
scoped infix:50 " ⊆ " => IsSubstructure
108+
109+
lemma substructure_is_substructure {A: Set B} [Nonempty A] {ℬ: Structure L B}
110+
{h: ∀ F (a: Fin (arity F) → A), interpFun ℬ F (a ↑·) ∈ A}: Substructure A ℬ h ⊆ ℬ :=
111+
⟨h, rfl⟩
112+
113+
end Substructure
114+
115+
section Hom
116+
117+
variable {A: Type u} [Nonempty A] {B: Type v} [Nonempty B]
118+
variable (𝒜: Structure L A) (ℬ: Structure L B) (h: A → B)
119+
120+
structure Hom where
121+
hRel: ∀ R a, a ∈ 𝒜.interpRel R → h ∘ a ∈ ℬ.interpRel R
122+
hFun: ∀ F a, h ((𝒜.interpFun F) a) = (ℬ.interpFun F) (h ∘ a)
123+
124+
structure StrongHom where
125+
hRel: ∀ R a, a ∈ 𝒜.interpRel R ↔ h ∘ a ∈ ℬ.interpRel R
126+
hFun: ∀ F a, h ((𝒜.interpFun F) a) = (ℬ.interpFun F) (h ∘ a)
127+
128+
lemma StrongHom.mk' (hom: Hom 𝒜 ℬ h) (hh: ∀ R a, h ∘ a ∈ ℬ.interpRel R → a ∈ 𝒜.interpRel R):
129+
StrongHom 𝒜 ℬ h where
130+
hRel R a := ⟨hom.hRel R a, hh R a⟩
131+
hFun := hom.hFun
132+
133+
lemma StrongHom.toHom: StrongHom 𝒜 ℬ h → Hom 𝒜 ℬ h
134+
| {hRel, hFun} => ⟨fun R a => (hRel R a).mp, hFun⟩
135+
136+
structure Emb extends StrongHom 𝒜 ℬ h where
137+
inj: Function.Injective h
138+
139+
structure Iso extends StrongHom 𝒜 ℬ h where
140+
bij: Function.Bijective h
141+
142+
abbrev Auto h := Iso 𝒜 𝒜 h
143+
144+
lemma emb_inclusion_map {A: Set B} [Nonempty ↑A] {𝒜: Structure L A} {ℬ: Structure L B}
145+
(h: 𝒜 ⊆ ℬ): Emb 𝒜 ℬ (fun a => a) :=
146+
have ⟨hR, hF⟩ := Structure.mk.inj h.h₂
147+
{ inj := fun _ _ => Subtype.eq,
148+
hRel _R _a := hR ▸ Iff.rfl
149+
hFun _F _a := hF ▸ rfl }
150+
151+
def Substructure.ofHom {𝒜: Structure L A} {ℬ: Structure L B} {h: A → B} (hh: Hom 𝒜 ℬ h) :=
152+
Substructure (Set.range h) ℬ fun F bs => by
153+
let as (i): A := -- h(as) = bs
154+
Exists.choose (bs i).prop
155+
have has (i): h (as i) = bs i :=
156+
Exists.choose_spec (bs i).prop
157+
use (F^𝒜) as
158+
convert hh.hFun F as using 2
159+
funext i
160+
exact (has i).symm
161+
162+
lemma Substructure.ofHom_bijection_of_emb {𝒜: Structure L A} {ℬ: Structure L B} {h: A → B}
163+
(hh: Emb 𝒜 ℬ h): Iso 𝒜 (ofHom hh.toHom) (⟨h ·, Set.mem_range_self _⟩) :=
164+
have ⟨⟨hRel, hFun⟩, inj⟩ := hh
165+
{ bij := ⟨fun _ _ ha => inj (Subtype.mk.injEq .. ▸ ha),
166+
fun ⟨_, a, ha⟩ => ⟨a, Subtype.eq ha⟩⟩,
167+
hRel := hRel,
168+
hFun := fun F a => Subtype.eq (hFun F a) }
169+
170+
variable {C: Type w} [Nonempty C]
171+
variable {𝒜: Structure L A} {ℬ: Structure L B} {𝒞: Structure L C}
172+
variable {i: A → B} {j: B → C}
173+
174+
lemma hom_comp (hj: Hom ℬ 𝒞 j) (hi: Hom 𝒜 ℬ i): Hom 𝒜 𝒞 (j ∘ i) where
175+
hRel R a ha :=
176+
have hj := hj.hRel R (i ∘ a)
177+
have hi := hi.hRel R a
178+
hj (hi ha)
179+
hFun F a :=
180+
have hj := hj.hFun F (i ∘ a)
181+
have hi := hi.hFun F a
182+
show j _ = _ from hi.symm ▸ hj
183+
184+
lemma strongHom_comp (hj: StrongHom ℬ 𝒞 j) (hi: StrongHom 𝒜 ℬ i): StrongHom 𝒜 𝒞 (j ∘ i) :=
185+
.mk' 𝒜 𝒞 (j ∘ i) (hom_comp hj.toHom hi.toHom) fun R a ha =>
186+
have hj := (hj.hRel R (i ∘ a)).mpr
187+
have hi := (hi.hRel R a).mpr
188+
hi (hj ha)
189+
190+
lemma emb_comp (hj: Emb ℬ 𝒞 j) (hi: Emb 𝒜 ℬ i): Emb 𝒜 𝒞 (j ∘ i) where
191+
toStrongHom := strongHom_comp hj.toStrongHom hi.toStrongHom
192+
inj := Function.Injective.comp hj.inj hi.inj
193+
194+
lemma iso_comp (hj: Iso ℬ 𝒞 j) (hi: Iso 𝒜 ℬ i): Iso 𝒜 𝒞 (j ∘ i) where
195+
toStrongHom := strongHom_comp hj.toStrongHom hi.toStrongHom
196+
bij := Function.Bijective.comp hj.bij hi.bij
197+
198+
lemma auto_comp {j i: A → A} (hj: Auto 𝒜 j) (hi: Auto 𝒜 i): Auto 𝒜 (j ∘ i) :=
199+
iso_comp hj hi
200+
201+
lemma auto_id: Auto 𝒜 id := by
202+
constructor
203+
· constructor <;> simp
204+
· exact Function.bijective_id
205+
206+
section -- TODO: maybe PR these to Mathlib?
207+
208+
open Function
209+
variable {α: Type u} {β: Type v} [Nonempty α] {f: α → β}
210+
211+
private lemma bijective_invFun_of_bijective:
212+
Bijective f → Bijective (invFun f)
213+
| ⟨_, _⟩ => by
214+
refine bijective_iff_has_inverse.mpr ⟨f, ?_, ?_⟩
215+
· apply RightInverse.leftInverse
216+
apply rightInverse_invFun
217+
assumption
218+
· apply LeftInverse.rightInverse
219+
apply leftInverse_invFun
220+
assumption
221+
222+
private lemma comp_invFun (hf: Surjective f): f ∘ invFun f = id :=
223+
funext <| rightInverse_invFun hf
224+
225+
end
226+
227+
open Function in
228+
lemma auto_inv {i: A → A} (hi: Auto 𝒜 i): Auto 𝒜 (invFun i) :=
229+
have ⟨⟨hRel, hFun⟩, hinj, hsur⟩ := hi
230+
let iInv := invFun i
231+
{ bij := bijective_invFun_of_bijective hi.bij,
232+
hRel R a := by
233+
have := hRel R (iInv ∘ a)
234+
convert this.symm
235+
rw [←comp_assoc, comp_invFun hsur]
236+
rfl
237+
hFun F a := by
238+
apply hinj
239+
have := hFun F (iInv ∘ a)
240+
convert this.symm
241+
show (i ∘ iInv) ((F^𝒜) a) = (F^𝒜) ((i ∘ iInv) ∘ a)
242+
repeat rw [comp_invFun hsur]
243+
rfl }
244+
245+
noncomputable instance Aut: Group {i: A → A // Auto 𝒜 i} where
246+
mul | ⟨i, hi⟩, ⟨j, hj⟩ => ⟨j ∘ i, auto_comp hj hi⟩
247+
mul_assoc a b c := rfl
248+
one := ⟨id, auto_id⟩
249+
one_mul a := rfl
250+
mul_one a := rfl
251+
inv | ⟨i, hi⟩ => ⟨Function.invFun i, auto_inv hi⟩
252+
inv_mul_cancel a := by
253+
dsimp only [HMul.hMul, OfNat.ofNat]
254+
congr 1
255+
exact comp_invFun a.prop.bij.right
256+
257+
-- TODO: examples
258+
259+
-- Somewhat clunky since `MonoidHom` is a `Type`
260+
lemma group_hom_iff [Group A] [Group B] {h: A → B}: (∃ h': A →* B, ↑h' = h) ↔ Hom Gr Gr h := by
261+
constructor
262+
· intro ⟨⟨⟨h', h₁⟩, h₂⟩, hcoe⟩
263+
replace hcoe: h' = h := hcoe
264+
subst h'
265+
replace h₂: ∀ (x y : A), h (x * y) = h x * h y := h₂
266+
constructor
267+
· exact (nomatch ·)
268+
· rintro (_|_) <;> intro as
269+
· simpa only [Gr, forall_const]
270+
· simp only [Gr, Function.comp_apply]
271+
apply MonoidHom.map_inv ⟨⟨h, h₁⟩, h₂⟩
272+
· simp only [Gr]
273+
apply h₂
274+
· intro ⟨_, hFun⟩
275+
have (a₁ a₂: A): h (a₁ * a₂) = h a₁ * h a₂ := by
276+
have := hFun Language.Gr.ϝ.mul
277+
simp only [Gr] at this
278+
let a: Fin 2 → A
279+
| 0 => a₁
280+
| 1 => a₂
281+
exact this a
282+
exact ⟨MonoidHom.mk' h this, rfl⟩
283+
284+
-- TODO: show ring, etc. homomorphisms, isomorphisms are the same. Probably automate this
285+
end Hom
286+
287+
-- TODO: congruence
288+
-- TODO: products
289+
-- TODO: homeworks

0 commit comments

Comments
 (0)