Zulip Chat Archive
Stream: general
Topic: simplifying local terms introduced by `let`
Ayhon (Mar 14 2025 at 12:42):
If I have a local definition in a proposition, introduced by let
like the following.
example(x : Int)
: let aux := if x >= 0 then x else -x
aux = x.natAbs
:= by
intro aux
if h:x >= 0 then
simp [h] at *
sorry
else
sorry
How can I simplify aux
in each branch of the if
? Understandably, simp
only works at the type level, but I would like to invoke it at the "value" level of the let
definition.
Sebastian Ullrich (Mar 14 2025 at 12:54):
simp [h, aux] at *
, assuming your Lean is sufficiently new
Ayhon (Mar 14 2025 at 12:54):
Sebastian Ullrich said:
simp [h, aux] at *
, assuming your Lean is sufficiently new
That might be the problem then. I'm using 4.16.0-rc2
Sebastian Ullrich (Mar 14 2025 at 12:55):
It works with 4.17.0 in the playground
Sebastian Ullrich (Mar 14 2025 at 12:55):
unfold
may be an alternative
Ayhon (Mar 14 2025 at 12:56):
But that would just substitute the definition of aux
in my current goal or proposition I chose, no?
Sebastian Ullrich (Mar 14 2025 at 12:57):
Oh, you want to simplify the RHS of aux without substituting it?
Ayhon (Mar 14 2025 at 12:57):
Yes, indeed
Ayhon (Mar 14 2025 at 12:59):
I'm actually using these let
definitions as a way of managing the readability of my proof state. So far I've found that using generalize x_def: rhs = x
works for my use case, but it introduces two elements to my local context, x
and x_def
, which I would prefer to prevent. I was wondering if there was a way of doing so
Sebastian Ullrich (Mar 14 2025 at 13:01):
But that is likely the right way to do it as then you can rewrite in x_def
without affecting anyone else. With let
, you can only do defeq transformations in general because dependent terms may otherwise become type-incorrect.
Ayhon (Mar 14 2025 at 13:06):
I see. In that case I will use generalize
instead, or something based upon it. Another perceived advantage of introducing these terms with let is that I could define them in the proposion I'm trying to prove and simply introduce them with intro
, without having to explicitly set the term I'm substituting. But I can imagine having some kind of intro'
which introduces let bindings in this way.
As an illustrating example, here I don't have to do generalize tree'_def: tree.delete_rebalance target = tree'
, but just intro tree'
.
theorem Spec.BSTree.delete_rebalance.spec[LinearOrder α][Inhabited α]
{tree tree': BSTree α}{target: α}
: tree.is_avl
→ let tree' := tree.delete_rebalance target
tree'.toSet = tree.toSet \ {target} ∧
tree'.is_avl
Ayhon (Mar 14 2025 at 13:19):
Arguably, if you want to set the equality from the proof, you'd do so as a proposition directly, so perhaps it's not even that useful to have such an intro'
if you write the proposition correctly.
Last updated: May 02 2025 at 03:31 UTC