The issue was that instantiate_mvars(infer(m)) had a metavariable, while
infer(instantiate_mvars(m)) did not. Changing the call from assign to
is_def_eq also unifies the type, assigning the metavariable inside the
type.
We need this feature for:
1) Defining nonlinear search patterns. Example: (?m <= ?m + 1)
2) Preprocessing recursive equations and support the pattern
refinement approach used in Agda. Example: in Agda, they accept
```
def append {A : Type} : Π (m n : nat), Vec A m -> Vec A n -> Vec A (m + n)
| m n nil ys := ys
| m n (cons m' x xs) ys := cons x (append m' n xs ys)
```
These equations have to be refined. For example, `m` has to be
replaced with `0` (in the first equation), and `succ m'` in the
second. To implement this kind of refinement, we need to convert
the pattern variables (local constants) into metavariables during
elaboration. Then, the unassigned metavariables become local constants
again. This preprocessing step will fix some of the issues on #1594.
To completely fix#1594, we will need yet another preprocessing step
which will implement "complete transition" used in the equation
compiler before we start elim_match.cpp
`rewrite` tactic improvements
- Add support for `auto_param` and `opt_param`
- Order new goals using the same strategies available for `apply`
- Allow user to set configuration object in interactive mode.
@Armael This commit should address the issue you raised about the order
of new goals in the `rewrite` tactic.
See new test tests/lean/run/rw1.lean for examples.
@dselsam `simp` now supports lemmas containing metavariables.
The metavariables are automatically converted into tmp metavars.
The new test contains a few examples.
@dselsam The method `try_user_congr` was leaking a temporary
meta-variable into the formula. The problem in the congruence lemma
```
dif_ctx_simp_congr :
∀ {α : Sort u_1} {b c : Prop} [dec_b : decidable b] {x : b → α} {u : c → α} {y : ¬b → α} {v : ¬c → α}
(h_c : b ↔ c),
(∀ (h : c), x (h_c.mpr h) = u h) →
(∀ (h : ¬c), y ((not_iff_not_of_iff h_c).mpr h) = v h) → dite b x y = dite c u v
```
when the hypothesis `(∀ (h : c), x (h_c.mpr h) = u h)` is processed,
`h_c` is still unassigned. `h_c` was being assigned in a second
loop (the one that I deleted). Do you see any reason for having this
second pass? I think it is an optimization, we can skip the potentially
expensive
```
expr hyp = finalize(m_ctx, rel, r_congr_hyp).get_proof();
expr pf = local_factory.mk_lambda(hyp);
```
if the expression has not been simplified.
Anyway, I removed this code and merged both loops.
I don't think it should impact performance since we barely use custom
congruence lemmas.
Before this commit, simp would not silently apply refl-lemmas, and use
reflexivity. This strategy produces compact proofs but may generate
performance problems. For example, the new test timeouts without this
commit.
I believe a similar performance problem is affecting the Certigrad
project developed by @dselsam.