[GOAL]
ι : Type u_1
α : ι → Type u
U : (i : ι) → UniformSpace (α i)
β : Type u_2
inst✝ : UniformSpace β
f : β → (i : ι) → α i
⊢ UniformContinuous f ↔ ∀ (i : ι), UniformContinuous fun x => f x i
[PROOFSTEP]
simp only [UniformContinuous, Pi.uniformity, tendsto_iInf, tendsto_comap_iff, Function.comp]
[GOAL]
ι : Type u_1
α : ι → Type u
U : (i : ι) → UniformSpace (α i)
inst✝ : ∀ (i : ι), CompleteSpace (α i)
⊢ ∀ {f : Filter ((i : ι) → α i)}, Cauchy f → ∃ x, f ≤ 𝓝 x
[PROOFSTEP]
intro f hf
[GOAL]
ι : Type u_1
α : ι → Type u
U : (i : ι) → UniformSpace (α i)
inst✝ : ∀ (i : ι), CompleteSpace (α i)
f : Filter ((i : ι) → α i)
hf : Cauchy f
⊢ ∃ x, f ≤ 𝓝 x
[PROOFSTEP]
haveI := hf.1
[GOAL]
ι : Type u_1
α : ι → Type u
U : (i : ι) → UniformSpace (α i)
inst✝ : ∀ (i : ι), CompleteSpace (α i)
f : Filter ((i : ι) → α i)
hf : Cauchy f
this : NeBot f
⊢ ∃ x, f ≤ 𝓝 x
[PROOFSTEP]
have : ∀ i, ∃ x : α i, Filter.map (fun a : ∀ i, α i => a i) f ≤ 𝓝 x :=
  by
  intro i
  have key : Cauchy (map (fun a : ∀ i : ι, α i => a i) f) := hf.map (Pi.uniformContinuous_proj α i)
  exact cauchy_iff_exists_le_nhds.1 key
[GOAL]
ι : Type u_1
α : ι → Type u
U : (i : ι) → UniformSpace (α i)
inst✝ : ∀ (i : ι), CompleteSpace (α i)
f : Filter ((i : ι) → α i)
hf : Cauchy f
this : NeBot f
⊢ ∀ (i : ι), ∃ x, map (fun a => a i) f ≤ 𝓝 x
[PROOFSTEP]
intro i
[GOAL]
ι : Type u_1
α : ι → Type u
U : (i : ι) → UniformSpace (α i)
inst✝ : ∀ (i : ι), CompleteSpace (α i)
f : Filter ((i : ι) → α i)
hf : Cauchy f
this : NeBot f
i : ι
⊢ ∃ x, map (fun a => a i) f ≤ 𝓝 x
[PROOFSTEP]
have key : Cauchy (map (fun a : ∀ i : ι, α i => a i) f) := hf.map (Pi.uniformContinuous_proj α i)
[GOAL]
ι : Type u_1
α : ι → Type u
U : (i : ι) → UniformSpace (α i)
inst✝ : ∀ (i : ι), CompleteSpace (α i)
f : Filter ((i : ι) → α i)
hf : Cauchy f
this : NeBot f
i : ι
key : Cauchy (map (fun a => a i) f)
⊢ ∃ x, map (fun a => a i) f ≤ 𝓝 x
[PROOFSTEP]
exact cauchy_iff_exists_le_nhds.1 key
[GOAL]
ι : Type u_1
α : ι → Type u
U : (i : ι) → UniformSpace (α i)
inst✝ : ∀ (i : ι), CompleteSpace (α i)
f : Filter ((i : ι) → α i)
hf : Cauchy f
this✝ : NeBot f
this : ∀ (i : ι), ∃ x, map (fun a => a i) f ≤ 𝓝 x
⊢ ∃ x, f ≤ 𝓝 x
[PROOFSTEP]
choose x hx using this
[GOAL]
ι : Type u_1
α : ι → Type u
U : (i : ι) → UniformSpace (α i)
inst✝ : ∀ (i : ι), CompleteSpace (α i)
f : Filter ((i : ι) → α i)
hf : Cauchy f
this : NeBot f
x : (i : ι) → α i
hx : ∀ (i : ι), map (fun a => a i) f ≤ 𝓝 (x i)
⊢ ∃ x, f ≤ 𝓝 x
[PROOFSTEP]
use x
[GOAL]
case h
ι : Type u_1
α : ι → Type u
U : (i : ι) → UniformSpace (α i)
inst✝ : ∀ (i : ι), CompleteSpace (α i)
f : Filter ((i : ι) → α i)
hf : Cauchy f
this : NeBot f
x : (i : ι) → α i
hx : ∀ (i : ι), map (fun a => a i) f ≤ 𝓝 (x i)
⊢ f ≤ 𝓝 x
[PROOFSTEP]
rwa [nhds_pi, le_pi]
[GOAL]
ι : Type u_1
α : ι → Type u
U : (i : ι) → UniformSpace (α i)
inst✝ : ∀ (i : ι), SeparatedSpace (α i)
x y : (i : ι) → α i
H : ∀ (r : Set (((i : ι) → α i) × ((i : ι) → α i))), r ∈ 𝓤 ((i : ι) → α i) → (x, y) ∈ r
⊢ x = y
[PROOFSTEP]
ext i
[GOAL]
case h
ι : Type u_1
α : ι → Type u
U : (i : ι) → UniformSpace (α i)
inst✝ : ∀ (i : ι), SeparatedSpace (α i)
x y : (i : ι) → α i
H : ∀ (r : Set (((i : ι) → α i) × ((i : ι) → α i))), r ∈ 𝓤 ((i : ι) → α i) → (x, y) ∈ r
i : ι
⊢ x i = y i
[PROOFSTEP]
apply eq_of_separated_of_uniformContinuous (Pi.uniformContinuous_proj α i)
[GOAL]
case h
ι : Type u_1
α : ι → Type u
U : (i : ι) → UniformSpace (α i)
inst✝ : ∀ (i : ι), SeparatedSpace (α i)
x y : (i : ι) → α i
H : ∀ (r : Set (((i : ι) → α i) × ((i : ι) → α i))), r ∈ 𝓤 ((i : ι) → α i) → (x, y) ∈ r
i : ι
⊢ (fun i => x i) ≈ fun i => y i
[PROOFSTEP]
apply H


[GOAL]
F : Type u
K : Type v
A : Type w
inst✝¹⁰ : CommRing F
inst✝⁹ : Ring K
inst✝⁸ : AddCommGroup A
inst✝⁷ : Algebra F K
inst✝⁶ : Module K A
inst✝⁵ : Module F A
inst✝⁴ : IsScalarTower F K A
inst✝³ : StrongRankCondition F
inst✝² : StrongRankCondition K
inst✝¹ : Module.Free F K
inst✝ : Module.Free K A
⊢ lift (Module.rank F K) * lift (Module.rank K A) = lift (Module.rank F A)
[PROOFSTEP]
obtain ⟨_, b⟩ := Module.Free.exists_basis (R := F) (M := K)
[GOAL]
case intro.mk
F : Type u
K : Type v
A : Type w
inst✝¹⁰ : CommRing F
inst✝⁹ : Ring K
inst✝⁸ : AddCommGroup A
inst✝⁷ : Algebra F K
inst✝⁶ : Module K A
inst✝⁵ : Module F A
inst✝⁴ : IsScalarTower F K A
inst✝³ : StrongRankCondition F
inst✝² : StrongRankCondition K
inst✝¹ : Module.Free F K
inst✝ : Module.Free K A
fst✝ : Type v
b : Basis fst✝ F K
⊢ lift (Module.rank F K) * lift (Module.rank K A) = lift (Module.rank F A)
[PROOFSTEP]
obtain ⟨_, c⟩ := Module.Free.exists_basis (R := K) (M := A)
[GOAL]
case intro.mk.intro.mk
F : Type u
K : Type v
A : Type w
inst✝¹⁰ : CommRing F
inst✝⁹ : Ring K
inst✝⁸ : AddCommGroup A
inst✝⁷ : Algebra F K
inst✝⁶ : Module K A
inst✝⁵ : Module F A
inst✝⁴ : IsScalarTower F K A
inst✝³ : StrongRankCondition F
inst✝² : StrongRankCondition K
inst✝¹ : Module.Free F K
inst✝ : Module.Free K A
fst✝¹ : Type v
b : Basis fst✝¹ F K
fst✝ : Type w
c : Basis fst✝ K A
⊢ lift (Module.rank F K) * lift (Module.rank K A) = lift (Module.rank F A)
[PROOFSTEP]
rw [← (Module.rank F K).lift_id, ← b.mk_eq_rank, ← (Module.rank K A).lift_id, ← c.mk_eq_rank, ← lift_umax.{w, v}, ←
  (b.smul c).mk_eq_rank, mk_prod, lift_mul, lift_lift, lift_lift, lift_lift, lift_lift, lift_umax.{v, w}]
