Skip to content

Commit

Permalink
feat(set_theory/ordinal/arithmetic): Add missing instances for `ordin…
Browse files Browse the repository at this point in the history
…al` (#14128)

We add the following instances:
- `monoid_with_zero ordinal`
- `no_zero_divisors ordinal`
- `is_left_distrib_class ordinal`
- `contravariant_class ordinal ordinal (swap (+)) (<)`
- `is_antisymm ordinal (∣)`
  • Loading branch information
vihdzp committed May 28, 2022
1 parent 3280d00 commit 762fc15
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 76 deletions.
87 changes: 37 additions & 50 deletions src/set_theory/ordinal/arithmetic.lean
Expand Up @@ -71,7 +71,7 @@ quotient.sound ⟨(rel_iso.preimage equiv.ulift _).trans
@[simp] theorem lift_succ (a) : lift (succ a) = succ (lift a) :=
by { rw [←add_one_eq_succ, lift_add, lift_one], refl }

instance has_le.le.add_contravariant_class : contravariant_class ordinal.{u} ordinal.{u} (+) (≤) :=
instance add_contravariant_class_le : contravariant_class ordinal.{u} ordinal.{u} (+) (≤) :=
⟨λ a b c, induction_on a $ λ α r hr, induction_on b $ λ β₁ s₁ hs₁, induction_on c $ λ β₂ s₂ hs₂ ⟨f⟩,
have fl : ∀ a, f (sum.inl a) = sum.inl a := λ a,
by simpa only [initial_seg.trans_apply, initial_seg.le_add_apply]
Expand All @@ -98,7 +98,7 @@ instance has_le.le.add_contravariant_class : contravariant_class ordinal.{u} ord
theorem add_succ (o₁ o₂ : ordinal) : o₁ + succ o₂ = succ (o₁ + o₂) :=
(add_assoc _ _ _).symm

@[simp] theorem succ_zero : succ (0 : ordinal) = 1 := zero_add _
@[simp] theorem succ_zero : succ (0 : ordinal) = 1 := zero_add 1
@[simp] theorem succ_one : succ (1 : ordinal) = 2 := rfl

theorem one_le_iff_pos {o : ordinal} : 1 ≤ o ↔ 0 < o :=
Expand Down Expand Up @@ -127,14 +127,15 @@ by rw [←succ_zero, lt_succ_iff, ordinal.le_zero]
private theorem add_lt_add_iff_left' (a) {b c : ordinal} : a + b < a + c ↔ b < c :=
by rw [← not_le, ← not_le, add_le_add_iff_left]

instance : covariant_class ordinal.{u} ordinal.{u} (+) (<) :=
instance add_covariant_class_lt : covariant_class ordinal.{u} ordinal.{u} (+) (<) :=
⟨λ a b c, (add_lt_add_iff_left' a).2

instance : contravariant_class ordinal.{u} ordinal.{u} (+) (<) :=
instance add_contravariant_class_lt : contravariant_class ordinal.{u} ordinal.{u} (+) (<) :=
⟨λ a b c, (add_lt_add_iff_left' a).1

theorem lt_of_add_lt_add_right {a b c : ordinal} : a + b < c + b → a < c :=
lt_imp_lt_of_le_imp_le (λ h, add_le_add_right h _)
instance add_swap_contravariant_class_lt :
contravariant_class ordinal.{u} ordinal.{u} (swap (+)) (<) :=
⟨λ a b c, lt_imp_lt_of_le_imp_le (λ h, add_le_add_right h _)⟩

theorem add_le_add_iff_right {a b : ordinal} (n : ℕ) : a + n ≤ b + n ↔ a ≤ b :=
by induction n with n ih; [rw [nat.cast_zero, add_zero, add_zero],
Expand Down Expand Up @@ -584,7 +585,23 @@ instance : monoid ordinal.{u} :=
simp only [prod.lex_def, empty_relation, and_false, or_false]; refl⟩⟩ }

@[simp] theorem type_mul {α β : Type u} (r : α → α → Prop) (s : β → β → Prop)
[is_well_order α r] [is_well_order β s] : type r * type s = type (prod.lex s r) := rfl
[is_well_order α r] [is_well_order β s] : type (prod.lex s r) = type r * type s := rfl

private theorem mul_eq_zero' {a b : ordinal} : a * b = 0 ↔ a = 0 ∨ b = 0 :=
induction_on a $ λ α _ _, induction_on b $ λ β _ _, begin
simp_rw [←type_mul, type_eq_zero_iff_is_empty],
rw or_comm,
exact is_empty_prod
end

instance : monoid_with_zero ordinal :=
{ zero := 0,
mul_zero := λ a, mul_eq_zero'.2 $ or.inr rfl,
zero_mul := λ a, mul_eq_zero'.2 $ or.inl rfl,
..ordinal.monoid }

instance : no_zero_divisors ordinal :=
⟨λ a b, mul_eq_zero'.1

@[simp] theorem lift_mul (a b) : lift (a * b) = lift a * lift b :=
quotient.induction_on₂ a b $ λ ⟨α, r, _⟩ ⟨β, s, _⟩,
Expand All @@ -596,40 +613,19 @@ quotient.sound ⟨(rel_iso.preimage equiv.ulift _).trans
quotient.induction_on₂ a b $ λ ⟨α, r, _⟩ ⟨β, s, _⟩,
mul_comm (mk β) (mk α)

theorem mul_eq_zero_iff {a b : ordinal} : a * b = 0 ↔ (a = 0 ∨ b = 0) :=
induction_on a $ λ α _ _, induction_on b $ λ β _ _, begin
simp_rw [type_mul, type_eq_zero_iff_is_empty],
rw or_comm,
exact is_empty_prod
end

@[simp] theorem mul_zero (a : ordinal) : a * 0 = 0 :=
mul_eq_zero_iff.2 $ or.inr rfl

@[simp] theorem zero_mul (a : ordinal) : 0 * a = 0 :=
mul_eq_zero_iff.2 $ or.inl rfl

theorem mul_add (a b c : ordinal) : a * (b + c) = a * b + a * c :=
quotient.induction_on₃ a b c $ λ ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨γ, t, _⟩,
instance : left_distrib_class ordinal.{u} :=
⟨λ a b c, quotient.induction_on₃ a b c $ λ ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨γ, t, _⟩,
quotient.sound ⟨⟨sum_prod_distrib _ _ _, begin
rintro ⟨a₁|a₁, a₂⟩ ⟨b₁|b₁, b₂⟩; simp only [prod.lex_def,
rintro ⟨a₁|a₁, a₂⟩ ⟨b₁|b₁, b₂⟩;
simp only [prod.lex_def,
sum.lex_inl_inl, sum.lex.sep, sum.lex_inr_inl, sum.lex_inr_inr,
sum_prod_distrib_apply_left, sum_prod_distrib_apply_right];
simp only [sum.inl.inj_iff, true_or, false_and, false_or]
end⟩⟩

theorem mul_add_one (a b : ordinal) : a * (b + 1) = a * b + a :=
by rw [mul_add, mul_one]

theorem mul_one_add (a b : ordinal) : a * (1 + b) = a + a * b :=
by rw [mul_add, mul_one]

theorem mul_succ (a b : ordinal) : a * succ b = a * b + a := mul_add_one _ _
end⟩⟩⟩

theorem mul_two (a : ordinal) : a * 2 = a + a :=
by { change a * (succ 1) = a + a, rw [mul_succ, mul_one] }
theorem mul_succ (a b : ordinal) : a * succ b = a * b + a := mul_add_one a b

instance has_le.le.mul_covariant_class : covariant_class ordinal.{u} ordinal.{u} (*) (≤) :=
instance mul_covariant_class_le : covariant_class ordinal.{u} ordinal.{u} (*) (≤) :=
⟨λ c a b, quotient.induction_on₃ a b c $ λ ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨γ, t, _⟩ ⟨f⟩, begin
resetI,
refine type_le'.2 ⟨rel_embedding.of_monotone
Expand All @@ -640,8 +636,7 @@ instance has_le.le.mul_covariant_class : covariant_class ordinal.{u} ordinal.{u}
{ exact prod.lex.right _ h' }
end

instance has_le.le.mul_swap_covariant_class :
covariant_class ordinal.{u} ordinal.{u} (swap (*)) (≤) :=
instance mul_swap_covariant_class_le : covariant_class ordinal.{u} ordinal.{u} (swap (*)) (≤) :=
⟨λ c a b, quotient.induction_on₃ a b c $ λ ⟨α, r, _⟩ ⟨β, s, _⟩ ⟨γ, t, _⟩ ⟨f⟩, begin
resetI,
refine type_le'.2 ⟨rel_embedding.of_monotone
Expand Down Expand Up @@ -855,16 +850,6 @@ theorem dvd_add_iff : ∀ {a b c : ordinal}, a ∣ b → (a ∣ b + c ↔ a ∣
⟨λ ⟨d, e⟩, ⟨d - b, by rw [mul_sub, ← e, add_sub_cancel]⟩,
λ ⟨d, e⟩, by { rw [e, ← mul_add], apply dvd_mul_right }⟩

theorem dvd_add {a b c : ordinal} (h₁ : a ∣ b) : a ∣ c → a ∣ b + c :=
(dvd_add_iff h₁).2

theorem dvd_zero (a : ordinal) : a ∣ 0 := ⟨_, (mul_zero _).symm⟩

theorem zero_dvd {a : ordinal} : 0 ∣ a ↔ a = 0 :=
⟨λ ⟨h, e⟩, by simp only [e, zero_mul], λ e, e.symm ▸ dvd_zero _⟩

theorem one_dvd (a : ordinal) : 1 ∣ a := ⟨a, (one_mul _).symm⟩

theorem div_mul_cancel : ∀ {a b : ordinal}, a ≠ 0 → a ∣ b → a * (b / a) = b
| a _ a0 ⟨b, rfl⟩ := by rw [mul_div_cancel _ a0]

Expand All @@ -873,9 +858,11 @@ theorem le_of_dvd : ∀ {a b : ordinal}, b ≠ 0 → a ∣ b → a ≤ b
(one_le_iff_ne_zero.2 (λ h : b = 0, by simpa only [h, mul_zero] using b0)) a

theorem dvd_antisymm {a b : ordinal} (h₁ : a ∣ b) (h₂ : b ∣ a) : a = b :=
if a0 : a = 0 then by subst a; exact (zero_dvd.1 h₁).symm else
if b0 : b = 0 then by subst b; exact zero_dvd.1 h₂ else
le_antisymm (le_of_dvd b0 h₁) (le_of_dvd a0 h₂)
if a0 : a = 0 then by subst a; exact (eq_zero_of_zero_dvd h₁).symm else
if b0 : b = 0 then by subst b; exact eq_zero_of_zero_dvd h₂ else
(le_of_dvd b0 h₁).antisymm (le_of_dvd a0 h₂)

instance : is_antisymm ordinal (∣) := ⟨@dvd_antisymm⟩

/-- `a % b` is the unique ordinal `o'` satisfying
`a = b * o + o'` with `o' < b`. -/
Expand Down
24 changes: 12 additions & 12 deletions src/set_theory/ordinal/basic.lean
Expand Up @@ -933,12 +933,17 @@ the addition, together with properties of the other operations, are proved in
`ordinal_arithmetic.lean`.
-/

/-- `o₁ + o₂` is the order on the disjoint union of `o₁` and `o₂` obtained by declaring that
every element of `o₁` is smaller than every element of `o₂`. -/
instance : has_add ordinal.{u} :=
⟨λ o₁ o₂, quotient.lift_on₂ o₁ o₂
(λ ⟨α, r, wo⟩ ⟨β, s, wo'⟩, ⟦⟨α ⊕ β, sum.lex r s, by exactI sum.lex.is_well_order _ _⟩⟧
: Well_order → Well_order → ordinal) $
λ ⟨α₁, r₁, o₁⟩ ⟨α₂, r₂, o₂⟩ ⟨β₁, s₁, p₁⟩ ⟨β₂, s₂, p₂⟩ ⟨f⟩ ⟨g⟩,
quot.sound ⟨rel_iso.sum_lex_congr f g⟩⟩

instance : add_monoid ordinal.{u} :=
{ add := λ o₁ o₂, quotient.lift_on₂ o₁ o₂
(λ ⟨α, r, wo⟩ ⟨β, s, wo'⟩, ⟦⟨α ⊕ β, sum.lex r s, by exactI sum.lex.is_well_order _ _⟩⟧
: Well_order → Well_order → ordinal) $
λ ⟨α₁, r₁, o₁⟩ ⟨α₂, r₂, o₂⟩ ⟨β₁, s₁, p₁⟩ ⟨β₂, s₂, p₂⟩ ⟨f⟩ ⟨g⟩,
quot.sound ⟨rel_iso.sum_lex_congr f g⟩,
{ add := (+),
zero := 0,
zero_add := λ o, induction_on o $ λ α r _, eq.symm $ quotient.sound
⟨⟨(empty_sum pempty α).symm, λ a b, sum.lex_inr_inr⟩⟩,
Expand All @@ -951,10 +956,6 @@ instance : add_monoid ordinal.{u} :=
simp only [sum_assoc_apply_inl_inl, sum_assoc_apply_inl_inr, sum_assoc_apply_inr,
sum.lex_inl_inl, sum.lex_inr_inr, sum.lex.sep, sum.lex_inr_inl] end⟩⟩ }

/-- `o₁ + o₂` is the order on the disjoint union of `o₁` and `o₂` obtained by declaring that
every element of `o₁` is smaller than every element of `o₂`. -/
add_decl_doc ordinal.add_monoid.add

@[simp] theorem card_add (o₁ o₂ : ordinal) : card (o₁ + o₂) = card o₁ + card o₂ :=
induction_on o₁ $ λ α r _, induction_on o₂ $ λ β s _, rfl

Expand All @@ -964,7 +965,7 @@ by induction n; [refl, simp only [card_add, card_one, nat.cast_succ, *]]
@[simp] theorem type_add {α β : Type u} (r : α → α → Prop) (s : β → β → Prop)
[is_well_order α r] [is_well_order β s] : type r + type s = type (sum.lex r s) := rfl

instance has_le.le.add_covariant_class : covariant_class ordinal.{u} ordinal.{u} (+) (≤) :=
instance add_covariant_class_le : covariant_class ordinal.{u} ordinal.{u} (+) (≤) :=
⟨λ c a b h, begin
revert h c, exact (
induction_on a $ λ α₁ r₁ _, induction_on b $ λ α₂ r₂ _ ⟨⟨⟨f, fo⟩, fi⟩⟩ c,
Expand All @@ -984,8 +985,7 @@ instance has_le.le.add_covariant_class : covariant_class ordinal.{u} ordinal.{u}
end⟩⟩)
end

instance has_le.le.add_swap_covariant_class :
covariant_class ordinal.{u} ordinal.{u} (swap (+)) (≤) :=
instance add_swap_covariant_class_le : covariant_class ordinal.{u} ordinal.{u} (swap (+)) (≤) :=
⟨λ c a b h, begin
revert h c, exact (
induction_on a $ λ α₁ r₁ hr₁, induction_on b $ λ α₂ r₂ hr₂ ⟨⟨⟨f, fo⟩, fi⟩⟩ c,
Expand Down
2 changes: 1 addition & 1 deletion src/set_theory/ordinal/fixed_point.lean
Expand Up @@ -560,7 +560,7 @@ end
theorem mul_eq_right_iff_opow_omega_dvd {a b : ordinal} : a * b = b ↔ a ^ omega ∣ b :=
begin
cases eq_zero_or_pos a with ha ha,
{ rw [ha, zero_mul, zero_opow omega_ne_zero, zero_dvd],
{ rw [ha, zero_mul, zero_opow omega_ne_zero, zero_dvd_iff],
exact eq_comm },
refine ⟨λ hab, _, λ h, _⟩,
{ rw dvd_iff_mod_eq_zero,
Expand Down
28 changes: 15 additions & 13 deletions src/set_theory/ordinal/notation.lean
Expand Up @@ -388,7 +388,7 @@ instance add_NF (o₁ o₂) : ∀ [NF o₁] [NF o₂], NF (o₁ + o₂)
{ simpa using (mul_le_mul_iff_left $
opow_pos (repr e') omega_pos).2 (nat_cast_le.2 n'.pos) } },
{ change e = e' at ee, substI e',
rw [← add_assoc, ← ordinal.mul_add, ← nat.cast_add] }
rw [← add_assoc, ← mul_add, ← nat.cast_add] }
end

theorem sub_NF_below : ∀ {o₁ o₂ b}, NF_below o₁ b → NF o₂ → NF_below (o₁ - o₂) b
Expand Down Expand Up @@ -434,7 +434,7 @@ instance sub_NF (o₁ o₂) : ∀ [NF o₁] [NF o₂], NF (o₁ - o₂)
lt_of_le_of_ne (tsub_eq_zero_iff_le.1 mn) (mt pnat.eq en)).symm } },
{ simp [nat.succ_pnat, -nat.cast_succ],
rw [(tsub_eq_iff_eq_add_of_le $ le_of_lt $ nat.lt_of_sub_eq_succ mn).1 mn,
add_comm, nat.cast_add, ordinal.mul_add, add_assoc, add_sub_add_cancel],
add_comm, nat.cast_add, mul_add, add_assoc, add_sub_add_cancel],
refine (ordinal.sub_eq_of_add_eq $ add_absorp h₂.snd'.repr_lt $
le_trans _ (le_add_right _ _)).symm,
simpa using mul_le_mul_left' (nat_cast_le.2 $ nat.succ_pos _) _ } },
Expand All @@ -452,8 +452,11 @@ def mul : onote → onote → onote

instance : has_mul onote := ⟨mul⟩

@[simp] theorem zero_mul (o : onote) : 0 * o = 0 := by cases o; refl
@[simp] theorem mul_zero (o : onote) : o * 0 = 0 := by cases o; refl
instance : mul_zero_class onote :=
{ mul := (*),
zero := 0,
zero_mul := λ o, by cases o; refl,
mul_zero := λ o, by cases o; refl }

theorem oadd_mul (e₁ n₁ a₁ e₂ n₂ a₂) : oadd e₁ n₁ a₁ * oadd e₂ n₂ a₂ =
if e₂ = 0 then oadd e₁ (n₁ * n₂) a₁ else
Expand All @@ -480,8 +483,8 @@ instance mul_NF : ∀ o₁ o₂ [NF o₁] [NF o₂], NF (o₁ * o₂)
⟨⟨_, oadd_mul_NF_below hb₁ hb₂⟩⟩

@[simp] theorem repr_mul : ∀ o₁ o₂ [NF o₁] [NF o₂], repr (o₁ * o₂) = repr o₁ * repr o₂
| 0 o h₁ h₂ := by cases o; exact (ordinal.zero_mul _).symm
| (oadd e₁ n₁ a₁) 0 h₁ h₂ := (ordinal.mul_zero _).symm
| 0 o h₁ h₂ := by cases o; exact (zero_mul _).symm
| (oadd e₁ n₁ a₁) 0 h₁ h₂ := (mul_zero _).symm
| (oadd e₁ n₁ a₁) (oadd e₂ n₂ a₂) h₁ h₂ := begin
have IH : repr (mul _ _) = _ := @repr_mul _ _ h₁ h₂.snd,
conv {to_lhs, simp [(*)]},
Expand All @@ -494,7 +497,7 @@ instance mul_NF : ∀ o₁ o₂ [NF o₁] [NF o₂], NF (o₁ * o₂)
simp [h₂.zero_of_zero e0, xe, -nat.cast_succ],
rw [← nat_cast_succ x, add_mul_succ _ ao, mul_assoc] },
{ haveI := h₁.fst, haveI := h₂.fst,
simp [IH, repr_add, opow_add, ordinal.mul_add],
simp [IH, repr_add, opow_add, mul_add],
rw ← mul_assoc, congr' 2,
have := mt repr_inj.1 e0,
rw [add_mul_limit ao (opow_is_limit_left omega_is_limit this),
Expand Down Expand Up @@ -587,7 +590,7 @@ theorem NF_repr_split' : ∀ {o o' m} [NF o], split' o = (o', m) → NF o' ∧ r
refine IH₁.below_of_lt' ((mul_lt_mul_iff_left omega_pos).1 $
lt_of_le_of_lt (le_add_right _ m') _),
rw [← this, ← IH₂], exact h.snd'.repr_lt },
{ rw this, simp [ordinal.mul_add, mul_assoc, add_assoc] } }
{ rw this, simp [mul_add, mul_assoc, add_assoc] } }
end

theorem scale_eq_mul (x) [NF x] : ∀ o [NF o], scale x o = oadd x 1 0 * o
Expand Down Expand Up @@ -665,8 +668,7 @@ end
theorem scale_opow_aux (e a0 a : onote) [NF e] [NF a0] [NF a] :
∀ k m, repr (opow_aux e a0 a k m) = ω ^ repr e * repr (opow_aux 0 a0 a k m)
| 0 m := by cases m; simp [opow_aux]
| (k+1) m := by by_cases m = 0; simp [h, opow_aux,
ordinal.mul_add, opow_add, mul_assoc, scale_opow_aux]
| (k+1) m := by by_cases m = 0; simp [h, opow_aux, mul_add, opow_add, mul_assoc, scale_opow_aux]

theorem repr_opow_aux₁ {e a} [Ne : NF e] [Na : NF a] {a' : ordinal}
(e0 : repr e ≠ 0) (h : a' < ω ^ repr e) (aa : repr a = a') (n : ℕ+) :
Expand Down Expand Up @@ -737,11 +739,11 @@ begin
ω0 ^ k.succ * α' + R'
= ω0 ^ succ k * α' + (ω0 ^ k * α' * m + R) : by rw [nat_cast_succ, RR, ← mul_assoc]
... = (ω0 ^ k * α' + R) * α' + (ω0 ^ k * α' + R) * m : _
... = (α' + m) ^ succ k.succ : by rw [← ordinal.mul_add, ← nat_cast_succ, opow_succ, IH.2],
... = (α' + m) ^ succ k.succ : by rw [← mul_add, ← nat_cast_succ, opow_succ, IH.2],
congr' 1,
{ have αd : ω ∣ α' := dvd_add (dvd_mul_of_dvd_left
(by simpa using opow_dvd_opow ω (one_le_iff_ne_zero.2 e0)) _) d,
rw [ordinal.mul_add (ω0 ^ k), add_assoc, ← mul_assoc, ← opow_succ,
rw [mul_add (ω0 ^ k), add_assoc, ← mul_assoc, ← opow_succ,
add_mul_limit _ (is_limit_iff_omega_dvd.2 ⟨ne_of_gt α0, αd⟩), mul_assoc,
@mul_omega_dvd n (nat_cast_pos.2 n.pos) (nat_lt_omega _) _ αd],
apply @add_absorp _ (repr a0 * succ k),
Expand Down Expand Up @@ -785,7 +787,7 @@ begin
{ simp [opow, r₂, opow_mul, repr_opow_aux₁ a00 al aa, add_assoc] },
{ simp [opow, r₂, opow_add, opow_mul, mul_assoc, add_assoc],
rw [repr_opow_aux₁ a00 al aa, scale_opow_aux], simp [opow_mul],
rw [← ordinal.mul_add, ← add_assoc (ω ^ repr a0 * (n:ℕ))], congr' 1,
rw [← mul_add, ← add_assoc (ω ^ repr a0 * (n:ℕ))], congr' 1,
rw [← opow_succ],
exact (repr_opow_aux₂ _ ad a00 al _ _).2 } }
end
Expand Down

0 comments on commit 762fc15

Please sign in to comment.