172 lines
5.1 KiB
C++
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;
|
|
}
|