[GOAL]
F✝ : Type u
K✝ : Type v
A✝ : Type w
inst✝²¹ : CommRing F✝
inst✝²⁰ : Ring K✝
inst✝¹⁹ : AddCommGroup A✝
inst✝¹⁸ : Algebra F✝ K✝
inst✝¹⁷ : Module K✝ A✝
inst✝¹⁶ : Module F✝ A✝
inst✝¹⁵ : IsScalarTower F✝ K✝ A✝
inst✝¹⁴ : StrongRankCondition F✝
inst✝¹³ : StrongRankCondition K✝
inst✝¹² : Module.Free F✝ K✝
inst✝¹¹ : Module.Free K✝ A✝
F : Type u
K A : Type v
inst✝¹⁰ : CommRing F
inst✝⁹ : Ring K
inst✝⁸ : AddCommGroup A
inst✝⁷ : Algebra F K
inst✝⁶ : Module K A
inst✝⁵ : Module F A
inst✝⁴ : IsScalarTower F K A
inst✝³ : StrongRankCondition F
inst✝² : StrongRankCondition K
inst✝¹ : Module.Free F K
inst✝ : Module.Free K A
⊢ Module.rank F K * Module.rank K A = Module.rank F A
[PROOFSTEP]
convert lift_rank_mul_lift_rank F K A
[GOAL]
case h.e'_2.h.e'_5
F✝ : Type u
K✝ : Type v
A✝ : Type w
inst✝²¹ : CommRing F✝
inst✝²⁰ : Ring K✝
inst✝¹⁹ : AddCommGroup A✝
inst✝¹⁸ : Algebra F✝ K✝
inst✝¹⁷ : Module K✝ A✝
inst✝¹⁶ : Module F✝ A✝
inst✝¹⁵ : IsScalarTower F✝ K✝ A✝
inst✝¹⁴ : StrongRankCondition F✝
inst✝¹³ : StrongRankCondition K✝
inst✝¹² : Module.Free F✝ K✝
inst✝¹¹ : Module.Free K✝ A✝
F : Type u
K A : Type v
inst✝¹⁰ : CommRing F
inst✝⁹ : Ring K
inst✝⁸ : AddCommGroup A
inst✝⁷ : Algebra F K
inst✝⁶ : Module K A
inst✝⁵ : Module F A
inst✝⁴ : IsScalarTower F K A
inst✝³ : StrongRankCondition F
inst✝² : StrongRankCondition K
inst✝¹ : Module.Free F K
inst✝ : Module.Free K A
⊢ Module.rank F K = lift (Module.rank F K)
[PROOFSTEP]
rw [lift_id]
[GOAL]
case h.e'_2.h.e'_6
F✝ : Type u
K✝ : Type v
A✝ : Type w
inst✝²¹ : CommRing F✝
inst✝²⁰ : Ring K✝
inst✝¹⁹ : AddCommGroup A✝
inst✝¹⁸ : Algebra F✝ K✝
inst✝¹⁷ : Module K✝ A✝
inst✝¹⁶ : Module F✝ A✝
inst✝¹⁵ : IsScalarTower F✝ K✝ A✝
inst✝¹⁴ : StrongRankCondition F✝
inst✝¹³ : StrongRankCondition K✝
inst✝¹² : Module.Free F✝ K✝
inst✝¹¹ : Module.Free K✝ A✝
F : Type u
K A : Type v
inst✝¹⁰ : CommRing F
inst✝⁹ : Ring K
inst✝⁸ : AddCommGroup A
inst✝⁷ : Algebra F K
inst✝⁶ : Module K A
inst✝⁵ : Module F A
inst✝⁴ : IsScalarTower F K A
inst✝³ : StrongRankCondition F
inst✝² : StrongRankCondition K
inst✝¹ : Module.Free F K
inst✝ : Module.Free K A
⊢ Module.rank K A = lift (Module.rank K A)
[PROOFSTEP]
rw [lift_id]
[GOAL]
case h.e'_3
F✝ : Type u
K✝ : Type v
A✝ : Type w
inst✝²¹ : CommRing F✝
inst✝²⁰ : Ring K✝
inst✝¹⁹ : AddCommGroup A✝
inst✝¹⁸ : Algebra F✝ K✝
inst✝¹⁷ : Module K✝ A✝
inst✝¹⁶ : Module F✝ A✝
inst✝¹⁵ : IsScalarTower F✝ K✝ A✝
inst✝¹⁴ : StrongRankCondition F✝
inst✝¹³ : StrongRankCondition K✝
inst✝¹² : Module.Free F✝ K✝
inst✝¹¹ : Module.Free K✝ A✝
F : Type u
K A : Type v
inst✝¹⁰ : CommRing F
inst✝⁹ : Ring K
inst✝⁸ : AddCommGroup A
inst✝⁷ : Algebra F K
inst✝⁶ : Module K A
inst✝⁵ : Module F A
inst✝⁴ : IsScalarTower F K A
inst✝³ : StrongRankCondition F
inst✝² : StrongRankCondition K
inst✝¹ : Module.Free F K
inst✝ : Module.Free K A
⊢ Module.rank F A = lift (Module.rank F A)
[PROOFSTEP]
rw [lift_id]
[GOAL]
F : Type u
K : Type v
A : Type w
inst✝¹² : CommRing F
inst✝¹¹ : Ring K
inst✝¹⁰ : AddCommGroup A
inst✝⁹ : Algebra F K
inst✝⁸ : Module K A
inst✝⁷ : Module F A
inst✝⁶ : IsScalarTower F K A
inst✝⁵ : StrongRankCondition F
inst✝⁴ : StrongRankCondition K
inst✝³ : Module.Free F K
inst✝² : Module.Free K A
inst✝¹ : Module.Finite F K
inst✝ : Module.Finite K A
⊢ finrank F K * finrank K A = finrank F A
[PROOFSTEP]
letI := nontrivial_of_invariantBasisNumber F
[GOAL]
F : Type u
K : Type v
A : Type w
inst✝¹² : CommRing F
inst✝¹¹ : Ring K
inst✝¹⁰ : AddCommGroup A
inst✝⁹ : Algebra F K
inst✝⁸ : Module K A
inst✝⁷ : Module F A
inst✝⁶ : IsScalarTower F K A
inst✝⁵ : StrongRankCondition F
inst✝⁴ : StrongRankCondition K
inst✝³ : Module.Free F K
inst✝² : Module.Free K A
inst✝¹ : Module.Finite F K
inst✝ : Module.Finite K A
this : Nontrivial F := nontrivial_of_invariantBasisNumber F
⊢ finrank F K * finrank K A = finrank F A
[PROOFSTEP]
let b := Module.Free.chooseBasis F K
[GOAL]
F : Type u
K : Type v
A : Type w
inst✝¹² : CommRing F
inst✝¹¹ : Ring K
inst✝¹⁰ : AddCommGroup A
inst✝⁹ : Algebra F K
inst✝⁸ : Module K A
inst✝⁷ : Module F A
inst✝⁶ : IsScalarTower F K A
inst✝⁵ : StrongRankCondition F
inst✝⁴ : StrongRankCondition K
inst✝³ : Module.Free F K
inst✝² : Module.Free K A
inst✝¹ : Module.Finite F K
inst✝ : Module.Finite K A
this : Nontrivial F := nontrivial_of_invariantBasisNumber F
b : Basis (Module.Free.ChooseBasisIndex F K) F K := Module.Free.chooseBasis F K
⊢ finrank F K * finrank K A = finrank F A
[PROOFSTEP]
let c := Module.Free.chooseBasis K A
[GOAL]
F : Type u
K : Type v
A : Type w
inst✝¹² : CommRing F
inst✝¹¹ : Ring K
inst✝¹⁰ : AddCommGroup A
inst✝⁹ : Algebra F K
inst✝⁸ : Module K A
inst✝⁷ : Module F A
inst✝⁶ : IsScalarTower F K A
inst✝⁵ : StrongRankCondition F
inst✝⁴ : StrongRankCondition K
inst✝³ : Module.Free F K
inst✝² : Module.Free K A
inst✝¹ : Module.Finite F K
inst✝ : Module.Finite K A
this : Nontrivial F := nontrivial_of_invariantBasisNumber F
b : Basis (Module.Free.ChooseBasisIndex F K) F K := Module.Free.chooseBasis F K
c : Basis (Module.Free.ChooseBasisIndex K A) K A := Module.Free.chooseBasis K A
⊢ finrank F K * finrank K A = finrank F A
[PROOFSTEP]
rw [finrank_eq_card_basis b, finrank_eq_card_basis c, finrank_eq_card_basis (b.smul c), Fintype.card_prod]
[GOAL]
F : Type u
K : Type v
A : Type w
inst✝⁶ : Field F
inst✝⁵ : DivisionRing K
inst✝⁴ : AddCommGroup A
inst✝³ : Algebra F K
inst✝² : Module K A
inst✝¹ : Module F A
inst✝ : IsScalarTower F K A
hf : FiniteDimensional F A
b : Finset A
hb : span F ↑b = ⊤
⊢ restrictScalars F (span K ↑b) = restrictScalars F ⊤
[PROOFSTEP]
rw [Submodule.restrictScalars_top, eq_top_iff, ← hb, Submodule.span_le]
[GOAL]
F : Type u
K : Type v
A : Type w
inst✝⁶ : Field F
inst✝⁵ : DivisionRing K
inst✝⁴ : AddCommGroup A
inst✝³ : Algebra F K
inst✝² : Module K A
inst✝¹ : Module F A
inst✝ : IsScalarTower F K A
hf : FiniteDimensional F A
b : Finset A
hb : span F ↑b = ⊤
⊢ ↑b ⊆ ↑(restrictScalars F (span K ↑b))
[PROOFSTEP]
exact Submodule.subset_span
[GOAL]
F : Type u
K : Type v
A : Type w
inst✝⁷ : Field F
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup A
inst✝⁴ : Algebra F K
inst✝³ : Module K A
inst✝² : Module F A
inst✝¹ : IsScalarTower F K A
inst✝ : FiniteDimensional F K
⊢ finrank F K * finrank K A = finrank F A
[PROOFSTEP]
by_cases hA : FiniteDimensional K A
[GOAL]
case pos
F : Type u
K : Type v
A : Type w
inst✝⁷ : Field F
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup A
inst✝⁴ : Algebra F K
inst✝³ : Module K A
inst✝² : Module F A
inst✝¹ : IsScalarTower F K A
inst✝ : FiniteDimensional F K
hA : FiniteDimensional K A
⊢ finrank F K * finrank K A = finrank F A
[PROOFSTEP]
replace hA : FiniteDimensional K A := hA
[GOAL]
case pos
F : Type u
K : Type v
A : Type w
inst✝⁷ : Field F
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup A
inst✝⁴ : Algebra F K
inst✝³ : Module K A
inst✝² : Module F A
inst✝¹ : IsScalarTower F K A
inst✝ : FiniteDimensional F K
hA : FiniteDimensional K A
⊢ finrank F K * finrank K A = finrank F A
[PROOFSTEP]
rw [finrank_mul_finrank']
[GOAL]
case neg
F : Type u
K : Type v
A : Type w
inst✝⁷ : Field F
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup A
inst✝⁴ : Algebra F K
inst✝³ : Module K A
inst✝² : Module F A
inst✝¹ : IsScalarTower F K A
inst✝ : FiniteDimensional F K
hA : ¬FiniteDimensional K A
⊢ finrank F K * finrank K A = finrank F A
[PROOFSTEP]
rw [finrank_of_infinite_dimensional hA, mul_zero, finrank_of_infinite_dimensional]
[GOAL]
case neg
F : Type u
K : Type v
A : Type w
inst✝⁷ : Field F
inst✝⁶ : DivisionRing K
inst✝⁵ : AddCommGroup A
inst✝⁴ : Algebra F K
inst✝³ : Module K A
inst✝² : Module F A
inst✝¹ : IsScalarTower F K A
inst✝ : FiniteDimensional F K
hA : ¬FiniteDimensional K A
⊢ ¬FiniteDimensional F A
[PROOFSTEP]
exact mt (@right F K A _ _ _ _ _ _ _) hA
[GOAL]
F : Type u
K✝ : Type v
A✝ : Type w
inst✝⁹ : Field F
inst✝⁸ : DivisionRing K✝
inst✝⁷ : AddCommGroup A✝
inst✝⁶ : Algebra F K✝
inst✝⁵ : Module K✝ A✝
inst✝⁴ : Module F A✝
inst✝³ : IsScalarTower F K✝ A✝
A : Type u_1
inst✝² : Ring A
inst✝¹ : IsDomain A
inst✝ : Algebra F A
hp : Nat.Prime (finrank F A)
K : Subalgebra F A
⊢ K = ⊥ ∨ K = ⊤
[PROOFSTEP]
haveI : FiniteDimensional _ _ := finiteDimensional_of_finrank hp.pos
[GOAL]
F : Type u
K✝ : Type v
A✝ : Type w
inst✝⁹ : Field F
inst✝⁸ : DivisionRing K✝
inst✝⁷ : AddCommGroup A✝
inst✝⁶ : Algebra F K✝
inst✝⁵ : Module K✝ A✝
inst✝⁴ : Module F A✝
inst✝³ : IsScalarTower F K✝ A✝
A : Type u_1
inst✝² : Ring A
inst✝¹ : IsDomain A
inst✝ : Algebra F A
hp : Nat.Prime (finrank F A)
K : Subalgebra F A
this : FiniteDimensional F A
⊢ K = ⊥ ∨ K = ⊤
[PROOFSTEP]
letI := divisionRingOfFiniteDimensional F K
[GOAL]
F : Type u
K✝ : Type v
A✝ : Type w
inst✝⁹ : Field F
inst✝⁸ : DivisionRing K✝
inst✝⁷ : AddCommGroup A✝
inst✝⁶ : Algebra F K✝
inst✝⁵ : Module K✝ A✝
inst✝⁴ : Module F A✝
inst✝³ : IsScalarTower F K✝ A✝
A : Type u_1
inst✝² : Ring A
inst✝¹ : IsDomain A
inst✝ : Algebra F A
hp : Nat.Prime (finrank F A)
K : Subalgebra F A
this✝ : FiniteDimensional F A
this : DivisionRing { x // x ∈ K } := divisionRingOfFiniteDimensional F { x // x ∈ K }
⊢ K = ⊥ ∨ K = ⊤
[PROOFSTEP]
refine' (hp.eq_one_or_self_of_dvd _ ⟨_, (finrank_mul_finrank F K A).symm⟩).imp _ fun h => _
[GOAL]
case refine'_1
F : Type u
K✝ : Type v
A✝ : Type w
inst✝⁹ : Field F
inst✝⁸ : DivisionRing K✝
inst✝⁷ : AddCommGroup A✝
inst✝⁶ : Algebra F K✝
inst✝⁵ : Module K✝ A✝
inst✝⁴ : Module F A✝
inst✝³ : IsScalarTower F K✝ A✝
A : Type u_1
inst✝² : Ring A
inst✝¹ : IsDomain A
inst✝ : Algebra F A
hp : Nat.Prime (finrank F A)
K : Subalgebra F A
this✝ : FiniteDimensional F A
this : DivisionRing { x // x ∈ K } := divisionRingOfFiniteDimensional F { x // x ∈ K }
⊢ finrank F { x // x ∈ K } = 1 → K = ⊥
[PROOFSTEP]
exact Subalgebra.eq_bot_of_finrank_one
[GOAL]
case refine'_2
F : Type u
K✝ : Type v
A✝ : Type w
inst✝⁹ : Field F
inst✝⁸ : DivisionRing K✝
inst✝⁷ : AddCommGroup A✝
inst✝⁶ : Algebra F K✝
inst✝⁵ : Module K✝ A✝
inst✝⁴ : Module F A✝
inst✝³ : IsScalarTower F K✝ A✝
A : Type u_1
inst✝² : Ring A
inst✝¹ : IsDomain A
inst✝ : Algebra F A
hp : Nat.Prime (finrank F A)
K : Subalgebra F A
this✝ : FiniteDimensional F A
this : DivisionRing { x // x ∈ K } := divisionRingOfFiniteDimensional F { x // x ∈ K }
h : finrank F { x // x ∈ K } = finrank F A
⊢ K = ⊤
[PROOFSTEP]
exact Algebra.toSubmodule_eq_top.1 (eq_top_of_finrank_eq <| K.finrank_toSubmodule.trans h)


[GOAL]
r n : ℕ
⊢ choose (2 * n) (2 * n / 2) = choose (2 * n) n
[PROOFSTEP]
rw [Nat.mul_div_cancel_left n zero_lt_two]
[GOAL]
n : ℕ
⊢ choose (2 * n + 2) (n + 1) * (n + 1) = choose (2 * n + 1) n * (2 * n + 2)
[PROOFSTEP]
rw [choose_succ_right_eq, choose_mul_succ_eq]
[GOAL]
n : ℕ
⊢ choose (2 * n + 1) n * (2 * n + 2) = 2 * (choose (2 * n + 1) n * (n + 1))
[PROOFSTEP]
ring
[GOAL]
n : ℕ
⊢ 2 * (choose (2 * n + 1) n * (n + 1)) = 2 * (choose (2 * n + 1) n * (2 * n + 1 - n))
[PROOFSTEP]
rw [two_mul n, add_assoc, Nat.add_sub_cancel_left]
[GOAL]
n : ℕ
⊢ 2 * (choose (2 * n + 1) n * (2 * n + 1 - n)) = 2 * (choose (2 * n) n * (2 * n + 1))
[PROOFSTEP]
rw [choose_mul_succ_eq]
[GOAL]
n : ℕ
⊢ 2 * (choose (2 * n) n * (2 * n + 1)) = 2 * (2 * n + 1) * choose (2 * n) n
[PROOFSTEP]
rw [mul_assoc, mul_comm (2 * n + 1)]
[GOAL]
n : ℕ
n_big : 4 ≤ n
⊢ 4 ^ n < n * centralBinom n
[PROOFSTEP]
induction' n using Nat.strong_induction_on with n IH
[GOAL]
case h
n✝ : ℕ
n_big✝ : 4 ≤ n✝
n : ℕ
IH : ∀ (m : ℕ), m < n → 4 ≤ m → 4 ^ m < m * centralBinom m
n_big : 4 ≤ n
⊢ 4 ^ n < n * centralBinom n
[PROOFSTEP]
rcases lt_trichotomy n 4 with (hn | rfl | hn)
[GOAL]
case h.inl
n✝ : ℕ
n_big✝ : 4 ≤ n✝
n : ℕ
IH : ∀ (m : ℕ), m < n → 4 ≤ m → 4 ^ m < m * centralBinom m
n_big : 4 ≤ n
hn : n < 4
⊢ 4 ^ n < n * centralBinom n
[PROOFSTEP]
clear IH
[GOAL]
case h.inl
n✝ : ℕ
n_big✝ : 4 ≤ n✝
n : ℕ
n_big : 4 ≤ n
hn : n < 4
⊢ 4 ^ n < n * centralBinom n
[PROOFSTEP]
exact False.elim ((not_lt.2 n_big) hn)
[GOAL]
case h.inr.inl
n : ℕ
n_big✝ : 4 ≤ n
IH : ∀ (m : ℕ), m < 4 → 4 ≤ m → 4 ^ m < m * centralBinom m
n_big : 4 ≤ 4
⊢ 4 ^ 4 < 4 * centralBinom 4
[PROOFSTEP]
norm_num [centralBinom, choose]
[GOAL]
case h.inr.inr
n✝ : ℕ
n_big✝ : 4 ≤ n✝
n : ℕ
IH : ∀ (m : ℕ), m < n → 4 ≤ m → 4 ^ m < m * centralBinom m
n_big : 4 ≤ n
hn : 4 < n
⊢ 4 ^ n < n * centralBinom n
[PROOFSTEP]
obtain ⟨n, rfl⟩ : ∃ m, n = m + 1 := Nat.exists_eq_succ_of_ne_zero (Nat.not_eq_zero_of_lt hn)
[GOAL]
case h.inr.inr.intro
n✝ : ℕ
n_big✝ : 4 ≤ n✝
n : ℕ
IH : ∀ (m : ℕ), m < n + 1 → 4 ≤ m → 4 ^ m < m * centralBinom m
n_big : 4 ≤ n + 1
hn : 4 < n + 1
⊢ 4 ^ (n + 1) < (n + 1) * centralBinom (n + 1)
[PROOFSTEP]
calc
  4 ^ (n + 1) < 4 * (n * centralBinom n) :=
    lt_of_eq_of_lt (pow_succ'' n 4) $
      (mul_lt_mul_left <| zero_lt_four' ℕ).mpr (IH n n.lt_succ_self (Nat.le_of_lt_succ hn))
  _ ≤ 2 * (2 * n + 1) * centralBinom n := by rw [← mul_assoc]; linarith
  _ = (n + 1) * centralBinom (n + 1) := (succ_mul_centralBinom_succ n).symm
[GOAL]
n✝ : ℕ
n_big✝ : 4 ≤ n✝
n : ℕ
IH : ∀ (m : ℕ), m < n + 1 → 4 ≤ m → 4 ^ m < m * centralBinom m
n_big : 4 ≤ n + 1
hn : 4 < n + 1
⊢ 4 * (n * centralBinom n) ≤ 2 * (2 * n + 1) * centralBinom n
[PROOFSTEP]
rw [← mul_assoc]
[GOAL]
n✝ : ℕ
n_big✝ : 4 ≤ n✝
n : ℕ
IH : ∀ (m : ℕ), m < n + 1 → 4 ≤ m → 4 ^ m < m * centralBinom m
n_big : 4 ≤ n + 1
hn : 4 < n + 1
⊢ 4 * n * centralBinom n ≤ 2 * (2 * n + 1) * centralBinom n
[PROOFSTEP]
linarith
[GOAL]
x✝ : 0 < 1
⊢ 4 ^ 1 ≤ 2 * 1 * centralBinom 1
[PROOFSTEP]
norm_num [centralBinom, choose]
[GOAL]
x✝ : 0 < 2
⊢ 4 ^ 2 ≤ 2 * 2 * centralBinom 2
[PROOFSTEP]
norm_num [centralBinom, choose]
[GOAL]
x✝ : 0 < 3
⊢ 4 ^ 3 ≤ 2 * 3 * centralBinom 3
[PROOFSTEP]
norm_num [centralBinom, choose]
[GOAL]
n : ℕ
x✝ : 0 < n + 4
⊢ (n + 4) * centralBinom (n + 4) ≤ 2 * (n + 4) * centralBinom (n + 4)
[PROOFSTEP]
rw [mul_assoc]
[GOAL]
n : ℕ
x✝ : 0 < n + 4
⊢ (n + 4) * centralBinom (n + 4) ≤ 2 * ((n + 4) * centralBinom (n + 4))
[PROOFSTEP]
refine' le_mul_of_pos_left zero_lt_two
[GOAL]
n : ℕ
⊢ 2 ∣ centralBinom (n + 1)
[PROOFSTEP]
use(n + 1 + n).choose n
[GOAL]
case h
n : ℕ
⊢ centralBinom (n + 1) = 2 * choose (n + 1 + n) n
[PROOFSTEP]
rw [centralBinom_eq_two_mul_choose, two_mul, ← add_assoc, choose_succ_succ' (n + 1 + n) n, choose_symm_add, ← two_mul]
[GOAL]
n : ℕ
h : 0 < n
⊢ 2 ∣ centralBinom n
[PROOFSTEP]
rw [← Nat.succ_pred_eq_of_pos h]
[GOAL]
n : ℕ
h : 0 < n
⊢ 2 ∣ centralBinom (succ (pred n))
[PROOFSTEP]
exact two_dvd_centralBinom_succ n.pred
[GOAL]
n : ℕ
⊢ n + 1 ∣ centralBinom n
[PROOFSTEP]
have h_s : (n + 1).coprime (2 * n + 1) :=
  by
  rw [two_mul, add_assoc, coprime_add_self_right, coprime_self_add_left]
  exact coprime_one_left n
[GOAL]
n : ℕ
⊢ coprime (n + 1) (2 * n + 1)
[PROOFSTEP]
rw [two_mul, add_assoc, coprime_add_self_right, coprime_self_add_left]
[GOAL]
n : ℕ
⊢ coprime 1 n
[PROOFSTEP]
exact coprime_one_left n
[GOAL]
n : ℕ
h_s : coprime (n + 1) (2 * n + 1)
⊢ n + 1 ∣ centralBinom n
[PROOFSTEP]
apply h_s.dvd_of_dvd_mul_left
[GOAL]
n : ℕ
h_s : coprime (n + 1) (2 * n + 1)
⊢ n + 1 ∣ (2 * n + 1) * centralBinom n
[PROOFSTEP]
apply Nat.dvd_of_mul_dvd_mul_left zero_lt_two
[GOAL]
n : ℕ
h_s : coprime (n + 1) (2 * n + 1)
⊢ 2 * (n + 1) ∣ 2 * ((2 * n + 1) * centralBinom n)
[PROOFSTEP]
rw [← mul_assoc, ← succ_mul_centralBinom_succ, mul_comm]
[GOAL]
n : ℕ
h_s : coprime (n + 1) (2 * n + 1)
⊢ (n + 1) * 2 ∣ (n + 1) * centralBinom (n + 1)
[PROOFSTEP]
exact mul_dvd_mul_left _ (two_dvd_centralBinom_succ n)


[GOAL]
m n a b c d : ℕ
⊢ a ≡ 0 [MOD n] ↔ n ∣ a
[PROOFSTEP]
rw [ModEq, zero_mod, dvd_iff_mod_eq_zero]
[GOAL]
m n a b c d : ℕ
⊢ a ≡ b [MOD n] ↔ ↑n ∣ ↑b - ↑a
[PROOFSTEP]
rw [ModEq, eq_comm, ← Int.coe_nat_inj', Int.coe_nat_mod, Int.coe_nat_mod, Int.emod_eq_emod_iff_emod_sub_eq_zero,
  Int.dvd_iff_emod_eq_zero]
[GOAL]
m n a b c d : ℕ
h : a ≤ b
⊢ a ≡ b [MOD n] ↔ n ∣ b - a
[PROOFSTEP]
rw [modEq_iff_dvd, ← Int.coe_nat_dvd, Int.ofNat_sub h]
[GOAL]
m n a b c✝ d c : ℕ
h : a ≡ b [MOD n]
⊢ c * a ≡ c * b [MOD c * n]
[PROOFSTEP]
unfold ModEq at *
[GOAL]
m n a b c✝ d c : ℕ
h : a % n = b % n
⊢ c * a % (c * n) = c * b % (c * n)
[PROOFSTEP]
rw [mul_mod_mul_left, mul_mod_mul_left, h]
[GOAL]
m n a b c✝ d c : ℕ
h : a ≡ b [MOD n]
⊢ a * c ≡ b * c [MOD n * c]
[PROOFSTEP]
rw [mul_comm a, mul_comm b, mul_comm n]
[GOAL]
m n a b c✝ d c : ℕ
h : a ≡ b [MOD n]
⊢ c * a ≡ c * b [MOD c * n]
[PROOFSTEP]
exact h.mul_left' c
[GOAL]
m n a b c✝ d c : ℕ
h : a ≡ b [MOD n]
⊢ a * c ≡ b * c [MOD n]
[PROOFSTEP]
rw [mul_comm a, mul_comm b]
[GOAL]
m n a b c✝ d c : ℕ
h : a ≡ b [MOD n]
⊢ c * a ≡ c * b [MOD n]
[PROOFSTEP]
exact h.mul_left c
[GOAL]
m✝ n a b c d m : ℕ
h : a ≡ b [MOD n]
⊢ a ^ m ≡ b ^ m [MOD n]
[PROOFSTEP]
induction m with
| zero => rfl
| succ d hd =>
  rw [pow_succ, pow_succ]
  exact hd.mul h
[GOAL]
m✝ n a b c d m : ℕ
h : a ≡ b [MOD n]
⊢ a ^ m ≡ b ^ m [MOD n]
[PROOFSTEP]
induction m with
| zero => rfl
| succ d hd =>
  rw [pow_succ, pow_succ]
  exact hd.mul h
[GOAL]
case zero
m n a b c d : ℕ
h : a ≡ b [MOD n]
⊢ a ^ zero ≡ b ^ zero [MOD n]
[PROOFSTEP]

| zero => rfl
[GOAL]
case zero
m n a b c d : ℕ
h : a ≡ b [MOD n]
⊢ a ^ zero ≡ b ^ zero [MOD n]
[PROOFSTEP]
rfl
[GOAL]
case succ
m n a b c d✝ : ℕ
h : a ≡ b [MOD n]
d : ℕ
hd : a ^ d ≡ b ^ d [MOD n]
⊢ a ^ succ d ≡ b ^ succ d [MOD n]
[PROOFSTEP]

| succ d hd =>
  rw [pow_succ, pow_succ]
  exact hd.mul h
[GOAL]
case succ
m n a b c d✝ : ℕ
h : a ≡ b [MOD n]
d : ℕ
hd : a ^ d ≡ b ^ d [MOD n]
⊢ a ^ succ d ≡ b ^ succ d [MOD n]
[PROOFSTEP]
rw [pow_succ, pow_succ]
[GOAL]
case succ
m n a b c d✝ : ℕ
h : a ≡ b [MOD n]
d : ℕ
hd : a ^ d ≡ b ^ d [MOD n]
⊢ a ^ d * a ≡ b ^ d * b [MOD n]
[PROOFSTEP]
exact hd.mul h
[GOAL]
m n a b c d : ℕ
h₁ : a ≡ b [MOD n]
h₂ : c ≡ d [MOD n]
⊢ a + c ≡ b + d [MOD n]
[PROOFSTEP]
rw [modEq_iff_dvd, Int.ofNat_add, Int.ofNat_add, add_sub_add_comm]
[GOAL]
m n a b c d : ℕ
h₁ : a ≡ b [MOD n]
h₂ : c ≡ d [MOD n]
⊢ ↑n ∣ ↑b - ↑a + (↑d - ↑c)
[PROOFSTEP]
exact dvd_add h₁.dvd h₂.dvd
[GOAL]
m n a b c d : ℕ
h₁ : a ≡ b [MOD n]
h₂ : a + c ≡ b + d [MOD n]
⊢ c ≡ d [MOD n]
[PROOFSTEP]
simp only [modEq_iff_dvd, Int.ofNat_add] at *
[GOAL]
m n a b c d : ℕ
h₁ : ↑n ∣ ↑b - ↑a
h₂ : ↑n ∣ ↑b + ↑d - (↑a + ↑c)
⊢ ↑n ∣ ↑d - ↑c
[PROOFSTEP]
rw [add_sub_add_comm] at h₂
[GOAL]
m n a b c d : ℕ
h₁ : ↑n ∣ ↑b - ↑a
h₂ : ↑n ∣ ↑b - ↑a + (↑d - ↑c)
⊢ ↑n ∣ ↑d - ↑c
[PROOFSTEP]
convert _root_.dvd_sub h₂ h₁ using 1
[GOAL]
case h.e'_4
m n a b c d : ℕ
h₁ : ↑n ∣ ↑b - ↑a
h₂ : ↑n ∣ ↑b - ↑a + (↑d - ↑c)
⊢ ↑d - ↑c = ↑b - ↑a + (↑d - ↑c) - (↑b - ↑a)
[PROOFSTEP]
rw [add_sub_cancel']
[GOAL]
m n a b c d : ℕ
h₁ : c ≡ d [MOD n]
h₂ : a + c ≡ b + d [MOD n]
⊢ a ≡ b [MOD n]
[PROOFSTEP]
rw [add_comm a, add_comm b] at h₂
[GOAL]
m n a b c d : ℕ
h₁ : c ≡ d [MOD n]
h₂ : c + a ≡ d + b [MOD n]
⊢ a ≡ b [MOD n]
[PROOFSTEP]
exact h₁.add_left_cancel h₂
[GOAL]
m✝ n a✝ b✝ c✝ d a b c m : ℕ
hc : c ≠ 0
⊢ c * a ≡ c * b [MOD c * m] → a ≡ b [MOD m]
[PROOFSTEP]
simp [modEq_iff_dvd, ← mul_sub, mul_dvd_mul_iff_left (by simp [hc] : (c : ℤ) ≠ 0)]
[GOAL]
m✝ n a✝ b✝ c✝ d a b c m : ℕ
hc : c ≠ 0
⊢ ↑c ≠ 0
[PROOFSTEP]
simp [hc]
[GOAL]
m✝ n a✝ b✝ c✝ d a b c m : ℕ
hc : c ≠ 0
⊢ a * c ≡ b * c [MOD m * c] → a ≡ b [MOD m]
[PROOFSTEP]
simp [modEq_iff_dvd, ← sub_mul, mul_dvd_mul_iff_right (by simp [hc] : (c : ℤ) ≠ 0)]
[GOAL]
m✝ n a✝ b✝ c✝ d a b c m : ℕ
hc : c ≠ 0
⊢ ↑c ≠ 0
[PROOFSTEP]
simp [hc]
[GOAL]
m✝ n a b c d m : ℕ
h : a ≡ b [MOD m * n]
⊢ a ≡ b [MOD n]
[PROOFSTEP]
rw [modEq_iff_dvd] at *
[GOAL]
m✝ n a b c d m : ℕ
h : ↑(m * n) ∣ ↑b - ↑a
⊢ ↑n ∣ ↑b - ↑a
[PROOFSTEP]
exact (dvd_mul_left (n : ℤ) (m : ℤ)).trans h
[GOAL]
m n a b c d : ℕ
h : a / c ≡ b / c [MOD m / c]
ha✝¹ : c ∣ a
ha✝ : c ∣ b
ha : c ∣ m
⊢ a ≡ b [MOD m]
[PROOFSTEP]
convert h.mul_left' c
[GOAL]
case h.e'_1
m n a b c d : ℕ
h : a / c ≡ b / c [MOD m / c]
ha✝¹ : c ∣ a
ha✝ : c ∣ b
ha : c ∣ m
⊢ m = c * (m / c)
[PROOFSTEP]
rwa [Nat.mul_div_cancel']
[GOAL]
case h.e'_2
m n a b c d : ℕ
h : a / c ≡ b / c [MOD m / c]
ha✝¹ : c ∣ a
ha✝ : c ∣ b
ha : c ∣ m
⊢ a = c * (a / c)
[PROOFSTEP]
rwa [Nat.mul_div_cancel']
[GOAL]
case h.e'_3
m n a b c d : ℕ
h : a / c ≡ b / c [MOD m / c]
ha✝¹ : c ∣ a
ha✝ : c ∣ b
ha : c ∣ m
⊢ b = c * (b / c)
[PROOFSTEP]
rwa [Nat.mul_div_cancel']
[GOAL]
m n a b c d : ℕ
h : b ≤ a
⊢ ↑(a - b) ∣ ↑a - ↑b
[PROOFSTEP]
rw [Int.ofNat_sub h]
[GOAL]
m n a b c d : ℕ
⊢ a ≡ b [MOD 0] ↔ a = b
[PROOFSTEP]
rw [ModEq, mod_zero, mod_zero]
[GOAL]
m n a b c d : ℕ
⊢ n + a ≡ a [MOD n]
[PROOFSTEP]
rw [ModEq, add_mod_left]
[GOAL]
m n a b c d : ℕ
⊢ a + n ≡ a [MOD n]
[PROOFSTEP]
rw [ModEq, add_mod_right]
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD m]
hdm : d ∣ m
⊢ d ∣ a ↔ d ∣ b
[PROOFSTEP]
simp only [← modEq_zero_iff_dvd]
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD m]
hdm : d ∣ m
⊢ a ≡ 0 [MOD d] ↔ b ≡ 0 [MOD d]
[PROOFSTEP]
replace h := h.of_dvd hdm
[GOAL]
m n a b c d : ℕ
hdm : d ∣ m
h : a ≡ b [MOD d]
⊢ a ≡ 0 [MOD d] ↔ b ≡ 0 [MOD d]
[PROOFSTEP]
exact ⟨h.symm.trans, h.trans⟩
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD m]
⊢ gcd a m = gcd b m
[PROOFSTEP]
have h1 := gcd_dvd_right a m
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD m]
h1 : gcd a m ∣ m
⊢ gcd a m = gcd b m
[PROOFSTEP]
have h2 := gcd_dvd_right b m
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD m]
h1 : gcd a m ∣ m
h2 : gcd b m ∣ m
⊢ gcd a m = gcd b m
[PROOFSTEP]
exact
  dvd_antisymm (dvd_gcd ((h.dvd_iff h1).mp (gcd_dvd_left a m)) h1) (dvd_gcd ((h.dvd_iff h2).mpr (gcd_dvd_left b m)) h2)
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD m]
h2 : |↑b - ↑a| < ↑m
⊢ a = b
[PROOFSTEP]
apply Int.ofNat.inj
[GOAL]
case x
m n a b c d : ℕ
h : a ≡ b [MOD m]
h2 : |↑b - ↑a| < ↑m
⊢ Int.ofNat a = Int.ofNat b
[PROOFSTEP]
rw [eq_comm, ← sub_eq_zero]
[GOAL]
case x
m n a b c d : ℕ
h : a ≡ b [MOD m]
h2 : |↑b - ↑a| < ↑m
⊢ Int.ofNat b - Int.ofNat a = 0
[PROOFSTEP]
exact Int.eq_zero_of_abs_lt_dvd h.dvd h2
[GOAL]
m n a b c d : ℕ
hm : 0 < m
h : c * a ≡ c * b [MOD m]
⊢ a ≡ b [MOD m / gcd m c]
[PROOFSTEP]
let d := gcd m c
[GOAL]
m n a b c d✝ : ℕ
hm : 0 < m
h : c * a ≡ c * b [MOD m]
d : ℕ := gcd m c
⊢ a ≡ b [MOD m / gcd m c]
[PROOFSTEP]
have hmd := gcd_dvd_left m c
[GOAL]
m n a b c d✝ : ℕ
hm : 0 < m
h : c * a ≡ c * b [MOD m]
d : ℕ := gcd m c
hmd : gcd m c ∣ m
⊢ a ≡ b [MOD m / gcd m c]
[PROOFSTEP]
have hcd := gcd_dvd_right m c
[GOAL]
m n a b c d✝ : ℕ
hm : 0 < m
h : c * a ≡ c * b [MOD m]
d : ℕ := gcd m c
hmd : gcd m c ∣ m
hcd : gcd m c ∣ c
⊢ a ≡ b [MOD m / gcd m c]
[PROOFSTEP]
rw [modEq_iff_dvd]
[GOAL]
m n a b c d✝ : ℕ
hm : 0 < m
h : c * a ≡ c * b [MOD m]
d : ℕ := gcd m c
hmd : gcd m c ∣ m
hcd : gcd m c ∣ c
⊢ ↑(m / gcd m c) ∣ ↑b - ↑a
[PROOFSTEP]
refine' @Int.dvd_of_dvd_mul_right_of_gcd_one (m / d) (c / d) (b - a) _ _
[GOAL]
case refine'_1
m n a b c d✝ : ℕ
hm : 0 < m
h : c * a ≡ c * b [MOD m]
d : ℕ := gcd m c
hmd : gcd m c ∣ m
hcd : gcd m c ∣ c
⊢ ↑m / ↑d ∣ ↑c / ↑d * (↑b - ↑a)
case refine'_2
m n a b c d✝ : ℕ
hm : 0 < m
h : c * a ≡ c * b [MOD m]
d : ℕ := gcd m c
hmd : gcd m c ∣ m
hcd : gcd m c ∣ c
⊢ Int.gcd (↑m / ↑d) (↑c / ↑d) = 1
[PROOFSTEP]
show (m / d : ℤ) ∣ c / d * (b - a)
[GOAL]
case refine'_1
m n a b c d✝ : ℕ
hm : 0 < m
h : c * a ≡ c * b [MOD m]
d : ℕ := gcd m c
hmd : gcd m c ∣ m
hcd : gcd m c ∣ c
⊢ ↑m / ↑d ∣ ↑c / ↑d * (↑b - ↑a)
[PROOFSTEP]
rw [mul_comm, ← Int.mul_ediv_assoc (b - a) (Int.coe_nat_dvd.mpr hcd), mul_comm]
[GOAL]
case refine'_1
m n a b c d✝ : ℕ
hm : 0 < m
h : c * a ≡ c * b [MOD m]
d : ℕ := gcd m c
hmd : gcd m c ∣ m
hcd : gcd m c ∣ c
⊢ ↑m / ↑d ∣ ↑c * (↑b - ↑a) / ↑(gcd m c)
[PROOFSTEP]
apply Int.ediv_dvd_ediv (Int.coe_nat_dvd.mpr hmd)
[GOAL]
case refine'_1
m n a b c d✝ : ℕ
hm : 0 < m
h : c * a ≡ c * b [MOD m]
d : ℕ := gcd m c
hmd : gcd m c ∣ m
hcd : gcd m c ∣ c
⊢ ↑m ∣ ↑c * (↑b - ↑a)
[PROOFSTEP]
rw [mul_sub]
[GOAL]
case refine'_1
m n a b c d✝ : ℕ
hm : 0 < m
h : c * a ≡ c * b [MOD m]
d : ℕ := gcd m c
hmd : gcd m c ∣ m
hcd : gcd m c ∣ c
⊢ ↑m ∣ ↑c * ↑b - ↑c * ↑a
[PROOFSTEP]
exact modEq_iff_dvd.mp h
[GOAL]
case refine'_2
m n a b c d✝ : ℕ
hm : 0 < m
h : c * a ≡ c * b [MOD m]
d : ℕ := gcd m c
hmd : gcd m c ∣ m
hcd : gcd m c ∣ c
⊢ Int.gcd (↑m / ↑d) (↑c / ↑d) = 1
[PROOFSTEP]
show Int.gcd (m / d) (c / d) = 1
[GOAL]
case refine'_2
m n a b c d✝ : ℕ
hm : 0 < m
h : c * a ≡ c * b [MOD m]
d : ℕ := gcd m c
hmd : gcd m c ∣ m
hcd : gcd m c ∣ c
⊢ Int.gcd (↑m / ↑d) (↑c / ↑d) = 1
[PROOFSTEP]
simp only [← Int.coe_nat_div, Int.coe_nat_gcd (m / d) (c / d), gcd_div hmd hcd, Nat.div_self (gcd_pos_of_pos_left c hm)]
[GOAL]
m n a b c d : ℕ
hm : 0 < m
h : a * c ≡ b * c [MOD m]
⊢ a ≡ b [MOD m / gcd m c]
[PROOFSTEP]
apply cancel_left_div_gcd hm
[GOAL]
m n a b c d : ℕ
hm : 0 < m
h : a * c ≡ b * c [MOD m]
⊢ c * a ≡ c * b [MOD m]
[PROOFSTEP]
simpa [mul_comm] using h
[GOAL]
m n a b c d : ℕ
hmc : gcd m c = 1
h : c * a ≡ c * b [MOD m]
⊢ a ≡ b [MOD m]
[PROOFSTEP]
rcases m.eq_zero_or_pos with (rfl | hm)
[GOAL]
case inl
n a b c d : ℕ
hmc : gcd 0 c = 1
h : c * a ≡ c * b [MOD 0]
⊢ a ≡ b [MOD 0]
[PROOFSTEP]
simp only [gcd_zero_left] at hmc
[GOAL]
case inl
n a b c d : ℕ
hmc : c = 1
h : c * a ≡ c * b [MOD 0]
⊢ a ≡ b [MOD 0]
[PROOFSTEP]
simp only [gcd_zero_left, hmc, one_mul, modEq_zero_iff] at h
[GOAL]
case inl
n a b c d : ℕ
hmc : c = 1
h : a = b
⊢ a ≡ b [MOD 0]
[PROOFSTEP]
subst h
[GOAL]
case inl
n a c d : ℕ
hmc : c = 1
⊢ a ≡ a [MOD 0]
[PROOFSTEP]
rfl
[GOAL]
case inr
m n a b c d : ℕ
hmc : gcd m c = 1
h : c * a ≡ c * b [MOD m]
hm : m > 0
⊢ a ≡ b [MOD m]
[PROOFSTEP]
simpa [hmc] using h.cancel_left_div_gcd hm
[GOAL]
m n a b c d : ℕ
hmc : gcd m c = 1
h : a * c ≡ b * c [MOD m]
⊢ c * a ≡ c * b [MOD m]
[PROOFSTEP]
simpa [mul_comm] using h
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : n = 0
⊢ a ≡ a [MOD n] ∧ a ≡ b [MOD m]
[PROOFSTEP]
rw [hn, gcd_zero_left] at h
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD m]
hn : n = 0
⊢ a ≡ a [MOD n] ∧ a ≡ b [MOD m]
[PROOFSTEP]
constructor
[GOAL]
case left
m n a b c d : ℕ
h : a ≡ b [MOD m]
hn : n = 0
⊢ a ≡ a [MOD n]
case right m n a b c d : ℕ h : a ≡ b [MOD m] hn : n = 0 ⊢ a ≡ b [MOD m]
[PROOFSTEP]
rfl
[GOAL]
case right
m n a b c d : ℕ
h : a ≡ b [MOD m]
hn : n = 0
⊢ a ≡ b [MOD m]
[PROOFSTEP]
exact h
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : m = 0
⊢ b ≡ a [MOD n] ∧ b ≡ b [MOD m]
[PROOFSTEP]
rw [hm, gcd_zero_right] at h
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD n]
hn : ¬n = 0
hm : m = 0
⊢ b ≡ a [MOD n] ∧ b ≡ b [MOD m]
[PROOFSTEP]
constructor
[GOAL]
case left
m n a b c d : ℕ
h : a ≡ b [MOD n]
hn : ¬n = 0
hm : m = 0
⊢ b ≡ a [MOD n]
case right m n a b c d : ℕ h : a ≡ b [MOD n] hn : ¬n = 0 hm : m = 0 ⊢ b ≡ b [MOD m]
[PROOFSTEP]
exact h.symm
[GOAL]
case right
m n a b c d : ℕ
h : a ≡ b [MOD n]
hn : ¬n = 0
hm : m = 0
⊢ b ≡ b [MOD m]
[PROOFSTEP]
rfl
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
⊢ (match xgcd n m with
      | (c, d) => Int.toNat ((↑n * c * ↑b + ↑m * d * ↑a) / ↑(gcd n m) % ↑(lcm n m))) ≡
      a [MOD n] ∧
    (match xgcd n m with
      | (c, d) => Int.toNat ((↑n * c * ↑b + ↑m * d * ↑a) / ↑(gcd n m) % ↑(lcm n m))) ≡
      b [MOD m]
[PROOFSTEP]
rw [xgcd_val]
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
⊢ (match (gcdA n m, gcdB n m) with
      | (c, d) => Int.toNat ((↑n * c * ↑b + ↑m * d * ↑a) / ↑(gcd n m) % ↑(lcm n m))) ≡
      a [MOD n] ∧
    (match (gcdA n m, gcdB n m) with
      | (c, d) => Int.toNat ((↑n * c * ↑b + ↑m * d * ↑a) / ↑(gcd n m) % ↑(lcm n m))) ≡
      b [MOD m]
[PROOFSTEP]
dsimp
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
⊢ Int.toNat ((↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) % ↑(lcm n m)) ≡ a [MOD n] ∧
    Int.toNat ((↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) % ↑(lcm n m)) ≡ b [MOD m]
[PROOFSTEP]
rw [modEq_iff_dvd, modEq_iff_dvd, Int.toNat_of_nonneg (Int.emod_nonneg _ (Int.coe_nat_ne_zero.2 (lcm_ne_zero hn hm)))]
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
⊢ ↑n ∣ ↑a - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) % ↑(lcm n m) ∧
    ↑m ∣ ↑b - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) % ↑(lcm n m)
[PROOFSTEP]
have hnonzero : (gcd n m : ℤ) ≠ 0 := by
  norm_cast
  rw [Nat.gcd_eq_zero_iff, not_and]
  exact fun _ => hm
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
⊢ ↑(gcd n m) ≠ 0
[PROOFSTEP]
norm_cast
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
⊢ ¬gcd n m = 0
[PROOFSTEP]
rw [Nat.gcd_eq_zero_iff, not_and]
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
⊢ n = 0 → ¬m = 0
[PROOFSTEP]
exact fun _ => hm
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
⊢ ↑n ∣ ↑a - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) % ↑(lcm n m) ∧
    ↑m ∣ ↑b - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) % ↑(lcm n m)
