2013-08-10 01:00:05 +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 23:14:24 +00:00
|
|
|
#include <vector>
|
2013-09-13 03:04:10 +00:00
|
|
|
#include "util/test.h"
|
|
|
|
#include "kernel/environment.h"
|
|
|
|
#include "kernel/kernel_exception.h"
|
|
|
|
#include "kernel/builtin.h"
|
|
|
|
#include "kernel/abstract.h"
|
|
|
|
#include "library/printer.h"
|
2013-09-13 03:09:35 +00:00
|
|
|
#include "frontends/lean/frontend.h"
|
|
|
|
#include "frontends/lean/operator_info.h"
|
|
|
|
#include "frontends/lean/pp.h"
|
2013-08-10 01:00:05 +00:00
|
|
|
using namespace lean;
|
|
|
|
|
|
|
|
static void tst1() {
|
|
|
|
frontend f;
|
|
|
|
f.add_uvar("tst");
|
|
|
|
frontend c = f.mk_child();
|
|
|
|
lean_assert(c.get_uvar("tst") == f.get_uvar("tst"));
|
2013-08-17 03:39:24 +00:00
|
|
|
lean_assert(f.get_environment().has_children());
|
2013-08-10 01:00:05 +00:00
|
|
|
}
|
|
|
|
|
2013-08-12 01:06:37 +00:00
|
|
|
static void tst2() {
|
|
|
|
operator_info op1 = infixl(name("and"), 10);
|
|
|
|
operator_info op2 = infixr(name("implies"), 20);
|
|
|
|
lean_assert(op1.get_precedence() == 10);
|
2013-08-15 15:52:10 +00:00
|
|
|
lean_assert(op1.get_fixity() == fixity::Infixl);
|
2013-08-20 00:25:15 +00:00
|
|
|
op1.add_expr(mk_and_fn());
|
2013-08-12 01:06:37 +00:00
|
|
|
operator_info op3 = infixl(name("+"), 10);
|
2013-08-20 00:25:15 +00:00
|
|
|
op3.add_expr(Const(name{"Int", "plus"}));
|
|
|
|
op3.add_expr(Const(name{"Real", "plus"}));
|
2013-08-27 16:49:48 +00:00
|
|
|
std::cout << op3.get_denotations() << "\n";
|
|
|
|
lean_assert(length(op3.get_denotations()) == 2);
|
2013-08-12 01:06:37 +00:00
|
|
|
operator_info op4 = op3.copy();
|
2013-08-20 00:25:15 +00:00
|
|
|
op4.add_expr(Const(name{"Complex", "plus"}));
|
2013-08-27 16:49:48 +00:00
|
|
|
std::cout << op4.get_denotations() << "\n";
|
|
|
|
lean_assert(length(op3.get_denotations()) == 2);
|
|
|
|
lean_assert(length(op4.get_denotations()) == 3);
|
2013-08-15 15:52:10 +00:00
|
|
|
lean_assert(op4.get_fixity() == fixity::Infixl);
|
2013-08-12 01:06:37 +00:00
|
|
|
lean_assert(op4.get_op_name() == op3.get_op_name());
|
|
|
|
lean_assert(prefix("tst", 20).get_fixity() == fixity::Prefix);
|
|
|
|
lean_assert(postfix("!", 20).get_fixity() == fixity::Postfix);
|
|
|
|
lean_assert(length(mixfixl({"if", "then", "else"}, 10).get_op_name_parts()) == 3);
|
|
|
|
lean_assert(mixfixc({"if", "then", "else", "endif"}, 10).get_fixity() == fixity::Mixfixc);
|
|
|
|
std::cout << mixfixc({"if", "then", "else", "endif"}, 10).get_op_name_parts() << "\n";
|
|
|
|
std::cout << op4 << "\n";
|
|
|
|
std::cout << op2 << "\n";
|
|
|
|
std::cout << mixfixc({"if", "then", "else", "endif"}, 10) << "\n";
|
|
|
|
}
|
|
|
|
|
2013-08-15 15:52:10 +00:00
|
|
|
static void tst3() {
|
|
|
|
frontend f;
|
2013-08-16 16:30:08 +00:00
|
|
|
std::cout << "====================\n";
|
2013-08-17 03:39:24 +00:00
|
|
|
std::cout << f << "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
static void tst4() {
|
|
|
|
frontend f;
|
2013-08-17 18:29:43 +00:00
|
|
|
formatter fmt = mk_pp_formatter(f);
|
2013-08-17 03:39:24 +00:00
|
|
|
context c;
|
|
|
|
c = extend(c, "x", Bool);
|
|
|
|
c = extend(c, "y", Bool);
|
|
|
|
c = extend(c, "x", Bool, Var(1));
|
|
|
|
c = extend(c, "x", Bool, Var(2));
|
|
|
|
c = extend(c, "z", Bool, Var(1));
|
|
|
|
c = extend(c, "x", Bool, Var(4));
|
|
|
|
std::cout << fmt(c) << "\n";
|
2013-08-15 15:52:10 +00:00
|
|
|
}
|
|
|
|
|
2013-08-17 17:55:42 +00:00
|
|
|
static void tst5() {
|
|
|
|
std::cout << "=================\n";
|
|
|
|
frontend f;
|
2013-08-17 18:29:43 +00:00
|
|
|
formatter fmt = mk_pp_formatter(f);
|
2013-08-17 17:55:42 +00:00
|
|
|
f.add_var("A", Type());
|
|
|
|
f.add_var("x", Const("A"));
|
|
|
|
object const & obj = f.find_object("x");
|
|
|
|
lean_assert(obj);
|
|
|
|
lean_assert(obj.get_name() == "x");
|
|
|
|
std::cout << fmt(obj) << "\n";
|
|
|
|
object const & obj2 = f.find_object("y");
|
|
|
|
lean_assert(!obj2);
|
|
|
|
try {
|
|
|
|
f.get_object("y");
|
|
|
|
lean_unreachable();
|
|
|
|
} catch (unknown_name_exception & ex) {
|
|
|
|
std::cout << ex.what() << " " << ex.get_name() << "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-17 18:04:22 +00:00
|
|
|
class alien_cell : public neutral_object_cell {
|
|
|
|
unsigned m_data[128];
|
|
|
|
public:
|
|
|
|
alien_cell() {}
|
|
|
|
unsigned & get_data(unsigned i) { return m_data[i]; }
|
|
|
|
virtual char const * keyword() const { return "alien"; }
|
|
|
|
};
|
|
|
|
|
|
|
|
static void tst6() {
|
|
|
|
std::cout << "=================\n";
|
|
|
|
frontend f;
|
|
|
|
environment env;
|
|
|
|
env.add_neutral_object(new alien_cell());
|
2013-08-17 18:29:43 +00:00
|
|
|
formatter fmt = mk_pp_formatter(f);
|
2013-08-17 18:04:22 +00:00
|
|
|
std::cout << fmt(env) << "\n";
|
|
|
|
}
|
|
|
|
|
2013-08-17 19:33:19 +00:00
|
|
|
static void tst7() {
|
2013-08-20 21:22:55 +00:00
|
|
|
frontend f;
|
|
|
|
formatter fmt = mk_pp_formatter(f);
|
2013-08-17 19:33:19 +00:00
|
|
|
std::cout << fmt(And(Const("x"), Const("y"))) << "\n";
|
|
|
|
}
|
|
|
|
|
2013-08-17 19:38:32 +00:00
|
|
|
static void tst8() {
|
|
|
|
frontend fe;
|
|
|
|
formatter fmt = mk_pp_formatter(fe);
|
2013-08-20 00:25:15 +00:00
|
|
|
fe.add_infixl("<-$->", 10, mk_refl_fn());
|
2013-08-17 19:38:32 +00:00
|
|
|
std::cout << fmt(fe.find_object("Trivial")) << "\n";
|
|
|
|
}
|
|
|
|
|
2013-08-18 07:28:26 +00:00
|
|
|
static void tst9() {
|
|
|
|
frontend f;
|
|
|
|
lean_assert(!f.has_children());
|
|
|
|
{
|
|
|
|
frontend c = f.mk_child();
|
|
|
|
lean_assert(f.has_children());
|
|
|
|
lean_assert(c.parent().has_children());
|
|
|
|
}
|
|
|
|
lean_assert(!f.has_children());
|
|
|
|
f.add_uvar("l", level()+1);
|
|
|
|
lean_assert(f.get_uvar("l") == level("l"));
|
|
|
|
try { f.get_uvar("l2"); lean_unreachable(); }
|
|
|
|
catch (exception &) {}
|
|
|
|
f.add_definition("x", Bool, True);
|
|
|
|
object const & obj = f.get_object("x");
|
|
|
|
lean_assert(obj.get_name() == "x");
|
|
|
|
lean_assert(obj.get_type() == Bool);
|
|
|
|
lean_assert(obj.get_value() == True);
|
|
|
|
try { f.get_object("y"); lean_unreachable(); }
|
|
|
|
catch (exception &) {}
|
|
|
|
lean_assert(!f.find_object("y"));
|
|
|
|
f.add_definition("y", False);
|
|
|
|
lean_assert(f.find_object("y").get_type() == Bool);
|
|
|
|
lean_assert(f.has_object("y"));
|
|
|
|
lean_assert(!f.has_object("z"));
|
|
|
|
bool found = false;
|
|
|
|
std::for_each(f.begin_objects(), f.end_objects(), [&](object const & obj) { if (obj.has_name() && obj.get_name() == "y") found = true; });
|
|
|
|
lean_assert(found);
|
2013-08-20 00:25:15 +00:00
|
|
|
f.add_postfix("!", 10, Const("factorial"));
|
2013-08-18 07:28:26 +00:00
|
|
|
name parts[] = {"if", "then", "else"};
|
2013-08-20 00:25:15 +00:00
|
|
|
f.add_mixfixl(3, parts, 10, Const("if"));
|
2013-08-18 07:28:26 +00:00
|
|
|
}
|
|
|
|
|
2013-08-18 21:29:32 +00:00
|
|
|
static void tst10() {
|
|
|
|
frontend f;
|
|
|
|
formatter fmt = mk_pp_formatter(f);
|
|
|
|
expr x = Const("xxxxxxxxxxxx");
|
|
|
|
expr y = Const("y");
|
|
|
|
expr z = Const("foo");
|
2013-09-13 19:49:03 +00:00
|
|
|
expr e = Let({{x, True}, {y, And({x, x, x, x, x, x, x, x})}, {z, And(x, y)}}, Or({x, x, x, x, x, x, x, x, x, z, z, z, z, z, z, z}));
|
2013-08-18 21:29:32 +00:00
|
|
|
std::cout << e << "\n";
|
|
|
|
std::cout << fmt(e) << "\n";
|
|
|
|
}
|
|
|
|
|
2013-08-26 16:04:17 +00:00
|
|
|
static void tst11() {
|
|
|
|
frontend f;
|
|
|
|
expr A = Const("A");
|
|
|
|
f.add_var("g", Pi({A, Type()}, A >> (A >> A)));
|
2013-08-27 03:21:05 +00:00
|
|
|
lean_assert(!f.has_implicit_arguments("g"));
|
|
|
|
f.mark_implicit_arguments("g", {true, false, false});
|
2013-08-26 16:04:17 +00:00
|
|
|
lean_assert(f.has_implicit_arguments("g"))
|
|
|
|
name gexp = f.get_explicit_version("g");
|
|
|
|
lean_assert(f.find_object(gexp));
|
|
|
|
lean_assert(f.find_object("g").get_type() == f.find_object(gexp).get_type());
|
2013-08-27 03:21:05 +00:00
|
|
|
lean_assert(f.get_implicit_arguments("g") == std::vector<bool>({true, false, false}));
|
2013-08-26 16:04:17 +00:00
|
|
|
try {
|
2013-08-27 03:21:05 +00:00
|
|
|
f.mark_implicit_arguments("g", {true, false, false});
|
2013-08-26 16:04:17 +00:00
|
|
|
lean_unreachable();
|
|
|
|
} catch (exception & ex) {
|
|
|
|
std::cout << "Expected error: " << ex.what() << std::endl;
|
|
|
|
}
|
|
|
|
f.add_var("s", Pi({A, Type()}, A >> (A >> A)));
|
|
|
|
try {
|
2013-08-27 03:21:05 +00:00
|
|
|
f.mark_implicit_arguments("s", {true, true, true, true});
|
2013-08-26 16:04:17 +00:00
|
|
|
lean_unreachable();
|
|
|
|
} catch (exception & ex) {
|
|
|
|
std::cout << "Expected error: " << ex.what() << std::endl;
|
|
|
|
}
|
2013-09-13 19:49:03 +00:00
|
|
|
f.add_var(name{"h", "explicit"}, Pi({A, Type()}, A >> (A >> A)));
|
2013-08-26 16:04:17 +00:00
|
|
|
f.add_var("h", Pi({A, Type()}, A >> (A >> A)));
|
|
|
|
try {
|
2013-08-27 03:21:05 +00:00
|
|
|
f.mark_implicit_arguments("h", {true, false, false});
|
2013-08-26 16:04:17 +00:00
|
|
|
lean_unreachable();
|
|
|
|
} catch (exception & ex) {
|
|
|
|
std::cout << "Expected error: " << ex.what() << std::endl;
|
|
|
|
}
|
|
|
|
try {
|
2013-08-27 03:21:05 +00:00
|
|
|
f.mark_implicit_arguments("u", {true, false});
|
2013-08-26 16:04:17 +00:00
|
|
|
lean_unreachable();
|
|
|
|
} catch (exception & ex) {
|
|
|
|
std::cout << "Expected error: " << ex.what() << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-10 01:00:05 +00:00
|
|
|
int main() {
|
|
|
|
tst1();
|
2013-08-12 01:06:37 +00:00
|
|
|
tst2();
|
2013-08-15 15:52:10 +00:00
|
|
|
tst3();
|
2013-08-17 03:51:11 +00:00
|
|
|
tst4();
|
2013-08-17 17:55:42 +00:00
|
|
|
tst5();
|
2013-08-17 18:04:22 +00:00
|
|
|
tst6();
|
2013-08-17 19:33:19 +00:00
|
|
|
tst7();
|
2013-08-17 19:38:32 +00:00
|
|
|
tst8();
|
2013-08-18 07:28:26 +00:00
|
|
|
tst9();
|
2013-08-18 21:29:32 +00:00
|
|
|
tst10();
|
2013-08-26 16:04:17 +00:00
|
|
|
tst11();
|
2013-08-10 01:00:05 +00:00
|
|
|
return has_violations() ? 1 : 0;
|
|
|
|
}
|