Zulip Chat Archive

Stream: new members

Topic: How to "deconstruct" ordinal comparison?


Bbbbbbbbba (Jun 07 2024 at 05:10):

Basically, I want to prove
lemma oadd_lt_iff [ONote.NF (ONote.oadd e0 n0 a0)] [ONote.NF (ONote.oadd e1 n1 a1)] : e0.oadd n0 a0 < e1.oadd n1 a1 ↔ e0 < e1 ∨ e0 = e1 ∧ n0 < n1 ∨ e0 = e1 ∧ n0 = n1 ∧ a0 < a1 := sorry
so that when I encounter the condition o0 < o1 in the future, I can separately consider those three cases (in addition to the o0 = 0 case).

Is there an easy way to prove this, or a better way to do what I am trying to do?

Yaël Dillies (Jun 07 2024 at 05:12):

Can you provide a #mwe ?

Bbbbbbbbba (Jun 07 2024 at 05:26):

I cannot think of a simple realistic example right now, so I'll just show how I would prove the forward direction of this lemma with itself (obviously in real use cases exact Or.inl h etc. will be replaced by more complicated arguments)

import Mathlib

lemma oadd_lt_iff [ONote.NF (ONote.oadd e0 n0 a0)] [ONote.NF (ONote.oadd e1 n1 a1)] : e0.oadd n0 a0 < e1.oadd n1 a1  e0 < e1  e0 = e1  n0 < n1  e0 = e1  n0 = n1  a0 < a1 := sorry

lemma mwe [ONote.NF (ONote.oadd e0 n0 a0)] [ONote.NF (ONote.oadd e1 n1 a1)] : e0.oadd n0 a0 < e1.oadd n1 a1  e0 < e1  e0 = e1  n0 < n1  e0 = e1  n0 = n1  a0 < a1 := by
  intro h
  rw [oadd_lt_iff] at h
  cases h with
  | inl h => exact Or.inl h
  | inr h => cases h with
    | inl h => exact Or.inr (Or.inl h)
    | inr h => exact Or.inr (Or.inr h)

Yaël Dillies (Jun 07 2024 at 05:28):

Please add the imports

Bbbbbbbbba (Jun 07 2024 at 05:30):

Like this?

Yaël Dillies (Jun 07 2024 at 05:35):

If it doesn't work for you, it doesn't work for me!

Bbbbbbbbba (Jun 07 2024 at 05:53):

What do you mean, is it that I have to capitalize the import Mathlib? (Edited in the snippet above)

Bbbbbbbbba (Jun 07 2024 at 05:54):

import mathlib seems to be working fine in VSCode, but not on the web playground, and I don't have an idea why

Ira Fesefeldt (Jun 07 2024 at 06:05):

Could it be because of the operating system? Windows file system is case-insensitive, Linux is case-sensitive

Bbbbbbbbba (Jun 07 2024 at 06:17):

Oh right it could be, I am on Windows

Bbbbbbbbba (Jun 07 2024 at 06:56):

Bbbbbbbbba said:

I cannot think of a simple realistic example right now, so I'll just show how I would prove the forward direction of this lemma with itself (obviously in real use cases exact Or.inl h etc. will be replaced by more complicated arguments)

import Mathlib

lemma oadd_lt_iff [ONote.NF (ONote.oadd e0 n0 a0)] [ONote.NF (ONote.oadd e1 n1 a1)] : e0.oadd n0 a0 < e1.oadd n1 a1  e0 < e1  e0 = e1  n0 < n1  e0 = e1  n0 = n1  a0 < a1 := sorry

lemma mwe [ONote.NF (ONote.oadd e0 n0 a0)] [ONote.NF (ONote.oadd e1 n1 a1)] : e0.oadd n0 a0 < e1.oadd n1 a1  e0 < e1  e0 = e1  n0 < n1  e0 = e1  n0 = n1  a0 < a1 := by
  intro h
  rw [oadd_lt_iff] at h
  cases h with
  | inl h => exact Or.inl h
  | inr h => cases h with
    | inl h => exact Or.inr (Or.inl h)
    | inr h => exact Or.inr (Or.inr h)

But anyway now the mwe should be fixed, so does anyone know how to prove this lemma or do what I want to do in a better way?

Ira Fesefeldt (Jun 07 2024 at 07:49):

