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
```