This PR reworks the `simp` set around the `Id` monad, to not elide or unfold `pure` and `Id.run` In particular, it stops encoding the "defeq abuse" of `Id X = X` in the statements of theorems, instead using `Id.run` and `pure` to pass back and forth between these two spellings. Often when writing these with `pure`, they generalize to other lawful monads; though such changes were split off to other PRs. This fixes the problem with the current simp set where `Id.run (pure x)` is simplified to `Id.run x`, instead of the desirable `x`. This is particularly bad because the` x` is sometimes inferred with type `Id X` instead of `X`, which prevents other `simp` lemmas about `X` from firing. Making `Id` reducible instead is not an option, as then the `Monad` instances would have nothing to key on. --------- Co-authored-by: Sebastian Graf <sg@lean-fro.org> Co-authored-by: Kim Morrison <kim@tqft.net> Co-authored-by: Paul Reichert <6992158+datokrat@users.noreply.github.com>
12 lines
615 B
Text
12 lines
615 B
Text
theorem Array.sizeOf_lt_of_mem' [DecidableEq α] [SizeOf α] {as : Array α} (h : as.contains a) : sizeOf a < sizeOf as := by
|
||
simp [Membership.mem, contains, any, Id.run, BEq.beq, anyM] at h
|
||
let rec aux (j : Nat) : anyM.loop (m := Id) (fun b => pure <| decide (a = b)) as as.size (Nat.le_refl ..) j = true → sizeOf a < sizeOf as := by
|
||
unfold anyM.loop
|
||
intro h
|
||
split at h
|
||
· simp only [bind, decide_eq_true_eq, pure] at h; split at h
|
||
next he => subst a; apply sizeOf_get
|
||
next => have ih := aux (j+1) h; assumption
|
||
· contradiction
|
||
termination_by as.size - j
|
||
apply aux 0 h
|