Zulip Chat Archive
Stream: new members
Topic: Need help with ugly proof involving Fin and calc
Alex Mobius (Apr 27 2025 at 17:43):
Having trouble with a proof, the lowdown is this:
- I have
(a.push v).size = a.size + 1
, but the former is inside of Fin types in my expressions, and I don't know how to perform the substitution "globally" (rw at *
just masks hypotheses with new ones, but the goal still refers to the old ones), thus I'm unable to useFin.le_val_last
, and am forced to go to thesucc
projection for the proof. calc
seems to be very unhappy about inequalities involving Fin and Nat, which is how I've arrived at the wart in L60.
(Apologies for the larger example, really don't know how to minify further while preserving the problem at hand)
import Mathlib.Order.Fin.Basic
import Mathlib.Logic.Equiv.Defs
import Mathlib.Logic.Lemmas
import Mathlib.Data.List.Basic
import Mathlib.Data.List.Nodup
structure Labels (T: Type u) [DecidableEq T] where
data: Array T
nodup: data.toList.Nodup
variable {T: Type u} [DecidableEq T]
instance: Membership T (Labels T) where
mem := (Membership.mem ·.data ·)
instance (v: T) (l: Labels T): Decidable (v ∈ l) := Array.instDecidableMemOfDecidableEq v l.data
namespace Labels
variable (l: Labels T)
@[reducible] def size := l.data.size
abbrev Idx := Fin (l.size)
def find v (h: v ∈ l): l.Idx :=
let x := l.data.idxOf v
have sm: x < l.size := Array.idxOf_lt_length h
⟨ x, sm ⟩
def add v (h: v ∉ l): Σ (l: Labels T), l.Idx :=
let data' := l.data.push v
have nodup': data'.toList.Nodup := by
unfold data'
rw [Array.push_toList]
simp [List.nodup_middle, List.nodup_cons]
exact ⟨ h, l.nodup ⟩
let l' := {data:=data', nodup:=nodup'}
have : l.data.size < data'.size := by
unfold data'
rw [Array.size_push]
apply Nat.lt_add_one
let x: Labels.Idx l' := ⟨ l.data.size, this ⟩
⟨ l', x ⟩
theorem add_argmax: l.add v h = ⟨ l', x ⟩ -> ∀ u (h: u ∈ l'), l'.find u h ≤ x := by
intro added
simp [add] at added
intro u h
let x' := l'.find u h
change x' ≤ x
obtain ⟨ rfl, xeq ⟩ := added
have xeq := xeq.eq
let size' := (l.data.push v).size
have sizeplus1: size' = l.data.size + 1 := Array.size_push _ _
rw [←Fin.succ_le_succ_iff, Fin.le_iff_val_le_val]
apply Fin.val_eq_of_eq at xeq
calc
x'.succ.val ≤ size' := by
have vl := Fin.le_last x'.succ
rw [Fin.le_iff_val_le_val] at vl
exact vl
size' = l.data.size + 1 := sizeplus1
l.data.size + 1 = x.succ.val := Nat.succ_inj.mpr xeq
Last updated: May 02 2025 at 03:31 UTC