Theorem: String.lt_iff_toList_lt
File: Mathlib/Data/String/Basic.lean

tactic: induction s₁ generalizing s₂ <;> cases s₂
state_before: s₁ s₂ : List Char
⊢ ltb { s := { data := s₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ s₁ < s₂
state_after: case nil.nil

⊢ ltb { s := { data := [] }, i := 0 } { s := { data := [] }, i := 0 } = true ↔ [] < []

case nil.cons
head✝ : Char
tail✝ : List Char
⊢ ltb { s := { data := [] }, i := 0 } { s := { data := head✝ :: tail✝ }, i := 0 } = true ↔ [] < head✝ :: tail✝

case cons.nil
head✝ : Char
tail✝ : List Char
tail_ih✝ :
  ∀ (s₂ : List Char), ltb { s := { data := tail✝ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ tail✝ < s₂
⊢ ltb { s := { data := head✝ :: tail✝ }, i := 0 } { s := { data := [] }, i := 0 } = true ↔ head✝ :: tail✝ < []

case cons.cons
head✝¹ : Char
tail✝¹ : List Char
tail_ih✝ :
  ∀ (s₂ : List Char), ltb { s := { data := tail✝¹ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ tail✝¹ < s₂
head✝ : Char
tail✝ : List Char
⊢ ltb { s := { data := head✝¹ :: tail✝¹ }, i := 0 } { s := { data := head✝ :: tail✝ }, i := 0 } = true ↔
    head✝¹ :: tail✝¹ < head✝ :: tail✝

tactic: unfold ltb
state_before: case nil.nil

⊢ ltb { s := { data := [] }, i := 0 } { s := { data := [] }, i := 0 } = true ↔ [] < []
state_after: case nil.nil

⊢ (if { s := { data := [] }, i := 0 }.hasNext = true then
        if { s := { data := [] }, i := 0 }.hasNext = true then
          if { s := { data := [] }, i := 0 }.curr = { s := { data := [] }, i := 0 }.curr then
            ltb { s := { data := [] }, i := 0 }.next { s := { data := [] }, i := 0 }.next
          else decide ({ s := { data := [] }, i := 0 }.curr < { s := { data := [] }, i := 0 }.curr)
        else true
      else false) =
      true ↔
    [] < []

tactic: decide
state_before: case nil.nil

⊢ (if { s := { data := [] }, i := 0 }.hasNext = true then
        if { s := { data := [] }, i := 0 }.hasNext = true then
          if { s := { data := [] }, i := 0 }.curr = { s := { data := [] }, i := 0 }.curr then
            ltb { s := { data := [] }, i := 0 }.next { s := { data := [] }, i := 0 }.next
          else decide ({ s := { data := [] }, i := 0 }.curr < { s := { data := [] }, i := 0 }.curr)
        else true
      else false) =
      true ↔
    [] < []
state_after: no goals

tactic: rename_i c₂ cs₂
state_before: case nil.cons
head✝ : Char
tail✝ : List Char
⊢ ltb { s := { data := [] }, i := 0 } { s := { data := head✝ :: tail✝ }, i := 0 } = true ↔ [] < head✝ :: tail✝
state_after: case nil.cons
c₂ : Char
cs₂ : List Char
⊢ ltb { s := { data := [] }, i := 0 } { s := { data := c₂ :: cs₂ }, i := 0 } = true ↔ [] < c₂ :: cs₂

tactic: apply iff_of_true
state_before: case nil.cons
c₂ : Char
cs₂ : List Char
⊢ ltb { s := { data := [] }, i := 0 } { s := { data := c₂ :: cs₂ }, i := 0 } = true ↔ [] < c₂ :: cs₂
state_after: case nil.cons.ha
c₂ : Char
cs₂ : List Char
⊢ ltb { s := { data := [] }, i := 0 } { s := { data := c₂ :: cs₂ }, i := 0 } = true

case nil.cons.hb
c₂ : Char
cs₂ : List Char
⊢ [] < c₂ :: cs₂

tactic: unfold ltb
state_before: case nil.cons.ha
c₂ : Char
cs₂ : List Char
⊢ ltb { s := { data := [] }, i := 0 } { s := { data := c₂ :: cs₂ }, i := 0 } = true
state_after: case nil.cons.ha
c₂ : Char
cs₂ : List Char
⊢ (if { s := { data := c₂ :: cs₂ }, i := 0 }.hasNext = true then
      if { s := { data := [] }, i := 0 }.hasNext = true then
        if { s := { data := [] }, i := 0 }.curr = { s := { data := c₂ :: cs₂ }, i := 0 }.curr then
          ltb { s := { data := [] }, i := 0 }.next { s := { data := c₂ :: cs₂ }, i := 0 }.next
        else decide ({ s := { data := [] }, i := 0 }.curr < { s := { data := c₂ :: cs₂ }, i := 0 }.curr)
      else true
    else false) =
    true

tactic: simp [-reduceMk, Iterator.hasNext, Char.utf8Size_pos]
state_before: case nil.cons.ha
c₂ : Char
cs₂ : List Char
⊢ (if { s := { data := c₂ :: cs₂ }, i := 0 }.hasNext = true then
      if { s := { data := [] }, i := 0 }.hasNext = true then
        if { s := { data := [] }, i := 0 }.curr = { s := { data := c₂ :: cs₂ }, i := 0 }.curr then
          ltb { s := { data := [] }, i := 0 }.next { s := { data := c₂ :: cs₂ }, i := 0 }.next
        else decide ({ s := { data := [] }, i := 0 }.curr < { s := { data := c₂ :: cs₂ }, i := 0 }.curr)
      else true
    else false) =
    true
state_after: no goals

tactic: apply List.nil_lt_cons
state_before: case nil.cons.hb
c₂ : Char
cs₂ : List Char
⊢ [] < c₂ :: cs₂
state_after: no goals

tactic: rename_i c₁ cs₁ ih
state_before: case cons.nil
head✝ : Char
tail✝ : List Char
tail_ih✝ :
  ∀ (s₂ : List Char), ltb { s := { data := tail✝ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ tail✝ < s₂
⊢ ltb { s := { data := head✝ :: tail✝ }, i := 0 } { s := { data := [] }, i := 0 } = true ↔ head✝ :: tail✝ < []
state_after: case cons.nil
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
⊢ ltb { s := { data := c₁ :: cs₁ }, i := 0 } { s := { data := [] }, i := 0 } = true ↔ c₁ :: cs₁ < []

tactic: apply iff_of_false
state_before: case cons.nil
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
⊢ ltb { s := { data := c₁ :: cs₁ }, i := 0 } { s := { data := [] }, i := 0 } = true ↔ c₁ :: cs₁ < []
state_after: case cons.nil.ha
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
⊢ ¬ltb { s := { data := c₁ :: cs₁ }, i := 0 } { s := { data := [] }, i := 0 } = true

case cons.nil.hb
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
⊢ ¬c₁ :: cs₁ < []

tactic: unfold ltb
state_before: case cons.nil.ha
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
⊢ ¬ltb { s := { data := c₁ :: cs₁ }, i := 0 } { s := { data := [] }, i := 0 } = true
state_after: case cons.nil.ha
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
⊢ ¬(if { s := { data := [] }, i := 0 }.hasNext = true then
        if { s := { data := c₁ :: cs₁ }, i := 0 }.hasNext = true then
          if { s := { data := c₁ :: cs₁ }, i := 0 }.curr = { s := { data := [] }, i := 0 }.curr then
            ltb { s := { data := c₁ :: cs₁ }, i := 0 }.next { s := { data := [] }, i := 0 }.next
          else decide ({ s := { data := c₁ :: cs₁ }, i := 0 }.curr < { s := { data := [] }, i := 0 }.curr)
        else true
      else false) =
      true

tactic: simp [-reduceMk, Iterator.hasNext]
state_before: case cons.nil.ha
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
⊢ ¬(if { s := { data := [] }, i := 0 }.hasNext = true then
        if { s := { data := c₁ :: cs₁ }, i := 0 }.hasNext = true then
          if { s := { data := c₁ :: cs₁ }, i := 0 }.curr = { s := { data := [] }, i := 0 }.curr then
            ltb { s := { data := c₁ :: cs₁ }, i := 0 }.next { s := { data := [] }, i := 0 }.next
          else decide ({ s := { data := c₁ :: cs₁ }, i := 0 }.curr < { s := { data := [] }, i := 0 }.curr)
        else true
      else false) =
      true
state_after: no goals

tactic: apply not_lt_of_lt
state_before: case cons.nil.hb
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
⊢ ¬c₁ :: cs₁ < []
state_after: case cons.nil.hb.a
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
⊢ [] < c₁ :: cs₁

tactic: apply List.nil_lt_cons
state_before: case cons.nil.hb.a
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
⊢ [] < c₁ :: cs₁
state_after: no goals

tactic: rename_i c₁ cs₁ ih c₂ cs₂
state_before: case cons.cons
head✝¹ : Char
tail✝¹ : List Char
tail_ih✝ :
  ∀ (s₂ : List Char), ltb { s := { data := tail✝¹ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ tail✝¹ < s₂
head✝ : Char
tail✝ : List Char
⊢ ltb { s := { data := head✝¹ :: tail✝¹ }, i := 0 } { s := { data := head✝ :: tail✝ }, i := 0 } = true ↔
    head✝¹ :: tail✝¹ < head✝ :: tail✝
state_after: case cons.cons
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
c₂ : Char
cs₂ : List Char
⊢ ltb { s := { data := c₁ :: cs₁ }, i := 0 } { s := { data := c₂ :: cs₂ }, i := 0 } = true ↔ c₁ :: cs₁ < c₂ :: cs₂

tactic: unfold ltb
state_before: case cons.cons
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
c₂ : Char
cs₂ : List Char
⊢ ltb { s := { data := c₁ :: cs₁ }, i := 0 } { s := { data := c₂ :: cs₂ }, i := 0 } = true ↔ c₁ :: cs₁ < c₂ :: cs₂
state_after: case cons.cons
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
c₂ : Char
cs₂ : List Char
⊢ (if { s := { data := c₂ :: cs₂ }, i := 0 }.hasNext = true then
        if { s := { data := c₁ :: cs₁ }, i := 0 }.hasNext = true then
          if { s := { data := c₁ :: cs₁ }, i := 0 }.curr = { s := { data := c₂ :: cs₂ }, i := 0 }.curr then
            ltb { s := { data := c₁ :: cs₁ }, i := 0 }.next { s := { data := c₂ :: cs₂ }, i := 0 }.next
          else decide ({ s := { data := c₁ :: cs₁ }, i := 0 }.curr < { s := { data := c₂ :: cs₂ }, i := 0 }.curr)
        else true
      else false) =
      true ↔
    c₁ :: cs₁ < c₂ :: cs₂

tactic: simp only [Iterator.hasNext, Pos.byteIdx_zero, endPos, utf8ByteSize, utf8ByteSize.go,
  add_pos_iff, Char.utf8Size_pos, or_true, decide_eq_true_eq, ↓reduceIte, Iterator.curr, get,
  utf8GetAux, Iterator.next, next, Bool.ite_eq_true_distrib]
state_before: case cons.cons
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
c₂ : Char
cs₂ : List Char
⊢ (if { s := { data := c₂ :: cs₂ }, i := 0 }.hasNext = true then
        if { s := { data := c₁ :: cs₁ }, i := 0 }.hasNext = true then
          if { s := { data := c₁ :: cs₁ }, i := 0 }.curr = { s := { data := c₂ :: cs₂ }, i := 0 }.curr then
            ltb { s := { data := c₁ :: cs₁ }, i := 0 }.next { s := { data := c₂ :: cs₂ }, i := 0 }.next
          else decide ({ s := { data := c₁ :: cs₁ }, i := 0 }.curr < { s := { data := c₂ :: cs₂ }, i := 0 }.curr)
        else true
      else false) =
      true ↔
    c₁ :: cs₁ < c₂ :: cs₂
state_after: case cons.cons
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
c₂ : Char
cs₂ : List Char
⊢ (if c₁ = c₂ then ltb { s := { data := c₁ :: cs₁ }, i := 0 + c₁ } { s := { data := c₂ :: cs₂ }, i := 0 + c₂ } = true
    else c₁ < c₂) ↔
    c₁ :: cs₁ < c₂ :: cs₂

tactic: split_ifs with h
state_before: case cons.cons
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
c₂ : Char
cs₂ : List Char
⊢ (if c₁ = c₂ then ltb { s := { data := c₁ :: cs₁ }, i := 0 + c₁ } { s := { data := c₂ :: cs₂ }, i := 0 + c₂ } = true
    else c₁ < c₂) ↔
    c₁ :: cs₁ < c₂ :: cs₂
state_after: case pos
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
c₂ : Char
cs₂ : List Char
h : c₁ = c₂
⊢ ltb { s := { data := c₁ :: cs₁ }, i := 0 + c₁ } { s := { data := c₂ :: cs₂ }, i := 0 + c₂ } = true ↔
    c₁ :: cs₁ < c₂ :: cs₂

case neg
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
c₂ : Char
cs₂ : List Char
h : ¬c₁ = c₂
⊢ c₁ < c₂ ↔ c₁ :: cs₁ < c₂ :: cs₂

tactic: subst c₂
state_before: case pos
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
c₂ : Char
cs₂ : List Char
h : c₁ = c₂
⊢ ltb { s := { data := c₁ :: cs₁ }, i := 0 + c₁ } { s := { data := c₂ :: cs₂ }, i := 0 + c₂ } = true ↔
    c₁ :: cs₁ < c₂ :: cs₂
state_after: case pos
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
cs₂ : List Char
⊢ ltb { s := { data := c₁ :: cs₁ }, i := 0 + c₁ } { s := { data := c₁ :: cs₂ }, i := 0 + c₁ } = true ↔
    c₁ :: cs₁ < c₁ :: cs₂

tactic: suffices ltb ⟨⟨c₁ :: cs₁⟩, (0 : Pos) + c₁⟩ ⟨⟨c₁ :: cs₂⟩, (0 : Pos) + c₁⟩ =
  ltb ⟨⟨cs₁⟩, 0⟩ ⟨⟨cs₂⟩, 0⟩ by rw [this]; exact (ih cs₂).trans List.Lex.cons_iff.symm
state_before: case pos
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
cs₂ : List Char
⊢ ltb { s := { data := c₁ :: cs₁ }, i := 0 + c₁ } { s := { data := c₁ :: cs₂ }, i := 0 + c₁ } = true ↔
    c₁ :: cs₁ < c₁ :: cs₂
state_after: case pos
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
cs₂ : List Char
⊢ ltb { s := { data := c₁ :: cs₁ }, i := 0 + c₁ } { s := { data := c₁ :: cs₂ }, i := 0 + c₁ } =
    ltb { s := { data := cs₁ }, i := 0 } { s := { data := cs₂ }, i := 0 }

tactic: apply ltb_cons_addChar
state_before: case pos
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
cs₂ : List Char
⊢ ltb { s := { data := c₁ :: cs₁ }, i := 0 + c₁ } { s := { data := c₁ :: cs₂ }, i := 0 + c₁ } =
    ltb { s := { data := cs₁ }, i := 0 } { s := { data := cs₂ }, i := 0 }
state_after: no goals

tactic: rw [this]
state_before: c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
cs₂ : List Char
this :
  ltb { s := { data := c₁ :: cs₁ }, i := 0 + c₁ } { s := { data := c₁ :: cs₂ }, i := 0 + c₁ } =
    ltb { s := { data := cs₁ }, i := 0 } { s := { data := cs₂ }, i := 0 }
⊢ ltb { s := { data := c₁ :: cs₁ }, i := 0 + c₁ } { s := { data := c₁ :: cs₂ }, i := 0 + c₁ } = true ↔
    c₁ :: cs₁ < c₁ :: cs₂
state_after: c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
cs₂ : List Char
this :
  ltb { s := { data := c₁ :: cs₁ }, i := 0 + c₁ } { s := { data := c₁ :: cs₂ }, i := 0 + c₁ } =
    ltb { s := { data := cs₁ }, i := 0 } { s := { data := cs₂ }, i := 0 }
⊢ ltb { s := { data := cs₁ }, i := 0 } { s := { data := cs₂ }, i := 0 } = true ↔ c₁ :: cs₁ < c₁ :: cs₂

tactic: exact (ih cs₂).trans List.Lex.cons_iff.symm
state_before: c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
cs₂ : List Char
this :
  ltb { s := { data := c₁ :: cs₁ }, i := 0 + c₁ } { s := { data := c₁ :: cs₂ }, i := 0 + c₁ } =
    ltb { s := { data := cs₁ }, i := 0 } { s := { data := cs₂ }, i := 0 }
⊢ ltb { s := { data := cs₁ }, i := 0 } { s := { data := cs₂ }, i := 0 } = true ↔ c₁ :: cs₁ < c₁ :: cs₂
state_after: no goals

tactic: refine ⟨List.Lex.rel, fun e ↦ ?_⟩
state_before: case neg
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
c₂ : Char
cs₂ : List Char
h : ¬c₁ = c₂
⊢ c₁ < c₂ ↔ c₁ :: cs₁ < c₂ :: cs₂
state_after: case neg
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
c₂ : Char
cs₂ : List Char
h : ¬c₁ = c₂
e : c₁ :: cs₁ < c₂ :: cs₂
⊢ c₁ < c₂

tactic: cases e <;> rename_i h'
state_before: case neg
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
c₂ : Char
cs₂ : List Char
h : ¬c₁ = c₂
e : c₁ :: cs₁ < c₂ :: cs₂
⊢ c₁ < c₂
state_after: case neg.cons
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
cs₂ : List Char
h : ¬c₁ = c₁
h' : List.Lex (fun x x_1 => x < x_1) cs₁ cs₂
⊢ c₁ < c₁

case neg.rel
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
c₂ : Char
cs₂ : List Char
h : ¬c₁ = c₂
h' : c₁ < c₂
⊢ c₁ < c₂

tactic: contradiction
state_before: case neg.cons
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
cs₂ : List Char
h : ¬c₁ = c₁
h' : List.Lex (fun x x_1 => x < x_1) cs₁ cs₂
⊢ c₁ < c₁
state_after: no goals

tactic: assumption
state_before: case neg.rel
c₁ : Char
cs₁ : List Char
ih : ∀ (s₂ : List Char), ltb { s := { data := cs₁ }, i := 0 } { s := { data := s₂ }, i := 0 } = true ↔ cs₁ < s₂
c₂ : Char
cs₂ : List Char
h : ¬c₁ = c₂
h' : c₁ < c₂
⊢ c₁ < c₂
state_after: no goals