[PROOFSTEP]
have hcoedvd : ∀ t, (gcd n m : ℤ) ∣ t * (b - a) := fun t => h.dvd.mul_left _
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
⊢ ↑n ∣ ↑a - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) % ↑(lcm n m) ∧
    ↑m ∣ ↑b - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) % ↑(lcm n m)
[PROOFSTEP]
have := gcd_eq_gcd_ab n m
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ ↑n ∣ ↑a - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) % ↑(lcm n m) ∧
    ↑m ∣ ↑b - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) % ↑(lcm n m)
[PROOFSTEP]
constructor
[GOAL]
case left
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ ↑n ∣ ↑a - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) % ↑(lcm n m)
[PROOFSTEP]
rw [Int.emod_def, ← sub_add]
[GOAL]
case right
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ ↑m ∣ ↑b - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) % ↑(lcm n m)
[PROOFSTEP]
rw [Int.emod_def, ← sub_add]
[GOAL]
case left
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ ↑n ∣
    ↑a - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) +
      ↑(lcm n m) * ((↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) / ↑(lcm n m))
[PROOFSTEP]
refine' dvd_add _ (dvd_mul_of_dvd_left _ _)
[GOAL]
case right
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ ↑m ∣
    ↑b - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) +
      ↑(lcm n m) * ((↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m) / ↑(lcm n m))
