Unfold macros using the full typechecker in normalize.

Fix #7. The problem (as I understand it) was that macros were expanded using a typechecker which didn't unfold (semireducible) definitions, which led to the macros not being unfolded correctly.
Many many many thanks to @gebner!
This commit is contained in:
Floris van Doorn 2017-07-18 22:53:03 +01:00
parent 519dcee739
commit a02ea6b751
3 changed files with 34 additions and 1 deletions

View file

@ -126,7 +126,7 @@ public:
return none_expr(); return none_expr();
buffer<expr> args; buffer<expr> args;
expr const & I = get_app_args(s_type, args); expr const & I = get_app_args(s_type, args);
if (!is_constant(I) || length(m_ps) != length(const_levels(I))) if (!is_constant(I) || length(m_ps) != length(const_levels(I)) || const_name(I) != m_I_name)
return none_expr(); return none_expr();
expr r = instantiate_univ_params(m_val, m_ps, const_levels(I)); expr r = instantiate_univ_params(m_val, m_ps, const_levels(I));
args.push_back(new_s); args.push_back(new_s);

View file

@ -382,6 +382,16 @@ class normalize_fn {
check_system("normalize"); check_system("normalize");
if (!m_pred(e)) if (!m_pred(e))
return e; return e;
/* The following is an ugly hack to solve issue #7.
The problem was that the type of macros was not unfolded correctly,
and the type was used to figure out what the macro meant */
buffer<expr> args;
auto fn = get_app_args(e, args);
if (is_macro(fn)) {
if (auto fn2 = m_full_tc.expand_macro(fn)) {
e = mk_app(*fn2, args);
}
}
auto w = m_tc.whnf(e); auto w = m_tc.whnf(e);
e = w.first; e = w.first;
if (m_save_cnstrs) if (m_save_cnstrs)

23
tests/lean/run/7.hlean Normal file
View file

@ -0,0 +1,23 @@
open unit pointed eq bool
structure foo (u v : unit) :=
(b : bool → bool)
definition bar := foo star
definition bar.mk [constructor] : bar star := foo.mk star star (λx, tt)
definition bar.mk2 [constructor] : bar star := bar.mk
example : foo.b bar.mk2 ff = tt :=
begin esimp end
definition my_ppi_const [constructor] {A : Type*} (P : A → Type*) : ppi P :=
ppi.mk (λa, pt) idp
definition my_pconst [constructor] (A B : Type*) : ppi (λ(a : A), B) :=
!my_ppi_const
example {A : Type*} (P : A → Type*) (a : A) : ppi_gen.to_fun (my_ppi_const P) a = pt :=
begin esimp, end
example {A B : Type*} (a : A) : my_pconst A B a = pt :=
begin esimp end