Zulip Chat Archive
Stream: new members
Topic: rw/simp on value replaces it, existing refs are to old value
aron (Jun 10 2025 at 13:17):
When I rw or simp a value that is referenced by a type, lean creates a new value instead of changing the old value in place. This means that the type now references the old, unchanged value. Why is this and how can I prevent this from happening?
/-- A list which you add items onto at the end -/
inductive Ctx (α : Type u)
| nil : Ctx α
| add (body : Ctx α) (tip : α) : Ctx α
@[reducible] def Ctx.length {α} (ctx : Ctx α) : Nat :=
match ctx with
| .nil => 0
| .add ctx _ => ctx.length + 1
@[reducible] def Ctx.tryGet (ctx : Ctx α) (n : Nat) : Option α :=
if hlen : n >= ctx.length then
none
else if hlen : n + 1 = ctx.length then
match hctx : ctx with
| .nil => by
simp at hlen
| .add _ tip => tip
else
match ctx with
| .nil => by
expose_names
simp at hlen_1
| .add inner _ =>
inner.tryGet n
@[reducible] def Ctx.get {α : Type} (ctx : Ctx α) (n : Nat) (h : n < ctx.length) : α :=
match ctx, n with
| .add inner tip, _ =>
-- since we know this index is in the list, the only way we would get a `none` here is if the index is exactly the last item in the list, i.e. the tip
match inner.tryGet n with
| none => tip
| some item => item
/-- This is a type that proves that in this `ctx`, the item at index `n` is `a` -/
inductive HasItem {α : Type u} : (index : Nat) → (ctx : Ctx α) → (a : α) → Prop where
| stop : HasItem 0 (.add .nil a) a
| pop {ctx : Ctx α} : HasItem n ctx a → HasItem (n+1) (.add ctx other) a
theorem HasItem.from_ctx_get {ctx : Ctx α} {h : n < ctx.length} (prf : ctx.get n h = a) : HasItem n ctx a := by
rcases ctx with _ | _ | _
case nil => simp at h
case _ tip =>
simp only [Ctx.length] at h
-- This makes `prf` reference `h✝` instead of `h`! How can I change `h` in-place?
simp at h
sorry
case _ => sorry
Aaron Liu (Jun 10 2025 at 13:44):
Why do you want to do this?
aron (Jun 10 2025 at 13:47):
because i want to create a HasItem n ctx a
aron (Jun 10 2025 at 13:47):
and if we know ctx.get n h = a that should be sufficient to construct one
Aaron Liu (Jun 10 2025 at 13:52):
I guess you could subst h to replace n with 0 everywhere
Aaron Liu (Jun 10 2025 at 13:55):
Then you can start unfolding the definition of Ctx.get
Aaron Liu (Jun 10 2025 at 13:55):
But I don't think changing the proof that it is using will do anything.
aron (Jun 10 2025 at 14:01):
oh god :face_palm: yeah, if I just unfold Ctx.get then I get rid of h altogether and I don't need to worry about it anymore!
aron (Jun 10 2025 at 14:01):
thanks @Aaron Liu :folded_hands:
aron (Jun 10 2025 at 14:25):
Hm in addition to my original question, I think my HasItem type is actually malformed :thinking: I think it currently looks like it tells you the index from the start but in actuality it's impossible to make a HasItem ctx n a for any item that isn't at index 0
aron (Jun 10 2025 at 14:26):
I think in the original snippet I adapted this from, the index is from the end of the list, not the beginning
Last updated: Dec 20 2025 at 21:32 UTC