[PROOFSTEP]
refine' dvd_add _ (dvd_mul_of_dvd_left _ _)
[GOAL]
case left.refine'_1
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ ↑n ∣ ↑a - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m)
[PROOFSTEP]
try norm_cast
[GOAL]
case left.refine'_1
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ ↑n ∣ ↑a - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m)
[PROOFSTEP]
norm_cast
[GOAL]
case left.refine'_2
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ ↑n ∣ ↑(lcm n m)
[PROOFSTEP]
try norm_cast
[GOAL]
case left.refine'_2
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ ↑n ∣ ↑(lcm n m)
[PROOFSTEP]
norm_cast
[GOAL]
case right.refine'_1
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ ↑m ∣ ↑b - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m)
[PROOFSTEP]
try norm_cast
[GOAL]
case right.refine'_1
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ ↑m ∣ ↑b - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m)
[PROOFSTEP]
norm_cast
[GOAL]
case right.refine'_2
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ ↑m ∣ ↑(lcm n m)
[PROOFSTEP]
try norm_cast
[GOAL]
case right.refine'_2
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ ↑m ∣ ↑(lcm n m)
[PROOFSTEP]
norm_cast
[GOAL]
case left.refine'_1
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ ↑n ∣ ↑a - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m)
[PROOFSTEP]
rw [← sub_eq_iff_eq_add'] at this
[GOAL]
case left.refine'_1
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) - ↑n * gcdA n m = ↑m * gcdB n m
⊢ ↑n ∣ ↑a - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m)
[PROOFSTEP]
rw [← this, sub_mul, ← add_sub_assoc, add_comm, add_sub_assoc, ← mul_sub, Int.add_ediv_of_dvd_left,
  Int.mul_ediv_cancel_left _ hnonzero, Int.mul_ediv_assoc _ h.dvd, ← sub_sub, sub_self, zero_sub, dvd_neg, mul_assoc]