nvm

Ira Fesefeldt (Jun 07 2024 at 08:02):

I think the proof is rather cumbersome tho. I started it and required for the left-to-right-direction quite some cases or induction for every variable. The other direction can be proven easily with oadd_lt_oadd_1/2/3. But regarding the question of your title:
You can 'destruct' the ordinal comparison using ONote.lt_def and ONote.repr. This will transform it into its ordinal representative. Often this will give you contradictions in the inequality and finish your proof this way. I have not done the proof to its end though.

Bbbbbbbbba (Jun 07 2024 at 08:04):

Thanks for the advice, I'll try later

Ira Fesefeldt (Jun 07 2024 at 08:04):

i.e. like this:

import Mathlib

open ONote

lemma oadd_lt_iff [nf0 : (oadd e0 n0 a0).NF] [nf1 : (oadd e1 n1 a1).NF] :
    e0.oadd n0 a0 < e1.oadd n1 a1  e0 < e1  e0 = e1  n0 < n1  e0 = e1  n0 = n1  a0 < a1 := by
  apply Iff.intro
  · intro h
    simp only [lt_def, ONote.repr] at h
    sorry
  · rintro (h_e | h_e, h_n | h_e, h_n, h_a)
    · exact ONote.oadd_lt_oadd_1 nf0 h_e
    · rw [ h_e]; exact ONote.oadd_lt_oadd_2 nf0 h_n
    · rw [ h_e,  h_n]; exact ONote.oadd_lt_oadd_3 h_a

where the sorry part is what I believe is rather cumbersome.

Bbbbbbbbba (Jun 08 2024 at 02:56):

I have actually done this using just the trichotomy of ordinal comparison and the oadd_lt_oadd_* theorems. Thanks for showing me how to use rintro (whose documentation pointed me to rcases)! And please tell me if there are ways to improve the proof :stuck_out_tongue_wink:

import Mathlib

open ONote

lemma oadd_lt_iff [hnf0 : (oadd e0 n0 a0).NF] [hnf1 : (oadd e1 n1 a1).NF] :
    e0.oadd n0 a0 < e1.oadd n1 a1  e0 < e1  e0 = e1  n0 < n1  e0 = e1  n0 = n1  a0 < a1 := by
  apply Iff.intro
  · rw [ not_imp_not, not_or, not_or]
    intro he, hn, ha
    rw [lt_def]
    rcases lt_trichotomy e0.repr e1.repr with he1 | he1 | he1
    . apply lt_def.mpr at he1
      contradiction
    . have _ := hnf0.fst
      have _ := hnf1.fst
      apply repr_inj.mp at he1
      rcases lt_trichotomy n0 n1 with hn1 | hn1 | hn1
      . have : e0 = e1  n0 < n1 := he1, hn1
        contradiction
      . rcases lt_trichotomy a0.repr a1.repr with ha1 | ha1 | ha1
        . apply lt_def.mpr at ha1
          have : e0 = e1  n0 = n1  a0 < a1 := he1, hn1, ha1
          contradiction
        . have _ := hnf0.snd
          have _ := hnf1.snd
          apply repr_inj.mp at ha1
          rw [he1, hn1, ha1]
          exact gt_irrefl (e1.oadd n1 a1).repr
        . apply not_lt_of_gt
          apply lt_def.mp
          rw [he1, hn1]
          exact oadd_lt_oadd_3 ha1
      . apply not_lt_of_gt
        apply lt_def.mp
        rw [he1]
        exact oadd_lt_oadd_2 hnf1 hn1
    . apply lt_def.mpr at he1
      apply not_lt_of_gt
      apply lt_def.mp
      exact oadd_lt_oadd_1 hnf1 he1
  · rintro (he | he, hn | he, hn, ha)
    · exact oadd_lt_oadd_1 hnf0 he
    · rw [ he]; exact oadd_lt_oadd_2 hnf0 hn
    · rw [ he,  hn]; exact oadd_lt_oadd_3 ha

Bbbbbbbbba (Jun 08 2024 at 03:24):

One thing I'm wondering in particular is if there is a more concise way to fill in the implicit inputs [a.NF] [b.NF] to repr_inj than have _ := hnf0.fst; have _ := hnf1.fst etc.


Last updated: May 02 2025 at 03:31 UTC