diff --git a/src/frontends/lean/pp.cpp b/src/frontends/lean/pp.cpp index 2434e99563..8d158a0535 100644 --- a/src/frontends/lean/pp.cpp +++ b/src/frontends/lean/pp.cpp @@ -10,6 +10,7 @@ Author: Leonardo de Moura #include "library/aliases.h" #include "library/scoped_ext.h" #include "library/coercion.h" +#include "library/expr_pair.h" #include "frontends/lean/pp.h" #include "frontends/lean/pp_options.h" #include "frontends/lean/token_table.h" @@ -25,6 +26,9 @@ static format g_pi_n_fmt = highlight_keyword(format("Π")); static format g_pi_fmt = highlight_keyword(format("Pi")); static format g_arrow_n_fmt = highlight_keyword(format("\u2192")); static format g_arrow_fmt = highlight_keyword(format("->")); +static format g_let_fmt = highlight_keyword(format("let")); +static format g_in_fmt = highlight_keyword(format("in")); +static format g_assign_fmt = highlight_keyword(format(":=")); name pretty_fn::mk_metavar_name(name const & m) { if (auto it = m_purify_meta_table.find(m)) @@ -272,14 +276,51 @@ auto pretty_fn::pp_pi(expr const & e) -> result { } } +auto pretty_fn::pp_let(expr e) -> result { + buffer decls; + while (true) { + if (!is_let_macro(e)) + break; + e = let_macro_arg(e); + if (!is_app(e) || !is_lambda(app_fn(e))) + break; + expr v = app_arg(e); + auto p = binding_body_fresh(app_fn(e), true); + decls.emplace_back(p.second, v); + e = p.first; + } + if (decls.empty()) + return pp(e); + format r = g_let_fmt; + unsigned sz = decls.size(); + for (unsigned i = 0; i < sz; i++) { + auto const & d = decls[i]; + format beg = i == 0 ? space() : line(); + format sep = i < sz - 1 ? comma() : format(); + name const & n = local_pp_name(d.first); + format t = pp_child(mlocal_type(d.first), 0).first; + format v = pp_child(d.second, 0).first; + r += nest(3 + 1, compose(beg, group(format{format(n), space(), + colon(), nest(n.size() + 1 + 1 + 1, compose(space(), t)), space(), g_assign_fmt, + nest(m_indent, format{line(), v, sep})}))); + } + format b = pp_child(e, 0).first; + r += format{line(), g_in_fmt, space(), nest(2 + 1, b)}; + return mk_result(r, 0); +} + auto pretty_fn::pp_macro(expr const & e) -> result { - // TODO(Leo): handle let, have macro annotations - // fix macro<->pp interface - format r = compose(format("["), format(macro_def(e).get_name())); - for (unsigned i = 0; i < macro_num_args(e); i++) - r += nest(m_indent, compose(line(), pp_child(macro_arg(e, i), max_bp()).first)); - r += format("]"); - return mk_result(group(r)); + if (is_let_macro(e)) { + return pp_let(e); + } else { + // TODO(Leo): have macro annotations + // fix macro<->pp interface + format r = compose(format("["), format(macro_def(e).get_name())); + for (unsigned i = 0; i < macro_num_args(e); i++) + r += nest(m_indent, compose(line(), pp_child(macro_arg(e, i), max_bp()).first)); + r += format("]"); + return mk_result(group(r)); + } } auto pretty_fn::pp(expr const & e) -> result { diff --git a/src/frontends/lean/pp.h b/src/frontends/lean/pp.h index bf86075ca0..47a9a71851 100644 --- a/src/frontends/lean/pp.h +++ b/src/frontends/lean/pp.h @@ -62,6 +62,7 @@ private: result pp_app(expr const & e); result pp_lambda(expr const & e); result pp_pi(expr const & e); + result pp_let(expr e); result pp_macro(expr const & e); public: diff --git a/src/util/sexpr/format.cpp b/src/util/sexpr/format.cpp index 6a7e1a5fcb..15573937f9 100644 --- a/src/util/sexpr/format.cpp +++ b/src/util/sexpr/format.cpp @@ -20,7 +20,7 @@ #include "util/sexpr/options.h" #ifndef LEAN_DEFAULT_PP_INDENTATION -#define LEAN_DEFAULT_PP_INDENTATION 4 +#define LEAN_DEFAULT_PP_INDENTATION 2 #endif #ifndef LEAN_DEFAULT_PP_UNICODE diff --git a/tests/lean/bug1.lean.expected.out b/tests/lean/bug1.lean.expected.out index 8372fa6c9b..4b3dd52b9b 100644 --- a/tests/lean/bug1.lean.expected.out +++ b/tests/lean/bug1.lean.expected.out @@ -1,19 +1,19 @@ bug1.lean:9:7: error: type mismatch at definition 'and_intro', expected type - ∀ (p q : bool), - p → q → a + ∀ (p q : bool), + p → q → a given type: - ∀ (p q : bool), - p → q → (∀ (c : bool), (p → q → c) → c) + ∀ (p q : bool), + p → q → (∀ (c : bool), (p → q → c) → c) bug1.lean:13:7: error: type mismatch at definition 'and_intro', expected type - ∀ (p q : bool), - p → q → and p p + ∀ (p q : bool), + p → q → and p p given type: - ∀ (p q : bool), - p → q → (∀ (c : bool), (p → q → c) → c) + ∀ (p q : bool), + p → q → (∀ (c : bool), (p → q → c) → c) bug1.lean:17:7: error: type mismatch at definition 'and_intro', expected type - ∀ (p q : bool), - p → q → and q p + ∀ (p q : bool), + p → q → and q p given type: - ∀ (p q : bool), - p → q → (∀ (c : bool), (p → q → c) → c) + ∀ (p q : bool), + p → q → (∀ (c : bool), (p → q → c) → c) and_intro : ∀ (p q : bool), p → q → and p q diff --git a/tests/lean/let1.lean.expected.out b/tests/lean/let1.lean.expected.out index 95ea7fb12b..92a3a57a59 100644 --- a/tests/lean/let1.lean.expected.out +++ b/tests/lean/let1.lean.expected.out @@ -1,40 +1,33 @@ -[let - ((λ (and_intro : ∀ (p q : Bool), p → q → (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q), - [let - ((λ - (and_elim_left : ∀ (p q : Bool), (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → p), - [let - ((λ - (and_elim_right : - ∀ (p q : Bool), - (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → q), - and_intro) - (λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q), - H q (λ (H1 : p) (H2 : q), H2)))]) - (λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q), - H p (λ (H1 : p) (H2 : q), H1)))]) - (λ (p q : Bool) (H1 : p) (H2 : q) (c : Bool) (H : p → q → c), H H1 H2))] : - ∀ (p q : Bool), - p → q → (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q +let and_intro : ∀ (p q : Bool), + p → q → (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q := + λ (p q : Bool) (H1 : p) (H2 : q) (c : Bool) (H : p → q → c), + H H1 H2, + and_elim_left : ∀ (p q : Bool), + (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → p := + λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q), + H p (λ (H1 : p) (H2 : q), H1), + and_elim_right : ∀ (p q : Bool), + (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → q := + λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q), + H q (λ (H1 : p) (H2 : q), H2) +in and_intro : + ∀ (p q : Bool), + p → q → (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q let1.lean:17:20: error: type mismatch at application - (λ (and_intro : ∀ (p q : Bool), p → q → (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) q p), - [let - ((λ - (and_elim_left : ∀ (p q : Bool), (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → p), - [let - ((λ - (and_elim_right : - ∀ (p q : Bool), - (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → q), - and_intro) - (λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q), - H q (λ (H1 : p) (H2 : q), H2)))]) - (λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q), - H p (λ (H1 : p) (H2 : q), H1)))]) - (λ (p q : Bool) (H1 : p) (H2 : q) (c : Bool) (H : p → q → c), H H1 H2) + (λ (and_intro : ∀ (p q : Bool), p → q → (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) q p), + let and_elim_left : ∀ (p q : Bool), + (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → p := + λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q), + H p (λ (H1 : p) (H2 : q), H1), + and_elim_right : ∀ (p q : Bool), + (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q → q := + λ (p q : Bool) (H : (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) p q), + H q (λ (H1 : p) (H2 : q), H2) + in and_intro) + (λ (p q : Bool) (H1 : p) (H2 : q) (c : Bool) (H : p → q → c), H H1 H2) expected type: - ∀ (p q : Bool), - p → q → (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) q p + ∀ (p q : Bool), + p → q → (λ (p q : Bool), ∀ (c : Bool), (p → q → c) → c) q p given type: - ∀ (p q : Bool), - p → q → (∀ (c : Bool), (p → q → c) → c) + ∀ (p q : Bool), + p → q → (∀ (c : Bool), (p → q → c) → c) diff --git a/tests/lean/run/t6.lean b/tests/lean/run/t6.lean index 41b6a8579e..706080e095 100644 --- a/tests/lean/run/t6.lean +++ b/tests/lean/run/t6.lean @@ -3,7 +3,7 @@ precedence `++` : 100 variable N : Type.{1} variable f : N → N → N variable a : N -print raw +check let g x y := f x y, infix + := g, b : N := a+a, diff --git a/tests/lean/t10.lean.expected.out b/tests/lean/t10.lean.expected.out index 1752ccacf7..1904d191cf 100644 --- a/tests/lean/t10.lean.expected.out +++ b/tests/lean/t10.lean.expected.out @@ -1,10 +1,10 @@ ite (and p q) (f x) y : N t10.lean:14:22: error: type mismatch at application - ite (and p q) q + ite (and p q) q expected type: - N + N given type: - B + B cons x (cons y (cons z (cons x (cons y (cons y nil))))) : list cons x nil : list nil : list diff --git a/tests/lean/t7.lean.expected.out b/tests/lean/t7.lean.expected.out index 8a0bf77d7f..ff853a0341 100644 --- a/tests/lean/t7.lean.expected.out +++ b/tests/lean/t7.lean.expected.out @@ -3,4 +3,4 @@ trans : (?M_1 → ?M_1 → Bool) → Bool symm : (?M_1 → ?M_1 → Bool) → Bool equivalence : (?M_1 → ?M_1 → Bool) → Bool λ (A : Type) (R : A → A → Bool), - and (and (refl R) (symm R)) (trans R) + and (and (refl R) (symm R)) (trans R)