[GOAL]
case left.refine'_1
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) - ↑n * gcdA n m = ↑m * gcdB n m
⊢ ↑n ∣ ↑n * (gcdA n m * ((↑b - ↑a) / ↑(gcd n m)))
case left.refine'_1
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) - ↑n * gcdA n m = ↑m * gcdB n m
⊢ ↑(gcd n m) ∣ ↑(gcd n m) * ↑a
[PROOFSTEP]
exact dvd_mul_right _ _
[GOAL]
case left.refine'_1
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) - ↑n * gcdA n m = ↑m * gcdB n m
⊢ ↑(gcd n m) ∣ ↑(gcd n m) * ↑a
[PROOFSTEP]
norm_cast
[GOAL]
case left.refine'_1
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) - ↑n * gcdA n m = ↑m * gcdB n m
⊢ gcd n m ∣ gcd n m * a
[PROOFSTEP]
exact dvd_mul_right _ _
[GOAL]
case left.refine'_2
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ n ∣ lcm n m
[PROOFSTEP]
exact dvd_lcm_left n m
[GOAL]
case right.refine'_1
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ ↑m ∣ ↑b - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m)
[PROOFSTEP]
rw [← sub_eq_iff_eq_add] at this
[GOAL]
case right.refine'_1
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) - ↑m * gcdB n m = ↑n * gcdA n m
⊢ ↑m ∣ ↑b - (↑n * gcdA n m * ↑b + ↑m * gcdB n m * ↑a) / ↑(gcd n m)
[PROOFSTEP]
rw [← this, sub_mul, sub_add, ← mul_sub, Int.sub_ediv_of_dvd, Int.mul_ediv_cancel_left _ hnonzero,
  Int.mul_ediv_assoc _ h.dvd, ← sub_add, sub_self, zero_add, mul_assoc]
