2013-09-27 02:42:02 +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-12-09 22:56:48 +00:00
|
|
|
#include "util/thread.h"
|
2013-09-27 02:42:02 +00:00
|
|
|
#include "util/test.h"
|
|
|
|
#include "kernel/builtin.h"
|
|
|
|
#include "kernel/normalizer.h"
|
2013-12-01 20:42:32 +00:00
|
|
|
#include "kernel/type_checker.h"
|
|
|
|
#include "kernel/abstract.h"
|
2014-01-02 21:14:21 +00:00
|
|
|
#include "library/io_state_stream.h"
|
2013-09-27 02:42:02 +00:00
|
|
|
#include "library/arith/arith.h"
|
2013-12-29 10:44:49 +00:00
|
|
|
#include "frontends/lean/frontend.h"
|
2013-09-27 02:42:02 +00:00
|
|
|
using namespace lean;
|
|
|
|
|
2013-12-01 20:42:32 +00:00
|
|
|
static void tst0() {
|
2013-09-27 02:42:02 +00:00
|
|
|
environment env;
|
2014-01-02 15:11:55 +00:00
|
|
|
init_test_frontend(env);
|
2013-09-27 02:42:02 +00:00
|
|
|
normalizer norm(env);
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_var("n", Nat);
|
2013-09-27 02:42:02 +00:00
|
|
|
expr n = Const("n");
|
|
|
|
lean_assert_eq(mk_nat_type(), Nat);
|
2014-01-10 02:09:53 +00:00
|
|
|
lean_assert_eq(norm(mk_Nat_mul(nVal(2), nVal(3))), nVal(6));
|
|
|
|
lean_assert_eq(norm(mk_Nat_le(nVal(2), nVal(3))), True);
|
|
|
|
lean_assert_eq(norm(mk_Nat_le(nVal(5), nVal(3))), False);
|
|
|
|
lean_assert_eq(norm(mk_Nat_le(nVal(2), nVal(3))), True);
|
|
|
|
lean_assert_eq(norm(mk_Nat_le(n, nVal(3))), mk_Nat_le(n, nVal(3)));
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_var("x", Real);
|
2013-09-27 02:42:02 +00:00
|
|
|
expr x = Const("x");
|
|
|
|
lean_assert_eq(mk_real_type(), Real);
|
2014-01-10 02:09:53 +00:00
|
|
|
lean_assert_eq(norm(mk_Real_mul(rVal(2), rVal(3))), rVal(6));
|
|
|
|
lean_assert_eq(norm(mk_Real_div(rVal(2), rVal(0))), rVal(0));
|
|
|
|
lean_assert_eq(norm(mk_Real_le(rVal(2), rVal(3))), True);
|
|
|
|
lean_assert_eq(norm(mk_Real_le(rVal(5), rVal(3))), False);
|
|
|
|
lean_assert_eq(norm(mk_Real_le(rVal(2), rVal(3))), True);
|
|
|
|
lean_assert_eq(norm(mk_Real_le(x, rVal(3))), mk_Real_le(x, rVal(3)));
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_var("i", Int);
|
2013-09-27 02:42:02 +00:00
|
|
|
expr i = Const("i");
|
2014-01-10 02:09:53 +00:00
|
|
|
lean_assert_eq(norm(mk_int_to_real(i)), mk_int_to_real(i));
|
|
|
|
lean_assert_eq(norm(mk_int_to_real(iVal(2))), rVal(2));
|
2013-09-27 02:42:02 +00:00
|
|
|
lean_assert_eq(mk_int_type(), Int);
|
2014-01-10 02:09:53 +00:00
|
|
|
lean_assert_eq(norm(mk_nat_to_int(n)), mk_nat_to_int(n));
|
|
|
|
lean_assert_eq(norm(mk_nat_to_int(nVal(2))), iVal(2));
|
|
|
|
lean_assert_eq(norm(mk_Int_div(iVal(2), iVal(0))), iVal(0));
|
2013-09-27 02:42:02 +00:00
|
|
|
}
|
|
|
|
|
2013-12-01 20:42:32 +00:00
|
|
|
static void tst1() {
|
|
|
|
environment env;
|
2014-01-02 15:11:55 +00:00
|
|
|
init_test_frontend(env);
|
2013-12-01 20:42:32 +00:00
|
|
|
expr e = mk_int_value(mpz(10));
|
|
|
|
lean_assert(is_int_value(e));
|
2013-12-22 19:51:38 +00:00
|
|
|
lean_assert(type_check(e, env) == Int);
|
2013-12-01 20:42:32 +00:00
|
|
|
std::cout << "e: " << e << "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
static void tst2() {
|
|
|
|
environment env;
|
2014-01-02 15:11:55 +00:00
|
|
|
init_test_frontend(env);
|
2014-01-10 02:09:53 +00:00
|
|
|
expr e = mk_Int_add(iVal(10), iVal(30));
|
2013-12-01 20:42:32 +00:00
|
|
|
std::cout << e << "\n";
|
|
|
|
std::cout << normalize(e, env) << "\n";
|
|
|
|
lean_assert(normalize(e, env) == iVal(40));
|
2014-01-10 02:09:53 +00:00
|
|
|
std::cout << type_check(mk_Int_add_fn(), env) << "\n";
|
2013-12-22 19:51:38 +00:00
|
|
|
lean_assert(type_check(e, env) == Int);
|
2014-01-10 02:09:53 +00:00
|
|
|
lean_assert(type_check(mk_app(mk_Int_add_fn(), iVal(10)), env) == (Int >> Int));
|
2013-12-01 20:42:32 +00:00
|
|
|
lean_assert(is_int_value(normalize(e, env)));
|
2014-01-10 02:09:53 +00:00
|
|
|
expr e2 = Fun("a", Int, mk_Int_add(Const("a"), mk_Int_add(iVal(10), iVal(30))));
|
2013-12-01 20:42:32 +00:00
|
|
|
std::cout << e2 << " --> " << normalize(e2, env) << "\n";
|
2013-12-22 19:51:38 +00:00
|
|
|
lean_assert(type_check(e2, env) == mk_arrow(Int, Int));
|
2014-01-10 02:09:53 +00:00
|
|
|
lean_assert(normalize(e2, env) == Fun("a", Int, mk_Int_add(Const("a"), iVal(40))));
|
2013-12-01 20:42:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void tst3() {
|
|
|
|
environment env;
|
2014-01-02 15:11:55 +00:00
|
|
|
init_test_frontend(env);
|
2014-01-10 02:09:53 +00:00
|
|
|
expr e = mk_Int_mul(iVal(10), iVal(30));
|
2013-12-01 20:42:32 +00:00
|
|
|
std::cout << e << "\n";
|
|
|
|
std::cout << normalize(e, env) << "\n";
|
|
|
|
lean_assert(normalize(e, env) == iVal(300));
|
2014-01-10 02:09:53 +00:00
|
|
|
std::cout << type_check(mk_Int_mul_fn(), env) << "\n";
|
2013-12-22 19:51:38 +00:00
|
|
|
lean_assert(type_check(e, env) == Int);
|
2014-01-10 02:09:53 +00:00
|
|
|
lean_assert(type_check(mk_app(mk_Int_mul_fn(), iVal(10)), env) == mk_arrow(Int, Int));
|
2013-12-01 20:42:32 +00:00
|
|
|
lean_assert(is_int_value(normalize(e, env)));
|
2014-01-10 02:09:53 +00:00
|
|
|
expr e2 = Fun("a", Int, mk_Int_mul(Const("a"), mk_Int_mul(iVal(10), iVal(30))));
|
2013-12-01 20:42:32 +00:00
|
|
|
std::cout << e2 << " --> " << normalize(e2, env) << "\n";
|
2013-12-22 19:51:38 +00:00
|
|
|
lean_assert(type_check(e2, env) == (Int >> Int));
|
2014-01-10 02:09:53 +00:00
|
|
|
lean_assert(normalize(e2, env) == Fun("a", Int, mk_Int_mul(Const("a"), iVal(300))));
|
2013-12-01 20:42:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void tst4() {
|
|
|
|
environment env;
|
2014-01-02 15:11:55 +00:00
|
|
|
init_test_frontend(env);
|
2014-01-10 02:09:53 +00:00
|
|
|
expr e = mk_Int_sub(iVal(10), iVal(30));
|
2013-12-01 20:42:32 +00:00
|
|
|
std::cout << e << "\n";
|
|
|
|
std::cout << normalize(e, env) << "\n";
|
refactor(kernel): add unfold_opaque flag to normalizer, modify how type checker uses the opaque flag, remove hidden_defs, and mark most builtin definitions as opaque
After this commit, in the type checker, when checking convertability, we first compute a normal form without expanding opaque terms.
If the terms are convertible, then we are done, and saved a lot of time by not expanding unnecessary definitions.
If they are not, instead of throwing an error, we try again expanding the opaque terms.
This seems to be the best of both worlds.
The opaque flag is a hint for the type checker, but it would never prevent us from type checking a valid term.
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2013-12-20 20:47:36 +00:00
|
|
|
lean_assert(normalize(e, env, context(), true) == iVal(-20));
|
2014-01-10 02:09:53 +00:00
|
|
|
std::cout << type_check(mk_Int_sub_fn(), env) << "\n";
|
2013-12-22 19:51:38 +00:00
|
|
|
lean_assert(type_check(e, env) == Int);
|
2014-01-10 02:09:53 +00:00
|
|
|
lean_assert(type_check(mk_app(mk_Int_sub_fn(), iVal(10)), env) == mk_arrow(Int, Int));
|
refactor(kernel): add unfold_opaque flag to normalizer, modify how type checker uses the opaque flag, remove hidden_defs, and mark most builtin definitions as opaque
After this commit, in the type checker, when checking convertability, we first compute a normal form without expanding opaque terms.
If the terms are convertible, then we are done, and saved a lot of time by not expanding unnecessary definitions.
If they are not, instead of throwing an error, we try again expanding the opaque terms.
This seems to be the best of both worlds.
The opaque flag is a hint for the type checker, but it would never prevent us from type checking a valid term.
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2013-12-20 20:47:36 +00:00
|
|
|
lean_assert(is_int_value(normalize(e, env, context(), true)));
|
2014-01-10 02:09:53 +00:00
|
|
|
expr e2 = Fun("a", Int, mk_Int_sub(Const("a"), mk_Int_sub(iVal(10), iVal(30))));
|
2013-12-01 20:42:32 +00:00
|
|
|
std::cout << e2 << " --> " << normalize(e2, env) << "\n";
|
2013-12-22 19:51:38 +00:00
|
|
|
lean_assert(type_check(e2, env) == (Int >> Int));
|
2014-01-10 02:09:53 +00:00
|
|
|
lean_assert_eq(normalize(e2, env, context(), true), Fun("a", Int, mk_Int_add(Const("a"), iVal(20))));
|
2013-12-01 20:42:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void tst5() {
|
|
|
|
environment env;
|
2014-01-02 15:11:55 +00:00
|
|
|
init_test_frontend(env);
|
2013-12-13 00:33:31 +00:00
|
|
|
env->add_var(name("a"), Int);
|
2014-01-10 02:09:53 +00:00
|
|
|
expr e = HEq(iVal(3), iVal(4));
|
2013-12-01 20:42:32 +00:00
|
|
|
std::cout << e << " --> " << normalize(e, env) << "\n";
|
|
|
|
lean_assert(normalize(e, env) == False);
|
2014-01-10 02:09:53 +00:00
|
|
|
lean_assert(normalize(HEq(Const("a"), iVal(3)), env) == HEq(Const("a"), iVal(3)));
|
2013-12-01 20:42:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void tst6() {
|
|
|
|
std::cout << "tst6\n";
|
2014-01-10 02:09:53 +00:00
|
|
|
std::cout << mk_Int_add_fn().raw() << "\n";
|
|
|
|
std::cout << mk_Int_add_fn().raw() << "\n";
|
2013-12-01 20:42:32 +00:00
|
|
|
|
|
|
|
#ifndef __APPLE__
|
2014-01-10 02:09:53 +00:00
|
|
|
thread t1([](){ save_stack_info(); std::cout << "t1: " << mk_Int_add_fn().raw() << "\n"; });
|
2013-12-01 20:42:32 +00:00
|
|
|
t1.join();
|
2014-01-10 02:09:53 +00:00
|
|
|
thread t2([](){ save_stack_info(); std::cout << "t2: " << mk_Int_add_fn().raw() << "\n"; });
|
2013-12-01 20:42:32 +00:00
|
|
|
t2.join();
|
|
|
|
#endif
|
2014-01-10 02:09:53 +00:00
|
|
|
std::cout << mk_Int_add_fn().raw() << "\n";
|
2013-12-01 20:42:32 +00:00
|
|
|
}
|
|
|
|
|
2013-09-27 02:42:02 +00:00
|
|
|
int main() {
|
2013-12-01 20:42:32 +00:00
|
|
|
save_stack_info();
|
|
|
|
tst0();
|
2013-09-27 02:42:02 +00:00
|
|
|
tst1();
|
2013-12-01 20:42:32 +00:00
|
|
|
tst2();
|
|
|
|
tst3();
|
|
|
|
tst4();
|
|
|
|
tst5();
|
|
|
|
tst6();
|
2013-09-27 02:42:02 +00:00
|
|
|
return has_violations() ? 1 : 0;
|
|
|
|
}
|