Zulip Chat Archive

Stream: new members

Topic: Best way to eliminate `match` with a proof?


C7X (Jul 31 2025 at 06:28):

Hi!

I have a goal that has a match term in it, and a proof that one of the matched objects has a certain form. What is the recommended way to eliminate the match to simplify my goal? Is split the best option, or is there a better way?

To be more specific, my goal is ⊢ (match bad_root s, br_defined with | some x, x_1 => x) ≤ List.length s, but I have a proof (br_defined) that bad_root s is of the form some x. What should I do to change the goal into something like ⊢ (bad_root s).get ≤ List.length s, with no match term in it?

import Mathlib

set_option linter.unusedVariables false

def PrimitiveSeq : Type := List Nat

def bad_root : PrimitiveSeq  Option Nat
  | [] => none
  | 0 :: s => none
  | Nat.succ x :: s => (Nat.succ x :: s).idxOf x

lemma bad_root_leq_length : (s : PrimitiveSeq)  (br_defined : (bad_root s).isSome)  ((bad_root s).get br_defined  s.length) := by {
  /- The bad root of a PrimitiveSeq, if defined, is less than or equal to its length. -/
  intro s br_defined
  unfold Option.get
  let br :  := (bad_root s).get br_defined
  -- Here the goal has a match in it that I want to remove
}```

Johannes Tantow (Jul 31 2025 at 07:39):

import Mathlib

set_option linter.unusedVariables false

def PrimitiveSeq : Type := List Nat

def bad_root : PrimitiveSeq  Option Nat
  | [] => none
  | 0 :: s => none
  | Nat.succ x :: s => (Nat.succ x :: s).idxOf x

lemma bad_root_leq_length : (s : PrimitiveSeq)  (br_defined : (bad_root s).isSome)  ((bad_root s).get br_defined  s.length) := by {
  /- The bad root of a PrimitiveSeq, if defined, is less than or equal to its length. -/
  intro s br_defined
  unfold Option.get
  let br :  := (bad_root s).get br_defined
  -- Here the goal has a match in it that I want to remove
  cases s with
  | nil =>
    simp [bad_root] at br_defined
  | cons hd tl =>
    cases hd with
    | zero =>
      simp [bad_root] at br_defined
    | succ n =>
      grind [bad_root]
}

You can do a case distinction and eliminate the branches that are impossible based on the proof.

Michiel Huttener (Jul 31 2025 at 07:40):

If you are willing to change your proof structure a bit, you may write the following:

import Mathlib

def PrimitiveSeq : Type := List Nat

def bad_root : PrimitiveSeq  Option Nat
  | [] => none
  | 0 :: s => none
  | Nat.succ x :: s => (Nat.succ x :: s).idxOf x

lemma bad_root_leq_length (s : PrimitiveSeq) (br_defined : (bad_root s).isSome) :
    (bad_root s).get br_defined  s.length := by
  dsimp [bad_root]
  split
  . contradiction
  . contradiction
  . apply List.idxOf_le_length

C7X (Jul 31 2025 at 08:27):

These seem to work alright, thank you both!


Last updated: Dec 20 2025 at 21:32 UTC