Add parse_arrow

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-08-18 15:44:39 -07:00
parent 4d5b65fe87
commit 676ebcca3d
8 changed files with 49 additions and 35 deletions

5
examples/ex6.lean Normal file
View file

@ -0,0 +1,5 @@
Show Int -> Int -> Int
Variable f : Int -> Int -> Int
Eval f 0
Check f 0
Check f 0 1

View file

@ -6,7 +6,8 @@ Author: Leonardo de Moura
*/
#pragma once
namespace lean {
constexpr unsigned g_eq_precedence = 50;
constexpr unsigned g_eq_precedence = 50;
constexpr unsigned g_arrow_precedence = 70;
class frontend;
void init_builtin_notation(frontend & fe);
}

View file

@ -280,6 +280,12 @@ struct parser_fn {
return mk_eq(left, right);
}
expr parse_arrow(expr const & left) {
next();
expr right = parse_expr(g_arrow_precedence-1);
return mk_arrow(left, right);
}
expr parse_lparen() {
next();
expr r = parse_expr();
@ -429,6 +435,7 @@ struct parser_fn {
switch (curr()) {
case scanner::token::Id: return parse_led_id(left);
case scanner::token::Eq: return parse_eq(left);
case scanner::token::Arrow: return parse_arrow(left);
case scanner::token::LeftParen: return mk_app(left, parse_lparen());
case scanner::token::IntVal: return mk_app(left, parse_int());
case scanner::token::DecimalVal: return mk_app(left, parse_decimal());
@ -454,6 +461,7 @@ struct parser_fn {
}
}
case scanner::token::Eq : return g_eq_precedence;
case scanner::token::Arrow : return g_arrow_precedence;
case scanner::token::LeftParen: case scanner::token::IntVal: case scanner::token::DecimalVal:
case scanner::token::StringVal: case scanner::token::Type:
return 1;

View file

@ -268,8 +268,8 @@ inline expr mk_eq(expr const & l, expr const & r) { return expr(new expr_eq(l, r
inline expr Eq(expr const & l, expr const & r) { return mk_eq(l, r); }
inline expr mk_lambda(name const & n, expr const & t, expr const & e) { return expr(new expr_lambda(n, t, e)); }
inline expr mk_pi(name const & n, expr const & t, expr const & e) { return expr(new expr_pi(n, t, e)); }
inline expr arrow(expr const & t, expr const & e) { return mk_pi(name("_"), t, e); }
inline expr operator>>(expr const & t, expr const & e) { return arrow(t, e); }
inline expr mk_arrow(expr const & t, expr const & e) { return mk_pi(name("_"), t, e); }
inline expr operator>>(expr const & t, expr const & e) { return mk_arrow(t, e); }
inline expr mk_let(name const & n, expr const & v, expr const & e) { return expr(new expr_let(n, v, e)); }
inline expr mk_type(level const & l) { return expr(new expr_type(l)); }
expr mk_type();

View file

@ -34,7 +34,7 @@ static void tst2() {
lean_assert(is_int_value(normalize(e, env)));
expr e2 = Fun("a", Int, iAdd(Const("a"), iAdd(iVal(10), iVal(30))));
std::cout << e2 << " --> " << normalize(e2, env) << "\n";
lean_assert(infer_type(e2, env) == arrow(Int, Int));
lean_assert(infer_type(e2, env) == mk_arrow(Int, Int));
lean_assert(normalize(e2, env) == Fun("a", Int, iAdd(Const("a"), iVal(40))));
}
@ -46,7 +46,7 @@ static void tst3() {
lean_assert(normalize(e, env) == iVal(300));
std::cout << infer_type(mk_int_mul_fn(), env) << "\n";
lean_assert(infer_type(e, env) == Int);
lean_assert(infer_type(mk_app(mk_int_mul_fn(), iVal(10)), env) == arrow(Int, Int));
lean_assert(infer_type(mk_app(mk_int_mul_fn(), iVal(10)), env) == mk_arrow(Int, Int));
lean_assert(is_int_value(normalize(e, env)));
expr e2 = Fun("a", Int, iMul(Const("a"), iMul(iVal(10), iVal(30))));
std::cout << e2 << " --> " << normalize(e2, env) << "\n";
@ -62,7 +62,7 @@ static void tst4() {
lean_assert(normalize(e, env) == iVal(-20));
std::cout << infer_type(mk_int_sub_fn(), env) << "\n";
lean_assert(infer_type(e, env) == Int);
lean_assert(infer_type(mk_app(mk_int_sub_fn(), iVal(10)), env) == arrow(Int, Int));
lean_assert(infer_type(mk_app(mk_int_sub_fn(), iVal(10)), env) == mk_arrow(Int, Int));
lean_assert(is_int_value(normalize(e, env)));
expr e2 = Fun("a", Int, iSub(Const("a"), iSub(iVal(10), iVal(30))));
std::cout << e2 << " --> " << normalize(e2, env) << "\n";

View file

@ -78,7 +78,7 @@ static void tst3() {
std::cout << "b --> " << normalize(Const("b"), env) << "\n";
lean_assert(normalize(Const("b"), env) == iVal(6));
try {
env.add_definition("c", arrow(Int, Int), Const("a"));
env.add_definition("c", mk_arrow(Int, Int), Const("a"));
lean_unreachable();
} catch (exception const & ex) {
std::cout << "expected error: " << ex.what() << "\n";
@ -137,7 +137,7 @@ static void tst6() {
environment env;
level u = env.add_uvar("u", level() + 1);
level w = env.add_uvar("w", u + 1);
env.add_var("f", arrow(Type(u), Type(u)));
env.add_var("f", mk_arrow(Type(u), Type(u)));
expr t = Const("f")(Int);
std::cout << "type of " << t << " is " << infer_type(t, env) << "\n";
try {
@ -154,10 +154,10 @@ static void tst6() {
}
t = Const("f")(Type());
std::cout << "type of " << t << " is " << infer_type(t, env) << "\n";
std::cout << infer_type(arrow(Type(u), Type(w)), env) << "\n";
lean_assert(infer_type(arrow(Type(u), Type(w)), env) == Type(max(u+1, w+1)));
std::cout << infer_type(arrow(Int, Int), env) << "\n";
lean_assert(infer_type(arrow(Int, Int), env) == Type());
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());
}
static void tst7() {

View file

@ -24,18 +24,18 @@ static expr lam(expr const & t, expr const & e) { return mk_lambda("_", t, e); }
static expr v(unsigned i) { return Var(i); }
static expr zero() {
// fun (t : T) (s : t -> t) (z : t) z
return lam(t(), lam(arrow(v(0), v(0)), lam(v(1), v(0))));
return lam(t(), lam(mk_arrow(v(0), v(0)), lam(v(1), v(0))));
}
static expr one() {
// fun (t : T) (s : t -> t) s
return lam(t(), lam(arrow(v(0), v(0)), v(0)));
return lam(t(), lam(mk_arrow(v(0), v(0)), v(0)));
}
static expr num() { return Const("num"); }
static expr plus() {
// fun (m n : numeral) (A : Type 0) (f : A -> A) (x : A) => m A f (n A f x).
expr x = v(0), f = v(1), A = v(2), n = v(3), m = v(4);
expr body = m(A, f, n(A, f, x));
return lam(num(), lam(num(), lam(t(), lam(arrow(v(0), v(0)), lam(v(1), body)))));
return lam(num(), lam(num(), lam(t(), lam(mk_arrow(v(0), v(0)), lam(v(1), body)))));
}
static expr two() { return mk_app({plus(), one(), one()}); }
static expr three() { return mk_app({plus(), two(), one()}); }
@ -44,13 +44,13 @@ static expr times() {
// fun (m n : numeral) (A : Type 0) (f : A -> A) (x : A) => m A (n A f) x.
expr x = v(0), f = v(1), A = v(2), n = v(3), m = v(4);
expr body = m(A, n(A, f), x);
return lam(num(), lam(num(), lam(t(), lam(arrow(v(0), v(0)), lam(v(1), body)))));
return lam(num(), lam(num(), lam(t(), lam(mk_arrow(v(0), v(0)), lam(v(1), body)))));
}
static expr power() {
// fun (m n : numeral) (A : Type 0) => m (A -> A) (n A).
expr A = v(0), n = v(1), m = v(2);
expr body = n(arrow(A, A), m(A));
return lam(num(), lam(num(), lam(arrow(v(0), v(0)), body)));
expr body = n(mk_arrow(A, A), m(A));
return lam(num(), lam(num(), lam(mk_arrow(v(0), v(0)), body)));
}
unsigned count_core(expr const & a, expr_set & s) {
@ -114,7 +114,7 @@ static void tst1() {
environment env;
env.add_var("t", Type());
expr t = Type();
env.add_var("f", arrow(t, t));
env.add_var("f", mk_arrow(t, t));
expr f = Const("f");
env.add_var("a", t);
expr a = Const("a");
@ -140,13 +140,13 @@ static void tst1() {
static void tst2() {
environment env;
expr t = Type();
env.add_var("f", arrow(t, t));
env.add_var("f", mk_arrow(t, t));
expr f = Const("f");
env.add_var("a", t);
expr a = Const("a");
env.add_var("b", t);
expr b = Const("b");
env.add_var("h", arrow(t, t));
env.add_var("h", mk_arrow(t, t));
expr h = Const("h");
expr x = Var(0);
expr y = Var(1);

View file

@ -40,12 +40,12 @@ static void tst1() {
std::cout << infer_type(mk_lambda("Nat", Type(), mk_lambda("n", Var(0), Var(0))), env) << "\n";
expr nat = c("nat");
expr T = Fun("nat", Type(),
Fun("+", arrow(nat, arrow(nat, nat)),
Fun("+", mk_arrow(nat, mk_arrow(nat, nat)),
Fun("m", nat, mk_app({c("+"), c("m"), c("m")}))));
std::cout << T << "\n";
std::cout << infer_type(T, env) << "\n";
std::cout << Pi("nat", Type(), arrow(arrow(nat, arrow(nat, nat)), arrow(nat, nat))) << "\n";
lean_assert(infer_type(T, env) == Pi("nat", Type(), arrow(arrow(nat, arrow(nat, nat)), arrow(nat, nat))));
std::cout << Pi("nat", Type(), mk_arrow(mk_arrow(nat, mk_arrow(nat, nat)), mk_arrow(nat, nat))) << "\n";
lean_assert(infer_type(T, env) == Pi("nat", Type(), mk_arrow(mk_arrow(nat, mk_arrow(nat, nat)), mk_arrow(nat, nat))));
}
static void tst2() {
@ -56,9 +56,9 @@ static void tst2() {
expr t1 = Type(l1);
expr F =
Fun("Nat", t0,
Fun("Vec", arrow(c("Nat"), t0),
Fun("Vec", mk_arrow(c("Nat"), t0),
Fun("n", c("Nat"),
Fun("len", arrow(mk_app({c("Vec"), c("n")}), c("Nat")),
Fun("len", mk_arrow(mk_app({c("Vec"), c("n")}), c("Nat")),
Fun("v", mk_app({c("Vec"), c("n")}),
mk_app({c("len"), c("v")}))))));
std::cout << F << "\n";
@ -73,7 +73,7 @@ static void tst3() {
environment env;
expr f = Fun("a", Bool, Eq(Const("a"), True));
std::cout << infer_type(f, env) << "\n";
lean_assert(infer_type(f, env) == arrow(Bool, Bool));
lean_assert(infer_type(f, env) == mk_arrow(Bool, Bool));
expr t = mk_let("a", True, Var(0));
std::cout << infer_type(t, env) << "\n";
}
@ -107,7 +107,7 @@ static void tst6() {
expr A = Const("A");
expr f = Const("f");
expr x = Const("x");
expr t = Fun({A, Type()}, Fun({f, arrow(Int, A)}, Fun({x, Int}, f(x, x))));
expr t = Fun({A, Type()}, Fun({f, mk_arrow(Int, A)}, Fun({x, Int}, f(x, x))));
try {
infer_type(t, env);
lean_unreachable();
@ -121,7 +121,7 @@ static void tst7() {
expr A = Const(name{"foo", "bla", "bla", "foo"});
expr f = Const("f");
expr x = Const("x");
expr t = Fun({A, Type()}, Fun({f, arrow(Int, arrow(A, arrow(A, arrow(A, arrow(A, arrow(A, A))))))}, Fun({x, Int}, f(x, x))));
expr t = Fun({A, Type()}, Fun({f, mk_arrow(Int, mk_arrow(A, mk_arrow(A, mk_arrow(A, mk_arrow(A, mk_arrow(A, A))))))}, Fun({x, Int}, f(x, x))));
try {
infer_type(t, env);
lean_unreachable();
@ -132,12 +132,12 @@ static void tst7() {
static void tst8() {
environment env = mk_toplevel();
env.add_var("P", arrow(Int, arrow(Int, Bool)));
env.add_var("P", mk_arrow(Int, mk_arrow(Int, Bool)));
env.add_var("x", Int);
expr P = Const("P");
context c;
c = extend(c, "P", arrow(Bool, Bool));
c = extend(c, "P", arrow(Int, Int));
c = extend(c, "P", mk_arrow(Bool, Bool));
c = extend(c, "P", mk_arrow(Int, Int));
c = extend(c, "H", Var(1)(True));
c = extend(c, "x", Bool);
expr t = P(Const("x"), Var(0));
@ -151,11 +151,11 @@ static void tst8() {
static void tst9() {
environment env = mk_toplevel();
env.add_var("P", arrow(Int, arrow(Int, Bool)));
env.add_var("P", mk_arrow(Int, mk_arrow(Int, Bool)));
env.add_var("x", Int);
expr P = Const("P");
context c;
c = extend(c, "P", arrow(Bool, Bool));
c = extend(c, "P", mk_arrow(Bool, Bool));
c = extend(c, "P", Bool, Var(0)(True));
c = extend(c, "H", Var(1)(True));
c = extend(c, "x", Bool);
@ -170,7 +170,7 @@ static void tst9() {
static void tst10() {
environment env = mk_toplevel();
env.add_var("f", arrow(Int, Int));
env.add_var("f", mk_arrow(Int, Int));
env.add_var("b", Int);
expr f = Const("f");
expr a = Const("a");