Unfold and non-refl equational lemmas. #1694
Comments
Is it possible to make the syntax |
I suggested |
I've mentioned before that I am baffled by the number of definitional reduction tactics that currently exist, so I am reticent to have yet another one with a somewhat different name. Perhaps we should have an issue on restructuring them and/or providing clear documentation on the purpose and use cases for each tactic. |
Is the semantic and performance difference of |
@Kha We already have performance problem with |
I agree with @digama0, there are too many non-discoverable different reduction tactics. My vote would go for |
@gebner We need an efficient |
@leodemoura I'm just arguing about naming. I agree, the actual implementation should be different. |
My concern is also not about performance, but about semantics and user-discoverability. Under the hood, you can implement each combination of options whatever way you think will make it fastest, but the porcelain commands should have a memorable and consistent notation. The fact that Performance aside, how many tactics do you need to get all of the current semantics? I really don't understand how
using gebner's notation so it is clear which I am referring to. In terms of this,
If the behavior of these commands matches what I have written here, then I think that we could get away with just one tactic I assume the reason (Again, I am talking only about the behavior of these tactics, not performance. If the underlying |
@digama0 There are other dimensions (e.g., definitional vs propositional equality).
It is not always clear what is the most efficient.
You ignored many cases: occurrences,
The motivation is to allow users to fix parameters of a refl-lemma. |
Very true. We can uniformize the initial
AFAIK there is no support for occurrences anywhere in the tactic framework. We should implement support for them, but again, it should be done in a consistent and uniform way and deserves its own issue for nailing down the syntax.
I 100% agree on the first sentence, but I am confused by the second because my operational definition for these synonymizes the two. I think I know what reduction is (consistent replacement of expressions matching a certain form, hopefully associated with some kind of termination pathway), but this is what I get from the
I put the How then do you feel about the equality |
https://github.com/leanprover/lean/blob/master/library/init/meta/occurrences.lean
For me, For me,
This is not true in the current implementation since |
I don't know about this. If you are creating a general reduction engine, you will probably want to have special reduction rules which are not associated to the standard reduction pathway of DTT, and thus are not definitional equalities (for example, it would be great if
Okay, now I think we are converging. If Regarding the choice of |
@digama0 I'm not sure I like a Perhaps, you want a symbolic evaluator that can be extended, is efficient (and does not produce proofs). In interactive tactic mode, I agree we can survive with:
They all support the We can still provide the |
From an implementation point of view, I agree. But from a UX point of view this is confusing as hell, since
The rationale for the naming scheme is the following: we already use the We need to have a non-definitional reduction tactic. Functions on nested inductives are implemented using well-founded recursion and hence don't reduce definitionally, even if they're structurally recursive. Not being able to reduce them is inconvenient. (I'm aware of the obvious non-termination issue, maybe we should require the user to explicitly mark these definitions as reductions.) |
I just wanted to point out that lemma gcd_zero_right (x : nat) : gcd 0 x = x := rfl Having |
@gebner I used lemma gcd_ne_zero (x y : nat) (h : x ≠ 0) : gcd x y = gcd (y % x) x :=
by rw [gcd]; simph |
@gebner "Confusing as hell" is in the eye of the beholder. I also think
I disagree. Most users will use I usually I agree that is sad that a function application |
While all these tactics are being discussed together, could I bring up an incidental point: could we aim to have consistent failure behaviour across all these reduction tactics? Ideally I would prefer that all of these tactics fail if they can't find anything to do. (I know that this sometimes costs extra uses of |
Ok. We will use this approach. |
… `dsimp` tactic family Now, `dsimp` fails if the goal did not change. We can use the config object to obtain the previous behavior: ``` dsimp {fail_if_unchaged := ff} ``` See comment #1694 (comment) at issue #1694
Here are modifications: - It fails if no definition is unfolded. See comment #1694 (comment) at issue #1694 - Users can provide configuration parameters. - `dunfold_occs` was deleted.
The commits above address the original issue and the @semorrison's suggestion. |
The
unfold
tactic is implemented using the automatically generated equational lemmas.unfold
is currently just an alternative name fordunfold
.So, it doesn't work, for example, for functions defined using well founded recursion.
We need an
unfold
tactic that usesnon-refl
equational lemmas.There is a problem. The current
dunfold f
is "multi-pass". In the following exampleunfold f
will reducef (succ (succ a))
intof (succ a) + 2
and then it will unfold again the newf (succ a)
.We cannot do this for functions such as
gcd
since it will produce non-termination.I'm assuming it would be confusing to have a different behavior for
non-refl
lemmas.One option is to rename the current
unfold/dunfold
toreduce
, and add a newunfold
tactic which performs a single pass. That is, in the example above,unfold f
would produce the goalThe text was updated successfully, but these errors were encountered: