This feature is needed when we declare an inductive predicate/type
which is indexed by a mutual and/or nested inductive datatype.
See tests/lean/run/term_pred.lean for an example.
@Armael: this commit should fix the issue with the `cases` tactic that
you reported today.
See issue #1175
BTW, we may have to revise this decision in the future when we decide to
populate the string library with lemmas.
It is inconvenient to prove the lemmas at string/basic.lean since the
tactic framework has not been defined yet.
Anyway, I think it is worth to keep the private for now, and make sure
nobody relies on its implementation.
We want to make sure string users do not depend on the string
implementation. This is the first step.
We need this refactoring *now* to make sure it will not be
super painful to address issue #1175
The `unsafe_change e` tactic is similar to the `change e` tactic, but it
does not check whether `e` is definitionally equal to the current
tactic. It is useful when implementing tactics such as:
```
meta def dunfold : list name → tactic unit :=
λ cs, target >>= dunfold_core transparency.instances default_max_steps cs >>= unsafe_change
```
The tactic `dunfold_core` guarantees that the resultant expression is
definitionally equal to the input one.
This was one of the performance problems at issue #1646.
Here are the runtimes for size 7 in the example described at issue #1646.
Before this commit:
tactic execution took 4.96s
elaboration of some_lifted_lets took 7.6s
type checking time of some_lifted_lets took 31.1ms (aka QED time)
total execution time: 12.785s
After this commit:
tactic execution took 3.78s
elaboration of some_lifted_lets took 5.71s
type checking time of some_lifted_lets took 35.2ms
total execution time: 10.693s
Before this commit they were implemented using C++ and Lean.
A Lean procedure was being invoked for each subterm of the input term.
This is one of the performance problems at issue #1646.
Here are the runtimes for size 7 in the example described at issue #1646.
Before this commit:
tactic execution took 7.48s
elaboration of some_lifted_lets took 11.5s
type checking time of some_lifted_lets took 33.4ms (aka QED time)
total execution time: 16.841s
After this commit:
tactic execution took 4.96s
elaboration of some_lifted_lets took 7.6s
type checking time of some_lifted_lets took 31.1ms (aka QED time)
total execution time: 12.785s
This is one of the performance problems at issue #1646.
The method `local_context::erase_user_name(local_decl const & d)` was
inefficient when there are many locals with the same user facing name.
For size 7 in the example described at issue #1646, the average size of the
declaration list was 400. Here are the runtimes for size 7
Before: 19.021 secs
After: 16.433 secs
There are more performance issues.
@Armael: the new file `tests/lean/run/add_interactive.lean` contains a
small example. Note that we don't have auto quotation for commands yet.
So, I have to use the backtick in the example.
@Kha: this is a good candidate for the future command parser extensions.
replace_target uses id_locked.
The id_locked solution is more robust because simp may build a proof
using refl lemmas, but type_context may not be able to establish that
the previous and new target are definitionally equal.
@Armael This commit fixes the issue in the KreMLin proof you showed me.
Now, the following tactic succeeds (as expected)
```
simp [lowstar_semantics.apply_ectx],
```
and the resulting goal is
```
...
|- exp.subbuf (exp.loc (b, n, list.nil field)) a_1 = exp.subbuf ↑?m_1 ?m_2
```