fix(kernel/normalizer): metavariable reification

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-12-21 06:40:26 -08:00
parent 9444c1f47f
commit 7b0b363b32
4 changed files with 34 additions and 18 deletions

View file

@ -380,7 +380,9 @@ expr metavar_env_cell::instantiate_metavars(expr const & e, buffer<justification
if (!has_metavar(e)) { if (!has_metavar(e)) {
return e; return e;
} else { } else {
return instantiate_metavars_proc(this, jsts)(e); expr r = instantiate_metavars_proc(this, jsts)(e);
lean_assert(!has_assigned_metavar(r));
return r;
} }
} }

View file

@ -159,17 +159,18 @@ class normalizer::imp {
}); });
} else { } else {
lean_assert(is_metavar(e)); lean_assert(is_metavar(e));
if (is_identity_stack(s, k)) local_context lctx = metavar_lctx(e);
return e; // nothing to be done unsigned len_s = length(s);
local_context lctx = metavar_lctx(e); unsigned len_ctx = ctx.size();
unsigned len_s = length(s);
unsigned len_ctx = ctx.size();
lean_assert(k >= len_ctx); lean_assert(k >= len_ctx);
expr r; expr r;
if (k > len_ctx) if (k > len_ctx + len_s)
r = add_lift(e, len_s, k - len_ctx); r = add_lift(e, len_s, k - len_ctx - len_s);
else else
r = e; r = e;
if (is_identity_stack(s, k)) {
return r;
}
buffer<expr> subst; buffer<expr> subst;
for (auto v : s) for (auto v : s)
subst.push_back(reify(v, k)); subst.push_back(reify(v, k));

View file

@ -376,9 +376,6 @@ static void tst18() {
environment env; environment env;
metavar_env menv; metavar_env menv;
normalizer norm(env); normalizer norm(env);
context ctx;
ctx = extend(ctx, "w1", Type());
ctx = extend(ctx, "w2", Type());
expr f = Const("f"); expr f = Const("f");
expr g = Const("g"); expr g = Const("g");
expr h = Const("h"); expr h = Const("h");
@ -387,12 +384,13 @@ static void tst18() {
expr z = Const("z"); expr z = Const("z");
expr N = Const("N"); expr N = Const("N");
expr a = Const("a"); expr a = Const("a");
context ctx({{"x1", N}});
env->add_var("N", Type()); env->add_var("N", Type());
env->add_var("a", N); env->add_var("a", N);
env->add_var("g", N >> N); env->add_var("g", N >> N);
env->add_var("h", N >> (N >> N)); env->add_var("h", N >> (N >> N));
expr m1 = menv->mk_metavar(context({{"z", Type()}, {"f", N >> N}, {"y", Type()}})); expr m1 = menv->mk_metavar(context({{"x1", N}, {"z", Type()}, {"f", N >> N}, {"y", Type()}}));
expr m2 = menv->mk_metavar(context({{"z", Type()}, {"x", N}, {"x1", N}})); expr m2 = menv->mk_metavar(context({{"x1", N}, {"z", Type()}, {"x", N}}));
expr F = Fun({z, Type()}, Fun({{f, N >> N}, {y, Type()}}, m1)(Fun({x, N}, g(z, x, m2)), N)); expr F = Fun({z, Type()}, Fun({{f, N >> N}, {y, Type()}}, m1)(Fun({x, N}, g(z, x, m2)), N));
std::cout << norm(F, ctx) << "\n"; std::cout << norm(F, ctx) << "\n";
metavar_env menv2 = menv.copy(); metavar_env menv2 = menv.copy();
@ -400,9 +398,12 @@ static void tst18() {
menv2->assign(m2, h(Var(2), Var(1))); menv2->assign(m2, h(Var(2), Var(1)));
std::cout << menv2->instantiate_metavars(norm(F, ctx)) << "\n"; std::cout << menv2->instantiate_metavars(norm(F, ctx)) << "\n";
std::cout << menv2->instantiate_metavars(F) << "\n"; std::cout << menv2->instantiate_metavars(F) << "\n";
lean_assert_eq(menv2->instantiate_metavars(norm(F, ctx)), lean_assert_eq(menv2->instantiate_metavars(norm(F, ctx, menv2)),
norm(menv2->instantiate_metavars(F), ctx)); norm(menv2->instantiate_metavars(F), ctx, menv2));
lean_assert_eq(menv2->instantiate_metavars(norm(F, ctx)), std::cout << "norm(F...): " << norm(F, ctx, menv2) << "\n";
lean_assert(menv2->is_assigned(m1));
lean_assert(menv2->is_assigned(m2));
lean_assert_eq(menv2->instantiate_metavars(norm(F, ctx, menv2)),
Fun({{z, Type()}, {x, N}}, g(z, x, h(Var(2), z)))); Fun({{z, Type()}, {x, N}}, g(z, x, h(Var(2), z))));
} }
@ -420,8 +421,8 @@ static void tst19() {
expr F = Fun({{N, Type()}, {x, N}, {y, N}}, m1); expr F = Fun({{N, Type()}, {x, N}, {y, N}}, m1);
std::cout << norm(F) << "\n"; std::cout << norm(F) << "\n";
std::cout << norm(F, ctx) << "\n"; std::cout << norm(F, ctx) << "\n";
lean_assert(norm(F) == F); lean_assert_eq(norm(F, context(), menv), F);
lean_assert(norm(F, ctx) == F); lean_assert_eq(norm(F, ctx, menv), F);
} }
static void tst20() { static void tst20() {

View file

@ -303,6 +303,17 @@ static void tst9() {
lean_assert_eq(N, Fun({x, Type()}, f(x, Bool))); lean_assert_eq(N, Fun({x, Type()}, f(x, Bool)));
} }
static void tst10() {
environment env;
import_all(env);
metavar_env menv;
context ctx({{"x", Bool}, {"y", Bool}});
expr m = menv->mk_metavar(ctx);
ctx = extend(ctx, "z", none_expr(), m);
std::cout << normalizer(env)(Var(0), ctx) << "\n";
lean_assert_eq(normalizer(env)(Var(0), ctx), add_lift(m, 0, 1));
}
int main() { int main() {
save_stack_info(); save_stack_info();
tst_church_numbers(); tst_church_numbers();
@ -315,5 +326,6 @@ int main() {
tst7(); tst7();
tst8(); tst8();
tst9(); tst9();
tst10();
return has_violations() ? 1 : 0; return has_violations() ? 1 : 0;
} }