feat(frontends/lean/pp): add support for abbreviations in the pretty printer

closes #365
This commit is contained in:
Leonardo de Moura 2015-02-10 18:27:02 -08:00
parent 13748b9347
commit 43f849bf95
4 changed files with 34 additions and 0 deletions

View file

@ -23,6 +23,7 @@ Author: Leonardo de Moura
#include "library/num.h" #include "library/num.h"
#include "library/let.h" #include "library/let.h"
#include "library/print.h" #include "library/print.h"
#include "library/abbreviation.h"
#include "library/pp_options.h" #include "library/pp_options.h"
#include "library/constants.h" #include "library/constants.h"
#include "frontends/lean/pp.h" #include "frontends/lean/pp.h"
@ -274,6 +275,7 @@ void pretty_fn::set_options_core(options const & o) {
m_purify_locals = get_pp_purify_locals(o); m_purify_locals = get_pp_purify_locals(o);
m_beta = get_pp_beta(o); m_beta = get_pp_beta(o);
m_numerals = get_pp_numerals(o); m_numerals = get_pp_numerals(o);
m_abbreviations = get_pp_abbreviations(o);
m_num_nat_coe = m_numerals && !m_coercion && has_coercion_num_nat(m_env); m_num_nat_coe = m_numerals && !m_coercion && has_coercion_num_nat(m_env);
} }
@ -470,6 +472,11 @@ bool pretty_fn::has_implicit_args(expr const & f) {
auto pretty_fn::pp_app(expr const & e) -> result { auto pretty_fn::pp_app(expr const & e) -> result {
expr const & fn = app_fn(e); expr const & fn = app_fn(e);
if (m_abbreviations) {
if (auto it = is_abbreviated(m_env, fn)) {
return pp_abbreviation(e, *it);
}
}
result res_fn = pp_child(fn, max_bp()-1); result res_fn = pp_child(fn, max_bp()-1);
format fn_fmt = res_fn.fmt(); format fn_fmt = res_fn.fmt();
if (m_implict && !is_app(fn) && has_implicit_args(fn)) if (m_implict && !is_app(fn) && has_implicit_args(fn))
@ -1030,6 +1037,17 @@ auto pretty_fn::pp_notation(expr const & e) -> optional<result> {
return optional<result>(); return optional<result>();
} }
auto pretty_fn::pp_abbreviation(expr const & e, name const & abbrev) -> result {
declaration const & d = m_env.get(abbrev);
unsigned num_univs = d.get_num_univ_params();
buffer<level> ls;
for (unsigned i = 0; i < num_univs; i++)
ls.push_back(mk_meta_univ(name("?l", i+1)));
buffer<expr> args;
get_app_args(e, args);
return pp(mk_app(mk_constant(abbrev, to_list(ls)), args));
}
auto pretty_fn::pp(expr const & e) -> result { auto pretty_fn::pp(expr const & e) -> result {
if (m_depth > m_max_depth || m_num_steps > m_max_steps) if (m_depth > m_max_depth || m_num_steps > m_max_steps)
return result(m_unicode ? *g_ellipsis_n_fmt : *g_ellipsis_fmt); return result(m_unicode ? *g_ellipsis_n_fmt : *g_ellipsis_fmt);
@ -1045,6 +1063,9 @@ auto pretty_fn::pp(expr const & e) -> result {
if (is_let(e)) return pp_let(e); if (is_let(e)) return pp_let(e);
if (is_typed_expr(e)) return pp(get_typed_expr_expr(e)); if (is_typed_expr(e)) return pp(get_typed_expr_expr(e));
if (is_let_value(e)) return pp(get_let_value_expr(e)); if (is_let_value(e)) return pp(get_let_value_expr(e));
if (m_abbreviations)
if (auto n = is_abbreviated(m_env, e))
return pp_abbreviation(e, *n);
if (m_numerals) if (m_numerals)
if (auto n = to_num(e)) return pp_num(*n); if (auto n = to_num(e)) return pp_num(*n);
if (m_num_nat_coe) if (m_num_nat_coe)

View file

@ -66,6 +66,7 @@ private:
bool m_purify_locals; bool m_purify_locals;
bool m_beta; bool m_beta;
bool m_numerals; bool m_numerals;
bool m_abbreviations;
name mk_metavar_name(name const & m); name mk_metavar_name(name const & m);
name mk_local_name(name const & n, name const & suggested); name mk_local_name(name const & n, name const & suggested);
@ -104,6 +105,7 @@ private:
result pp_explicit(expr const & e); result pp_explicit(expr const & e);
result pp_let(expr e); result pp_let(expr e);
result pp_num(mpz const & n); result pp_num(mpz const & n);
result pp_abbreviation(expr const & e, name const & abbrev);
void set_options_core(options const & o); void set_options_core(options const & o);
public: public:

View file

@ -59,6 +59,10 @@ Author: Leonardo de Moura
#define LEAN_DEFAULT_PP_NUMERALS true #define LEAN_DEFAULT_PP_NUMERALS true
#endif #endif
#ifndef LEAN_DEFAULT_PP_ABBREVIATIONS
#define LEAN_DEFAULT_PP_ABBREVIATIONS true
#endif
namespace lean { namespace lean {
static name * g_pp_max_depth = nullptr; static name * g_pp_max_depth = nullptr;
static name * g_pp_max_steps = nullptr; static name * g_pp_max_steps = nullptr;
@ -73,6 +77,7 @@ static name * g_pp_purify_metavars = nullptr;
static name * g_pp_purify_locals = nullptr; static name * g_pp_purify_locals = nullptr;
static name * g_pp_beta = nullptr; static name * g_pp_beta = nullptr;
static name * g_pp_numerals = nullptr; static name * g_pp_numerals = nullptr;
static name * g_pp_abbreviations = nullptr;
static list<options> * g_distinguishing_pp_options = nullptr; static list<options> * g_distinguishing_pp_options = nullptr;
void initialize_pp_options() { void initialize_pp_options() {
@ -89,6 +94,7 @@ void initialize_pp_options() {
g_pp_purify_locals = new name{"pp", "purify_locals"}; g_pp_purify_locals = new name{"pp", "purify_locals"};
g_pp_beta = new name{"pp", "beta"}; g_pp_beta = new name{"pp", "beta"};
g_pp_numerals = new name{"pp", "numerals"}; g_pp_numerals = new name{"pp", "numerals"};
g_pp_abbreviations = new name{"pp", "abbreviations"};
register_unsigned_option(*g_pp_max_depth, LEAN_DEFAULT_PP_MAX_DEPTH, register_unsigned_option(*g_pp_max_depth, LEAN_DEFAULT_PP_MAX_DEPTH,
"(pretty printer) maximum expression depth, after that it will use ellipsis"); "(pretty printer) maximum expression depth, after that it will use ellipsis");
register_unsigned_option(*g_pp_max_steps, LEAN_DEFAULT_PP_MAX_STEPS, register_unsigned_option(*g_pp_max_steps, LEAN_DEFAULT_PP_MAX_STEPS,
@ -117,6 +123,8 @@ void initialize_pp_options() {
"(pretty printer) apply beta-reduction when pretty printing"); "(pretty printer) apply beta-reduction when pretty printing");
register_bool_option(*g_pp_numerals, LEAN_DEFAULT_PP_NUMERALS, register_bool_option(*g_pp_numerals, LEAN_DEFAULT_PP_NUMERALS,
"(pretty printer) display nat/num numerals in decimal notation"); "(pretty printer) display nat/num numerals in decimal notation");
register_bool_option(*g_pp_abbreviations, LEAN_DEFAULT_PP_ABBREVIATIONS,
"(pretty printer) display abbreviations (i.e., revert abbreviation expansion when pretty printing)");
options universes_true(*g_pp_universes, true); options universes_true(*g_pp_universes, true);
options full_names_true(*g_pp_full_names, true); options full_names_true(*g_pp_full_names, true);
@ -131,6 +139,7 @@ void initialize_pp_options() {
} }
void finalize_pp_options() { void finalize_pp_options() {
delete g_pp_abbreviations;
delete g_pp_numerals; delete g_pp_numerals;
delete g_pp_max_depth; delete g_pp_max_depth;
delete g_pp_max_steps; delete g_pp_max_steps;
@ -169,5 +178,6 @@ bool get_pp_purify_metavars(options const & opts) { return opts.get_bool(*g_
bool get_pp_purify_locals(options const & opts) { return opts.get_bool(*g_pp_purify_locals, LEAN_DEFAULT_PP_PURIFY_LOCALS); } bool get_pp_purify_locals(options const & opts) { return opts.get_bool(*g_pp_purify_locals, LEAN_DEFAULT_PP_PURIFY_LOCALS); }
bool get_pp_beta(options const & opts) { return opts.get_bool(*g_pp_beta, LEAN_DEFAULT_PP_BETA); } bool get_pp_beta(options const & opts) { return opts.get_bool(*g_pp_beta, LEAN_DEFAULT_PP_BETA); }
bool get_pp_numerals(options const & opts) { return opts.get_bool(*g_pp_numerals, LEAN_DEFAULT_PP_NUMERALS); } bool get_pp_numerals(options const & opts) { return opts.get_bool(*g_pp_numerals, LEAN_DEFAULT_PP_NUMERALS); }
bool get_pp_abbreviations(options const & opts) { return opts.get_bool(*g_pp_abbreviations, LEAN_DEFAULT_PP_ABBREVIATIONS); }
list<options> const & get_distinguishing_pp_options() { return *g_distinguishing_pp_options; } list<options> const & get_distinguishing_pp_options() { return *g_distinguishing_pp_options; }
} }

View file

@ -29,6 +29,7 @@ bool get_pp_beta(options const & opts);
bool get_pp_purify_metavars(options const & opts); bool get_pp_purify_metavars(options const & opts);
bool get_pp_purify_locals(options const & opts); bool get_pp_purify_locals(options const & opts);
bool get_pp_numerals(options const & opts); bool get_pp_numerals(options const & opts);
bool get_pp_abbreviations(options const & opts);
list<options> const & get_distinguishing_pp_options(); list<options> const & get_distinguishing_pp_options();
void initialize_pp_options(); void initialize_pp_options();