[GOAL]
d : ℕ
h : d ≠ 0
w : Nat.coprime (Int.natAbs 0) d
⊢ mk' 0 d = 0
[PROOFSTEP]
congr
[GOAL]
q : ℚ
⊢ q.num = 0 ↔ q = 0
[PROOFSTEP]
induction q
[GOAL]
case mk'
num✝ : ℤ
den✝ : ℕ
den_nz✝ : den✝ ≠ 0
reduced✝ : Nat.coprime (Int.natAbs num✝) den✝
⊢ (mk' num✝ den✝).num = 0 ↔ mk' num✝ den✝ = 0
[PROOFSTEP]
constructor
[GOAL]
case mk'.mp
num✝ : ℤ
den✝ : ℕ
den_nz✝ : den✝ ≠ 0
reduced✝ : Nat.coprime (Int.natAbs num✝) den✝
⊢ (mk' num✝ den✝).num = 0 → mk' num✝ den✝ = 0
[PROOFSTEP]
rintro rfl
[GOAL]
case mk'.mp
den✝ : ℕ
den_nz✝ : den✝ ≠ 0
reduced✝ : Nat.coprime (Int.natAbs 0) den✝
⊢ mk' 0 den✝ = 0
[PROOFSTEP]
exact zero_mk _ _ _
[GOAL]
case mk'.mpr
num✝ : ℤ
den✝ : ℕ
den_nz✝ : den✝ ≠ 0
reduced✝ : Nat.coprime (Int.natAbs num✝) den✝
⊢ mk' num✝ den✝ = 0 → (mk' num✝ den✝).num = 0
[PROOFSTEP]
exact congr_arg num
[GOAL]
a b : ℤ
b0 : b ≠ 0
⊢ a /. b = 0 ↔ a = 0
[PROOFSTEP]
rw [← zero_divInt b, divInt_eq_iff b0 b0, zero_mul, mul_eq_zero, or_iff_left b0]
[GOAL]
C : ℚ → Sort u
n : ℤ
d : ℕ
h : d ≠ 0
c : Nat.coprime (Int.natAbs n) d
H : (n : ℤ) → (d : ℕ) → 0 < d → Nat.coprime (Int.natAbs n) d → C (n /. ↑d)
⊢ C (mk' n d)
[PROOFSTEP]
rw [num_den']
[GOAL]
C : ℚ → Sort u
n : ℤ
d : ℕ
h : d ≠ 0
c : Nat.coprime (Int.natAbs n) d
H : (n : ℤ) → (d : ℕ) → 0 < d → Nat.coprime (Int.natAbs n) d → C (n /. ↑d)
⊢ C (n /. ↑d)
[PROOFSTEP]
exact H n d (Nat.pos_of_ne_zero h) c
[GOAL]
f : ℚ → ℚ → ℚ
f₁ f₂ : ℤ → ℤ → ℤ → ℤ → ℤ
fv :
  ∀ {n₁ : ℤ} {d₁ : ℕ} {h₁ : d₁ ≠ 0} {c₁ : Nat.coprime (Int.natAbs n₁) d₁} {n₂ : ℤ} {d₂ : ℕ} {h₂ : d₂ ≠ 0}
    {c₂ : Nat.coprime (Int.natAbs n₂) d₂}, f (mk' n₁ d₁) (mk' n₂ d₂) = f₁ n₁ (↑d₁) n₂ ↑d₂ /. f₂ n₁ (↑d₁) n₂ ↑d₂
f0 : ∀ {n₁ d₁ n₂ d₂ : ℤ}, d₁ ≠ 0 → d₂ ≠ 0 → f₂ n₁ d₁ n₂ d₂ ≠ 0
a b c d : ℤ
b0 : b ≠ 0
d0 : d ≠ 0
H : ∀ {n₁ d₁ n₂ d₂ : ℤ}, a * d₁ = n₁ * b → c * d₂ = n₂ * d → f₁ n₁ d₁ n₂ d₂ * f₂ a b c d = f₁ a b c d * f₂ n₁ d₁ n₂ d₂
⊢ f (a /. b) (c /. d) = f₁ a b c d /. f₂ a b c d
[PROOFSTEP]
generalize ha : a /. b = x
[GOAL]
f : ℚ → ℚ → ℚ
f₁ f₂ : ℤ → ℤ → ℤ → ℤ → ℤ
fv :
  ∀ {n₁ : ℤ} {d₁ : ℕ} {h₁ : d₁ ≠ 0} {c₁ : Nat.coprime (Int.natAbs n₁) d₁} {n₂ : ℤ} {d₂ : ℕ} {h₂ : d₂ ≠ 0}
    {c₂ : Nat.coprime (Int.natAbs n₂) d₂}, f (mk' n₁ d₁) (mk' n₂ d₂) = f₁ n₁ (↑d₁) n₂ ↑d₂ /. f₂ n₁ (↑d₁) n₂ ↑d₂
f0 : ∀ {n₁ d₁ n₂ d₂ : ℤ}, d₁ ≠ 0 → d₂ ≠ 0 → f₂ n₁ d₁ n₂ d₂ ≠ 0
a b c d : ℤ
b0 : b ≠ 0
d0 : d ≠ 0
H : ∀ {n₁ d₁ n₂ d₂ : ℤ}, a * d₁ = n₁ * b → c * d₂ = n₂ * d → f₁ n₁ d₁ n₂ d₂ * f₂ a b c d = f₁ a b c d * f₂ n₁ d₁ n₂ d₂
x : ℚ
ha : a /. b = x
⊢ f x (c /. d) = f₁ a b c d /. f₂ a b c d
[PROOFSTEP]
cases' x with n₁ d₁ h₁ c₁
[GOAL]
case mk'
f : ℚ → ℚ → ℚ
f₁ f₂ : ℤ → ℤ → ℤ → ℤ → ℤ
fv :
  ∀ {n₁ : ℤ} {d₁ : ℕ} {h₁ : d₁ ≠ 0} {c₁ : Nat.coprime (Int.natAbs n₁) d₁} {n₂ : ℤ} {d₂ : ℕ} {h₂ : d₂ ≠ 0}
    {c₂ : Nat.coprime (Int.natAbs n₂) d₂}, f (mk' n₁ d₁) (mk' n₂ d₂) = f₁ n₁ (↑d₁) n₂ ↑d₂ /. f₂ n₁ (↑d₁) n₂ ↑d₂
f0 : ∀ {n₁ d₁ n₂ d₂ : ℤ}, d₁ ≠ 0 → d₂ ≠ 0 → f₂ n₁ d₁ n₂ d₂ ≠ 0
a b c d : ℤ
b0 : b ≠ 0
d0 : d ≠ 0
H : ∀ {n₁ d₁ n₂ d₂ : ℤ}, a * d₁ = n₁ * b → c * d₂ = n₂ * d → f₁ n₁ d₁ n₂ d₂ * f₂ a b c d = f₁ a b c d * f₂ n₁ d₁ n₂ d₂
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
c₁ : Nat.coprime (Int.natAbs n₁) d₁
ha : a /. b = mk' n₁ d₁
⊢ f (mk' n₁ d₁) (c /. d) = f₁ a b c d /. f₂ a b c d
[PROOFSTEP]
rw [num_den'] at ha
[GOAL]
case mk'
f : ℚ → ℚ → ℚ
f₁ f₂ : ℤ → ℤ → ℤ → ℤ → ℤ
fv :
  ∀ {n₁ : ℤ} {d₁ : ℕ} {h₁ : d₁ ≠ 0} {c₁ : Nat.coprime (Int.natAbs n₁) d₁} {n₂ : ℤ} {d₂ : ℕ} {h₂ : d₂ ≠ 0}
    {c₂ : Nat.coprime (Int.natAbs n₂) d₂}, f (mk' n₁ d₁) (mk' n₂ d₂) = f₁ n₁ (↑d₁) n₂ ↑d₂ /. f₂ n₁ (↑d₁) n₂ ↑d₂
f0 : ∀ {n₁ d₁ n₂ d₂ : ℤ}, d₁ ≠ 0 → d₂ ≠ 0 → f₂ n₁ d₁ n₂ d₂ ≠ 0
a b c d : ℤ
b0 : b ≠ 0
d0 : d ≠ 0
H : ∀ {n₁ d₁ n₂ d₂ : ℤ}, a * d₁ = n₁ * b → c * d₂ = n₂ * d → f₁ n₁ d₁ n₂ d₂ * f₂ a b c d = f₁ a b c d * f₂ n₁ d₁ n₂ d₂
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
c₁ : Nat.coprime (Int.natAbs n₁) d₁
ha : a /. b = n₁ /. ↑d₁
⊢ f (mk' n₁ d₁) (c /. d) = f₁ a b c d /. f₂ a b c d
[PROOFSTEP]
generalize hc : c /. d = x
[GOAL]
case mk'
f : ℚ → ℚ → ℚ
f₁ f₂ : ℤ → ℤ → ℤ → ℤ → ℤ
fv :
  ∀ {n₁ : ℤ} {d₁ : ℕ} {h₁ : d₁ ≠ 0} {c₁ : Nat.coprime (Int.natAbs n₁) d₁} {n₂ : ℤ} {d₂ : ℕ} {h₂ : d₂ ≠ 0}
    {c₂ : Nat.coprime (Int.natAbs n₂) d₂}, f (mk' n₁ d₁) (mk' n₂ d₂) = f₁ n₁ (↑d₁) n₂ ↑d₂ /. f₂ n₁ (↑d₁) n₂ ↑d₂
f0 : ∀ {n₁ d₁ n₂ d₂ : ℤ}, d₁ ≠ 0 → d₂ ≠ 0 → f₂ n₁ d₁ n₂ d₂ ≠ 0
a b c d : ℤ
b0 : b ≠ 0
d0 : d ≠ 0
H : ∀ {n₁ d₁ n₂ d₂ : ℤ}, a * d₁ = n₁ * b → c * d₂ = n₂ * d → f₁ n₁ d₁ n₂ d₂ * f₂ a b c d = f₁ a b c d * f₂ n₁ d₁ n₂ d₂
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
c₁ : Nat.coprime (Int.natAbs n₁) d₁
ha : a /. b = n₁ /. ↑d₁
x : ℚ
hc : c /. d = x
⊢ f (mk' n₁ d₁) x = f₁ a b c d /. f₂ a b c d
[PROOFSTEP]
cases' x with n₂ d₂ h₂ c₂
[GOAL]
case mk'.mk'
f : ℚ → ℚ → ℚ
f₁ f₂ : ℤ → ℤ → ℤ → ℤ → ℤ
fv :
  ∀ {n₁ : ℤ} {d₁ : ℕ} {h₁ : d₁ ≠ 0} {c₁ : Nat.coprime (Int.natAbs n₁) d₁} {n₂ : ℤ} {d₂ : ℕ} {h₂ : d₂ ≠ 0}
    {c₂ : Nat.coprime (Int.natAbs n₂) d₂}, f (mk' n₁ d₁) (mk' n₂ d₂) = f₁ n₁ (↑d₁) n₂ ↑d₂ /. f₂ n₁ (↑d₁) n₂ ↑d₂
f0 : ∀ {n₁ d₁ n₂ d₂ : ℤ}, d₁ ≠ 0 → d₂ ≠ 0 → f₂ n₁ d₁ n₂ d₂ ≠ 0
a b c d : ℤ
b0 : b ≠ 0
d0 : d ≠ 0
H : ∀ {n₁ d₁ n₂ d₂ : ℤ}, a * d₁ = n₁ * b → c * d₂ = n₂ * d → f₁ n₁ d₁ n₂ d₂ * f₂ a b c d = f₁ a b c d * f₂ n₁ d₁ n₂ d₂
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
c₁ : Nat.coprime (Int.natAbs n₁) d₁
ha : a /. b = n₁ /. ↑d₁
n₂ : ℤ
d₂ : ℕ
h₂ : d₂ ≠ 0
c₂ : Nat.coprime (Int.natAbs n₂) d₂
hc : c /. d = mk' n₂ d₂
⊢ f (mk' n₁ d₁) (mk' n₂ d₂) = f₁ a b c d /. f₂ a b c d
[PROOFSTEP]
rw [num_den'] at hc
[GOAL]
case mk'.mk'
f : ℚ → ℚ → ℚ
f₁ f₂ : ℤ → ℤ → ℤ → ℤ → ℤ
fv :
  ∀ {n₁ : ℤ} {d₁ : ℕ} {h₁ : d₁ ≠ 0} {c₁ : Nat.coprime (Int.natAbs n₁) d₁} {n₂ : ℤ} {d₂ : ℕ} {h₂ : d₂ ≠ 0}
    {c₂ : Nat.coprime (Int.natAbs n₂) d₂}, f (mk' n₁ d₁) (mk' n₂ d₂) = f₁ n₁ (↑d₁) n₂ ↑d₂ /. f₂ n₁ (↑d₁) n₂ ↑d₂
f0 : ∀ {n₁ d₁ n₂ d₂ : ℤ}, d₁ ≠ 0 → d₂ ≠ 0 → f₂ n₁ d₁ n₂ d₂ ≠ 0
a b c d : ℤ
b0 : b ≠ 0
d0 : d ≠ 0
H : ∀ {n₁ d₁ n₂ d₂ : ℤ}, a * d₁ = n₁ * b → c * d₂ = n₂ * d → f₁ n₁ d₁ n₂ d₂ * f₂ a b c d = f₁ a b c d * f₂ n₁ d₁ n₂ d₂
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
c₁ : Nat.coprime (Int.natAbs n₁) d₁
ha : a /. b = n₁ /. ↑d₁
n₂ : ℤ
d₂ : ℕ
h₂ : d₂ ≠ 0
c₂ : Nat.coprime (Int.natAbs n₂) d₂
hc : c /. d = n₂ /. ↑d₂
⊢ f (mk' n₁ d₁) (mk' n₂ d₂) = f₁ a b c d /. f₂ a b c d
[PROOFSTEP]
rw [fv]
[GOAL]
case mk'.mk'
f : ℚ → ℚ → ℚ
f₁ f₂ : ℤ → ℤ → ℤ → ℤ → ℤ
fv :
  ∀ {n₁ : ℤ} {d₁ : ℕ} {h₁ : d₁ ≠ 0} {c₁ : Nat.coprime (Int.natAbs n₁) d₁} {n₂ : ℤ} {d₂ : ℕ} {h₂ : d₂ ≠ 0}
    {c₂ : Nat.coprime (Int.natAbs n₂) d₂}, f (mk' n₁ d₁) (mk' n₂ d₂) = f₁ n₁ (↑d₁) n₂ ↑d₂ /. f₂ n₁ (↑d₁) n₂ ↑d₂
f0 : ∀ {n₁ d₁ n₂ d₂ : ℤ}, d₁ ≠ 0 → d₂ ≠ 0 → f₂ n₁ d₁ n₂ d₂ ≠ 0
a b c d : ℤ
b0 : b ≠ 0
d0 : d ≠ 0
H : ∀ {n₁ d₁ n₂ d₂ : ℤ}, a * d₁ = n₁ * b → c * d₂ = n₂ * d → f₁ n₁ d₁ n₂ d₂ * f₂ a b c d = f₁ a b c d * f₂ n₁ d₁ n₂ d₂
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
c₁ : Nat.coprime (Int.natAbs n₁) d₁
ha : a /. b = n₁ /. ↑d₁
n₂ : ℤ
d₂ : ℕ
h₂ : d₂ ≠ 0
c₂ : Nat.coprime (Int.natAbs n₂) d₂
hc : c /. d = n₂ /. ↑d₂
⊢ f₁ n₁ (↑d₁) n₂ ↑d₂ /. f₂ n₁ (↑d₁) n₂ ↑d₂ = f₁ a b c d /. f₂ a b c d
[PROOFSTEP]
have d₁0 := ne_of_gt (Int.ofNat_lt.2 $ Nat.pos_of_ne_zero h₁)
[GOAL]
case mk'.mk'
f : ℚ → ℚ → ℚ
f₁ f₂ : ℤ → ℤ → ℤ → ℤ → ℤ
fv :
  ∀ {n₁ : ℤ} {d₁ : ℕ} {h₁ : d₁ ≠ 0} {c₁ : Nat.coprime (Int.natAbs n₁) d₁} {n₂ : ℤ} {d₂ : ℕ} {h₂ : d₂ ≠ 0}
    {c₂ : Nat.coprime (Int.natAbs n₂) d₂}, f (mk' n₁ d₁) (mk' n₂ d₂) = f₁ n₁ (↑d₁) n₂ ↑d₂ /. f₂ n₁ (↑d₁) n₂ ↑d₂
f0 : ∀ {n₁ d₁ n₂ d₂ : ℤ}, d₁ ≠ 0 → d₂ ≠ 0 → f₂ n₁ d₁ n₂ d₂ ≠ 0
a b c d : ℤ
b0 : b ≠ 0
d0 : d ≠ 0
H : ∀ {n₁ d₁ n₂ d₂ : ℤ}, a * d₁ = n₁ * b → c * d₂ = n₂ * d → f₁ n₁ d₁ n₂ d₂ * f₂ a b c d = f₁ a b c d * f₂ n₁ d₁ n₂ d₂
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
c₁ : Nat.coprime (Int.natAbs n₁) d₁
ha : a /. b = n₁ /. ↑d₁
n₂ : ℤ
d₂ : ℕ
h₂ : d₂ ≠ 0
c₂ : Nat.coprime (Int.natAbs n₂) d₂
hc : c /. d = n₂ /. ↑d₂
d₁0 : ↑d₁ ≠ ↑0
⊢ f₁ n₁ (↑d₁) n₂ ↑d₂ /. f₂ n₁ (↑d₁) n₂ ↑d₂ = f₁ a b c d /. f₂ a b c d
[PROOFSTEP]
have d₂0 := ne_of_gt (Int.ofNat_lt.2 $ Nat.pos_of_ne_zero h₂)
[GOAL]
case mk'.mk'
f : ℚ → ℚ → ℚ
f₁ f₂ : ℤ → ℤ → ℤ → ℤ → ℤ
fv :
  ∀ {n₁ : ℤ} {d₁ : ℕ} {h₁ : d₁ ≠ 0} {c₁ : Nat.coprime (Int.natAbs n₁) d₁} {n₂ : ℤ} {d₂ : ℕ} {h₂ : d₂ ≠ 0}
    {c₂ : Nat.coprime (Int.natAbs n₂) d₂}, f (mk' n₁ d₁) (mk' n₂ d₂) = f₁ n₁ (↑d₁) n₂ ↑d₂ /. f₂ n₁ (↑d₁) n₂ ↑d₂
f0 : ∀ {n₁ d₁ n₂ d₂ : ℤ}, d₁ ≠ 0 → d₂ ≠ 0 → f₂ n₁ d₁ n₂ d₂ ≠ 0
a b c d : ℤ
b0 : b ≠ 0
d0 : d ≠ 0
H : ∀ {n₁ d₁ n₂ d₂ : ℤ}, a * d₁ = n₁ * b → c * d₂ = n₂ * d → f₁ n₁ d₁ n₂ d₂ * f₂ a b c d = f₁ a b c d * f₂ n₁ d₁ n₂ d₂
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
c₁ : Nat.coprime (Int.natAbs n₁) d₁
ha : a /. b = n₁ /. ↑d₁
n₂ : ℤ
d₂ : ℕ
h₂ : d₂ ≠ 0
c₂ : Nat.coprime (Int.natAbs n₂) d₂
hc : c /. d = n₂ /. ↑d₂
d₁0 : ↑d₁ ≠ ↑0
d₂0 : ↑d₂ ≠ ↑0
⊢ f₁ n₁ (↑d₁) n₂ ↑d₂ /. f₂ n₁ (↑d₁) n₂ ↑d₂ = f₁ a b c d /. f₂ a b c d
[PROOFSTEP]
exact (divInt_eq_iff (f0 d₁0 d₂0) (f0 b0 d0)).2 (H ((divInt_eq_iff b0 d₁0).1 ha) ((divInt_eq_iff d0 d₂0).1 hc))
[GOAL]
a b c : ℚ
n : ℤ
d : ℕ
h : d ≠ 0
⊢ n /. ↑d + 0 = n /. ↑d
[PROOFSTEP]
rw [← zero_divInt d, add_def'', zero_mul, add_zero, divInt_mul_right]
[GOAL]
a b c : ℚ
n : ℤ
d : ℕ
h : d ≠ 0
⊢ ↑d ≠ 0
[PROOFSTEP]
simp [h]
[GOAL]
case b0
a b c : ℚ
n : ℤ
d : ℕ
h : d ≠ 0
⊢ ↑d ≠ 0
[PROOFSTEP]
simp [h]
[GOAL]
case d0
a b c : ℚ
n : ℤ
d : ℕ
h : d ≠ 0
⊢ ↑d ≠ 0
[PROOFSTEP]
simp [h]
[GOAL]
a b c : ℚ
n : ℤ
d : ℕ
h : d ≠ 0
⊢ 0 + n /. ↑d = n /. ↑d
[PROOFSTEP]
rw [← zero_divInt d, add_def'', zero_mul, zero_add, divInt_mul_right]
[GOAL]
a b c : ℚ
n : ℤ
d : ℕ
h : d ≠ 0
⊢ ↑d ≠ 0
[PROOFSTEP]
simp [h]
[GOAL]
case b0
a b c : ℚ
n : ℤ
d : ℕ
h : d ≠ 0
⊢ ↑d ≠ 0
[PROOFSTEP]
simp [h]
[GOAL]
case d0
a b c : ℚ
n : ℤ
d : ℕ
h : d ≠ 0
⊢ ↑d ≠ 0
[PROOFSTEP]
simp [h]
[GOAL]
a b c : ℚ
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
n₂ : ℤ
d₂ : ℕ
h₂ : d₂ ≠ 0
⊢ n₁ /. ↑d₁ + n₂ /. ↑d₂ = n₂ /. ↑d₂ + n₁ /. ↑d₁
[PROOFSTEP]
simp [h₁, h₂, add_comm, mul_comm]
[GOAL]
a b c : ℚ
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
n₂ : ℤ
d₂ : ℕ
h₂ : d₂ ≠ 0
n₃ : ℤ
d₃ : ℕ
h₃ : d₃ ≠ 0
⊢ n₁ /. ↑d₁ + n₂ /. ↑d₂ + n₃ /. ↑d₃ = n₁ /. ↑d₁ + (n₂ /. ↑d₂ + n₃ /. ↑d₃)
[PROOFSTEP]
simp [h₁, h₂, h₃]
[GOAL]
a b c : ℚ
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
n₂ : ℤ
d₂ : ℕ
h₂ : d₂ ≠ 0
n₃ : ℤ
d₃ : ℕ
h₃ : d₃ ≠ 0
⊢ ((n₁ * ↑d₂ + n₂ * ↑d₁) * ↑d₃ + n₃ * (↑d₁ * ↑d₂)) /. (↑d₁ * ↑d₂ * ↑d₃) =
    (n₁ * (↑d₂ * ↑d₃) + (n₂ * ↑d₃ + n₃ * ↑d₂) * ↑d₁) /. (↑d₁ * (↑d₂ * ↑d₃))
[PROOFSTEP]
rw [mul_assoc, add_mul, add_mul, mul_assoc, add_assoc]
[GOAL]
a b c : ℚ
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
n₂ : ℤ
d₂ : ℕ
h₂ : d₂ ≠ 0
n₃ : ℤ
d₃ : ℕ
h₃ : d₃ ≠ 0
⊢ (n₁ * (↑d₂ * ↑d₃) + (n₂ * ↑d₁ * ↑d₃ + n₃ * (↑d₁ * ↑d₂))) /. (↑d₁ * (↑d₂ * ↑d₃)) =
    (n₁ * (↑d₂ * ↑d₃) + (n₂ * ↑d₃ * ↑d₁ + n₃ * ↑d₂ * ↑d₁)) /. (↑d₁ * (↑d₂ * ↑d₃))
[PROOFSTEP]
congr 2
[GOAL]
case e_a.e_a
a b c : ℚ
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
n₂ : ℤ
d₂ : ℕ
h₂ : d₂ ≠ 0
n₃ : ℤ
d₃ : ℕ
h₃ : d₃ ≠ 0
⊢ n₂ * ↑d₁ * ↑d₃ + n₃ * (↑d₁ * ↑d₂) = n₂ * ↑d₃ * ↑d₁ + n₃ * ↑d₂ * ↑d₁
[PROOFSTEP]
ac_rfl
[GOAL]
a b c : ℚ
n : ℤ
d : ℕ
h : d ≠ 0
⊢ -(n /. ↑d) + n /. ↑d = 0
[PROOFSTEP]
simp [h, mkRat_add_mkRat]
[GOAL]
a b c : ℚ
⊢ 0 /. 1 = 0
[PROOFSTEP]
rw [divInt]
[GOAL]
a b c : ℚ
⊢ (match 0, 1 with
    | n, Int.ofNat d => inline (mkRat n d)
    | n, Int.negSucc d => normalize (-n) (Nat.succ d)) =
    0
[PROOFSTEP]
simp
[GOAL]
a b c : ℚ
⊢ 1 /. 1 = 1
[PROOFSTEP]
rw [divInt]
[GOAL]
a b c : ℚ
⊢ (match 1, 1 with
    | n, Int.ofNat d => inline (mkRat n d)
    | n, Int.negSucc d => normalize (-n) (Nat.succ d)) =
    1
[PROOFSTEP]
simp
[GOAL]
a b c : ℚ
⊢ -1 /. 1 = -1
[PROOFSTEP]
rw [divInt]
[GOAL]
a b c : ℚ
⊢ (match -1, 1 with
    | n, Int.ofNat d => inline (mkRat n d)
    | n, Int.negSucc d => normalize (-n) (Nat.succ d)) =
    -1
[PROOFSTEP]
simp
[GOAL]
a b c : ℚ
n : ℤ
⊢ n /. 1 = ↑n
[PROOFSTEP]
rw [divInt]
[GOAL]
a b c : ℚ
n : ℤ
⊢ (match n, 1 with
    | n, Int.ofNat d => inline (mkRat n d)
    | n, Int.negSucc d => normalize (-n) (Nat.succ d)) =
    ↑n
[PROOFSTEP]
simp [mkRat, normalize]
[GOAL]
a b c : ℚ
n : ℤ
⊢ mk' n 1 = ↑n
[PROOFSTEP]
rfl
[GOAL]
a b c : ℚ
n : ℤ
⊢ mkRat n 1 = ↑n
[PROOFSTEP]
simp [Rat.mkRat_eq, Rat.divInt_one]
[GOAL]
a b c : ℚ
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
n₂ : ℤ
d₂ : ℕ
h₂ : d₂ ≠ 0
n₃ : ℤ
d₃ : ℕ
h₃ : d₃ ≠ 0
⊢ n₁ /. ↑d₁ * (n₂ /. ↑d₂) * (n₃ /. ↑d₃) = n₁ /. ↑d₁ * (n₂ /. ↑d₂ * (n₃ /. ↑d₃))
[PROOFSTEP]
simp [h₁, h₂, h₃, mul_ne_zero, mul_comm, mul_assoc, mul_left_comm]
[GOAL]
a b c : ℚ
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
n₂ : ℤ
d₂ : ℕ
h₂ : d₂ ≠ 0
n₃ : ℤ
d₃ : ℕ
h₃ : d₃ ≠ 0
⊢ (n₁ /. ↑d₁ + n₂ /. ↑d₂) * (n₃ /. ↑d₃) = n₁ /. ↑d₁ * (n₃ /. ↑d₃) + n₂ /. ↑d₂ * (n₃ /. ↑d₃)
[PROOFSTEP]
simp [h₁, h₂, h₃, mul_ne_zero]
[GOAL]
a b c : ℚ
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
n₂ : ℤ
d₂ : ℕ
h₂ : d₂ ≠ 0
n₃ : ℤ
d₃ : ℕ
h₃ : d₃ ≠ 0
⊢ (n₁ * ↑d₂ + n₂ * ↑d₁) * n₃ /. (↑d₁ * ↑d₂ * ↑d₃) =
    (n₁ * n₃ * (↑d₂ * ↑d₃) + n₂ * n₃ * (↑d₁ * ↑d₃)) /. (↑d₁ * ↑d₃ * (↑d₂ * ↑d₃))
[PROOFSTEP]
rw [← divInt_mul_right (Int.coe_nat_ne_zero.2 h₃), add_mul, add_mul]
[GOAL]
a b c : ℚ
n₁ : ℤ
d₁ : ℕ
h₁ : d₁ ≠ 0
n₂ : ℤ
d₂ : ℕ
h₂ : d₂ ≠ 0
n₃ : ℤ
d₃ : ℕ
h₃ : d₃ ≠ 0
⊢ (n₁ * ↑d₂ * n₃ * ↑d₃ + n₂ * ↑d₁ * n₃ * ↑d₃) /. (↑d₁ * ↑d₂ * ↑d₃ * ↑d₃) =
    (n₁ * n₃ * (↑d₂ * ↑d₃) + n₂ * n₃ * (↑d₁ * ↑d₃)) /. (↑d₁ * ↑d₃ * (↑d₂ * ↑d₃))
[PROOFSTEP]
ac_rfl
[GOAL]
a b c : ℚ
⊢ a * (b + c) = a * b + a * c
[PROOFSTEP]
rw [Rat.mul_comm, Rat.add_mul, Rat.mul_comm, Rat.mul_comm c a]
[GOAL]
a b c : ℚ
⊢ 0 ≠ 1
[PROOFSTEP]
rw [ne_comm, ← divInt_one_one, divInt_ne_zero one_ne_zero]
[GOAL]
a b c : ℚ
⊢ 1 ≠ 0
[PROOFSTEP]
exact one_ne_zero
[GOAL]
a b c : ℚ
n : ℤ
d : ℕ
h : d ≠ 0
a0 : n /. ↑d ≠ 0
⊢ n /. ↑d * (n /. ↑d)⁻¹ = 1
[PROOFSTEP]
have n0 : n ≠ 0 := mt (by rintro rfl; simp) a0
[GOAL]
a b c : ℚ
n : ℤ
d : ℕ
h : d ≠ 0
a0 : n /. ↑d ≠ 0
⊢ n = 0 → n /. ↑d = 0
[PROOFSTEP]
rintro rfl
[GOAL]
a b c : ℚ
d : ℕ
h : d ≠ 0
a0 : 0 /. ↑d ≠ 0
⊢ 0 /. ↑d = 0
[PROOFSTEP]
simp
[GOAL]
a b c : ℚ
n : ℤ
d : ℕ
h : d ≠ 0
a0 : n /. ↑d ≠ 0
n0 : n ≠ 0
⊢ n /. ↑d * (n /. ↑d)⁻¹ = 1
[PROOFSTEP]
simpa [h, n0, mul_comm] using @divInt_mul_right 1 1 (n * d) (by simp [h, n0])
[GOAL]
a b c : ℚ
n : ℤ
d : ℕ
h : d ≠ 0
a0 : n /. ↑d ≠ 0
n0 : n ≠ 0
⊢ n * ↑d ≠ 0
[PROOFSTEP]
simp [h, n0]
[GOAL]
a b c : ℚ
n : ℕ
⊢ NatCast.natCast (n + 1) = NatCast.natCast n + 1
[PROOFSTEP]
simp only [coe_int_eq_divInt, add_def'' one_ne_zero one_ne_zero, ← divInt_one_one, Nat.cast_add, Nat.cast_one, mul_one]
[GOAL]
a b c : ℚ
⊢ 0⁻¹ = 0
[PROOFSTEP]
change Rat.inv 0 = 0
[GOAL]
a b c : ℚ
⊢ Rat.inv 0 = 0
[PROOFSTEP]
rw [Rat.inv_def]
[GOAL]
a b c : ℚ
⊢ ↑0.den /. 0.num = 0
[PROOFSTEP]
rfl
[GOAL]
a b c : ℚ
⊢ Nontrivial ℚ
[PROOFSTEP]
infer_instance
[GOAL]
a b c : ℚ
⊢ CommSemiring ℚ
[PROOFSTEP]
infer_instance
[GOAL]
a b c : ℚ
⊢ Semiring ℚ
[PROOFSTEP]
infer_instance
[GOAL]
a b c : ℚ
⊢ AddCommGroup ℚ
[PROOFSTEP]
infer_instance
[GOAL]
a b c : ℚ
⊢ AddGroup ℚ
[PROOFSTEP]
infer_instance
[GOAL]
a b c : ℚ
⊢ AddCommMonoid ℚ
[PROOFSTEP]
infer_instance
[GOAL]
a b c : ℚ
⊢ AddMonoid ℚ
[PROOFSTEP]
infer_instance
[GOAL]
a b c : ℚ
⊢ AddLeftCancelSemigroup ℚ
[PROOFSTEP]
infer_instance
[GOAL]
a b c : ℚ
⊢ AddRightCancelSemigroup ℚ
[PROOFSTEP]
infer_instance
[GOAL]
a b c : ℚ
⊢ AddCommSemigroup ℚ
[PROOFSTEP]
infer_instance
[GOAL]
a b c : ℚ
⊢ AddSemigroup ℚ
[PROOFSTEP]
infer_instance
[GOAL]
a b c : ℚ
⊢ CommMonoid ℚ
[PROOFSTEP]
infer_instance
[GOAL]
a b c : ℚ
⊢ Monoid ℚ
[PROOFSTEP]
infer_instance
[GOAL]
a b c : ℚ
⊢ CommSemigroup ℚ
[PROOFSTEP]
infer_instance
[GOAL]
a b c : ℚ
⊢ Semigroup ℚ
[PROOFSTEP]
infer_instance
[GOAL]
a b c p q : ℚ
⊢ p = q ↔ p.num * ↑q.den = q.num * ↑p.den
[PROOFSTEP]
conv =>
  lhs
  rw [← @num_den p, ← @num_den q]
[GOAL]
a b c p q : ℚ
| p = q ↔ p.num * ↑q.den = q.num * ↑p.den
[PROOFSTEP]
  lhs
  rw [← @num_den p, ← @num_den q]
[GOAL]
a b c p q : ℚ
| p = q ↔ p.num * ↑q.den = q.num * ↑p.den
[PROOFSTEP]
  lhs
  rw [← @num_den p, ← @num_den q]
[GOAL]
a b c p q : ℚ
| p = q ↔ p.num * ↑q.den = q.num * ↑p.den
[PROOFSTEP]
lhs
[GOAL]
a b c p q : ℚ
| p = q
[PROOFSTEP]
rw [← @num_den p, ← @num_den q]
[GOAL]
a b c p q : ℚ
⊢ p.num /. ↑p.den = q.num /. ↑q.den ↔ p.num * ↑q.den = q.num * ↑p.den
[PROOFSTEP]
apply Rat.divInt_eq_iff
[GOAL]
case z₁
a b c p q : ℚ
⊢ ↑p.den ≠ 0
[PROOFSTEP]
rw [← Nat.cast_zero, Ne, Int.ofNat_inj]
[GOAL]
case z₁
a b c p q : ℚ
⊢ ¬p.den = 0
[PROOFSTEP]
apply den_nz
[GOAL]
case z₂
a b c p q : ℚ
⊢ ↑q.den ≠ 0
[PROOFSTEP]
rw [← Nat.cast_zero, Ne, Int.ofNat_inj]
[GOAL]
case z₂
a b c p q : ℚ
⊢ ¬q.den = 0
[PROOFSTEP]
apply den_nz
[GOAL]
a b c q : ℚ
hq : q.num = 0
⊢ q = 0
[PROOFSTEP]
have : q = q.num /. q.den := num_den.symm
[GOAL]
a b c q : ℚ
hq : q.num = 0
this : q = q.num /. ↑q.den
⊢ q = 0
[PROOFSTEP]
simpa [hq] using this
[GOAL]
a b c q : ℚ
x✝ : q = 0
⊢ q.num = 0
[PROOFSTEP]
simp [*]
[GOAL]
a b c q : ℚ
n d : ℤ
hq : q ≠ 0
hqnd : q = n /. d
this : n = 0
⊢ q = 0
[PROOFSTEP]
simpa [this] using hqnd
[GOAL]
a b c q : ℚ
n d : ℤ
hq : q ≠ 0
hqnd : q = n /. d
this : d = 0
⊢ q = 0
[PROOFSTEP]
simpa [this] using hqnd
[GOAL]
a b c q r : ℚ
⊢ q * r = q.num * r.num /. ↑(q.den * r.den)
[PROOFSTEP]
have hq' : (↑q.den : ℤ) ≠ 0 := by have := den_nz q; simpa
[GOAL]
a b c q r : ℚ
⊢ ↑q.den ≠ 0
[PROOFSTEP]
have := den_nz q
[GOAL]
a b c q r : ℚ
this : q.den ≠ 0
⊢ ↑q.den ≠ 0
[PROOFSTEP]
simpa
[GOAL]
a b c q r : ℚ
hq' : ↑q.den ≠ 0
⊢ q * r = q.num * r.num /. ↑(q.den * r.den)
[PROOFSTEP]
have hr' : (↑r.den : ℤ) ≠ 0 := by have := den_nz r; simpa
[GOAL]
a b c q r : ℚ
hq' : ↑q.den ≠ 0
⊢ ↑r.den ≠ 0
[PROOFSTEP]
have := den_nz r
[GOAL]
a b c q r : ℚ
hq' : ↑q.den ≠ 0
this : r.den ≠ 0
⊢ ↑r.den ≠ 0
[PROOFSTEP]
simpa
[GOAL]
a b c q r : ℚ
hq' : ↑q.den ≠ 0
hr' : ↑r.den ≠ 0
⊢ q * r = q.num * r.num /. ↑(q.den * r.den)
[PROOFSTEP]
suffices q.num /. ↑q.den * (r.num /. ↑r.den) = q.num * r.num /. ↑(q.den * r.den) by simpa [num_den] using this
[GOAL]
a b c q r : ℚ
hq' : ↑q.den ≠ 0
hr' : ↑r.den ≠ 0
this : q.num /. ↑q.den * (r.num /. ↑r.den) = q.num * r.num /. ↑(q.den * r.den)
⊢ q * r = q.num * r.num /. ↑(q.den * r.den)
[PROOFSTEP]
simpa [num_den] using this
[GOAL]
a b c q r : ℚ
hq' : ↑q.den ≠ 0
hr' : ↑r.den ≠ 0
⊢ q.num /. ↑q.den * (r.num /. ↑r.den) = q.num * r.num /. ↑(q.den * r.den)
[PROOFSTEP]
simp [mul_def' hq' hr']
[GOAL]
a b c q r : ℚ
hr : r.num = 0
⊢ q / r = q.num * ↑r.den /. (↑q.den * r.num)
[PROOFSTEP]
have hr' : r = 0 := zero_of_num_zero hr
[GOAL]
a b c q r : ℚ
hr : r.num = 0
hr' : r = 0
⊢ q / r = q.num * ↑r.den /. (↑q.den * r.num)
[PROOFSTEP]
simp [*]
[GOAL]
a b c q r : ℚ
hr : ¬r.num = 0
⊢ q * r⁻¹ = q.num /. ↑q.den * (r.num /. ↑r.den)⁻¹
[PROOFSTEP]
simp [num_den]
[GOAL]
a b c q r : ℚ
hr : ¬r.num = 0
⊢ q.num /. ↑q.den * (r.num /. ↑r.den)⁻¹ = q.num /. ↑q.den * (↑r.den /. r.num)
[PROOFSTEP]
rw [inv_def']
[GOAL]
a b c q r : ℚ
hr : ¬r.num = 0
⊢ ↑q.den ≠ 0
[PROOFSTEP]
simpa using den_nz q
[GOAL]
a✝ b✝ c✝ : ℚ
a b c : ℤ
h : c = 0
⊢ (a + b) /. c = a /. c + b /. c
[PROOFSTEP]
simp [h]
[GOAL]
a✝ b✝ c✝ : ℚ
a b c : ℤ
h : ¬c = 0
⊢ (a + b) /. c = a /. c + b /. c
[PROOFSTEP]
rw [add_def'' h h, divInt_eq_iff h (mul_ne_zero h h)]
[GOAL]
a✝ b✝ c✝ : ℚ
a b c : ℤ
h : ¬c = 0
⊢ (a + b) * (c * c) = (a * c + b * c) * c
[PROOFSTEP]
simp [add_mul, mul_assoc]
[GOAL]
a b c : ℚ
n d : ℤ
⊢ n /. d = ↑n / ↑d
[PROOFSTEP]
by_cases d0 : d = 0
[GOAL]
case pos
a b c : ℚ
n d : ℤ
d0 : d = 0
⊢ n /. d = ↑n / ↑d
[PROOFSTEP]
simp [d0, div_zero]
[GOAL]
case neg
a b c : ℚ
n d : ℤ
d0 : ¬d = 0
⊢ n /. d = ↑n / ↑d
[PROOFSTEP]
simp [division_def, coe_int_eq_divInt, mul_def' one_ne_zero d0]
[GOAL]
a b c : ℚ
x : ℤ
hx : x ≠ 0
n d : ℤ
⊢ n /. x * (x /. d) = n /. d
[PROOFSTEP]
by_cases hd : d = 0
[GOAL]
case pos
a b c : ℚ
x : ℤ
hx : x ≠ 0
n d : ℤ
hd : d = 0
⊢ n /. x * (x /. d) = n /. d
[PROOFSTEP]
rw [hd]
[GOAL]
case pos
a b c : ℚ
x : ℤ
hx : x ≠ 0
n d : ℤ
hd : d = 0
⊢ n /. x * (x /. 0) = n /. 0
[PROOFSTEP]
simp
[GOAL]
case neg
a b c : ℚ
x : ℤ
hx : x ≠ 0
n d : ℤ
hd : ¬d = 0
⊢ n /. x * (x /. d) = n /. d
[PROOFSTEP]
rw [mul_def' hx hd, mul_comm x, divInt_mul_right hx]
[GOAL]
a b c : ℚ
x : ℤ
hx : x ≠ 0
n d : ℤ
⊢ n /. x / (d /. x) = n /. d
[PROOFSTEP]
rw [div_eq_mul_inv, inv_def', divInt_mul_divInt_cancel hx]
[GOAL]
a b c : ℚ
x : ℤ
hx : x ≠ 0
n d : ℤ
⊢ x /. n / (x /. d) = d /. n
[PROOFSTEP]
rw [div_eq_mul_inv, inv_def', mul_comm, divInt_mul_divInt_cancel hx]
[GOAL]
a b c : ℚ
n d : ℤ
⊢ ↑n / ↑d = n /. d
[PROOFSTEP]
repeat' rw [coe_int_eq_divInt]
[GOAL]
a b c : ℚ
n d : ℤ
⊢ ↑n / ↑d = n /. d
[PROOFSTEP]
rw [coe_int_eq_divInt]
[GOAL]
a b c : ℚ
n d : ℤ
⊢ n /. 1 / ↑d = n /. d
[PROOFSTEP]
rw [coe_int_eq_divInt]
[GOAL]
a b c : ℚ
n d : ℤ
⊢ n /. 1 / (d /. 1) = n /. d
[PROOFSTEP]
rw [coe_int_eq_divInt]
[GOAL]
a b c : ℚ
n d : ℤ
⊢ n /. 1 / (d /. 1) = n /. d
[PROOFSTEP]
exact divInt_div_divInt_cancel_left one_ne_zero n d
[GOAL]
a b c r : ℚ
⊢ ↑r.num / ↑r.den = r
[PROOFSTEP]
rw [← Int.cast_ofNat]
[GOAL]
a b c r : ℚ
⊢ ↑r.num / ↑↑r.den = r
[PROOFSTEP]
erw [← divInt_eq_div, num_den]
[GOAL]
a b c q : ℚ
hq : q.den = 1
⊢ ↑q.num = q
[PROOFSTEP]
conv_rhs => rw [← @num_den q, hq]
[GOAL]
a b c q : ℚ
hq : q.den = 1
| q
[PROOFSTEP]
rw [← @num_den q, hq]
[GOAL]
a b c q : ℚ
hq : q.den = 1
| q
[PROOFSTEP]
rw [← @num_den q, hq]
[GOAL]
a b c q : ℚ
hq : q.den = 1
| q
[PROOFSTEP]
rw [← @num_den q, hq]
[GOAL]
a b c q : ℚ
hq : q.den = 1
⊢ ↑q.num = q.num /. ↑1
[PROOFSTEP]
rw [coe_int_eq_divInt]
[GOAL]
a b c q : ℚ
hq : q.den = 1
⊢ q.num /. 1 = q.num /. ↑1
[PROOFSTEP]
rfl
[GOAL]
a b c : ℚ
n : ℕ
⊢ ↑n = ↑n /. 1
[PROOFSTEP]
rw [← Int.cast_ofNat, coe_int_eq_divInt]
[GOAL]
a b c : ℚ
n : ℕ
⊢ (↑n).num = ↑n
[PROOFSTEP]
rw [← Int.cast_ofNat, coe_int_num]
[GOAL]
a b c : ℚ
n : ℕ
⊢ (↑n).den = 1
[PROOFSTEP]
rw [← Int.cast_ofNat, coe_int_den]
[GOAL]
a b c : ℚ
n : ℤ
d : ℕ
⊢ mkRat n d = ↑n / ↑d
[PROOFSTEP]
simp [mkRat]
[GOAL]
a b c : ℚ
n : ℤ
d : ℕ
⊢ (if h : d = 0 then 0 else normalize n d) = ↑n / ↑d
[PROOFSTEP]
by_cases d = 0
[GOAL]
a b c : ℚ
n : ℤ
d : ℕ
⊢ (if h : d = 0 then 0 else normalize n d) = ↑n / ↑d
[PROOFSTEP]
by_cases d = 0
[GOAL]
case pos
a b c : ℚ
n : ℤ
d : ℕ
h : d = 0
⊢ (if h : d = 0 then 0 else normalize n d) = ↑n / ↑d
[PROOFSTEP]
simp [h]
[GOAL]
case neg
a b c : ℚ
n : ℤ
d : ℕ
h : ¬d = 0
⊢ (if h : d = 0 then 0 else normalize n d) = ↑n / ↑d
[PROOFSTEP]
simp [h, HDiv.hDiv, Rat.div, Div.div]
[GOAL]
case neg
a b c : ℚ
n : ℤ
d : ℕ
h : ¬d = 0
⊢ normalize n d = ↑n * Rat.inv ↑d
[PROOFSTEP]
unfold Rat.inv
[GOAL]
case neg
a b c : ℚ
n : ℤ
d : ℕ
h : ¬d = 0
⊢ normalize n d =
    ↑n *
      if h : (↑d).num < 0 then mk' (-↑(↑d).den) (Int.natAbs (↑d).num)
      else if h : (↑d).num > 0 then mk' (↑(↑d).den) (Int.natAbs (↑d).num) else ↑d
[PROOFSTEP]
have h₁ : 0 < d := Nat.pos_iff_ne_zero.2 h
[GOAL]
case neg
a b c : ℚ
n : ℤ
d : ℕ
h : ¬d = 0
h₁ : 0 < d
⊢ normalize n d =
    ↑n *
      if h : (↑d).num < 0 then mk' (-↑(↑d).den) (Int.natAbs (↑d).num)
      else if h : (↑d).num > 0 then mk' (↑(↑d).den) (Int.natAbs (↑d).num) else ↑d
[PROOFSTEP]
have h₂ : ¬(d : ℤ) < 0 := by simp
[GOAL]
a b c : ℚ
n : ℤ
d : ℕ
h : ¬d = 0
h₁ : 0 < d
⊢ ¬↑d < 0
[PROOFSTEP]
simp
[GOAL]
case neg
a b c : ℚ
n : ℤ
d : ℕ
h : ¬d = 0
h₁ : 0 < d
h₂ : ¬↑d < 0
⊢ normalize n d =
    ↑n *
      if h : (↑d).num < 0 then mk' (-↑(↑d).den) (Int.natAbs (↑d).num)
      else if h : (↑d).num > 0 then mk' (↑(↑d).den) (Int.natAbs (↑d).num) else ↑d
[PROOFSTEP]
simp [h, h₁, h₂, ← Rat.normalize_eq_mk', Rat.normalize_eq_mkRat, ← mkRat_one, Rat.mkRat_mul_mkRat]


[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
h : Countable M
⊢ Set.Countable (Quotient.mk' '' age L M)
[PROOFSTEP]
classical
refine'
  (congr_arg _ (Set.ext <| forall_quotient_iff.2 fun N => _)).mp
    (countable_range fun s : Finset M => ⟦⟨closure L (s : Set M), inferInstance⟩⟧)
constructor
· rintro ⟨s, hs⟩
  use Bundled.of (closure L (s : Set M))
  exact ⟨⟨(fg_iff_structure_fg _).1 (fg_closure s.finite_toSet), ⟨Substructure.subtype _⟩⟩, hs⟩
· simp only [mem_range, Quotient.eq]
  rintro ⟨P, ⟨⟨s, hs⟩, ⟨PM⟩⟩, hP2⟩
  have : P ≈ N := by apply Quotient.eq'.mp; rw [hP2];
    rfl
      -- Porting note: added
  refine' ⟨s.image PM, Setoid.trans (b := P) _ this⟩
  rw [← Embedding.coe_toHom, Finset.coe_image, closure_image PM.toHom, hs, ← Hom.range_eq_map]
  exact ⟨PM.equivRange.symm⟩
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
h : Countable M
⊢ Set.Countable (Quotient.mk' '' age L M)
[PROOFSTEP]
refine'
  (congr_arg _ (Set.ext <| forall_quotient_iff.2 fun N => _)).mp
    (countable_range fun s : Finset M => ⟦⟨closure L (s : Set M), inferInstance⟩⟧)
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : Countable M
N : Bundled (Structure L)
⊢ (Quotient.mk equivSetoid N ∈
      range fun s => Quotient.mk equivSetoid (Bundled.mk { x // x ∈ LowerAdjoint.toFun (closure L) ↑s })) ↔
    Quotient.mk equivSetoid N ∈ Quotient.mk' '' age L M
[PROOFSTEP]
constructor
[GOAL]
case mp
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : Countable M
N : Bundled (Structure L)
⊢ (Quotient.mk equivSetoid N ∈
      range fun s => Quotient.mk equivSetoid (Bundled.mk { x // x ∈ LowerAdjoint.toFun (closure L) ↑s })) →
    Quotient.mk equivSetoid N ∈ Quotient.mk' '' age L M
[PROOFSTEP]
rintro ⟨s, hs⟩
[GOAL]
case mp.intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : Countable M
N : Bundled (Structure L)
s : Finset M
hs :
  (fun s => Quotient.mk equivSetoid (Bundled.mk { x // x ∈ LowerAdjoint.toFun (closure L) ↑s })) s =
    Quotient.mk equivSetoid N
⊢ Quotient.mk equivSetoid N ∈ Quotient.mk' '' age L M
[PROOFSTEP]
use Bundled.of (closure L (s : Set M))
[GOAL]
case h
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : Countable M
N : Bundled (Structure L)
s : Finset M
hs :
  (fun s => Quotient.mk equivSetoid (Bundled.mk { x // x ∈ LowerAdjoint.toFun (closure L) ↑s })) s =
    Quotient.mk equivSetoid N
⊢ Bundled.of { x // x ∈ LowerAdjoint.toFun (closure L) ↑s } ∈ age L M ∧
    Quotient.mk' (Bundled.of { x // x ∈ LowerAdjoint.toFun (closure L) ↑s }) = Quotient.mk equivSetoid N
[PROOFSTEP]
exact ⟨⟨(fg_iff_structure_fg _).1 (fg_closure s.finite_toSet), ⟨Substructure.subtype _⟩⟩, hs⟩
[GOAL]
case mpr
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : Countable M
N : Bundled (Structure L)
⊢ Quotient.mk equivSetoid N ∈ Quotient.mk' '' age L M →
    Quotient.mk equivSetoid N ∈
      range fun s => Quotient.mk equivSetoid (Bundled.mk { x // x ∈ LowerAdjoint.toFun (closure L) ↑s })
[PROOFSTEP]
simp only [mem_range, Quotient.eq]
[GOAL]
case mpr
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : Countable M
N : Bundled (Structure L)
⊢ Quotient.mk equivSetoid N ∈ Quotient.mk' '' age L M →
    ∃ y, Bundled.mk { x // x ∈ LowerAdjoint.toFun (closure L) ↑y } ≈ N
[PROOFSTEP]
rintro ⟨P, ⟨⟨s, hs⟩, ⟨PM⟩⟩, hP2⟩
[GOAL]
case mpr.intro.intro.intro.mk.intro.intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : Countable M
N P : Bundled (Structure L)
hP2 : Quotient.mk' P = Quotient.mk equivSetoid N
s : Finset ↑P
hs : LowerAdjoint.toFun (closure L) ↑s = ⊤
PM : ↑P ↪[L] M
⊢ ∃ y, Bundled.mk { x // x ∈ LowerAdjoint.toFun (closure L) ↑y } ≈ N
[PROOFSTEP]
have : P ≈ N := by apply Quotient.eq'.mp; rw [hP2];
  rfl
    -- Porting note: added
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : Countable M
N P : Bundled (Structure L)
hP2 : Quotient.mk' P = Quotient.mk equivSetoid N
s : Finset ↑P
hs : LowerAdjoint.toFun (closure L) ↑s = ⊤
PM : ↑P ↪[L] M
⊢ P ≈ N
[PROOFSTEP]
apply Quotient.eq'.mp
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : Countable M
N P : Bundled (Structure L)
hP2 : Quotient.mk' P = Quotient.mk equivSetoid N
s : Finset ↑P
hs : LowerAdjoint.toFun (closure L) ↑s = ⊤
PM : ↑P ↪[L] M
⊢ Quotient.mk' P = Quotient.mk' N
[PROOFSTEP]
rw [hP2]
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : Countable M
N P : Bundled (Structure L)
hP2 : Quotient.mk' P = Quotient.mk equivSetoid N
s : Finset ↑P
hs : LowerAdjoint.toFun (closure L) ↑s = ⊤
PM : ↑P ↪[L] M
⊢ Quotient.mk equivSetoid N = Quotient.mk' N
[PROOFSTEP]
rfl
  -- Porting note: added
[GOAL]
case mpr.intro.intro.intro.mk.intro.intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : Countable M
N P : Bundled (Structure L)
hP2 : Quotient.mk' P = Quotient.mk equivSetoid N
s : Finset ↑P
hs : LowerAdjoint.toFun (closure L) ↑s = ⊤
PM : ↑P ↪[L] M
this : P ≈ N
⊢ ∃ y, Bundled.mk { x // x ∈ LowerAdjoint.toFun (closure L) ↑y } ≈ N
[PROOFSTEP]
refine' ⟨s.image PM, Setoid.trans (b := P) _ this⟩
[GOAL]
case mpr.intro.intro.intro.mk.intro.intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : Countable M
N P : Bundled (Structure L)
hP2 : Quotient.mk' P = Quotient.mk equivSetoid N
s : Finset ↑P
hs : LowerAdjoint.toFun (closure L) ↑s = ⊤
PM : ↑P ↪[L] M
this : P ≈ N
⊢ Bundled.mk { x // x ∈ LowerAdjoint.toFun (closure L) ↑(Finset.image (↑PM) s) } ≈ P
[PROOFSTEP]
rw [← Embedding.coe_toHom, Finset.coe_image, closure_image PM.toHom, hs, ← Hom.range_eq_map]
[GOAL]
case mpr.intro.intro.intro.mk.intro.intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : Countable M
N P : Bundled (Structure L)
hP2 : Quotient.mk' P = Quotient.mk equivSetoid N
s : Finset ↑P
hs : LowerAdjoint.toFun (closure L) ↑s = ⊤
PM : ↑P ↪[L] M
this : P ≈ N
⊢ Bundled.mk { x // x ∈ Hom.range (Embedding.toHom PM) } ≈ P
[PROOFSTEP]
exact ⟨PM.equivRange.symm⟩
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝⁶ : Structure L M
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
⊢ age L (DirectLimit G f) = ⋃ (i : ι), age L (G i)
[PROOFSTEP]
classical
ext M
simp only [mem_iUnion]
constructor
· rintro ⟨Mfg, ⟨e⟩⟩
  obtain ⟨s, hs⟩ := Mfg.range e.toHom
  let out := @Quotient.out _ (DirectLimit.setoid G f)
  obtain ⟨i, hi⟩ := Finset.exists_le (s.image (Sigma.fst ∘ out))
  have e' := (DirectLimit.of L ι G f i).equivRange.symm.toEmbedding
  refine' ⟨i, Mfg, ⟨e'.comp ((Substructure.inclusion _).comp e.equivRange.toEmbedding)⟩⟩
  rw [← hs, closure_le]
  intro x hx
  refine' ⟨f (out x).1 i (hi (out x).1 (Finset.mem_image_of_mem _ hx)) (out x).2, _⟩
  rw [Embedding.coe_toHom, DirectLimit.of_apply, @Quotient.mk_eq_iff_out _ (_),
    DirectLimit.equiv_iff G f _ (hi (out x).1 (Finset.mem_image_of_mem _ hx)), DirectedSystem.map_self]
  rfl
· rintro ⟨i, Mfg, ⟨e⟩⟩
  exact ⟨Mfg, ⟨Embedding.comp (DirectLimit.of L ι G f i) e⟩⟩
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝⁶ : Structure L M
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
⊢ age L (DirectLimit G f) = ⋃ (i : ι), age L (G i)
[PROOFSTEP]
ext M
[GOAL]
case h
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
⊢ M ∈ age L (DirectLimit G f) ↔ M ∈ ⋃ (i : ι), age L (G i)
[PROOFSTEP]
simp only [mem_iUnion]
[GOAL]
case h
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
⊢ M ∈ age L (DirectLimit G f) ↔ ∃ i, M ∈ age L (G i)
[PROOFSTEP]
constructor
[GOAL]
case h.mp
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
⊢ M ∈ age L (DirectLimit G f) → ∃ i, M ∈ age L (G i)
[PROOFSTEP]
rintro ⟨Mfg, ⟨e⟩⟩
[GOAL]
case h.mp.intro.intro
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
Mfg : Structure.FG L ↑M
e : ↑M ↪[L] DirectLimit G f
⊢ ∃ i, M ∈ age L (G i)
[PROOFSTEP]
obtain ⟨s, hs⟩ := Mfg.range e.toHom
[GOAL]
case h.mp.intro.intro.intro
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
Mfg : Structure.FG L ↑M
e : ↑M ↪[L] DirectLimit G f
s : Finset (DirectLimit G f)
hs : LowerAdjoint.toFun (closure L) ↑s = Hom.range (Embedding.toHom e)
⊢ ∃ i, M ∈ age L (G i)
[PROOFSTEP]
let out := @Quotient.out _ (DirectLimit.setoid G f)
[GOAL]
case h.mp.intro.intro.intro
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
Mfg : Structure.FG L ↑M
e : ↑M ↪[L] DirectLimit G f
s : Finset (DirectLimit G f)
hs : LowerAdjoint.toFun (closure L) ↑s = Hom.range (Embedding.toHom e)
out : Quotient (DirectLimit.setoid G f) → Structure.Sigma f := Quotient.out
⊢ ∃ i, M ∈ age L (G i)
[PROOFSTEP]
obtain ⟨i, hi⟩ := Finset.exists_le (s.image (Sigma.fst ∘ out))
[GOAL]
case h.mp.intro.intro.intro.intro
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
Mfg : Structure.FG L ↑M
e : ↑M ↪[L] DirectLimit G f
s : Finset (DirectLimit G f)
hs : LowerAdjoint.toFun (closure L) ↑s = Hom.range (Embedding.toHom e)
out : Quotient (DirectLimit.setoid G f) → Structure.Sigma f := Quotient.out
i : ι
hi : ∀ (i_1 : ι), i_1 ∈ Finset.image (Sigma.fst ∘ out) s → i_1 ≤ i
⊢ ∃ i, M ∈ age L (G i)
[PROOFSTEP]
have e' := (DirectLimit.of L ι G f i).equivRange.symm.toEmbedding
[GOAL]
case h.mp.intro.intro.intro.intro
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
Mfg : Structure.FG L ↑M
e : ↑M ↪[L] DirectLimit G f
s : Finset (DirectLimit G f)
hs : LowerAdjoint.toFun (closure L) ↑s = Hom.range (Embedding.toHom e)
out : Quotient (DirectLimit.setoid G f) → Structure.Sigma f := Quotient.out
i : ι
hi : ∀ (i_1 : ι), i_1 ∈ Finset.image (Sigma.fst ∘ out) s → i_1 ≤ i
e' : { x // x ∈ Hom.range (Embedding.toHom (DirectLimit.of L ι G f i)) } ↪[L] G i
⊢ ∃ i, M ∈ age L (G i)
[PROOFSTEP]
refine' ⟨i, Mfg, ⟨e'.comp ((Substructure.inclusion _).comp e.equivRange.toEmbedding)⟩⟩
[GOAL]
case h.mp.intro.intro.intro.intro
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
Mfg : Structure.FG L ↑M
e : ↑M ↪[L] DirectLimit G f
s : Finset (DirectLimit G f)
hs : LowerAdjoint.toFun (closure L) ↑s = Hom.range (Embedding.toHom e)
out : Quotient (DirectLimit.setoid G f) → Structure.Sigma f := Quotient.out
i : ι
hi : ∀ (i_1 : ι), i_1 ∈ Finset.image (Sigma.fst ∘ out) s → i_1 ≤ i
e' : { x // x ∈ Hom.range (Embedding.toHom (DirectLimit.of L ι G f i)) } ↪[L] G i
⊢ Hom.range (Embedding.toHom e) ≤ Hom.range (Embedding.toHom (DirectLimit.of L ι G f i))
[PROOFSTEP]
rw [← hs, closure_le]
[GOAL]
case h.mp.intro.intro.intro.intro
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
Mfg : Structure.FG L ↑M
e : ↑M ↪[L] DirectLimit G f
s : Finset (DirectLimit G f)
hs : LowerAdjoint.toFun (closure L) ↑s = Hom.range (Embedding.toHom e)
out : Quotient (DirectLimit.setoid G f) → Structure.Sigma f := Quotient.out
i : ι
hi : ∀ (i_1 : ι), i_1 ∈ Finset.image (Sigma.fst ∘ out) s → i_1 ≤ i
e' : { x // x ∈ Hom.range (Embedding.toHom (DirectLimit.of L ι G f i)) } ↪[L] G i
⊢ ↑s ⊆ ↑(Hom.range (Embedding.toHom (DirectLimit.of L ι G f i)))
[PROOFSTEP]
intro x hx
[GOAL]
case h.mp.intro.intro.intro.intro
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
Mfg : Structure.FG L ↑M
e : ↑M ↪[L] DirectLimit G f
s : Finset (DirectLimit G f)
hs : LowerAdjoint.toFun (closure L) ↑s = Hom.range (Embedding.toHom e)
out : Quotient (DirectLimit.setoid G f) → Structure.Sigma f := Quotient.out
i : ι
hi : ∀ (i_1 : ι), i_1 ∈ Finset.image (Sigma.fst ∘ out) s → i_1 ≤ i
e' : { x // x ∈ Hom.range (Embedding.toHom (DirectLimit.of L ι G f i)) } ↪[L] G i
x : DirectLimit G f
hx : x ∈ ↑s
⊢ x ∈ ↑(Hom.range (Embedding.toHom (DirectLimit.of L ι G f i)))
[PROOFSTEP]
refine' ⟨f (out x).1 i (hi (out x).1 (Finset.mem_image_of_mem _ hx)) (out x).2, _⟩
[GOAL]
case h.mp.intro.intro.intro.intro
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
Mfg : Structure.FG L ↑M
e : ↑M ↪[L] DirectLimit G f
s : Finset (DirectLimit G f)
hs : LowerAdjoint.toFun (closure L) ↑s = Hom.range (Embedding.toHom e)
out : Quotient (DirectLimit.setoid G f) → Structure.Sigma f := Quotient.out
i : ι
hi : ∀ (i_1 : ι), i_1 ∈ Finset.image (Sigma.fst ∘ out) s → i_1 ≤ i
e' : { x // x ∈ Hom.range (Embedding.toHom (DirectLimit.of L ι G f i)) } ↪[L] G i
x : DirectLimit G f
hx : x ∈ ↑s
⊢ ↑(Embedding.toHom (DirectLimit.of L ι G f i)) (↑(f (out x).fst i (_ : (out x).fst ≤ i)) (out x).snd) = x
[PROOFSTEP]
rw [Embedding.coe_toHom, DirectLimit.of_apply, @Quotient.mk_eq_iff_out _ (_),
  DirectLimit.equiv_iff G f _ (hi (out x).1 (Finset.mem_image_of_mem _ hx)), DirectedSystem.map_self]
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
Mfg : Structure.FG L ↑M
e : ↑M ↪[L] DirectLimit G f
s : Finset (DirectLimit G f)
hs : LowerAdjoint.toFun (closure L) ↑s = Hom.range (Embedding.toHom e)
out : Quotient (DirectLimit.setoid G f) → Structure.Sigma f := Quotient.out
i : ι
hi : ∀ (i_1 : ι), i_1 ∈ Finset.image (Sigma.fst ∘ out) s → i_1 ≤ i
e' : { x // x ∈ Hom.range (Embedding.toHom (DirectLimit.of L ι G f i)) } ↪[L] G i
x : DirectLimit G f
hx : x ∈ ↑s
⊢ (Structure.Sigma.mk f i (↑(f (out x).fst i (_ : (out x).fst ≤ i)) (out x).snd)).fst ≤ i
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
Mfg : Structure.FG L ↑M
e : ↑M ↪[L] DirectLimit G f
s : Finset (DirectLimit G f)
hs : LowerAdjoint.toFun (closure L) ↑s = Hom.range (Embedding.toHom e)
out : Quotient (DirectLimit.setoid G f) → Structure.Sigma f := Quotient.out
i : ι
hi : ∀ (i_1 : ι), i_1 ∈ Finset.image (Sigma.fst ∘ out) s → i_1 ≤ i
e' : { x // x ∈ Hom.range (Embedding.toHom (DirectLimit.of L ι G f i)) } ↪[L] G i
x : DirectLimit G f
hx : x ∈ ↑s
⊢ (Structure.Sigma.mk f i (↑(f (out x).fst i (_ : (out x).fst ≤ i)) (out x).snd)).fst ≤ i
[PROOFSTEP]
rfl
[GOAL]
case h.mpr
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
⊢ (∃ i, M ∈ age L (G i)) → M ∈ age L (DirectLimit G f)
[PROOFSTEP]
rintro ⟨i, Mfg, ⟨e⟩⟩
[GOAL]
case h.mpr.intro.intro.intro
L : Language
K : Set (Bundled (Structure L))
M✝ : Type w
inst✝⁶ : Structure L M✝
N : Type w
inst✝⁵ : Structure L N
ι : Type w
inst✝⁴ : Preorder ι
inst✝³ : IsDirected ι fun x x_1 => x ≤ x_1
inst✝² : Nonempty ι
G : ι → Type (max w w')
inst✝¹ : (i : ι) → Structure L (G i)
f : (i j : ι) → i ≤ j → G i ↪[L] G j
inst✝ : DirectedSystem G fun i j h => ↑(f i j h)
M : Bundled (Structure L)
i : ι
Mfg : Structure.FG L ↑M
e : ↑M ↪[L] G i
⊢ M ∈ age L (DirectLimit G f)
[PROOFSTEP]
exact ⟨Mfg, ⟨Embedding.comp (DirectLimit.of L ι G f i) e⟩⟩
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
⊢ ∃ M, Structure.CG L ↑M ∧ age L ↑M = K
[PROOFSTEP]
obtain ⟨F, hF⟩ := hc.exists_eq_range (hn.image _)
[GOAL]
case intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : Quotient.mk' '' K = range F
⊢ ∃ M, Structure.CG L ↑M ∧ age L ↑M = K
[PROOFSTEP]
simp only [Set.ext_iff, forall_quotient_iff, mem_image, mem_range, Quotient.eq'] at hF
[GOAL]
case intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF :
  ∀ (a : Bundled (Structure L)),
    (∃ x, x ∈ K ∧ Quotient.mk' x = Quotient.mk equivSetoid a) ↔ ∃ y, F y = Quotient.mk equivSetoid a
⊢ ∃ M, Structure.CG L ↑M ∧ age L ↑M = K
[PROOFSTEP]
simp_rw [Quotient.eq_mk_iff_out] at hF
[GOAL]
case intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
⊢ ∃ M, Structure.CG L ↑M ∧ age L ↑M = K
[PROOFSTEP]
have hF' : ∀ n : ℕ, (F n).out ∈ K := by
  intro n
  obtain ⟨P, hP1, hP2⟩ :=
    (hF (F n).out).2
      ⟨n, Setoid.refl _⟩
        -- Porting note: fix hP2 because `Quotient.out (Quotient.mk' x) ≈ a` was not simplified
            -- to `x ≈ a` in hF
  replace hP2 := Setoid.trans (Setoid.symm (Quotient.mk_out P)) hP2
  exact (h _ _ hP2).1 hP1
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
⊢ ∀ (n : ℕ), Quotient.out (F n) ∈ K
[PROOFSTEP]
intro n
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
n : ℕ
⊢ Quotient.out (F n) ∈ K
[PROOFSTEP]
obtain ⟨P, hP1, hP2⟩ :=
  (hF (F n).out).2
    ⟨n, Setoid.refl _⟩
      -- Porting note: fix hP2 because `Quotient.out (Quotient.mk' x) ≈ a` was not simplified
          -- to `x ≈ a` in hF
[GOAL]
case intro.intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
n : ℕ
P : Bundled (Structure L)
hP1 : P ∈ K
hP2 : Quotient.out (Quotient.mk' P) ≈ Quotient.out (F n)
⊢ Quotient.out (F n) ∈ K
[PROOFSTEP]
replace hP2 := Setoid.trans (Setoid.symm (Quotient.mk_out P)) hP2
[GOAL]
case intro.intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
n : ℕ
P : Bundled (Structure L)
hP1 : P ∈ K
hP2 : P ≈ Quotient.out (F n)
⊢ Quotient.out (F n) ∈ K
[PROOFSTEP]
exact (h _ _ hP2).1 hP1
[GOAL]
case intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
⊢ ∃ M, Structure.CG L ↑M ∧ age L ↑M = K
[PROOFSTEP]
choose P hPK hP hFP using fun (N : K) (n : ℕ) => jep N N.2 (F (n + 1)).out (hF' _)
[GOAL]
case intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
⊢ ∃ M, Structure.CG L ↑M ∧ age L ↑M = K
[PROOFSTEP]
let G : ℕ → K :=
  @Nat.rec (fun _ => K) ⟨(F 0).out, hF' 0⟩ fun n N =>
    ⟨P N n, hPK N n⟩
      -- Poting note: was
        -- let f : ∀ i j, i ≤ j → G i ↪[L] G j := DirectedSystem.natLeRec fun n => (hP _ n).some
[GOAL]
case intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
⊢ ∃ M, Structure.CG L ↑M ∧ age L ↑M = K
[PROOFSTEP]
let f : ∀ (i j : ℕ), i ≤ j → (G i).val ↪[L] (G j).val :=
  by
  refine DirectedSystem.natLERec (G' := fun i => (G i).val) (L := L) ?_
  dsimp only
  exact (fun n => (hP _ n).some)
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
⊢ (i j : ℕ) → i ≤ j → ↑↑(G i) ↪[L] ↑↑(G j)
[PROOFSTEP]
refine DirectedSystem.natLERec (G' := fun i => (G i).val) (L := L) ?_
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
⊢ (n : ℕ) → (fun i => ↑↑(G i)) n ↪[L] (fun i => ↑↑(G i)) (n + 1)
[PROOFSTEP]
dsimp only
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
⊢ (n : ℕ) →
    ↑↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
            (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n) ↪[L]
      ↑↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
            (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) (n + 1))
[PROOFSTEP]
exact (fun n => (hP _ n).some)
[GOAL]
case intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
f : (i j : ℕ) → i ≤ j → ↑↑(G i) ↪[L] ↑↑(G j) :=
  DirectedSystem.natLERec
    (id fun n =>
      Nonempty.some
        (_ :
          (fun M N => Nonempty (↑M ↪[L] ↑N))
            (↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
            (P
              (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
              n)))
⊢ ∃ M, Structure.CG L ↑M ∧ age L ↑M = K
[PROOFSTEP]
have : DirectedSystem (fun n ↦ (G n).val) fun i j h ↦ ↑(f i j h) := by dsimp; infer_instance
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
f : (i j : ℕ) → i ≤ j → ↑↑(G i) ↪[L] ↑↑(G j) :=
  DirectedSystem.natLERec
    (id fun n =>
      Nonempty.some
        (_ :
          (fun M N => Nonempty (↑M ↪[L] ↑N))
            (↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
            (P
              (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
              n)))
⊢ DirectedSystem (fun n => ↑↑(G n)) fun i j h => ↑(f i j h)
[PROOFSTEP]
dsimp
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
f : (i j : ℕ) → i ≤ j → ↑↑(G i) ↪[L] ↑↑(G j) :=
  DirectedSystem.natLERec
    (id fun n =>
      Nonempty.some
        (_ :
          (fun M N => Nonempty (↑M ↪[L] ↑N))
            (↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
            (P
              (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
              n)))
⊢ DirectedSystem
    (fun n =>
      ↑↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
            (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
    fun i j h =>
    ↑(DirectedSystem.natLERec
        (fun n =>
          Nonempty.some
            (_ :
              (fun M N => Nonempty (↑M ↪[L] ↑N))
                (↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                    (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
                (P
                  (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                    (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
                  n)))
        i j h)
[PROOFSTEP]
infer_instance
[GOAL]
case intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
f : (i j : ℕ) → i ≤ j → ↑↑(G i) ↪[L] ↑↑(G j) :=
  DirectedSystem.natLERec
    (id fun n =>
      Nonempty.some
        (_ :
          (fun M N => Nonempty (↑M ↪[L] ↑N))
            (↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
            (P
              (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
              n)))
this : DirectedSystem (fun n => ↑↑(G n)) fun i j h => ↑(f i j h)
⊢ ∃ M, Structure.CG L ↑M ∧ age L ↑M = K
[PROOFSTEP]
refine ⟨Bundled.of (@DirectLimit L _ _ (fun n ↦ (G n).val) _ f _ _), ?_, ?_⟩
[GOAL]
case intro.refine_1
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
f : (i j : ℕ) → i ≤ j → ↑↑(G i) ↪[L] ↑↑(G j) :=
  DirectedSystem.natLERec
    (id fun n =>
      Nonempty.some
        (_ :
          (fun M N => Nonempty (↑M ↪[L] ↑N))
            (↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
            (P
              (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
              n)))
this : DirectedSystem (fun n => ↑↑(G n)) fun i j h => ↑(f i j h)
⊢ Structure.CG L ↑(Bundled.of (DirectLimit (fun n => ↑↑(G n)) f))
[PROOFSTEP]
exact DirectLimit.cg _ (fun n => (fg _ (G n).2).cg)
[GOAL]
case intro.refine_2
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
f : (i j : ℕ) → i ≤ j → ↑↑(G i) ↪[L] ↑↑(G j) :=
  DirectedSystem.natLERec
    (id fun n =>
      Nonempty.some
        (_ :
          (fun M N => Nonempty (↑M ↪[L] ↑N))
            (↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
            (P
              (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
              n)))
this : DirectedSystem (fun n => ↑↑(G n)) fun i j h => ↑(f i j h)
⊢ age L ↑(Bundled.of (DirectLimit (fun n => ↑↑(G n)) f)) = K
[PROOFSTEP]
refine
  (age_directLimit (fun n ↦ (G n).val) f).trans
    (subset_antisymm (iUnion_subset fun n N hN => hp (G n).val (G n).2 hN) fun N KN => ?_)
[GOAL]
case intro.refine_2
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
f : (i j : ℕ) → i ≤ j → ↑↑(G i) ↪[L] ↑↑(G j) :=
  DirectedSystem.natLERec
    (id fun n =>
      Nonempty.some
        (_ :
          (fun M N => Nonempty (↑M ↪[L] ↑N))
            (↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
            (P
              (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
              n)))
this : DirectedSystem (fun n => ↑↑(G n)) fun i j h => ↑(f i j h)
N : Bundled (Structure L)
KN : N ∈ K
⊢ N ∈ ⋃ (i : ℕ), age L ↑↑(G i)
[PROOFSTEP]
have : Quotient.out (Quotient.mk' N) ≈ N := Quotient.eq_mk_iff_out.mp rfl
[GOAL]
case intro.refine_2
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
f : (i j : ℕ) → i ≤ j → ↑↑(G i) ↪[L] ↑↑(G j) :=
  DirectedSystem.natLERec
    (id fun n =>
      Nonempty.some
        (_ :
          (fun M N => Nonempty (↑M ↪[L] ↑N))
            (↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
            (P
              (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
              n)))
this✝ : DirectedSystem (fun n => ↑↑(G n)) fun i j h => ↑(f i j h)
N : Bundled (Structure L)
KN : N ∈ K
this : Quotient.out (Quotient.mk' N) ≈ N
⊢ N ∈ ⋃ (i : ℕ), age L ↑↑(G i)
[PROOFSTEP]
obtain ⟨n, ⟨e⟩⟩ := (hF N).1 ⟨N, KN, this⟩
[GOAL]
case intro.refine_2.intro.intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
f : (i j : ℕ) → i ≤ j → ↑↑(G i) ↪[L] ↑↑(G j) :=
  DirectedSystem.natLERec
    (id fun n =>
      Nonempty.some
        (_ :
          (fun M N => Nonempty (↑M ↪[L] ↑N))
            (↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
            (P
              (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
              n)))
this✝ : DirectedSystem (fun n => ↑↑(G n)) fun i j h => ↑(f i j h)
N : Bundled (Structure L)
KN : N ∈ K
this : Quotient.out (Quotient.mk' N) ≈ N
n : ℕ
e : ↑(Quotient.out (F n)) ≃[L] ↑N
⊢ N ∈ ⋃ (i : ℕ), age L ↑↑(G i)
[PROOFSTEP]
refine mem_iUnion_of_mem n ⟨fg _ KN, ⟨Embedding.comp ?_ e.symm.toEmbedding⟩⟩
[GOAL]
case intro.refine_2.intro.intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
f : (i j : ℕ) → i ≤ j → ↑↑(G i) ↪[L] ↑↑(G j) :=
  DirectedSystem.natLERec
    (id fun n =>
      Nonempty.some
        (_ :
          (fun M N => Nonempty (↑M ↪[L] ↑N))
            (↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
            (P
              (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
              n)))
this✝ : DirectedSystem (fun n => ↑↑(G n)) fun i j h => ↑(f i j h)
N : Bundled (Structure L)
KN : N ∈ K
this : Quotient.out (Quotient.mk' N) ≈ N
n : ℕ
e : ↑(Quotient.out (F n)) ≃[L] ↑N
⊢ ↑(Quotient.out (F n)) ↪[L] ↑↑(G n)
[PROOFSTEP]
cases' n with n
[GOAL]
case intro.refine_2.intro.intro.zero
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
f : (i j : ℕ) → i ≤ j → ↑↑(G i) ↪[L] ↑↑(G j) :=
  DirectedSystem.natLERec
    (id fun n =>
      Nonempty.some
        (_ :
          (fun M N => Nonempty (↑M ↪[L] ↑N))
            (↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
            (P
              (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
              n)))
this✝ : DirectedSystem (fun n => ↑↑(G n)) fun i j h => ↑(f i j h)
N : Bundled (Structure L)
KN : N ∈ K
this : Quotient.out (Quotient.mk' N) ≈ N
e : ↑(Quotient.out (F Nat.zero)) ≃[L] ↑N
⊢ ↑(Quotient.out (F Nat.zero)) ↪[L] ↑↑(G Nat.zero)
[PROOFSTEP]
dsimp
[GOAL]
case intro.refine_2.intro.intro.zero
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
f : (i j : ℕ) → i ≤ j → ↑↑(G i) ↪[L] ↑↑(G j) :=
  DirectedSystem.natLERec
    (id fun n =>
      Nonempty.some
        (_ :
          (fun M N => Nonempty (↑M ↪[L] ↑N))
            (↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
            (P
              (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
              n)))
this✝ : DirectedSystem (fun n => ↑↑(G n)) fun i j h => ↑(f i j h)
N : Bundled (Structure L)
KN : N ∈ K
this : Quotient.out (Quotient.mk' N) ≈ N
e : ↑(Quotient.out (F Nat.zero)) ≃[L] ↑N
⊢ ↑(Quotient.out (F 0)) ↪[L] ↑(Quotient.out (F 0))
[PROOFSTEP]
exact Embedding.refl _ _
[GOAL]
case intro.refine_2.intro.intro.succ
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
f : (i j : ℕ) → i ≤ j → ↑↑(G i) ↪[L] ↑↑(G j) :=
  DirectedSystem.natLERec
    (id fun n =>
      Nonempty.some
        (_ :
          (fun M N => Nonempty (↑M ↪[L] ↑N))
            (↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
            (P
              (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
              n)))
this✝ : DirectedSystem (fun n => ↑↑(G n)) fun i j h => ↑(f i j h)
N : Bundled (Structure L)
KN : N ∈ K
this : Quotient.out (Quotient.mk' N) ≈ N
n : ℕ
e : ↑(Quotient.out (F (Nat.succ n))) ≃[L] ↑N
⊢ ↑(Quotient.out (F (Nat.succ n))) ↪[L] ↑↑(G (Nat.succ n))
[PROOFSTEP]
dsimp
[GOAL]
case intro.refine_2.intro.intro.succ
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
hn : Set.Nonempty K
h : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
hc : Set.Countable (Quotient.mk' '' K)
fg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
F : ℕ → Quotient equivSetoid
hF : ∀ (a : Bundled (Structure L)), (∃ x, x ∈ K ∧ Quotient.out (Quotient.mk' x) ≈ a) ↔ ∃ y, Quotient.out (F y) ≈ a
hF' : ∀ (n : ℕ), Quotient.out (F n) ∈ K
P : ↑K → ℕ → Bundled (Structure L)
hPK : ∀ (N : ↑K) (n : ℕ), P N n ∈ K
hP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (↑N) (P N n)
hFP : ∀ (N : ↑K) (n : ℕ), (fun M N => Nonempty (↑M ↪[L] ↑N)) (Quotient.out (F (n + 1))) (P N n)
G : ℕ → ↑K :=
  Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) } fun n N =>
    { val := P N n, property := (_ : P N n ∈ K) }
f : (i j : ℕ) → i ≤ j → ↑↑(G i) ↪[L] ↑↑(G j) :=
  DirectedSystem.natLERec
    (id fun n =>
      Nonempty.some
        (_ :
          (fun M N => Nonempty (↑M ↪[L] ↑N))
            (↑(Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n))
            (P
              (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
                (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
              n)))
this✝ : DirectedSystem (fun n => ↑↑(G n)) fun i j h => ↑(f i j h)
N : Bundled (Structure L)
KN : N ∈ K
this : Quotient.out (Quotient.mk' N) ≈ N
n : ℕ
e : ↑(Quotient.out (F (Nat.succ n))) ≃[L] ↑N
⊢ ↑(Quotient.out (F (Nat.succ n))) ↪[L]
    ↑(P
        (Nat.rec { val := Quotient.out (F 0), property := (_ : Quotient.out (F 0) ∈ K) }
          (fun n N => { val := P N n, property := (_ : P N n ∈ K) }) n)
        n)
[PROOFSTEP]
exact (hFP _ n).some
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝² : Structure L M
N : Type w
inst✝¹ : Structure L N
inst✝ : Countable ((l : ℕ) × Functions L l)
⊢ (∃ M, Countable ↑M ∧ age L ↑M = K) ↔
    Set.Nonempty K ∧
      (∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)) ∧
        Set.Countable (Quotient.mk' '' K) ∧
          (∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M) ∧ Hereditary K ∧ JointEmbedding K
[PROOFSTEP]
constructor
[GOAL]
case mp
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝² : Structure L M
N : Type w
inst✝¹ : Structure L N
inst✝ : Countable ((l : ℕ) × Functions L l)
⊢ (∃ M, Countable ↑M ∧ age L ↑M = K) →
    Set.Nonempty K ∧
      (∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)) ∧
        Set.Countable (Quotient.mk' '' K) ∧
          (∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M) ∧ Hereditary K ∧ JointEmbedding K
[PROOFSTEP]
rintro ⟨M, h1, h2, rfl⟩
[GOAL]
case mp.intro.intro.refl
L : Language
M✝ : Type w
inst✝² : Structure L M✝
N : Type w
inst✝¹ : Structure L N
inst✝ : Countable ((l : ℕ) × Functions L l)
M : Bundled (Structure L)
h1 : Countable ↑M
⊢ Set.Nonempty (age L ↑M) ∧
    (∀ (M_1 N : Bundled (Structure L)), Nonempty (↑M_1 ≃[L] ↑N) → (M_1 ∈ age L ↑M ↔ N ∈ age L ↑M)) ∧
      Set.Countable (Quotient.mk' '' age L ↑M) ∧
        (∀ (M_1 : Bundled (Structure L)), M_1 ∈ age L ↑M → Structure.FG L ↑M_1) ∧
          Hereditary (age L ↑M) ∧ JointEmbedding (age L ↑M)
[PROOFSTEP]
refine'
  ⟨age.nonempty M, age.is_equiv_invariant L M, age.countable_quotient M, fun N hN => hN.1, age.hereditary M,
    age.jointEmbedding M⟩
[GOAL]
case mpr
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝² : Structure L M
N : Type w
inst✝¹ : Structure L N
inst✝ : Countable ((l : ℕ) × Functions L l)
⊢ Set.Nonempty K ∧
      (∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)) ∧
        Set.Countable (Quotient.mk' '' K) ∧
          (∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M) ∧ Hereditary K ∧ JointEmbedding K →
    ∃ M, Countable ↑M ∧ age L ↑M = K
[PROOFSTEP]
rintro ⟨Kn, eqinv, cq, hfg, hp, jep⟩
[GOAL]
case mpr.intro.intro.intro.intro.intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝² : Structure L M
N : Type w
inst✝¹ : Structure L N
inst✝ : Countable ((l : ℕ) × Functions L l)
Kn : Set.Nonempty K
eqinv : ∀ (M N : Bundled (Structure L)), Nonempty (↑M ≃[L] ↑N) → (M ∈ K ↔ N ∈ K)
cq : Set.Countable (Quotient.mk' '' K)
hfg : ∀ (M : Bundled (Structure L)), M ∈ K → Structure.FG L ↑M
hp : Hereditary K
jep : JointEmbedding K
⊢ ∃ M, Countable ↑M ∧ age L ↑M = K
[PROOFSTEP]
obtain ⟨M, hM, rfl⟩ := exists_cg_is_age_of Kn eqinv cq hfg hp jep
[GOAL]
case mpr.intro.intro.intro.intro.intro.intro.intro
L : Language
M✝ : Type w
inst✝² : Structure L M✝
N : Type w
inst✝¹ : Structure L N
inst✝ : Countable ((l : ℕ) × Functions L l)
M : Bundled (Structure L)
hM : Structure.CG L ↑M
Kn : Set.Nonempty (age L ↑M)
eqinv : ∀ (M_1 N : Bundled (Structure L)), Nonempty (↑M_1 ≃[L] ↑N) → (M_1 ∈ age L ↑M ↔ N ∈ age L ↑M)
cq : Set.Countable (Quotient.mk' '' age L ↑M)
hfg : ∀ (M_1 : Bundled (Structure L)), M_1 ∈ age L ↑M → Structure.FG L ↑M_1
hp : Hereditary (age L ↑M)
jep : JointEmbedding (age L ↑M)
⊢ ∃ M_1, Countable ↑M_1 ∧ age L ↑M_1 = age L ↑M
[PROOFSTEP]
exact ⟨M, Structure.cg_iff_countable.1 hM, rfl⟩
[GOAL]
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N : Type w
inst✝ : Structure L N
h : IsUltrahomogeneous L M
⊢ Amalgamation (age L M)
[PROOFSTEP]
rintro N P Q NP NQ ⟨Nfg, ⟨-⟩⟩ ⟨Pfg, ⟨PM⟩⟩ ⟨Qfg, ⟨QM⟩⟩
[GOAL]
case intro.intro.intro.intro.intro.intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : IsUltrahomogeneous L M
N P Q : Bundled (Structure L)
NP : ↑N ↪[L] ↑P
NQ : ↑N ↪[L] ↑Q
Nfg : Structure.FG L ↑N
Pfg : Structure.FG L ↑P
PM : ↑P ↪[L] M
Qfg : Structure.FG L ↑Q
QM : ↑Q ↪[L] M
⊢ ∃ Q_1 NQ_1 PQ, Q_1 ∈ age L M ∧ Embedding.comp NQ_1 NP = Embedding.comp PQ NQ
[PROOFSTEP]
obtain ⟨g, hg⟩ := h (PM.comp NP).toHom.range (Nfg.range _) ((QM.comp NQ).comp (PM.comp NP).equivRange.symm.toEmbedding)
[GOAL]
case intro.intro.intro.intro.intro.intro.intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : IsUltrahomogeneous L M
N P Q : Bundled (Structure L)
NP : ↑N ↪[L] ↑P
NQ : ↑N ↪[L] ↑Q
Nfg : Structure.FG L ↑N
Pfg : Structure.FG L ↑P
PM : ↑P ↪[L] M
Qfg : Structure.FG L ↑Q
QM : ↑Q ↪[L] M
g : M ≃[L] M
hg :
  Embedding.comp (Embedding.comp QM NQ) (Equiv.toEmbedding (Equiv.symm (Embedding.equivRange (Embedding.comp PM NP)))) =
    Embedding.comp (Equiv.toEmbedding g) (subtype (Hom.range (Embedding.toHom (Embedding.comp PM NP))))
⊢ ∃ Q_1 NQ_1 PQ, Q_1 ∈ age L M ∧ Embedding.comp NQ_1 NP = Embedding.comp PQ NQ
[PROOFSTEP]
let s := (g.toHom.comp PM.toHom).range ⊔ QM.toHom.range
[GOAL]
case intro.intro.intro.intro.intro.intro.intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : IsUltrahomogeneous L M
N P Q : Bundled (Structure L)
NP : ↑N ↪[L] ↑P
NQ : ↑N ↪[L] ↑Q
Nfg : Structure.FG L ↑N
Pfg : Structure.FG L ↑P
PM : ↑P ↪[L] M
Qfg : Structure.FG L ↑Q
QM : ↑Q ↪[L] M
g : M ≃[L] M
hg :
  Embedding.comp (Embedding.comp QM NQ) (Equiv.toEmbedding (Equiv.symm (Embedding.equivRange (Embedding.comp PM NP)))) =
    Embedding.comp (Equiv.toEmbedding g) (subtype (Hom.range (Embedding.toHom (Embedding.comp PM NP))))
s : Substructure L M := Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)
⊢ ∃ Q_1 NQ_1 PQ, Q_1 ∈ age L M ∧ Embedding.comp NQ_1 NP = Embedding.comp PQ NQ
[PROOFSTEP]
refine'
  ⟨Bundled.of s, Embedding.comp (Substructure.inclusion le_sup_left) (g.toEmbedding.comp PM).equivRange.toEmbedding,
    Embedding.comp (Substructure.inclusion le_sup_right) QM.equivRange.toEmbedding,
    ⟨(fg_iff_structure_fg _).1 (FG.sup (Pfg.range _) (Qfg.range _)), ⟨Substructure.subtype _⟩⟩, _⟩
[GOAL]
case intro.intro.intro.intro.intro.intro.intro
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : IsUltrahomogeneous L M
N P Q : Bundled (Structure L)
NP : ↑N ↪[L] ↑P
NQ : ↑N ↪[L] ↑Q
Nfg : Structure.FG L ↑N
Pfg : Structure.FG L ↑P
PM : ↑P ↪[L] M
Qfg : Structure.FG L ↑Q
QM : ↑Q ↪[L] M
g : M ≃[L] M
hg :
  Embedding.comp (Embedding.comp QM NQ) (Equiv.toEmbedding (Equiv.symm (Embedding.equivRange (Embedding.comp PM NP)))) =
    Embedding.comp (Equiv.toEmbedding g) (subtype (Hom.range (Embedding.toHom (Embedding.comp PM NP))))
s : Substructure L M := Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)
⊢ Embedding.comp
      (Embedding.comp
        (Substructure.inclusion
          (_ :
            Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ≤
              Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)))
        (Equiv.toEmbedding (Embedding.equivRange (Embedding.comp (Equiv.toEmbedding g) PM))))
      NP =
    Embedding.comp
      (Embedding.comp
        (Substructure.inclusion
          (_ :
            Hom.range (Embedding.toHom QM) ≤
              Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)))
        (Equiv.toEmbedding (Embedding.equivRange QM)))
      NQ
[PROOFSTEP]
ext n
[GOAL]
case intro.intro.intro.intro.intro.intro.intro.h
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : IsUltrahomogeneous L M
N P Q : Bundled (Structure L)
NP : ↑N ↪[L] ↑P
NQ : ↑N ↪[L] ↑Q
Nfg : Structure.FG L ↑N
Pfg : Structure.FG L ↑P
PM : ↑P ↪[L] M
Qfg : Structure.FG L ↑Q
QM : ↑Q ↪[L] M
g : M ≃[L] M
hg :
  Embedding.comp (Embedding.comp QM NQ) (Equiv.toEmbedding (Equiv.symm (Embedding.equivRange (Embedding.comp PM NP)))) =
    Embedding.comp (Equiv.toEmbedding g) (subtype (Hom.range (Embedding.toHom (Embedding.comp PM NP))))
s : Substructure L M := Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)
n : ↑N
⊢ ↑(Embedding.comp
          (Embedding.comp
            (Substructure.inclusion
              (_ :
                Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ≤
                  Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)))
            (Equiv.toEmbedding (Embedding.equivRange (Embedding.comp (Equiv.toEmbedding g) PM))))
          NP)
      n =
    ↑(Embedding.comp
          (Embedding.comp
            (Substructure.inclusion
              (_ :
                Hom.range (Embedding.toHom QM) ≤
                  Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)))
            (Equiv.toEmbedding (Embedding.equivRange QM)))
          NQ)
      n
[PROOFSTEP]
apply Subtype.ext
[GOAL]
case intro.intro.intro.intro.intro.intro.intro.h.a
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : IsUltrahomogeneous L M
N P Q : Bundled (Structure L)
NP : ↑N ↪[L] ↑P
NQ : ↑N ↪[L] ↑Q
Nfg : Structure.FG L ↑N
Pfg : Structure.FG L ↑P
PM : ↑P ↪[L] M
Qfg : Structure.FG L ↑Q
QM : ↑Q ↪[L] M
g : M ≃[L] M
hg :
  Embedding.comp (Embedding.comp QM NQ) (Equiv.toEmbedding (Equiv.symm (Embedding.equivRange (Embedding.comp PM NP)))) =
    Embedding.comp (Equiv.toEmbedding g) (subtype (Hom.range (Embedding.toHom (Embedding.comp PM NP))))
s : Substructure L M := Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)
n : ↑N
⊢ ↑(↑(Embedding.comp
            (Embedding.comp
              (Substructure.inclusion
                (_ :
                  Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ≤
                    Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)))
              (Equiv.toEmbedding (Embedding.equivRange (Embedding.comp (Equiv.toEmbedding g) PM))))
            NP)
        n) =
    ↑(↑(Embedding.comp
            (Embedding.comp
              (Substructure.inclusion
                (_ :
                  Hom.range (Embedding.toHom QM) ≤
                    Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)))
              (Equiv.toEmbedding (Embedding.equivRange QM)))
            NQ)
        n)
[PROOFSTEP]
have hgn := (Embedding.ext_iff.1 hg) ((PM.comp NP).equivRange n)
[GOAL]
case intro.intro.intro.intro.intro.intro.intro.h.a
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : IsUltrahomogeneous L M
N P Q : Bundled (Structure L)
NP : ↑N ↪[L] ↑P
NQ : ↑N ↪[L] ↑Q
Nfg : Structure.FG L ↑N
Pfg : Structure.FG L ↑P
PM : ↑P ↪[L] M
Qfg : Structure.FG L ↑Q
QM : ↑Q ↪[L] M
g : M ≃[L] M
hg :
  Embedding.comp (Embedding.comp QM NQ) (Equiv.toEmbedding (Equiv.symm (Embedding.equivRange (Embedding.comp PM NP)))) =
    Embedding.comp (Equiv.toEmbedding g) (subtype (Hom.range (Embedding.toHom (Embedding.comp PM NP))))
s : Substructure L M := Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)
n : ↑N
hgn :
  ↑(Embedding.comp (Embedding.comp QM NQ)
          (Equiv.toEmbedding (Equiv.symm (Embedding.equivRange (Embedding.comp PM NP)))))
      (↑(Embedding.equivRange (Embedding.comp PM NP)) n) =
    ↑(Embedding.comp (Equiv.toEmbedding g) (subtype (Hom.range (Embedding.toHom (Embedding.comp PM NP)))))
      (↑(Embedding.equivRange (Embedding.comp PM NP)) n)
⊢ ↑(↑(Embedding.comp
            (Embedding.comp
              (Substructure.inclusion
                (_ :
                  Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ≤
                    Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)))
              (Equiv.toEmbedding (Embedding.equivRange (Embedding.comp (Equiv.toEmbedding g) PM))))
            NP)
        n) =
    ↑(↑(Embedding.comp
            (Embedding.comp
              (Substructure.inclusion
                (_ :
                  Hom.range (Embedding.toHom QM) ≤
                    Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)))
              (Equiv.toEmbedding (Embedding.equivRange QM)))
            NQ)
        n)
[PROOFSTEP]
simp only [Embedding.comp_apply, Equiv.coe_toEmbedding, Equiv.symm_apply_apply, Substructure.coeSubtype,
  Embedding.equivRange_apply] at hgn
[GOAL]
case intro.intro.intro.intro.intro.intro.intro.h.a
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : IsUltrahomogeneous L M
N P Q : Bundled (Structure L)
NP : ↑N ↪[L] ↑P
NQ : ↑N ↪[L] ↑Q
Nfg : Structure.FG L ↑N
Pfg : Structure.FG L ↑P
PM : ↑P ↪[L] M
Qfg : Structure.FG L ↑Q
QM : ↑Q ↪[L] M
g : M ≃[L] M
hg :
  Embedding.comp (Embedding.comp QM NQ) (Equiv.toEmbedding (Equiv.symm (Embedding.equivRange (Embedding.comp PM NP)))) =
    Embedding.comp (Equiv.toEmbedding g) (subtype (Hom.range (Embedding.toHom (Embedding.comp PM NP))))
s : Substructure L M := Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)
n : ↑N
hgn : ↑QM (↑NQ n) = ↑g (↑PM (↑NP n))
⊢ ↑(↑(Embedding.comp
            (Embedding.comp
              (Substructure.inclusion
                (_ :
                  Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ≤
                    Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)))
              (Equiv.toEmbedding (Embedding.equivRange (Embedding.comp (Equiv.toEmbedding g) PM))))
            NP)
        n) =
    ↑(↑(Embedding.comp
            (Embedding.comp
              (Substructure.inclusion
                (_ :
                  Hom.range (Embedding.toHom QM) ≤
                    Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)))
              (Equiv.toEmbedding (Embedding.equivRange QM)))
            NQ)
        n)
[PROOFSTEP]
simp only [Embedding.comp_apply, Equiv.coe_toEmbedding]
[GOAL]
case intro.intro.intro.intro.intro.intro.intro.h.a
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : IsUltrahomogeneous L M
N P Q : Bundled (Structure L)
NP : ↑N ↪[L] ↑P
NQ : ↑N ↪[L] ↑Q
Nfg : Structure.FG L ↑N
Pfg : Structure.FG L ↑P
PM : ↑P ↪[L] M
Qfg : Structure.FG L ↑Q
QM : ↑Q ↪[L] M
g : M ≃[L] M
hg :
  Embedding.comp (Embedding.comp QM NQ) (Equiv.toEmbedding (Equiv.symm (Embedding.equivRange (Embedding.comp PM NP)))) =
    Embedding.comp (Equiv.toEmbedding g) (subtype (Hom.range (Embedding.toHom (Embedding.comp PM NP))))
s : Substructure L M := Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)
n : ↑N
hgn : ↑QM (↑NQ n) = ↑g (↑PM (↑NP n))
⊢ ↑(↑(Substructure.inclusion
            (_ :
              Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ≤
                Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)))
        (↑(Embedding.equivRange (Embedding.comp (Equiv.toEmbedding g) PM)) (↑NP n))) =
    ↑(↑(Substructure.inclusion
            (_ :
              Hom.range (Embedding.toHom QM) ≤
                Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)))
        (↑(Embedding.equivRange QM) (↑NQ n)))
[PROOFSTEP]
erw [Substructure.coe_inclusion, Substructure.coe_inclusion]
[GOAL]
case intro.intro.intro.intro.intro.intro.intro.h.a
L : Language
K : Set (Bundled (Structure L))
M : Type w
inst✝¹ : Structure L M
N✝ : Type w
inst✝ : Structure L N✝
h : IsUltrahomogeneous L M
N P Q : Bundled (Structure L)
NP : ↑N ↪[L] ↑P
NQ : ↑N ↪[L] ↑Q
Nfg : Structure.FG L ↑N
Pfg : Structure.FG L ↑P
PM : ↑P ↪[L] M
Qfg : Structure.FG L ↑Q
QM : ↑Q ↪[L] M
g : M ≃[L] M
hg :
  Embedding.comp (Embedding.comp QM NQ) (Equiv.toEmbedding (Equiv.symm (Embedding.equivRange (Embedding.comp PM NP)))) =
    Embedding.comp (Equiv.toEmbedding g) (subtype (Hom.range (Embedding.toHom (Embedding.comp PM NP))))
s : Substructure L M := Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM)
n : ↑N
hgn : ↑QM (↑NQ n) = ↑g (↑PM (↑NP n))
⊢ ↑(Set.inclusion
        (_ :
          Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ≤
            Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM))
        (↑(Embedding.equivRange (Embedding.comp (Equiv.toEmbedding g) PM)) (↑NP n))) =
    ↑(Set.inclusion
        (_ :
          Hom.range (Embedding.toHom QM) ≤
            Hom.range (Hom.comp (Equiv.toHom g) (Embedding.toHom PM)) ⊔ Hom.range (Embedding.toHom QM))
        (↑(Embedding.equivRange QM) (↑NQ n)))
[PROOFSTEP]
simp only [Embedding.comp_apply, Equiv.coe_toEmbedding, Set.coe_inclusion, Embedding.equivRange_apply, hgn]