refactor(kernel/formatter): move simple_formatter to library
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
fdd37fb1f3
commit
7d987df429
16 changed files with 332 additions and 272 deletions
|
@ -16,6 +16,7 @@ Author: Leonardo de Moura
|
||||||
#include "library/private.h"
|
#include "library/private.h"
|
||||||
#include "library/explicit.h"
|
#include "library/explicit.h"
|
||||||
#include "library/num.h"
|
#include "library/num.h"
|
||||||
|
#include "library/simple_formatter.h"
|
||||||
#include "frontends/lean/pp.h"
|
#include "frontends/lean/pp.h"
|
||||||
#include "frontends/lean/pp_options.h"
|
#include "frontends/lean/pp_options.h"
|
||||||
#include "frontends/lean/token_table.h"
|
#include "frontends/lean/token_table.h"
|
||||||
|
|
|
@ -6,263 +6,21 @@ Author: Leonardo de Moura
|
||||||
*/
|
*/
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "kernel/formatter.h"
|
#include "kernel/formatter.h"
|
||||||
#include "kernel/environment.h"
|
|
||||||
#include "kernel/find_fn.h"
|
|
||||||
#include "kernel/instantiate.h"
|
|
||||||
#include "kernel/free_vars.h"
|
|
||||||
#include "kernel/annotation.h"
|
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
bool is_used_name(expr const & t, name const & n) {
|
static std::unique_ptr<std::function<void(std::ostream &, expr const & e)>> g_print;
|
||||||
return static_cast<bool>(
|
|
||||||
find(t, [&](expr const & e, unsigned) {
|
|
||||||
return (is_constant(e) && const_name(e) == n) // t has a constant named n
|
|
||||||
|| (is_local(e) && (mlocal_name(e) == n || local_pp_name(e) == n)); // t has a local constant named n
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
name pick_unused_name(expr const & t, name const & s) {
|
void set_print_fn(std::function<void(std::ostream &, expr const &)> const & fn) {
|
||||||
name r = s;
|
g_print.reset(new std::function<void(std::ostream &, expr const &)>(fn));
|
||||||
unsigned i = 1;
|
|
||||||
while (is_used_name(t, r)) {
|
|
||||||
r = name(s).append_after(i);
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_internal_name(name n) {
|
|
||||||
while (!n.is_atomic())
|
|
||||||
n = n.get_prefix();
|
|
||||||
return n.is_numeral();
|
|
||||||
}
|
|
||||||
|
|
||||||
static name g_x("x");
|
|
||||||
pair<expr, expr> binding_body_fresh(expr const & b, bool preserve_type) {
|
|
||||||
lean_assert(is_binding(b));
|
|
||||||
name n = binding_name(b);
|
|
||||||
if (is_internal_name(n))
|
|
||||||
n = g_x;
|
|
||||||
n = pick_unused_name(binding_body(b), n);
|
|
||||||
expr c = mk_local(n, preserve_type ? binding_domain(b) : expr(), binding_info(b));
|
|
||||||
return mk_pair(instantiate(binding_body(b), c), c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static name g_internal("M");
|
|
||||||
name fix_internal_name(name const & a) {
|
|
||||||
if (a.is_atomic()) {
|
|
||||||
if (a.is_numeral())
|
|
||||||
return g_internal;
|
|
||||||
else
|
|
||||||
return a;
|
|
||||||
} else {
|
|
||||||
name p = fix_internal_name(a.get_prefix());
|
|
||||||
if (p == a.get_prefix())
|
|
||||||
return a;
|
|
||||||
else if (a.is_numeral())
|
|
||||||
return name(p, a.get_numeral());
|
|
||||||
else
|
|
||||||
return name(p, a.get_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Very basic printer for expressions.
|
|
||||||
It is mainly used when debugging code.
|
|
||||||
*/
|
|
||||||
struct print_expr_fn {
|
|
||||||
std::ostream & m_out;
|
|
||||||
bool m_type0_as_bool;
|
|
||||||
|
|
||||||
std::ostream & out() { return m_out; }
|
|
||||||
|
|
||||||
bool is_atomic(expr const & a) {
|
|
||||||
return ::lean::is_atomic(a) || is_mlocal(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_child(expr const & a) {
|
|
||||||
if (is_atomic(a)) {
|
|
||||||
print(a);
|
|
||||||
} else {
|
|
||||||
out() << "("; print(a); out() << ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool print_let(expr const & a) {
|
|
||||||
if (!is_let_annotation(a))
|
|
||||||
return false;
|
|
||||||
expr l = get_annotation_arg(a);
|
|
||||||
if (!is_app(l) || !is_lambda(app_fn(l)))
|
|
||||||
return false;
|
|
||||||
name n = binding_name(app_fn(l));
|
|
||||||
expr t = binding_domain(app_fn(l));
|
|
||||||
expr b = binding_body(app_fn(l));
|
|
||||||
expr v = app_arg(l);
|
|
||||||
n = pick_unused_name(b, n);
|
|
||||||
expr c = mk_local(n, expr());
|
|
||||||
b = instantiate(b, c);
|
|
||||||
out() << "let " << c;
|
|
||||||
out() << " : ";
|
|
||||||
print(t);
|
|
||||||
out() << " := ";
|
|
||||||
print(v);
|
|
||||||
out() << " in ";
|
|
||||||
print_child(b);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_macro(expr const & a) {
|
|
||||||
if (!print_let(a)) {
|
|
||||||
macro_def(a).display(out());
|
|
||||||
for (unsigned i = 0; i < macro_num_args(a); i++) {
|
|
||||||
out() << " "; print_child(macro_arg(a, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_sort(expr const & a) {
|
|
||||||
if (is_zero(sort_level(a))) {
|
|
||||||
if (m_type0_as_bool)
|
|
||||||
out() << "Prop";
|
|
||||||
else
|
|
||||||
out() << "Type";
|
|
||||||
} else if (m_type0_as_bool && is_one(sort_level(a))) {
|
|
||||||
out() << "Type";
|
|
||||||
} else {
|
|
||||||
out() << "Type.{" << sort_level(a) << "}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_app(expr const & e) {
|
|
||||||
expr const & f = app_fn(e);
|
|
||||||
if (is_app(f))
|
|
||||||
print(f);
|
|
||||||
else
|
|
||||||
print_child(f);
|
|
||||||
out() << " ";
|
|
||||||
print_child(app_arg(e));
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_arrow_body(expr const & a) {
|
|
||||||
if (is_atomic(a) || is_arrow(a))
|
|
||||||
return print(a);
|
|
||||||
else
|
|
||||||
return print_child(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_binding(char const * bname, expr e) {
|
|
||||||
expr_kind k = e.kind();
|
|
||||||
out() << bname;
|
|
||||||
while (e.kind() == k) {
|
|
||||||
out() << " ";
|
|
||||||
auto p = binding_body_fresh(e);
|
|
||||||
expr const & n = p.second;
|
|
||||||
if (binding_info(e).is_implicit())
|
|
||||||
out() << "{";
|
|
||||||
else if (binding_info(e).is_cast())
|
|
||||||
out() << "[";
|
|
||||||
else if (!binding_info(e).is_contextual())
|
|
||||||
out() << "[[";
|
|
||||||
else if (binding_info(e).is_strict_implicit())
|
|
||||||
out() << "{{";
|
|
||||||
else
|
|
||||||
out() << "(";
|
|
||||||
out() << n << " : ";
|
|
||||||
print(binding_domain(e));
|
|
||||||
if (binding_info(e).is_implicit())
|
|
||||||
out() << "}";
|
|
||||||
else if (binding_info(e).is_cast())
|
|
||||||
out() << "]";
|
|
||||||
else if (!binding_info(e).is_contextual())
|
|
||||||
out() << "]]";
|
|
||||||
else if (binding_info(e).is_strict_implicit())
|
|
||||||
out() << "}}";
|
|
||||||
else
|
|
||||||
out() << ")";
|
|
||||||
e = p.first;
|
|
||||||
}
|
|
||||||
out() << ", ";
|
|
||||||
print_child(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_const(expr const & a) {
|
|
||||||
list<level> const & ls = const_levels(a);
|
|
||||||
out() << const_name(a);
|
|
||||||
if (!is_nil(ls)) {
|
|
||||||
out() << ".{";
|
|
||||||
bool first = true;
|
|
||||||
for (auto l : ls) {
|
|
||||||
if (first) first = false; else out() << " ";
|
|
||||||
if (is_max(l) || is_imax(l))
|
|
||||||
out() << "(" << l << ")";
|
|
||||||
else
|
|
||||||
out() << l;
|
|
||||||
}
|
|
||||||
out() << "}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void print(expr const & a) {
|
|
||||||
switch (a.kind()) {
|
|
||||||
case expr_kind::Meta:
|
|
||||||
out() << "?" << fix_internal_name(mlocal_name(a));
|
|
||||||
break;
|
|
||||||
case expr_kind::Local:
|
|
||||||
out() << fix_internal_name(local_pp_name(a));
|
|
||||||
break;
|
|
||||||
case expr_kind::Var:
|
|
||||||
out() << "#" << var_idx(a);
|
|
||||||
break;
|
|
||||||
case expr_kind::Constant:
|
|
||||||
print_const(a);
|
|
||||||
break;
|
|
||||||
case expr_kind::App:
|
|
||||||
print_app(a);
|
|
||||||
break;
|
|
||||||
case expr_kind::Lambda:
|
|
||||||
print_binding("fun", a);
|
|
||||||
break;
|
|
||||||
case expr_kind::Pi:
|
|
||||||
if (!is_arrow(a)) {
|
|
||||||
print_binding("Pi", a);
|
|
||||||
} else {
|
|
||||||
print_child(binding_domain(a));
|
|
||||||
out() << " -> ";
|
|
||||||
print_arrow_body(lower_free_vars(binding_body(a), 1));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case expr_kind::Sort:
|
|
||||||
print_sort(a);
|
|
||||||
break;
|
|
||||||
case expr_kind::Macro:
|
|
||||||
print_macro(a);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
print_expr_fn(std::ostream & out, bool type0_as_bool = true):m_out(out), m_type0_as_bool(type0_as_bool) {}
|
|
||||||
|
|
||||||
void operator()(expr const & e) {
|
|
||||||
scoped_expr_caching set(false);
|
|
||||||
print(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream & out, expr const & e) {
|
std::ostream & operator<<(std::ostream & out, expr const & e) {
|
||||||
print_expr_fn pr(out);
|
if (g_print) {
|
||||||
pr(e);
|
(*g_print)(out, e);
|
||||||
return out;
|
} else {
|
||||||
|
throw exception("print function is not available, Lean was not initialized correctly");
|
||||||
}
|
}
|
||||||
|
return out;
|
||||||
formatter_factory mk_simple_formatter_factory() {
|
|
||||||
return [](environment const & env, options const & o) { // NOLINT
|
|
||||||
return formatter(o, [=](expr const & e, options const &) {
|
|
||||||
std::ostringstream s;
|
|
||||||
print_expr_fn pr(s, env.prop_proof_irrel());
|
|
||||||
pr(e);
|
|
||||||
return format(s.str());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(lean::expr const & a) { std::cout << a << std::endl; }
|
void print(lean::expr const & a) { std::cout << a << std::endl; }
|
||||||
|
|
|
@ -13,20 +13,6 @@ namespace lean {
|
||||||
class expr;
|
class expr;
|
||||||
class environment;
|
class environment;
|
||||||
|
|
||||||
/** \brief Return true iff \c t contains a constant named \c n or a local constant with named (pp or not) \c n */
|
|
||||||
bool is_used_name(expr const & t, name const & n);
|
|
||||||
/**
|
|
||||||
\brief Return the body of the binding \c b, where variable #0 is replaced by a local constant with a "fresh" name.
|
|
||||||
The name is considered fresh if it is not used by a constant or local constant occuring in the body of \c b.
|
|
||||||
The fresh constant is also returned (second return value).
|
|
||||||
|
|
||||||
\remark If preserve_type is false, then the local constant will not use binding_domain.
|
|
||||||
*/
|
|
||||||
pair<expr, expr> binding_body_fresh(expr const & b, bool preserve_type = false);
|
|
||||||
|
|
||||||
/** \brief Return the body of the let-expression \c l, where variable #0 is replaced by a local constant with a "fresh" name. */
|
|
||||||
pair<expr, expr> let_body_fresh(expr const & l, bool preserve_type = false);
|
|
||||||
|
|
||||||
class formatter {
|
class formatter {
|
||||||
std::function<format(expr const &, options const &)> m_fn;
|
std::function<format(expr const &, options const &)> m_fn;
|
||||||
options m_options;
|
options m_options;
|
||||||
|
@ -40,8 +26,8 @@ public:
|
||||||
typedef std::function<formatter(environment const &, options const &)> formatter_factory;
|
typedef std::function<formatter(environment const &, options const &)> formatter_factory;
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream & out, expr const & e);
|
std::ostream & operator<<(std::ostream & out, expr const & e);
|
||||||
/** \brief Create a simple formatter object based on operator */
|
|
||||||
formatter_factory mk_simple_formatter_factory();
|
|
||||||
|
|
||||||
typedef std::function<format(formatter const &)> pp_fn;
|
typedef std::function<format(formatter const &)> pp_fn;
|
||||||
|
|
||||||
|
void set_print_fn(std::function<void(std::ostream &, expr const &)> const & fn);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ add_library(library deep_copy.cpp expr_lt.cpp io_state.cpp occurs.cpp
|
||||||
standard_kernel.cpp hott_kernel.cpp sorry.cpp
|
standard_kernel.cpp hott_kernel.cpp sorry.cpp
|
||||||
unifier.cpp unifier_plugin.cpp inductive_unifier_plugin.cpp
|
unifier.cpp unifier_plugin.cpp inductive_unifier_plugin.cpp
|
||||||
explicit.cpp num.cpp string.cpp opaque_hints.cpp head_map.cpp
|
explicit.cpp num.cpp string.cpp opaque_hints.cpp head_map.cpp
|
||||||
match.cpp definition_cache.cpp declaration_index.cpp)
|
match.cpp definition_cache.cpp declaration_index.cpp
|
||||||
|
simple_formatter.cpp)
|
||||||
|
|
||||||
target_link_libraries(library ${LEAN_LIBS})
|
target_link_libraries(library ${LEAN_LIBS})
|
||||||
|
|
|
@ -5,6 +5,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
||||||
Author: Leonardo de Moura
|
Author: Leonardo de Moura
|
||||||
*/
|
*/
|
||||||
#include "kernel/kernel_exception.h"
|
#include "kernel/kernel_exception.h"
|
||||||
|
#include "library/simple_formatter.h"
|
||||||
#include "library/io_state.h"
|
#include "library/io_state.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
|
|
@ -31,6 +31,7 @@ Author: Leonardo de Moura
|
||||||
#include "library/normalize.h"
|
#include "library/normalize.h"
|
||||||
#include "library/module.h"
|
#include "library/module.h"
|
||||||
#include "library/opaque_hints.h"
|
#include "library/opaque_hints.h"
|
||||||
|
#include "library/simple_formatter.h"
|
||||||
|
|
||||||
// Lua Bindings for the Kernel classes. We do not include the Lua
|
// Lua Bindings for the Kernel classes. We do not include the Lua
|
||||||
// bindings in the kernel because we do not want to inflate the Kernel.
|
// bindings in the kernel because we do not want to inflate the Kernel.
|
||||||
|
|
269
src/library/simple_formatter.cpp
Normal file
269
src/library/simple_formatter.cpp
Normal file
|
@ -0,0 +1,269 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
||||||
|
Released under Apache 2.0 license as described in the file LICENSE.
|
||||||
|
|
||||||
|
Author: Leonardo de Moura
|
||||||
|
*/
|
||||||
|
#include <utility>
|
||||||
|
#include "kernel/formatter.h"
|
||||||
|
#include "kernel/environment.h"
|
||||||
|
#include "kernel/find_fn.h"
|
||||||
|
#include "kernel/instantiate.h"
|
||||||
|
#include "kernel/free_vars.h"
|
||||||
|
#include "kernel/annotation.h"
|
||||||
|
#include "library/simple_formatter.h"
|
||||||
|
|
||||||
|
namespace lean {
|
||||||
|
bool is_used_name(expr const & t, name const & n) {
|
||||||
|
return static_cast<bool>(
|
||||||
|
find(t, [&](expr const & e, unsigned) {
|
||||||
|
return (is_constant(e) && const_name(e) == n) // t has a constant named n
|
||||||
|
|| (is_local(e) && (mlocal_name(e) == n || local_pp_name(e) == n)); // t has a local constant named n
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
name pick_unused_name(expr const & t, name const & s) {
|
||||||
|
name r = s;
|
||||||
|
unsigned i = 1;
|
||||||
|
while (is_used_name(t, r)) {
|
||||||
|
r = name(s).append_after(i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_internal_name(name n) {
|
||||||
|
while (!n.is_atomic())
|
||||||
|
n = n.get_prefix();
|
||||||
|
return n.is_numeral();
|
||||||
|
}
|
||||||
|
|
||||||
|
static name g_x("x");
|
||||||
|
pair<expr, expr> binding_body_fresh(expr const & b, bool preserve_type) {
|
||||||
|
lean_assert(is_binding(b));
|
||||||
|
name n = binding_name(b);
|
||||||
|
if (is_internal_name(n))
|
||||||
|
n = g_x;
|
||||||
|
n = pick_unused_name(binding_body(b), n);
|
||||||
|
expr c = mk_local(n, preserve_type ? binding_domain(b) : expr(), binding_info(b));
|
||||||
|
return mk_pair(instantiate(binding_body(b), c), c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static name g_internal("M");
|
||||||
|
name fix_internal_name(name const & a) {
|
||||||
|
if (a.is_atomic()) {
|
||||||
|
if (a.is_numeral())
|
||||||
|
return g_internal;
|
||||||
|
else
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
name p = fix_internal_name(a.get_prefix());
|
||||||
|
if (p == a.get_prefix())
|
||||||
|
return a;
|
||||||
|
else if (a.is_numeral())
|
||||||
|
return name(p, a.get_numeral());
|
||||||
|
else
|
||||||
|
return name(p, a.get_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Very basic printer for expressions.
|
||||||
|
It is mainly used when debugging code.
|
||||||
|
*/
|
||||||
|
struct print_expr_fn {
|
||||||
|
std::ostream & m_out;
|
||||||
|
bool m_type0_as_bool;
|
||||||
|
|
||||||
|
std::ostream & out() { return m_out; }
|
||||||
|
|
||||||
|
bool is_atomic(expr const & a) {
|
||||||
|
return ::lean::is_atomic(a) || is_mlocal(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_child(expr const & a) {
|
||||||
|
if (is_atomic(a)) {
|
||||||
|
print(a);
|
||||||
|
} else {
|
||||||
|
out() << "("; print(a); out() << ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool print_let(expr const & a) {
|
||||||
|
if (!is_let_annotation(a))
|
||||||
|
return false;
|
||||||
|
expr l = get_annotation_arg(a);
|
||||||
|
if (!is_app(l) || !is_lambda(app_fn(l)))
|
||||||
|
return false;
|
||||||
|
name n = binding_name(app_fn(l));
|
||||||
|
expr t = binding_domain(app_fn(l));
|
||||||
|
expr b = binding_body(app_fn(l));
|
||||||
|
expr v = app_arg(l);
|
||||||
|
n = pick_unused_name(b, n);
|
||||||
|
expr c = mk_local(n, expr());
|
||||||
|
b = instantiate(b, c);
|
||||||
|
out() << "let " << c;
|
||||||
|
out() << " : ";
|
||||||
|
print(t);
|
||||||
|
out() << " := ";
|
||||||
|
print(v);
|
||||||
|
out() << " in ";
|
||||||
|
print_child(b);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_macro(expr const & a) {
|
||||||
|
if (!print_let(a)) {
|
||||||
|
macro_def(a).display(out());
|
||||||
|
for (unsigned i = 0; i < macro_num_args(a); i++) {
|
||||||
|
out() << " "; print_child(macro_arg(a, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_sort(expr const & a) {
|
||||||
|
if (is_zero(sort_level(a))) {
|
||||||
|
if (m_type0_as_bool)
|
||||||
|
out() << "Prop";
|
||||||
|
else
|
||||||
|
out() << "Type";
|
||||||
|
} else if (m_type0_as_bool && is_one(sort_level(a))) {
|
||||||
|
out() << "Type";
|
||||||
|
} else {
|
||||||
|
out() << "Type.{" << sort_level(a) << "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_app(expr const & e) {
|
||||||
|
expr const & f = app_fn(e);
|
||||||
|
if (is_app(f))
|
||||||
|
print(f);
|
||||||
|
else
|
||||||
|
print_child(f);
|
||||||
|
out() << " ";
|
||||||
|
print_child(app_arg(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_arrow_body(expr const & a) {
|
||||||
|
if (is_atomic(a) || is_arrow(a))
|
||||||
|
return print(a);
|
||||||
|
else
|
||||||
|
return print_child(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_binding(char const * bname, expr e) {
|
||||||
|
expr_kind k = e.kind();
|
||||||
|
out() << bname;
|
||||||
|
while (e.kind() == k) {
|
||||||
|
out() << " ";
|
||||||
|
auto p = binding_body_fresh(e);
|
||||||
|
expr const & n = p.second;
|
||||||
|
if (binding_info(e).is_implicit())
|
||||||
|
out() << "{";
|
||||||
|
else if (binding_info(e).is_cast())
|
||||||
|
out() << "[";
|
||||||
|
else if (!binding_info(e).is_contextual())
|
||||||
|
out() << "[[";
|
||||||
|
else if (binding_info(e).is_strict_implicit())
|
||||||
|
out() << "{{";
|
||||||
|
else
|
||||||
|
out() << "(";
|
||||||
|
out() << n << " : ";
|
||||||
|
print(binding_domain(e));
|
||||||
|
if (binding_info(e).is_implicit())
|
||||||
|
out() << "}";
|
||||||
|
else if (binding_info(e).is_cast())
|
||||||
|
out() << "]";
|
||||||
|
else if (!binding_info(e).is_contextual())
|
||||||
|
out() << "]]";
|
||||||
|
else if (binding_info(e).is_strict_implicit())
|
||||||
|
out() << "}}";
|
||||||
|
else
|
||||||
|
out() << ")";
|
||||||
|
e = p.first;
|
||||||
|
}
|
||||||
|
out() << ", ";
|
||||||
|
print_child(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_const(expr const & a) {
|
||||||
|
list<level> const & ls = const_levels(a);
|
||||||
|
out() << const_name(a);
|
||||||
|
if (!is_nil(ls)) {
|
||||||
|
out() << ".{";
|
||||||
|
bool first = true;
|
||||||
|
for (auto l : ls) {
|
||||||
|
if (first) first = false; else out() << " ";
|
||||||
|
if (is_max(l) || is_imax(l))
|
||||||
|
out() << "(" << l << ")";
|
||||||
|
else
|
||||||
|
out() << l;
|
||||||
|
}
|
||||||
|
out() << "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(expr const & a) {
|
||||||
|
switch (a.kind()) {
|
||||||
|
case expr_kind::Meta:
|
||||||
|
out() << "?" << fix_internal_name(mlocal_name(a));
|
||||||
|
break;
|
||||||
|
case expr_kind::Local:
|
||||||
|
out() << fix_internal_name(local_pp_name(a));
|
||||||
|
break;
|
||||||
|
case expr_kind::Var:
|
||||||
|
out() << "#" << var_idx(a);
|
||||||
|
break;
|
||||||
|
case expr_kind::Constant:
|
||||||
|
print_const(a);
|
||||||
|
break;
|
||||||
|
case expr_kind::App:
|
||||||
|
print_app(a);
|
||||||
|
break;
|
||||||
|
case expr_kind::Lambda:
|
||||||
|
print_binding("fun", a);
|
||||||
|
break;
|
||||||
|
case expr_kind::Pi:
|
||||||
|
if (!is_arrow(a)) {
|
||||||
|
print_binding("Pi", a);
|
||||||
|
} else {
|
||||||
|
print_child(binding_domain(a));
|
||||||
|
out() << " -> ";
|
||||||
|
print_arrow_body(lower_free_vars(binding_body(a), 1));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case expr_kind::Sort:
|
||||||
|
print_sort(a);
|
||||||
|
break;
|
||||||
|
case expr_kind::Macro:
|
||||||
|
print_macro(a);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print_expr_fn(std::ostream & out, bool type0_as_bool = true):m_out(out), m_type0_as_bool(type0_as_bool) {}
|
||||||
|
|
||||||
|
void operator()(expr const & e) {
|
||||||
|
scoped_expr_caching set(false);
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
formatter_factory mk_simple_formatter_factory() {
|
||||||
|
return [](environment const & env, options const & o) { // NOLINT
|
||||||
|
return formatter(o, [=](expr const & e, options const &) {
|
||||||
|
std::ostringstream s;
|
||||||
|
print_expr_fn pr(s, env.prop_proof_irrel());
|
||||||
|
pr(e);
|
||||||
|
return format(s.str());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_default_print_fn() {
|
||||||
|
set_print_fn([](std::ostream & out, expr const & e) {
|
||||||
|
print_expr_fn pr(out);
|
||||||
|
pr(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
30
src/library/simple_formatter.h
Normal file
30
src/library/simple_formatter.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
||||||
|
Released under Apache 2.0 license as described in the file LICENSE.
|
||||||
|
|
||||||
|
Author: Leonardo de Moura
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include "kernel/formatter.h"
|
||||||
|
|
||||||
|
namespace lean {
|
||||||
|
/** \brief Return true iff \c t contains a constant named \c n or a local constant with named (pp or not) \c n */
|
||||||
|
bool is_used_name(expr const & t, name const & n);
|
||||||
|
/**
|
||||||
|
\brief Return the body of the binding \c b, where variable #0 is replaced by a local constant with a "fresh" name.
|
||||||
|
The name is considered fresh if it is not used by a constant or local constant occuring in the body of \c b.
|
||||||
|
The fresh constant is also returned (second return value).
|
||||||
|
|
||||||
|
\remark If preserve_type is false, then the local constant will not use binding_domain.
|
||||||
|
*/
|
||||||
|
pair<expr, expr> binding_body_fresh(expr const & b, bool preserve_type = false);
|
||||||
|
|
||||||
|
/** \brief Return the body of the let-expression \c l, where variable #0 is replaced by a local constant with a "fresh" name. */
|
||||||
|
pair<expr, expr> let_body_fresh(expr const & l, bool preserve_type = false);
|
||||||
|
|
||||||
|
/** \brief Create a simple formatter object based on operator */
|
||||||
|
formatter_factory mk_simple_formatter_factory();
|
||||||
|
|
||||||
|
/** \brief Use simple formatter as the default print function */
|
||||||
|
void init_default_print_fn();
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ Author: Leonardo de Moura
|
||||||
#include "library/opaque_hints.h"
|
#include "library/opaque_hints.h"
|
||||||
#include "library/unifier_plugin.h"
|
#include "library/unifier_plugin.h"
|
||||||
#include "library/kernel_bindings.h"
|
#include "library/kernel_bindings.h"
|
||||||
|
#include "library/simple_formatter.h"
|
||||||
|
|
||||||
#ifndef LEAN_DEFAULT_UNIFIER_MAX_STEPS
|
#ifndef LEAN_DEFAULT_UNIFIER_MAX_STEPS
|
||||||
#define LEAN_DEFAULT_UNIFIER_MAX_STEPS 20000
|
#define LEAN_DEFAULT_UNIFIER_MAX_STEPS 20000
|
||||||
|
|
|
@ -26,6 +26,7 @@ Author: Leonardo de Moura
|
||||||
#include "library/io_state_stream.h"
|
#include "library/io_state_stream.h"
|
||||||
#include "library/definition_cache.h"
|
#include "library/definition_cache.h"
|
||||||
#include "library/declaration_index.h"
|
#include "library/declaration_index.h"
|
||||||
|
#include "library/simple_formatter.h"
|
||||||
#include "library/error_handling/error_handling.h"
|
#include "library/error_handling/error_handling.h"
|
||||||
#include "frontends/lean/parser.h"
|
#include "frontends/lean/parser.h"
|
||||||
#include "frontends/lean/pp.h"
|
#include "frontends/lean/pp.h"
|
||||||
|
@ -150,6 +151,7 @@ public:
|
||||||
|
|
||||||
int main(int argc, char ** argv) {
|
int main(int argc, char ** argv) {
|
||||||
lean::save_stack_info();
|
lean::save_stack_info();
|
||||||
|
lean::init_default_print_fn();
|
||||||
lean::register_modules();
|
lean::register_modules();
|
||||||
bool export_objects = false;
|
bool export_objects = false;
|
||||||
unsigned trust_lvl = 0;
|
unsigned trust_lvl = 0;
|
||||||
|
|
|
@ -11,13 +11,13 @@ add_executable(free_vars free_vars.cpp)
|
||||||
target_link_libraries(free_vars "kernel" "util" ${EXTRA_LIBS})
|
target_link_libraries(free_vars "kernel" "util" ${EXTRA_LIBS})
|
||||||
add_test(free_vars ${CMAKE_CURRENT_BINARY_DIR}/free_vars)
|
add_test(free_vars ${CMAKE_CURRENT_BINARY_DIR}/free_vars)
|
||||||
add_executable(replace replace.cpp)
|
add_executable(replace replace.cpp)
|
||||||
target_link_libraries(replace "kernel" "util" ${EXTRA_LIBS})
|
target_link_libraries(replace "library" "kernel" "util" ${EXTRA_LIBS})
|
||||||
add_test(replace ${CMAKE_CURRENT_BINARY_DIR}/replace)
|
add_test(replace ${CMAKE_CURRENT_BINARY_DIR}/replace)
|
||||||
add_executable(environment environment.cpp)
|
add_executable(environment environment.cpp)
|
||||||
target_link_libraries(environment "kernel" "util" ${EXTRA_LIBS})
|
target_link_libraries(environment "library" "kernel" "util" ${EXTRA_LIBS})
|
||||||
add_test(environment ${CMAKE_CURRENT_BINARY_DIR}/environment)
|
add_test(environment ${CMAKE_CURRENT_BINARY_DIR}/environment)
|
||||||
add_executable(metavar metavar.cpp)
|
add_executable(metavar metavar.cpp)
|
||||||
target_link_libraries(metavar "kernel" "util" ${EXTRA_LIBS})
|
target_link_libraries(metavar "library" "kernel" "util" ${EXTRA_LIBS})
|
||||||
add_test(metavar ${CMAKE_CURRENT_BINARY_DIR}/metavar)
|
add_test(metavar ${CMAKE_CURRENT_BINARY_DIR}/metavar)
|
||||||
add_executable(instantiate instantiate.cpp)
|
add_executable(instantiate instantiate.cpp)
|
||||||
target_link_libraries(instantiate "kernel" "util" ${EXTRA_LIBS})
|
target_link_libraries(instantiate "kernel" "util" ${EXTRA_LIBS})
|
||||||
|
|
|
@ -12,6 +12,7 @@ Author: Leonardo de Moura
|
||||||
#include "kernel/type_checker.h"
|
#include "kernel/type_checker.h"
|
||||||
#include "kernel/abstract.h"
|
#include "kernel/abstract.h"
|
||||||
#include "kernel/kernel_exception.h"
|
#include "kernel/kernel_exception.h"
|
||||||
|
#include "library/simple_formatter.cpp"
|
||||||
using namespace lean;
|
using namespace lean;
|
||||||
|
|
||||||
static environment add_decl(environment const & env, declaration const & d) {
|
static environment add_decl(environment const & env, declaration const & d) {
|
||||||
|
@ -243,6 +244,7 @@ public:
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
save_stack_info();
|
save_stack_info();
|
||||||
|
init_default_print_fn();
|
||||||
tst1();
|
tst1();
|
||||||
tst2();
|
tst2();
|
||||||
tst3();
|
tst3();
|
||||||
|
|
|
@ -16,6 +16,7 @@ Author: Leonardo de Moura
|
||||||
#include "kernel/abstract.h"
|
#include "kernel/abstract.h"
|
||||||
#include "kernel/instantiate.h"
|
#include "kernel/instantiate.h"
|
||||||
#include "library/max_sharing.h"
|
#include "library/max_sharing.h"
|
||||||
|
#include "library/simple_formatter.h"
|
||||||
#include "library/deep_copy.h"
|
#include "library/deep_copy.h"
|
||||||
#include "library/kernel_serializer.h"
|
#include "library/kernel_serializer.h"
|
||||||
using namespace lean;
|
using namespace lean;
|
||||||
|
@ -362,6 +363,7 @@ static void tst18() {
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
save_stack_info();
|
save_stack_info();
|
||||||
|
init_default_print_fn();
|
||||||
lean_assert(sizeof(expr) == sizeof(optional<expr>));
|
lean_assert(sizeof(expr) == sizeof(optional<expr>));
|
||||||
tst1();
|
tst1();
|
||||||
tst2();
|
tst2();
|
||||||
|
|
|
@ -6,8 +6,9 @@ Author: Leonardo de Moura
|
||||||
*/
|
*/
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "util/test.h"
|
#include "util/test.h"
|
||||||
#include "library/max_sharing.h"
|
|
||||||
#include "kernel/abstract.h"
|
#include "kernel/abstract.h"
|
||||||
|
#include "library/max_sharing.h"
|
||||||
|
#include "library/simple_formatter.h"
|
||||||
using namespace lean;
|
using namespace lean;
|
||||||
|
|
||||||
static void tst1() {
|
static void tst1() {
|
||||||
|
@ -59,6 +60,7 @@ static void tst3() {
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
save_stack_info();
|
save_stack_info();
|
||||||
|
init_default_print_fn();
|
||||||
scoped_expr_caching set(false);
|
scoped_expr_caching set(false);
|
||||||
tst1();
|
tst1();
|
||||||
tst2();
|
tst2();
|
||||||
|
|
|
@ -14,6 +14,7 @@ Author: Leonardo de Moura
|
||||||
#include "kernel/metavar.h"
|
#include "kernel/metavar.h"
|
||||||
#include "kernel/instantiate.h"
|
#include "kernel/instantiate.h"
|
||||||
#include "kernel/abstract.h"
|
#include "kernel/abstract.h"
|
||||||
|
#include "library/simple_formatter.h"
|
||||||
using namespace lean;
|
using namespace lean;
|
||||||
|
|
||||||
void collect_assumptions(justification const & j, buffer<unsigned> & r) {
|
void collect_assumptions(justification const & j, buffer<unsigned> & r) {
|
||||||
|
@ -145,6 +146,7 @@ static void tst4() {
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
save_stack_info();
|
save_stack_info();
|
||||||
|
init_default_print_fn();
|
||||||
tst1();
|
tst1();
|
||||||
tst2();
|
tst2();
|
||||||
tst3();
|
tst3();
|
||||||
|
|
|
@ -11,6 +11,7 @@ Author: Leonardo de Moura
|
||||||
#include "kernel/instantiate.h"
|
#include "kernel/instantiate.h"
|
||||||
#include "kernel/expr_maps.h"
|
#include "kernel/expr_maps.h"
|
||||||
#include "kernel/replace_fn.h"
|
#include "kernel/replace_fn.h"
|
||||||
|
#include "library/simple_formatter.h"
|
||||||
using namespace lean;
|
using namespace lean;
|
||||||
|
|
||||||
expr mk_big(expr f, unsigned depth, unsigned val) {
|
expr mk_big(expr f, unsigned depth, unsigned val) {
|
||||||
|
@ -58,6 +59,7 @@ public:
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
save_stack_info();
|
save_stack_info();
|
||||||
|
init_default_print_fn();
|
||||||
tst1();
|
tst1();
|
||||||
tst2();
|
tst2();
|
||||||
std::cout << "done" << "\n";
|
std::cout << "done" << "\n";
|
||||||
|
|
Loading…
Reference in a new issue