Add parse_arrow
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
4d5b65fe87
commit
676ebcca3d
8 changed files with 49 additions and 35 deletions
5
examples/ex6.lean
Normal file
5
examples/ex6.lean
Normal file
|
@ -0,0 +1,5 @@
|
|||
Show Int -> Int -> Int
|
||||
Variable f : Int -> Int -> Int
|
||||
Eval f 0
|
||||
Check f 0
|
||||
Check f 0 1
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Add table
Reference in a new issue