lean4-htt/src/tests/library/ho_unifier.cpp
Leonardo de Moura c847d27763 Improve higher order unification
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2013-09-21 00:41:49 -07:00

172 lines
5.1 KiB
C++

/*
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura
*/
#include "util/test.h"
#include "kernel/environment.h"
#include "kernel/builtin.h"
#include "kernel/abstract.h"
#include "library/ho_unifier.h"
#include "library/printer.h"
#include "library/reduce.h"
#include "library/arith/arith.h"
using namespace lean;
void tst1() {
environment env;
metavar_env menv;
ho_unifier unify(env);
expr N = Const("N");
expr M = Const("M");
env.add_var("N", Type());
env.add_var("M", Type());
env.add_var("f", N >> (M >> M));
env.add_var("a", N);
env.add_var("b", M);
expr f = Const("f");
expr x = Const("x");
expr a = Const("a");
expr b = Const("b");
expr m1 = menv.mk_metavar();
expr l = m1(b, a);
expr r = f(b, f(a, b));
for (auto sol : unify(context(), l, r, menv)) {
std::cout << m1 << " -> " << beta_reduce(sol.first.get_subst(m1)) << "\n";
std::cout << beta_reduce(instantiate_metavars(l, sol.first)) << "\n";
lean_assert(beta_reduce(instantiate_metavars(l, sol.first)) == r);
std::cout << "--------------\n";
}
}
void tst2() {
environment env;
import_basic(env);
metavar_env menv;
ho_unifier unify(env);
expr N = Const("N");
expr M = Const("M");
env.add_var("N", Type());
env.add_var("f", N >> (Bool >> N));
env.add_var("a", N);
env.add_var("b", N);
expr f = Const("f");
expr x = Const("x");
expr a = Const("a");
expr b = Const("b");
expr m1 = menv.mk_metavar();
expr l = m1(b, a);
expr r = Fun({x, N}, f(x, Eq(a, b)));
for (auto sol : unify(context(), l, r, menv)) {
std::cout << m1 << " -> " << beta_reduce(sol.first.get_subst(m1)) << "\n";
std::cout << beta_reduce(instantiate_metavars(l, sol.first)) << "\n";
lean_assert(beta_reduce(instantiate_metavars(l, sol.first)) == r);
std::cout << "--------------\n";
}
}
void tst3() {
environment env;
import_basic(env);
import_arith(env);
metavar_env menv;
ho_unifier unify(env);
expr N = Const("N");
env.add_var("N", Type());
env.add_var("f", N >> (Int >> N));
env.add_var("a", N);
env.add_var("b", N);
expr m1 = menv.mk_metavar();
expr m2 = menv.mk_metavar();
expr m3 = menv.mk_metavar();
expr t1 = menv.get_type(m1);
expr t2 = menv.get_type(m2);
expr f = Const("f");
expr a = Const("a");
expr b = Const("b");
expr l = f(m1(a), iAdd(m3, iAdd(iVal(1), iVal(1))));
expr r = f(m2(b), iAdd(iVal(1), iVal(2)));
for (auto sol : unify(context(), l, r, menv)) {
std::cout << m3 << " -> " << sol.first.get_subst(m3) << "\n";
lean_assert(sol.first.get_subst(m3) == iVal(1));
lean_assert(length(sol.second) == 1);
for (auto c : sol.second) {
std::cout << std::get<1>(c) << " == " << std::get<2>(c) << "\n";
}
}
}
void tst4() {
environment env;
metavar_env menv;
ho_unifier unify(env);
expr N = Const("N");
env.add_var("N", Type());
env.add_var("f", N >> (N >> N));
expr x = Const("x");
expr y = Const("y");
expr f = Const("f");
expr m1 = menv.mk_metavar();
expr m2 = menv.mk_metavar();
expr l = Fun({{x, N}, {y, N}}, Eq(y, f(x, m1)));
expr r = Fun({{x, N}, {y, N}}, Eq(m2, f(m1, x)));
auto sols = unify(context(), l, r, menv);
lean_assert(length(sols) == 1);
for (auto sol : sols) {
std::cout << m1 << " -> " << sol.first.get_subst(m1) << "\n";
std::cout << m2 << " -> " << sol.first.get_subst(m2) << "\n";
lean_assert(empty(sol.second));
lean_assert(beta_reduce(instantiate_metavars(l, sol.first)) ==
beta_reduce(instantiate_metavars(r, sol.first)));
}
}
void tst5() {
environment env;
metavar_env menv;
ho_unifier unify(env);
expr N = Const("N");
env.add_var("N", Type());
env.add_var("f", N >> (N >> N));
expr f = Const("f");
expr m1 = menv.mk_metavar();
expr l = f(f(m1));
expr r = f(m1);
auto sols = unify(context(), l, r, menv);
lean_assert(length(sols) == 0);
}
void tst6() {
environment env;
metavar_env menv;
ho_unifier unify(env);
expr N = Const("N");
env.add_var("N", Type());
env.add_var("f", N >> (N >> N));
expr x = Const("x");
expr y = Const("y");
expr f = Const("f");
expr m1 = menv.mk_metavar();
expr l = Fun({x, N}, Fun({y, N}, f(m1, y))(x));
expr r = Fun({x, N}, f(x, x));
auto sols = unify(context(), l, r, menv);
lean_assert(length(sols) == 2);
for (auto sol : sols) {
std::cout << m1 << " -> " << sol.first.get_subst(m1) << "\n";
std::cout << instantiate_metavars(l, sol.first) << "\n";
lean_assert(empty(sol.second));
lean_assert(beta_reduce(instantiate_metavars(l, sol.first)) ==
beta_reduce(instantiate_metavars(r, sol.first)));
}
}
int main() {
tst1();
tst2();
tst3();
tst4();
tst5();
tst6();
return has_violations() ? 1 : 0;
}