2013-08-04 23:07:37 +00:00
|
|
|
/*
|
|
|
|
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
|
|
|
Author: Leonardo de Moura
|
|
|
|
*/
|
2013-09-13 03:04:10 +00:00
|
|
|
#include "util/test.h"
|
|
|
|
#include "util/exception.h"
|
|
|
|
#include "util/trace.h"
|
|
|
|
#include "kernel/kernel_exception.h"
|
|
|
|
#include "kernel/environment.h"
|
|
|
|
#include "kernel/type_checker.h"
|
|
|
|
#include "kernel/builtin.h"
|
|
|
|
#include "kernel/normalizer.h"
|
|
|
|
#include "kernel/abstract.h"
|
2013-10-01 01:16:13 +00:00
|
|
|
#include "kernel/printer.h"
|
2013-09-13 15:55:09 +00:00
|
|
|
#include "library/arith/arith.h"
|
2013-09-13 16:06:46 +00:00
|
|
|
#include "library/all/all.h"
|
2013-08-04 23:07:37 +00:00
|
|
|
using namespace lean;
|
|
|
|
|
|
|
|
static void tst1() {
|
|
|
|
environment env;
|
2013-12-13 00:33:31 +00:00
|
|
|
level u = env->add_uvar("u", level() + 1);
|
|
|
|
level w = env->add_uvar("w", u + 1);
|
|
|
|
lean_assert(!env->has_children());
|
|
|
|
lean_assert(!env->has_parent());
|
2013-08-04 23:07:37 +00:00
|
|
|
{
|
2013-12-13 00:33:31 +00:00
|
|
|
environment child = env->mk_child();
|
|
|
|
lean_assert(child->is_ge(w, u));
|
|
|
|
lean_assert(child->is_ge(w, level() + 2));
|
|
|
|
lean_assert(env->is_ge(w, level() + 2));
|
|
|
|
lean_assert(env->has_children());
|
|
|
|
lean_assert(child->has_parent());
|
|
|
|
lean_assert(!env->has_parent());
|
2013-08-04 23:07:37 +00:00
|
|
|
try {
|
2013-12-13 00:33:31 +00:00
|
|
|
level o = env->add_uvar("o", w + 1);
|
2013-08-04 23:07:37 +00:00
|
|
|
lean_unreachable();
|
2013-08-05 03:52:14 +00:00
|
|
|
} catch (exception const & ex) {
|
2013-08-04 23:07:37 +00:00
|
|
|
std::cout << "expected error: " << ex.what() << "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
std::cout << "tst1 checkpoint" << std::endl;
|
2013-12-13 00:33:31 +00:00
|
|
|
level o = env->add_uvar("o", w + 1);
|
|
|
|
lean_assert(!env->has_children());
|
2013-08-16 22:09:26 +00:00
|
|
|
std::cout << env;
|
2013-08-04 23:07:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static environment mk_child() {
|
|
|
|
environment env;
|
2013-12-13 00:33:31 +00:00
|
|
|
level u = env->add_uvar("u", level() + 1);
|
|
|
|
return env->mk_child();
|
2013-08-04 23:07:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void tst2() {
|
|
|
|
environment child = mk_child();
|
2013-12-13 00:33:31 +00:00
|
|
|
lean_assert(child->has_parent());
|
|
|
|
lean_assert(!child->has_children());
|
|
|
|
environment parent = child->parent();
|
2013-08-16 22:09:26 +00:00
|
|
|
std::cout << parent;
|
2013-12-13 00:33:31 +00:00
|
|
|
lean_assert(parent->has_children());
|
|
|
|
std::cout << "uvar: " << child->get_uvar("u") << "\n";
|
2013-08-04 23:07:37 +00:00
|
|
|
}
|
|
|
|
|
2013-08-05 03:52:14 +00:00
|
|
|
static void tst3() {
|
2013-10-22 21:02:45 +00:00
|
|
|
std::cout << "tst3\n";
|
2013-09-04 15:30:04 +00:00
|
|
|
environment env = mk_toplevel();
|
2013-08-05 03:52:14 +00:00
|
|
|
try {
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_definition("a", Int, Const("a"));
|
2013-08-05 03:52:14 +00:00
|
|
|
lean_unreachable();
|
2013-08-05 22:47:58 +00:00
|
|
|
} catch (exception const & ex) {
|
2013-08-05 03:52:14 +00:00
|
|
|
std::cout << "expected error: " << ex.what() << "\n";
|
|
|
|
}
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_definition("a", Int, iAdd(iVal(1), iVal(2)));
|
2013-08-13 22:13:54 +00:00
|
|
|
std::cout << env << "\n";
|
2013-08-06 18:27:14 +00:00
|
|
|
expr t = iAdd(Const("a"), iVal(1));
|
2013-08-05 03:52:14 +00:00
|
|
|
std::cout << t << " --> " << normalize(t, env) << "\n";
|
2013-08-06 18:27:14 +00:00
|
|
|
lean_assert(normalize(t, env) == iVal(4));
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_definition("b", Int, iMul(iVal(2), Const("a")));
|
2013-08-06 18:27:14 +00:00
|
|
|
std::cout << "b --> " << normalize(Const("b"), env) << "\n";
|
|
|
|
lean_assert(normalize(Const("b"), env) == iVal(6));
|
2013-08-05 03:52:14 +00:00
|
|
|
try {
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_definition("c", mk_arrow(Int, Int), Const("a"));
|
2013-08-05 03:52:14 +00:00
|
|
|
lean_unreachable();
|
2013-08-05 22:47:58 +00:00
|
|
|
} catch (exception const & ex) {
|
2013-08-05 03:52:14 +00:00
|
|
|
std::cout << "expected error: " << ex.what() << "\n";
|
|
|
|
}
|
|
|
|
try {
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_definition("a", Int, iVal(10));
|
2013-08-05 03:52:14 +00:00
|
|
|
lean_unreachable();
|
2013-08-05 22:47:58 +00:00
|
|
|
} catch (exception const & ex) {
|
2013-08-05 03:52:14 +00:00
|
|
|
std::cout << "expected error: " << ex.what() << "\n";
|
|
|
|
}
|
2013-12-13 00:33:31 +00:00
|
|
|
environment c_env = env->mk_child();
|
2013-08-05 03:52:14 +00:00
|
|
|
try {
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_definition("c", Int, Const("a"));
|
2013-08-05 03:52:14 +00:00
|
|
|
lean_unreachable();
|
2013-08-05 22:47:58 +00:00
|
|
|
} catch (exception const & ex) {
|
2013-08-05 03:52:14 +00:00
|
|
|
std::cout << "expected error: " << ex.what() << "\n";
|
|
|
|
}
|
2013-08-06 18:27:14 +00:00
|
|
|
lean_assert(normalize(Const("b"), env) == iVal(6));
|
|
|
|
lean_assert(normalize(Const("b"), c_env) == iVal(6));
|
2013-12-13 00:33:31 +00:00
|
|
|
c_env->add_definition("c", Int, Const("a"));
|
2013-08-06 18:27:14 +00:00
|
|
|
lean_assert(normalize(Const("c"), c_env) == iVal(3));
|
2013-08-05 03:52:14 +00:00
|
|
|
try {
|
2013-08-06 18:27:14 +00:00
|
|
|
expr r = normalize(Const("c"), env);
|
|
|
|
lean_assert(r == iVal(3));
|
2013-08-05 03:52:14 +00:00
|
|
|
lean_unreachable();
|
2013-08-05 22:47:58 +00:00
|
|
|
} catch (exception const & ex) {
|
|
|
|
std::cout << "expected error: " << ex.what() << std::endl;
|
2013-08-05 03:52:14 +00:00
|
|
|
}
|
2013-08-05 22:47:58 +00:00
|
|
|
std::cout << "end tst3" << std::endl;
|
2013-08-05 03:52:14 +00:00
|
|
|
}
|
|
|
|
|
2013-08-05 17:33:05 +00:00
|
|
|
static void tst4() {
|
2013-10-22 21:02:45 +00:00
|
|
|
std::cout << "tst4\n";
|
2013-09-02 23:09:55 +00:00
|
|
|
environment env = mk_toplevel();
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_definition("a", Int, iVal(1), true); // add opaque definition
|
2013-08-06 18:27:14 +00:00
|
|
|
expr t = iAdd(Const("a"), iVal(1));
|
2013-08-05 17:33:05 +00:00
|
|
|
std::cout << t << " --> " << normalize(t, env) << "\n";
|
|
|
|
lean_assert(normalize(t, env) == t);
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_definition("b", Int, iAdd(Const("a"), iVal(1)));
|
2013-08-06 18:27:14 +00:00
|
|
|
expr t2 = iSub(Const("b"), iVal(9));
|
2013-08-05 17:33:05 +00:00
|
|
|
std::cout << t2 << " --> " << normalize(t2, env) << "\n";
|
2013-09-02 23:09:55 +00:00
|
|
|
lean_assert(normalize(t2, env) == iAdd(iAdd(Const("a"), iVal(1)), iVal(-9)));
|
2013-08-05 17:33:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void tst5() {
|
2013-09-04 15:30:04 +00:00
|
|
|
environment env = mk_toplevel();
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_definition("a", Int, iVal(1), true); // add opaque definition
|
2013-08-05 17:33:05 +00:00
|
|
|
try {
|
2013-08-06 18:27:14 +00:00
|
|
|
std::cout << infer_type(iAdd(Const("a"), Int), env) << "\n";
|
2013-08-05 17:33:05 +00:00
|
|
|
lean_unreachable();
|
2013-08-05 22:47:58 +00:00
|
|
|
} catch (exception const & ex) {
|
2013-08-05 17:33:05 +00:00
|
|
|
std::cout << "expected error: " << ex.what() << "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-05 20:16:20 +00:00
|
|
|
static void tst6() {
|
2013-09-04 15:30:04 +00:00
|
|
|
environment env = mk_toplevel();
|
2013-12-13 00:33:31 +00:00
|
|
|
level u = env->add_uvar("u", level() + 1);
|
|
|
|
level w = env->add_uvar("w", u + 1);
|
|
|
|
env->add_var("f", mk_arrow(Type(u), Type(u)));
|
2013-08-06 18:27:14 +00:00
|
|
|
expr t = Const("f")(Int);
|
2013-08-05 20:16:20 +00:00
|
|
|
std::cout << "type of " << t << " is " << infer_type(t, env) << "\n";
|
|
|
|
try {
|
2013-08-06 18:27:14 +00:00
|
|
|
infer_type(Const("f")(Type(w)), env);
|
2013-08-05 20:16:20 +00:00
|
|
|
lean_unreachable();
|
2013-08-05 22:47:58 +00:00
|
|
|
} catch (exception const & ex) {
|
2013-08-05 20:16:20 +00:00
|
|
|
std::cout << "expected error: " << ex.what() << "\n";
|
|
|
|
}
|
|
|
|
try {
|
2013-08-06 18:27:14 +00:00
|
|
|
infer_type(Const("f")(Type(u)), env);
|
2013-08-05 20:16:20 +00:00
|
|
|
lean_unreachable();
|
2013-08-05 22:47:58 +00:00
|
|
|
} catch (exception const & ex) {
|
2013-08-05 20:16:20 +00:00
|
|
|
std::cout << "expected error: " << ex.what() << "\n";
|
|
|
|
}
|
2013-08-06 18:27:14 +00:00
|
|
|
t = Const("f")(Type());
|
2013-08-05 20:16:20 +00:00
|
|
|
std::cout << "type of " << t << " is " << infer_type(t, env) << "\n";
|
2013-08-18 22:44:39 +00:00
|
|
|
std::cout << infer_type(mk_arrow(Type(u), Type(w)), env) << "\n";
|
|
|
|
lean_assert(infer_type(mk_arrow(Type(u), Type(w)), env) == Type(max(u+1, w+1)));
|
|
|
|
std::cout << infer_type(mk_arrow(Int, Int), env) << "\n";
|
|
|
|
lean_assert(infer_type(mk_arrow(Int, Int), env) == Type());
|
2013-08-05 20:16:20 +00:00
|
|
|
}
|
|
|
|
|
2013-08-06 03:06:07 +00:00
|
|
|
static void tst7() {
|
|
|
|
environment env = mk_toplevel();
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_var("a", Int);
|
|
|
|
env->add_var("b", Int);
|
2013-08-06 18:27:14 +00:00
|
|
|
expr t = If(Int, True, Const("a"), Const("b"));
|
2013-08-06 03:06:07 +00:00
|
|
|
std::cout << t << " --> " << normalize(t, env) << "\n";
|
|
|
|
std::cout << infer_type(t, env) << "\n";
|
|
|
|
std::cout << "Environment\n" << env;
|
|
|
|
}
|
|
|
|
|
2013-08-15 16:29:42 +00:00
|
|
|
static void tst8() {
|
|
|
|
environment env;
|
|
|
|
std::cout << "=======================\n";
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_var("a", Type());
|
|
|
|
env->add_var("b", Type());
|
|
|
|
environment env2 = env->mk_child();
|
|
|
|
env2->add_var("c", Type());
|
|
|
|
env2->add_var("d", Type());
|
|
|
|
env2->add_var("e", Type());
|
2013-08-15 16:29:42 +00:00
|
|
|
unsigned counter = 0;
|
2013-12-13 00:33:31 +00:00
|
|
|
std::for_each(env2->begin_local_objects(), env2->end_local_objects(), [&](object const & obj) { std::cout << obj.keyword() << " " << obj.get_name() << "\n"; counter++; });
|
2013-08-15 16:29:42 +00:00
|
|
|
lean_assert(counter == 3);
|
|
|
|
std::cout << "=======================\n";
|
|
|
|
counter = 0;
|
2013-12-13 00:33:31 +00:00
|
|
|
std::for_each(env2->begin_objects(), env2->end_objects(), [&](object const & obj) { std::cout << obj.keyword() << " " << obj.get_name() << "\n"; counter++; });
|
2013-08-15 16:29:42 +00:00
|
|
|
lean_assert(counter == 5);
|
2013-12-13 00:33:31 +00:00
|
|
|
environment env3 = env2->mk_child();
|
|
|
|
env3->add_var("f", Type() >> Type());
|
2013-08-15 16:29:42 +00:00
|
|
|
std::cout << "=======================\n";
|
|
|
|
counter = 0;
|
2013-12-13 00:33:31 +00:00
|
|
|
std::for_each(env3->begin_objects(), env3->end_objects(), [&](object const & obj) { std::cout << obj.keyword() << " " << obj.get_name() << "\n"; counter++; });
|
2013-08-15 16:29:42 +00:00
|
|
|
lean_assert(counter == 6);
|
|
|
|
}
|
|
|
|
|
2013-08-16 19:51:12 +00:00
|
|
|
static void tst9() {
|
|
|
|
try {
|
|
|
|
environment env;
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_uvar("u1", level());
|
|
|
|
env->add_uvar("u2", level());
|
|
|
|
env->add_uvar("u1", level("u2"));
|
2013-08-16 22:09:26 +00:00
|
|
|
} catch (already_declared_exception & ex) {
|
2013-08-16 19:51:12 +00:00
|
|
|
std::cout << ex.what() << "\n";
|
2013-12-13 00:33:31 +00:00
|
|
|
level l = ex.get_environment()->get_uvar(ex.get_name());
|
2013-08-16 19:51:12 +00:00
|
|
|
std::cout << l << "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-15 21:50:08 +00:00
|
|
|
static void tst10() {
|
|
|
|
environment env;
|
|
|
|
import_all(env);
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_definition("a", Int, iVal(1));
|
|
|
|
lean_assert(env->get_object("a").get_weight() == 1);
|
2013-10-15 21:50:08 +00:00
|
|
|
expr a = Const("a");
|
|
|
|
expr b = Const("b");
|
|
|
|
expr c = Const("c");
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_definition("b", Int, iAdd(a, a));
|
|
|
|
lean_assert(env->get_object("b").get_weight() == 2);
|
|
|
|
env->add_definition("c", Int, iAdd(a, b));
|
|
|
|
lean_assert(env->get_object("c").get_weight() == 3);
|
|
|
|
env->add_definition("d", Int, iAdd(b, b));
|
|
|
|
lean_assert(env->get_object("d").get_weight() == 3);
|
2013-10-15 21:50:08 +00:00
|
|
|
}
|
|
|
|
|
2013-12-13 00:33:31 +00:00
|
|
|
struct my_extension : public environment_extension {
|
2013-11-07 03:21:22 +00:00
|
|
|
unsigned m_value1;
|
|
|
|
unsigned m_value2;
|
|
|
|
my_extension():m_value1(0), m_value2(0) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct my_extension_reg {
|
|
|
|
unsigned m_extid;
|
|
|
|
my_extension_reg() {
|
2013-12-13 00:33:31 +00:00
|
|
|
m_extid = environment_cell::register_extension([](){ return std::unique_ptr<environment_extension>(new my_extension()); });
|
2013-11-07 03:21:22 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static my_extension_reg R;
|
|
|
|
|
|
|
|
static void tst11() {
|
|
|
|
unsigned extid = R.m_extid;
|
|
|
|
environment env;
|
2013-12-13 00:33:31 +00:00
|
|
|
my_extension & ext = env->get_extension<my_extension>(extid);
|
2013-11-07 03:21:22 +00:00
|
|
|
ext.m_value1 = 10;
|
|
|
|
ext.m_value2 = 20;
|
2013-12-13 00:33:31 +00:00
|
|
|
my_extension & ext2 = env->get_extension<my_extension>(extid);
|
2013-11-07 03:21:22 +00:00
|
|
|
lean_assert(ext2.m_value1 == 10);
|
|
|
|
lean_assert(ext2.m_value2 == 20);
|
2013-12-13 00:33:31 +00:00
|
|
|
environment child = env->mk_child();
|
|
|
|
my_extension & ext3 = child->get_extension<my_extension>(extid);
|
2013-11-07 03:21:22 +00:00
|
|
|
lean_assert(ext3.m_value1 == 0);
|
|
|
|
lean_assert(ext3.m_value2 == 0);
|
|
|
|
my_extension const * ext4 = ext3.get_parent<my_extension>();
|
|
|
|
lean_assert(ext4);
|
|
|
|
lean_assert(ext4->m_value1 == 10);
|
|
|
|
lean_assert(ext4->m_value2 == 20);
|
|
|
|
lean_assert(ext4->get_parent<my_extension>() == nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void tst12() {
|
|
|
|
unsigned extid = R.m_extid;
|
|
|
|
environment env;
|
2013-12-13 00:33:31 +00:00
|
|
|
environment child = env->mk_child();
|
|
|
|
my_extension & ext = child->get_extension<my_extension>(extid);
|
2013-11-07 03:21:22 +00:00
|
|
|
lean_assert(ext.m_value1 == 0);
|
|
|
|
lean_assert(ext.m_value2 == 0);
|
|
|
|
lean_assert(ext.get_parent<my_extension>() == nullptr);
|
|
|
|
}
|
|
|
|
|
2013-11-17 02:35:17 +00:00
|
|
|
static void tst13() {
|
2013-12-13 00:33:31 +00:00
|
|
|
ro_environment::weak_ref wref;
|
2013-11-17 02:35:17 +00:00
|
|
|
{
|
|
|
|
environment env;
|
2013-12-13 00:33:31 +00:00
|
|
|
ro_environment roenv(env);
|
|
|
|
wref = roenv.to_weak_ref();
|
2013-11-17 02:35:17 +00:00
|
|
|
}
|
|
|
|
try {
|
2013-12-13 00:33:31 +00:00
|
|
|
ro_environment env2(wref);
|
2013-11-17 02:35:17 +00:00
|
|
|
lean_unreachable();
|
|
|
|
} catch (exception &) {}
|
|
|
|
}
|
|
|
|
|
2013-08-04 23:07:37 +00:00
|
|
|
int main() {
|
2013-12-01 20:42:32 +00:00
|
|
|
save_stack_info();
|
2013-08-05 17:33:05 +00:00
|
|
|
enable_trace("is_convertible");
|
2013-08-04 23:07:37 +00:00
|
|
|
tst1();
|
|
|
|
tst2();
|
2013-08-05 03:52:14 +00:00
|
|
|
tst3();
|
2013-08-05 17:33:05 +00:00
|
|
|
tst4();
|
|
|
|
tst5();
|
2013-08-05 20:16:20 +00:00
|
|
|
tst6();
|
2013-08-06 03:06:07 +00:00
|
|
|
tst7();
|
2013-08-15 16:29:42 +00:00
|
|
|
tst8();
|
2013-08-16 19:51:12 +00:00
|
|
|
tst9();
|
2013-10-15 21:50:08 +00:00
|
|
|
tst10();
|
2013-11-07 03:21:22 +00:00
|
|
|
tst11();
|
|
|
|
tst12();
|
2013-11-17 02:35:17 +00:00
|
|
|
tst13();
|
2013-08-04 23:07:37 +00:00
|
|
|
return has_violations() ? 1 : 0;
|
|
|
|
}
|