[GOAL]
case right.refine'_1
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) - ↑m * gcdB n m = ↑n * gcdA n m
⊢ ↑m ∣ ↑m * (gcdB n m * ((↑b - ↑a) / ↑(gcd n m)))
case right.refine'_1.hcb
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) - ↑m * gcdB n m = ↑n * gcdA n m
⊢ ↑(gcd n m) ∣ ↑m * gcdB n m * (↑b - ↑a)
[PROOFSTEP]
exact dvd_mul_right _ _
[GOAL]
case right.refine'_1.hcb
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) - ↑m * gcdB n m = ↑n * gcdA n m
⊢ ↑(gcd n m) ∣ ↑m * gcdB n m * (↑b - ↑a)
[PROOFSTEP]
exact hcoedvd _
[GOAL]
case right.refine'_2
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : ¬n = 0
hm : ¬m = 0
hnonzero : ↑(gcd n m) ≠ 0
hcoedvd : ∀ (t : ℤ), ↑(gcd n m) ∣ t * (↑b - ↑a)
this : ↑(gcd n m) = ↑n * gcdA n m + ↑m * gcdB n m
⊢ m ∣ lcm n m
[PROOFSTEP]
exact dvd_lcm_right n m
[GOAL]
m n a✝ b✝ c d : ℕ
co : coprime n m
a b : ℕ
⊢ a ≡ b [MOD gcd n m]
[PROOFSTEP]
convert @modEq_one a b
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : n ≠ 0
hm : m ≠ 0
⊢ ↑(chineseRemainder' h) < lcm n m
[PROOFSTEP]
dsimp only [chineseRemainder']
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : n ≠ 0
hm : m ≠ 0
⊢ ↑(if hn : n = 0 then { val := a, property := (_ : a ≡ a [MOD n] ∧ a ≡ b [MOD m]) }
      else
        if hm : m = 0 then { val := b, property := (_ : b ≡ a [MOD n] ∧ b ≡ b [MOD m]) }
        else
          { val := Int.toNat ((↑n * (xgcd n m).fst * ↑b + ↑m * (xgcd n m).snd * ↑a) / ↑(gcd n m) % ↑(lcm n m)),
            property :=
              (_ :
                (match xgcd n m with
                    | (c, d) => Int.toNat ((↑n * c * ↑b + ↑m * d * ↑a) / ↑(gcd n m) % ↑(lcm n m))) ≡
                    a [MOD n] ∧
                  (match xgcd n m with
                    | (c, d) => Int.toNat ((↑n * c * ↑b + ↑m * d * ↑a) / ↑(gcd n m) % ↑(lcm n m))) ≡
                    b [MOD m]) }) <
    lcm n m
[PROOFSTEP]
rw [dif_neg hn, dif_neg hm, Subtype.coe_mk, xgcd_val, ← Int.toNat_coe_nat (lcm n m)]
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : n ≠ 0
hm : m ≠ 0
⊢ Int.toNat
      ((↑n * (gcdA n m, gcdB n m).fst * ↑b + ↑m * (gcdA n m, gcdB n m).snd * ↑a) / ↑(gcd n m) %
        ↑(Int.toNat ↑(lcm n m))) <
    Int.toNat ↑(lcm n m)
[PROOFSTEP]
have lcm_pos := Int.coe_nat_pos.mpr (Nat.pos_of_ne_zero (lcm_ne_zero hn hm))
[GOAL]
m n a b c d : ℕ
h : a ≡ b [MOD gcd n m]
hn : n ≠ 0
hm : m ≠ 0
lcm_pos : 0 < ↑(lcm n m)
⊢ Int.toNat
      ((↑n * (gcdA n m, gcdB n m).fst * ↑b + ↑m * (gcdA n m, gcdB n m).snd * ↑a) / ↑(gcd n m) %
        ↑(Int.toNat ↑(lcm n m))) <
    Int.toNat ↑(lcm n m)
[PROOFSTEP]
exact (Int.toNat_lt_toNat lcm_pos).mpr (Int.emod_lt_of_pos _ lcm_pos)
[GOAL]
m✝ n✝ a✝ b✝ c d a b m n : ℕ
hmn : coprime m n
h : a ≡ b [MOD m] ∧ a ≡ b [MOD n]
⊢ a ≡ b [MOD m * n]
[PROOFSTEP]
rw [Nat.modEq_iff_dvd, Nat.modEq_iff_dvd, ← Int.dvd_natAbs, Int.coe_nat_dvd, ← Int.dvd_natAbs, Int.coe_nat_dvd] at h
[GOAL]
m✝ n✝ a✝ b✝ c d a b m n : ℕ
hmn : coprime m n
h : m ∣ Int.natAbs (↑b - ↑a) ∧ n ∣ Int.natAbs (↑b - ↑a)
⊢ a ≡ b [MOD m * n]
[PROOFSTEP]
rw [Nat.modEq_iff_dvd, ← Int.dvd_natAbs, Int.coe_nat_dvd]
[GOAL]
m✝ n✝ a✝ b✝ c d a b m n : ℕ
hmn : coprime m n
h : m ∣ Int.natAbs (↑b - ↑a) ∧ n ∣ Int.natAbs (↑b - ↑a)
⊢ m * n ∣ Int.natAbs (↑b - ↑a)
[PROOFSTEP]
exact hmn.mul_dvd_of_dvd_of_dvd h.1 h.2
[GOAL]
m n✝ a✝ b✝ c d b a n : ℕ
h : a * b ≡ 1 [MOD n]
⊢ coprime a n
[PROOFSTEP]
obtain ⟨g, hh⟩ := Nat.gcd_dvd_right a n
[GOAL]
case intro
m n✝ a✝ b✝ c d b a n : ℕ
h : a * b ≡ 1 [MOD n]
g : ℕ
hh : n = gcd a n * g
⊢ coprime a n
[PROOFSTEP]
rw [Nat.coprime_iff_gcd_eq_one, ← Nat.dvd_one, ← Nat.modEq_zero_iff_dvd]
[GOAL]
case intro
m n✝ a✝ b✝ c d b a n : ℕ
h : a * b ≡ 1 [MOD n]
g : ℕ
hh : n = gcd a n * g
⊢ 1 ≡ 0 [MOD gcd a n]
[PROOFSTEP]
calc
  1 ≡ a * b [MOD a.gcd n] := (hh ▸ h).symm.of_mul_right g
  _ ≡ 0 * b [MOD a.gcd n] := ((Nat.modEq_zero_iff_dvd.mpr (Nat.gcd_dvd_left _ _)).mul_right b)
  _ = 0 := by rw [zero_mul]
[GOAL]
m n✝ a✝ b✝ c d b a n : ℕ
h : a * b ≡ 1 [MOD n]
g : ℕ
hh : n = gcd a n * g
⊢ 0 * b = 0
[PROOFSTEP]
rw [zero_mul]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hb0 : b = 0
⊢ a / b % c = a % (b * c) / b
[PROOFSTEP]
simp [hb0]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hb0 : ¬b = 0
⊢ a / b % c = a % (b * c) / b
[PROOFSTEP]
rw [← @add_right_cancel_iff _ _ _ (c * (a / b / c)), mod_add_div, Nat.div_div_eq_div_mul, ← mul_right_inj' hb0, ←
  @add_left_cancel_iff _ _ _ (a % b), mod_add_div, mul_add, ← @add_left_cancel_iff _ _ _ (a % (b * c) % b),
  add_left_comm, ← add_assoc (a % (b * c) % b), mod_add_div, ← mul_assoc, mod_add_div, mod_mul_right_mod]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
this : (a + b) % c = (a % c + b % c) % c
hc0 : c = 0
⊢ ((a + b) % c + if c ≤ a % c + b % c then c else 0) = a % c + b % c
[PROOFSTEP]
simp [hc0, Nat.mod_zero]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
this : (a + b) % c = (a % c + b % c) % c
hc0 : ¬c = 0
⊢ ((a + b) % c + if c ≤ a % c + b % c then c else 0) = a % c + b % c
[PROOFSTEP]
rw [this]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
this : (a + b) % c = (a % c + b % c) % c
hc0 : ¬c = 0
⊢ ((a % c + b % c) % c + if c ≤ a % c + b % c then c else 0) = a % c + b % c
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
m n a✝ b✝ c✝ d a b c : ℕ
this : (a + b) % c = (a % c + b % c) % c
hc0 : ¬c = 0
h : c ≤ a % c + b % c
⊢ (a % c + b % c) % c + c = a % c + b % c
[PROOFSTEP]
have h2 : (a % c + b % c) / c < 2 :=
  Nat.div_lt_of_lt_mul
    (by
      rw [mul_two]
      exact add_lt_add (Nat.mod_lt _ (Nat.pos_of_ne_zero hc0)) (Nat.mod_lt _ (Nat.pos_of_ne_zero hc0)))
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
this : (a + b) % c = (a % c + b % c) % c
hc0 : ¬c = 0
h : c ≤ a % c + b % c
⊢ a % c + b % c < c * 2
[PROOFSTEP]
rw [mul_two]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
this : (a + b) % c = (a % c + b % c) % c
hc0 : ¬c = 0
h : c ≤ a % c + b % c
⊢ a % c + b % c < c + c
[PROOFSTEP]
exact add_lt_add (Nat.mod_lt _ (Nat.pos_of_ne_zero hc0)) (Nat.mod_lt _ (Nat.pos_of_ne_zero hc0))
[GOAL]
case pos
m n a✝ b✝ c✝ d a b c : ℕ
this : (a + b) % c = (a % c + b % c) % c
hc0 : ¬c = 0
h : c ≤ a % c + b % c
h2 : (a % c + b % c) / c < 2
⊢ (a % c + b % c) % c + c = a % c + b % c
[PROOFSTEP]
have h0 : 0 < (a % c + b % c) / c := Nat.div_pos h (Nat.pos_of_ne_zero hc0)
[GOAL]
case pos
m n a✝ b✝ c✝ d a b c : ℕ
this : (a + b) % c = (a % c + b % c) % c
hc0 : ¬c = 0
h : c ≤ a % c + b % c
h2 : (a % c + b % c) / c < 2
h0 : 0 < (a % c + b % c) / c
⊢ (a % c + b % c) % c + c = a % c + b % c
[PROOFSTEP]
rw [← @add_right_cancel_iff _ _ _ (c * ((a % c + b % c) / c)), add_comm _ c, add_assoc, mod_add_div,
  le_antisymm (le_of_lt_succ h2) h0, mul_one, add_comm]
[GOAL]
case neg
m n a✝ b✝ c✝ d a b c : ℕ
this : (a + b) % c = (a % c + b % c) % c
hc0 : ¬c = 0
h : ¬c ≤ a % c + b % c
⊢ (a % c + b % c) % c + 0 = a % c + b % c
[PROOFSTEP]
rw [Nat.mod_eq_of_lt (lt_of_not_ge h), add_zero]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc : a % c + b % c < c
⊢ (a + b) % c = a % c + b % c
[PROOFSTEP]
rw [← add_mod_add_ite, if_neg (not_le_of_lt hc), add_zero]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc : c ≤ a % c + b % c
⊢ (a + b) % c + c = a % c + b % c
[PROOFSTEP]
rw [← add_mod_add_ite, if_pos hc]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc0 : 0 < c
⊢ (a + b) / c = a / c + b / c + if c ≤ a % c + b % c then 1 else 0
[PROOFSTEP]
rw [← mul_right_inj' hc0.ne', ← @add_left_cancel_iff _ _ _ ((a + b) % c + a % c + b % c)]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc0 : 0 < c
⊢ (a + b) % c + a % c + b % c + c * ((a + b) / c) =
    (a + b) % c + a % c + b % c + c * (a / c + b / c + if c ≤ a % c + b % c then 1 else 0)
[PROOFSTEP]
suffices
  (a + b) % c + c * ((a + b) / c) + a % c + b % c =
    (a % c + c * (a / c) + (b % c + c * (b / c)) + c * if c ≤ a % c + b % c then 1 else 0) + (a + b) % c
  by simpa only [mul_add, add_comm, add_left_comm, add_assoc]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc0 : 0 < c
this :
  (a + b) % c + c * ((a + b) / c) + a % c + b % c =
    (a % c + c * (a / c) + (b % c + c * (b / c)) + c * if c ≤ a % c + b % c then 1 else 0) + (a + b) % c
⊢ (a + b) % c + a % c + b % c + c * ((a + b) / c) =
    (a + b) % c + a % c + b % c + c * (a / c + b / c + if c ≤ a % c + b % c then 1 else 0)
[PROOFSTEP]
simpa only [mul_add, add_comm, add_left_comm, add_assoc]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc0 : 0 < c
⊢ (a + b) % c + c * ((a + b) / c) + a % c + b % c =
    (a % c + c * (a / c) + (b % c + c * (b / c)) + c * if c ≤ a % c + b % c then 1 else 0) + (a + b) % c
[PROOFSTEP]
rw [mod_add_div, mod_add_div, mod_add_div, mul_ite, add_assoc, add_assoc]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc0 : 0 < c
⊢ a + (b + (a % c + b % c)) = (a + b + if c ≤ a % c + b % c then c * 1 else c * 0) + (a + b) % c
[PROOFSTEP]
conv_lhs => rw [← add_mod_add_ite]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc0 : 0 < c
| a + (b + (a % c + b % c))
[PROOFSTEP]
rw [← add_mod_add_ite]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc0 : 0 < c
| a + (b + (a % c + b % c))
[PROOFSTEP]
rw [← add_mod_add_ite]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc0 : 0 < c
| a + (b + (a % c + b % c))
[PROOFSTEP]
rw [← add_mod_add_ite]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc0 : 0 < c
⊢ a + (b + ((a + b) % c + if c ≤ a % c + b % c then c else 0)) =
    (a + b + if c ≤ a % c + b % c then c * 1 else c * 0) + (a + b) % c
[PROOFSTEP]
simp
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc0 : 0 < c
⊢ a + (b + ((a + b) % c + if c ≤ a % c + b % c then c else 0)) =
    (a + b + if c ≤ a % c + b % c then c else 0) + (a + b) % c
[PROOFSTEP]
ac_rfl
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc : a % c + b % c < c
hc0 : c = 0
⊢ (a + b) / c = a / c + b / c
[PROOFSTEP]
simp [hc0]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc : a % c + b % c < c
hc0 : ¬c = 0
⊢ (a + b) / c = a / c + b / c
[PROOFSTEP]
rw [add_div (Nat.pos_of_ne_zero hc0), if_neg (not_le_of_lt hc), add_zero]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hca : c ∣ a
h : c = 0
⊢ (a + b) / c = a / c + b / c
[PROOFSTEP]
simp [h]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hca : c ∣ a
h : ¬c = 0
⊢ a % c + b % c < c
[PROOFSTEP]
rw [Nat.mod_eq_zero_of_dvd hca, zero_add]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hca : c ∣ a
h : ¬c = 0
⊢ b % c < c
[PROOFSTEP]
exact Nat.mod_lt _ (pos_iff_ne_zero.mpr h)
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hca : c ∣ b
⊢ (a + b) / c = a / c + b / c
[PROOFSTEP]
rwa [add_comm, Nat.add_div_of_dvd_right, add_comm]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc : c ≤ a % c + b % c
hc0 : 0 < c
⊢ (a + b) / c = a / c + b / c + 1
[PROOFSTEP]
rw [add_div hc0, if_pos hc]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc0 : c = 0
⊢ a / c + b / c ≤ (a + b) / c
[PROOFSTEP]
simp [hc0]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc0 : ¬c = 0
⊢ a / c + b / c ≤ (a + b) / c
[PROOFSTEP]
rw [Nat.add_div (Nat.pos_of_ne_zero hc0)]
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
hc0 : ¬c = 0
⊢ a / c + b / c ≤ a / c + b / c + if c ≤ a % c + b % c then 1 else 0
[PROOFSTEP]
exact Nat.le_add_right _ _
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
h : c ∣ a + b
ha : ¬c ∣ a
hc : ¬c ≤ a % c + b % c
⊢ False
[PROOFSTEP]
have : (a + b) % c = a % c + b % c := add_mod_of_add_mod_lt (lt_of_not_ge hc)
[GOAL]
m n a✝ b✝ c✝ d a b c : ℕ
h : c ∣ a + b
ha : ¬c ∣ a
hc : ¬c ≤ a % c + b % c
this : (a + b) % c = a % c + b % c
⊢ False
[PROOFSTEP]
simp_all [dvd_iff_mod_eq_zero]
[GOAL]
m✝ n✝ a b c d n m : ℕ
⊢ n % 2 = 1 → m % 2 = 1 → n * m % 2 = 1
[PROOFSTEP]
simpa [Nat.ModEq] using @ModEq.mul 2 n 1 m 1
[GOAL]
m✝ n✝ a b c d m n : ℕ
hm1 : m % 2 = 1
hn1 : n % 2 = 1
h : m = 0
⊢ False
[PROOFSTEP]
simp_all
[GOAL]
m✝ n✝ a b c d m n : ℕ
hm1 : m % 2 = 1
hn1 : n % 2 = 1
hm0 : 0 < m
h : n = 0
⊢ False
[PROOFSTEP]
simp_all
[GOAL]
m✝ n✝ a b c d m n : ℕ
hm1 : m % 2 = 1
hn1 : n % 2 = 1
hm0 : 0 < m
hn0 : 0 < n
⊢ (fun x x_1 => x * x_1) 2 (m * n / 2) = (fun x x_1 => x * x_1) 2 (m * (n / 2) + m / 2)
[PROOFSTEP]
dsimp
[GOAL]
m✝ n✝ a b c d m n : ℕ
hm1 : m % 2 = 1
hn1 : n % 2 = 1
hm0 : 0 < m
hn0 : 0 < n
⊢ 2 * (m * n / 2) = 2 * (m * (n / 2) + m / 2)
[PROOFSTEP]
rw [mul_add, two_mul_odd_div_two hm1, mul_left_comm, two_mul_odd_div_two hn1,
  two_mul_odd_div_two (Nat.odd_mul_odd hm1 hn1), mul_tsub, mul_one, ← add_tsub_assoc_of_le (succ_le_of_lt hm0),
  tsub_add_cancel_of_le (le_mul_of_one_le_right (Nat.zero_le _) hn0)]
[GOAL]
m n✝ a b c d n : ℕ
⊢ n % 4 = 1 → n % 2 = 1
[PROOFSTEP]
simpa [ModEq, show 2 * 2 = 4 by norm_num] using @ModEq.of_mul_left 2 n 1 2
[GOAL]
m n✝ a b c d n : ℕ
⊢ 2 * 2 = 4
[PROOFSTEP]
norm_num
[GOAL]
m n✝ a b c d n : ℕ
⊢ n % 4 = 3 → n % 2 = 1
[PROOFSTEP]
simpa [ModEq, show 2 * 2 = 4 by norm_num, show 3 % 4 = 3 by norm_num] using @ModEq.of_mul_left 2 n 3 2
[GOAL]
m n✝ a b c d n : ℕ
⊢ 2 * 2 = 4
[PROOFSTEP]
norm_num
[GOAL]
m n✝ a b c d n : ℕ
⊢ 3 % 4 = 3
[PROOFSTEP]
norm_num
[GOAL]
m n✝ a b c d n : ℕ
⊢ ∀ (m : ℕ), m < 4 → m % 2 = 1 → m = 1 ∨ m = 3
[PROOFSTEP]
decide
[GOAL]
m n✝ a b c d n : ℕ
help : ∀ (m : ℕ), m < 4 → m % 2 = 1 → m = 1 ∨ m = 3
hn : n % 2 = 1
⊢ 4 > 0
[PROOFSTEP]
norm_num
[GOAL]
m n✝ a b c d n : ℕ
help : ∀ (m : ℕ), m < 4 → m % 2 = 1 → m = 1 ∨ m = 3
hn : n % 2 = 1
⊢ 2 ∣ 4
[PROOFSTEP]
norm_num


[GOAL]
α : Type u_1
inst✝ : Fintype α
⊢ ↑(powerset univ) = ↑univ
[PROOFSTEP]
simp [-coe_eq_univ]
[GOAL]
α : Type u_1
inst✝ : Fintype α
s : Finset α
⊢ powerset s = univ ↔ s = univ
[PROOFSTEP]
rw [← Finset.powerset_univ, powerset_inj]
[GOAL]
α✝ : Type u_1
α : Type u_2
inst✝ : Fintype α
k : ℕ
⊢ filter (fun s => card s = k) univ = powersetLen k univ
[PROOFSTEP]
ext
[GOAL]
case a
α✝ : Type u_1
α : Type u_2
inst✝ : Fintype α
k : ℕ
a✝ : Finset α
⊢ a✝ ∈ filter (fun s => card s = k) univ ↔ a✝ ∈ powersetLen k univ
[PROOFSTEP]
simp [Finset.mem_powersetLen]
[GOAL]
α : Type u_1
inst✝ : Fintype α
k : ℕ
⊢ card { s // Finset.card s = k } = Nat.choose (card α) k
[PROOFSTEP]
simp [Fintype.subtype_card, Finset.card_univ]
[GOAL]
α : Type u_1
inst✝ : Fintype α
s : Set α
⊢ s ∈ map { toFun := toSet, inj' := (_ : Function.Injective toSet) } (Finset.powerset Finset.univ)
[PROOFSTEP]
classical
refine' mem_map.2 ⟨Finset.univ.filter s, Finset.mem_powerset.2 (Finset.subset_univ _), _⟩
apply (coe_filter _ _).trans
simp
rfl
[GOAL]
α : Type u_1
inst✝ : Fintype α
s : Set α
⊢ s ∈ map { toFun := toSet, inj' := (_ : Function.Injective toSet) } (Finset.powerset Finset.univ)
[PROOFSTEP]
refine' mem_map.2 ⟨Finset.univ.filter s, Finset.mem_powerset.2 (Finset.subset_univ _), _⟩
[GOAL]
α : Type u_1
inst✝ : Fintype α
s : Set α
⊢ ↑{ toFun := toSet, inj' := (_ : Function.Injective toSet) } (filter s Finset.univ) = s
[PROOFSTEP]
apply (coe_filter _ _).trans
[GOAL]
α : Type u_1
inst✝ : Fintype α
s : Set α
⊢ {x | x ∈ Finset.univ ∧ s x} = s
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
inst✝ : Fintype α
s : Set α
⊢ {x | s x} = s
[PROOFSTEP]
rfl
[GOAL]
α : Type u_1
inst✝ : Finite α
⊢ Finite (Set α)
[PROOFSTEP]
cases nonempty_fintype α
[GOAL]
case intro
α : Type u_1
inst✝ : Finite α
val✝ : Fintype α
⊢ Finite (Set α)
[PROOFSTEP]
infer_instance


[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
⊢ #((n : ℕ) × Functions (Language.sum L (skolem₁ L)) n) = #((n : ℕ) × BoundedFormula L Empty (n + 1))
[PROOFSTEP]
simp only [card_functions_sum, skolem₁_Functions, mk_sigma, sum_add_distrib']
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
⊢ ((sum fun i => lift #(Functions L i)) + sum fun i => lift #(BoundedFormula L Empty (i + 1))) =
    sum fun i => #(BoundedFormula L Empty (i + 1))
[PROOFSTEP]
conv_lhs => enter [2, 1, i]; rw [lift_id'.{u, v}]
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
| (sum fun i => lift #(Functions L i)) + sum fun i => lift #(BoundedFormula L Empty (i + 1))
[PROOFSTEP]
enter [2, 1, i]; rw [lift_id'.{u, v}]
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
| (sum fun i => lift #(Functions L i)) + sum fun i => lift #(BoundedFormula L Empty (i + 1))
[PROOFSTEP]
enter [2, 1, i]; rw [lift_id'.{u, v}]
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
| (sum fun i => lift #(Functions L i)) + sum fun i => lift #(BoundedFormula L Empty (i + 1))
[PROOFSTEP]
enter [2, 1, i]
[GOAL]
case h
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
i : ℕ
| lift #(BoundedFormula L Empty (i + 1))
[PROOFSTEP]
rw [lift_id'.{u, v}]
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
⊢ ((sum fun i => lift #(Functions L i)) + sum fun i => #(BoundedFormula L Empty (i + 1))) =
    sum fun i => #(BoundedFormula L Empty (i + 1))
[PROOFSTEP]
rw [add_comm, add_eq_max, max_eq_left]
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
⊢ (sum fun i => lift #(Functions L i)) ≤ sum fun i => #(BoundedFormula L Empty (i + 1))
[PROOFSTEP]
refine' sum_le_sum _ _ fun n => _
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
n : ℕ
⊢ lift #(Functions L n) ≤ #(BoundedFormula L Empty (n + 1))
[PROOFSTEP]
rw [← lift_le.{_, max u v}, lift_lift, lift_mk_le.{v}]
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
n : ℕ
⊢ Nonempty (Functions L n ↪ BoundedFormula L Empty (n + 1))
[PROOFSTEP]
refine' ⟨⟨fun f => (func f default).bdEqual (func f default), fun f g h => _⟩⟩
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
n : ℕ
f g : Functions L n
h : (fun f => func f default =' func f default) f = (fun f => func f default =' func f default) g
⊢ f = g
[PROOFSTEP]
rcases h with ⟨rfl, ⟨rfl⟩⟩
[GOAL]
case refl
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
n : ℕ
f : Functions L n
⊢ f = f
[PROOFSTEP]
rfl
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
⊢ ℵ₀ ≤ sum fun i => #(BoundedFormula L Empty (i + 1))
[PROOFSTEP]
rw [← mk_sigma]
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
⊢ ℵ₀ ≤ #((i : ℕ) × BoundedFormula L Empty (i + 1))
[PROOFSTEP]
exact infinite_iff.1 (Infinite.of_injective (fun n => ⟨n, ⊥⟩) fun x y xy => (Sigma.mk.inj_iff.1 xy).1)
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
⊢ #((n : ℕ) × Functions (Language.sum L (skolem₁ L)) n) ≤ max ℵ₀ (card L)
[PROOFSTEP]
rw [card_functions_sum_skolem₁]
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
⊢ #((n : ℕ) × BoundedFormula L Empty (n + 1)) ≤ max ℵ₀ (card L)
[PROOFSTEP]
trans #(Σ n, L.BoundedFormula Empty n)
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
⊢ #((n : ℕ) × BoundedFormula L Empty (n + 1)) ≤ #((n : ℕ) × BoundedFormula L Empty n)
[PROOFSTEP]
exact ⟨⟨Sigma.map Nat.succ fun _ => id, Nat.succ_injective.sigma_map fun _ => Function.injective_id⟩⟩
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
⊢ #((n : ℕ) × BoundedFormula L Empty n) ≤ max ℵ₀ (card L)
[PROOFSTEP]
refine' _root_.trans BoundedFormula.card_le (lift_le.{max u v}.1 _)
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
⊢ lift (max ℵ₀ (lift #Empty + lift (card L))) ≤ lift (max ℵ₀ (card L))
[PROOFSTEP]
simp only [mk_empty, lift_zero, lift_uzero, zero_add]
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
⊢ lift (max ℵ₀ (card L)) ≤ lift (max ℵ₀ (card L))
[PROOFSTEP]
rfl
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
S : Substructure (Language.sum L (skolem₁ L)) M
⊢ IsElementary (↑(LHom.substructureReduct LHom.sumInl) S)
[PROOFSTEP]
apply (LHom.sumInl.substructureReduct S).isElementary_of_exists
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
S : Substructure (Language.sum L (skolem₁ L)) M
⊢ ∀ (n : ℕ) (φ : BoundedFormula L Empty (n + 1)) (x : Fin n → { x // x ∈ ↑(LHom.substructureReduct LHom.sumInl) S })
    (a : M),
    BoundedFormula.Realize φ default (Fin.snoc (Subtype.val ∘ x) a) →
      ∃ b, BoundedFormula.Realize φ default (Fin.snoc (Subtype.val ∘ x) ↑b)
[PROOFSTEP]
intro n φ x a h
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
S : Substructure (Language.sum L (skolem₁ L)) M
n : ℕ
φ : BoundedFormula L Empty (n + 1)
x : Fin n → { x // x ∈ ↑(LHom.substructureReduct LHom.sumInl) S }
a : M
h : BoundedFormula.Realize φ default (Fin.snoc (Subtype.val ∘ x) a)
⊢ ∃ b, BoundedFormula.Realize φ default (Fin.snoc (Subtype.val ∘ x) ↑b)
[PROOFSTEP]
let φ' : (L.sum L.skolem₁).Functions n := LHom.sumInr.onFunction φ
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
S : Substructure (Language.sum L (skolem₁ L)) M
n : ℕ
φ : BoundedFormula L Empty (n + 1)
x : Fin n → { x // x ∈ ↑(LHom.substructureReduct LHom.sumInl) S }
a : M
h : BoundedFormula.Realize φ default (Fin.snoc (Subtype.val ∘ x) a)
φ' : Functions (Language.sum L (skolem₁ L)) n := LHom.onFunction LHom.sumInr φ
⊢ ∃ b, BoundedFormula.Realize φ default (Fin.snoc (Subtype.val ∘ x) ↑b)
[PROOFSTEP]
exact
  ⟨⟨funMap φ' ((↑) ∘ x), S.fun_mem (LHom.sumInr.onFunction φ) ((↑) ∘ x) (by exact fun i => (x i).2)⟩, by
    exact Classical.epsilon_spec (p := fun a => BoundedFormula.Realize φ default (Fin.snoc (Subtype.val ∘ x) a)) ⟨a, h⟩⟩
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
S : Substructure (Language.sum L (skolem₁ L)) M
n : ℕ
φ : BoundedFormula L Empty (n + 1)
x : Fin n → { x // x ∈ ↑(LHom.substructureReduct LHom.sumInl) S }
a : M
h : BoundedFormula.Realize φ default (Fin.snoc (Subtype.val ∘ x) a)
φ' : Functions (Language.sum L (skolem₁ L)) n := LHom.onFunction LHom.sumInr φ
⊢ ∀ (i : Fin n), (Subtype.val ∘ x) i ∈ ↑S
[PROOFSTEP]
exact fun i => (x i).2
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
S : Substructure (Language.sum L (skolem₁ L)) M
n : ℕ
φ : BoundedFormula L Empty (n + 1)
x : Fin n → { x // x ∈ ↑(LHom.substructureReduct LHom.sumInl) S }
a : M
h : BoundedFormula.Realize φ default (Fin.snoc (Subtype.val ∘ x) a)
φ' : Functions (Language.sum L (skolem₁ L)) n := LHom.onFunction LHom.sumInr φ
⊢ BoundedFormula.Realize φ default
    (Fin.snoc (Subtype.val ∘ x)
      ↑{ val := funMap φ' (Subtype.val ∘ x),
          property := (_ : funMap (LHom.onFunction LHom.sumInr φ) (Subtype.val ∘ x) ∈ ↑S) })
[PROOFSTEP]
exact Classical.epsilon_spec (p := fun a => BoundedFormula.Realize φ default (Fin.snoc (Subtype.val ∘ x) a)) ⟨a, h⟩
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
⊢ Small.{?u.38330, w} { x // x ∈ elementarySkolem₁Reduct ⊥ }
[PROOFSTEP]
rw [coeSort_elementarySkolem₁Reduct]
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
⊢ Small.{?u.38330, w} { x // x ∈ ⊥ }
[PROOFSTEP]
infer_instance
[GOAL]
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h1 : ℵ₀ ≤ κ
h2 : lift #↑s ≤ lift κ
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
⊢ ∃ S, s ⊆ ↑S ∧ lift #{ x // x ∈ S } = lift κ
[PROOFSTEP]
obtain ⟨s', hs'⟩ := Cardinal.le_mk_iff_exists_set.1 h4
[GOAL]
case intro
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h1 : ℵ₀ ≤ κ
h2 : lift #↑s ≤ lift κ
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
hs' : #↑s' = lift κ
⊢ ∃ S, s ⊆ ↑S ∧ lift #{ x // x ∈ S } = lift κ
[PROOFSTEP]
rw [← aleph0_le_lift.{_, w}] at h1
[GOAL]
case intro
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h1 : ℵ₀ ≤ lift κ
h2 : lift #↑s ≤ lift κ
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
hs' : #↑s' = lift κ
⊢ ∃ S, s ⊆ ↑S ∧ lift #{ x // x ∈ S } = lift κ
[PROOFSTEP]
rw [← hs'] at h1 h2 ⊢
[GOAL]
case intro
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
⊢ ∃ S, s ⊆ ↑S ∧ lift #{ x // x ∈ S } = #↑s'
[PROOFSTEP]
refine'
  ⟨elementarySkolem₁Reduct (closure (L.sum L.skolem₁) (s ∪ Equiv.ulift '' s')),
    (s.subset_union_left _).trans subset_closure, _⟩
[GOAL]
case intro
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
⊢ lift
      #{ x //
          x ∈
            elementarySkolem₁Reduct
              (LowerAdjoint.toFun (closure (Language.sum L (skolem₁ L))) (s ∪ ↑Equiv.ulift '' s')) } =
    #↑s'
[PROOFSTEP]
have h := mk_image_eq_lift _ s' Equiv.ulift.injective
[GOAL]
case intro
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = lift #↑s'
⊢ lift
      #{ x //
          x ∈
            elementarySkolem₁Reduct
              (LowerAdjoint.toFun (closure (Language.sum L (skolem₁ L))) (s ∪ ↑Equiv.ulift '' s')) } =
    #↑s'
[PROOFSTEP]
rw [lift_umax.{w, w'}, lift_id'.{w, w'}] at h
[GOAL]
case intro
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = #↑s'
⊢ lift
      #{ x //
          x ∈
            elementarySkolem₁Reduct
              (LowerAdjoint.toFun (closure (Language.sum L (skolem₁ L))) (s ∪ ↑Equiv.ulift '' s')) } =
    #↑s'
[PROOFSTEP]
rw [coeSort_elementarySkolem₁Reduct, ← h, lift_inj]
[GOAL]
case intro
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = #↑s'
⊢ #{ x // x ∈ LowerAdjoint.toFun (closure (Language.sum L (skolem₁ L))) (s ∪ ↑Equiv.ulift '' s') } =
    #↑(↑Equiv.ulift '' s')
[PROOFSTEP]
refine'
  le_antisymm (lift_le.1 (lift_card_closure_le.trans _))
    (mk_le_mk_of_subset ((Set.subset_union_right _ _).trans subset_closure))
[GOAL]
case intro
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = #↑s'
⊢ max ℵ₀ (lift #↑(s ∪ ↑Equiv.ulift '' s') + lift #((i : ℕ) × Functions (Language.sum L (skolem₁ L)) i)) ≤
    lift #↑(↑Equiv.ulift '' s')
[PROOFSTEP]
rw [max_le_iff, aleph0_le_lift, ← aleph0_le_lift.{_, w'}, h, add_eq_max, max_le_iff, lift_le]
[GOAL]
case intro
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = #↑s'
⊢ ℵ₀ ≤ #↑s' ∧
    #↑(s ∪ ↑Equiv.ulift '' s') ≤ #↑(↑Equiv.ulift '' s') ∧
      lift #((i : ℕ) × Functions (Language.sum L (skolem₁ L)) i) ≤ lift #↑(↑Equiv.ulift '' s')
case intro
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = #↑s'
⊢ ℵ₀ ≤ lift #↑(s ∪ ↑Equiv.ulift '' s')
[PROOFSTEP]
refine' ⟨h1, (mk_union_le _ _).trans _, (lift_le.2 card_functions_sum_skolem₁_le).trans _⟩
[GOAL]
case intro.refine'_1
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = #↑s'
⊢ #↑s + #↑(↑Equiv.ulift '' s') ≤ #↑(↑Equiv.ulift '' s')
[PROOFSTEP]
rw [← lift_le, lift_add, h, add_comm, add_eq_max h1]
[GOAL]
case intro.refine'_1
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = #↑s'
⊢ max (#↑s') (lift #↑s) ≤ #↑s'
[PROOFSTEP]
exact max_le le_rfl h2
[GOAL]
case intro.refine'_2
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = #↑s'
⊢ lift (max ℵ₀ (card L)) ≤ lift #↑(↑Equiv.ulift '' s')
[PROOFSTEP]
rw [lift_max, lift_aleph0, max_le_iff, aleph0_le_lift, and_comm, ← lift_le.{w'}, lift_lift, lift_lift, ← aleph0_le_lift,
  h]
[GOAL]
case intro.refine'_2
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = #↑s'
⊢ lift (card L) ≤ lift #↑(↑Equiv.ulift '' s') ∧ ℵ₀ ≤ #↑s'
[PROOFSTEP]
refine' ⟨_, h1⟩
[GOAL]
case intro.refine'_2
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = #↑s'
⊢ lift (card L) ≤ lift #↑(↑Equiv.ulift '' s')
[PROOFSTEP]
rw [← lift_lift.{w', w}]
[GOAL]
case intro.refine'_2
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = #↑s'
⊢ lift (lift (card L)) ≤ lift #↑(↑Equiv.ulift '' s')
[PROOFSTEP]
refine' _root_.trans (lift_le.{w}.2 h3) _
[GOAL]
case intro.refine'_2
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = #↑s'
⊢ lift (lift κ) ≤ lift #↑(↑Equiv.ulift '' s')
[PROOFSTEP]
rw [lift_lift, ← lift_lift.{w, max u v}, ← hs', ← h, lift_lift]
[GOAL]
case intro
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = #↑s'
⊢ ℵ₀ ≤ lift #↑(s ∪ ↑Equiv.ulift '' s')
[PROOFSTEP]
refine' _root_.trans _ (lift_le.2 (mk_le_mk_of_subset (Set.subset_union_right _ _)))
[GOAL]
case intro
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = #↑s'
⊢ ℵ₀ ≤ lift #↑(↑Equiv.ulift '' s')
[PROOFSTEP]
rw [aleph0_le_lift, ← aleph0_le_lift, h]
[GOAL]
case intro
L : Language
M : Type w
inst✝¹ : Nonempty M
inst✝ : Structure L M
s : Set M
κ : Cardinal.{w'}
h3 : lift (card L) ≤ lift κ
h4 : lift κ ≤ lift #M
s' : Set (ULift M)
h2 : lift #↑s ≤ #↑s'
h1 : ℵ₀ ≤ #↑s'
hs' : #↑s' = lift κ
h : lift #↑(↑Equiv.ulift '' s') = #↑s'
⊢ ℵ₀ ≤ #↑s'
[PROOFSTEP]
exact h1