refactor(kernel): add formatter and simplify contexts
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
53ee205dc6
commit
d17990ed78
9 changed files with 203 additions and 195 deletions
|
@ -1,6 +1,6 @@
|
||||||
add_library(kernel level.cpp diff_cnstrs.cpp expr.cpp expr_eq_fn.cpp
|
add_library(kernel level.cpp diff_cnstrs.cpp expr.cpp expr_eq_fn.cpp
|
||||||
for_each_fn.cpp occurs.cpp replace_fn.cpp free_vars.cpp abstract.cpp
|
for_each_fn.cpp occurs.cpp replace_fn.cpp free_vars.cpp abstract.cpp
|
||||||
instantiate.cpp
|
instantiate.cpp context.cpp formatter.cpp
|
||||||
# normalizer.cpp context.cpp level.cpp object.cpp environment.cpp
|
# normalizer.cpp context.cpp level.cpp object.cpp environment.cpp
|
||||||
# type_checker.cpp kernel.cpp occurs.cpp metavar.cpp
|
# type_checker.cpp kernel.cpp occurs.cpp metavar.cpp
|
||||||
# justification.cpp unification_constraint.cpp kernel_exception.cpp
|
# justification.cpp unification_constraint.cpp kernel_exception.cpp
|
||||||
|
|
|
@ -7,84 +7,16 @@ Author: Leonardo de Moura
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "util/exception.h"
|
#include "util/exception.h"
|
||||||
#include "kernel/context.h"
|
#include "kernel/context.h"
|
||||||
#include "kernel/metavar.h"
|
|
||||||
#include "kernel/free_vars.h"
|
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
context::context(std::initializer_list<std::pair<char const *, expr const &>> const & l) {
|
std::pair<name, expr> const & lookup(context const & c, unsigned i) {
|
||||||
for (auto const & p : l)
|
auto const * it = &c;
|
||||||
m_list = cons(context_entry(name(p.first), p.second), m_list);
|
while (*it) {
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<context_entry const &, context> context::lookup_ext(unsigned i) const {
|
|
||||||
list<context_entry> const * it1 = &m_list;
|
|
||||||
while (*it1) {
|
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
return std::pair<context_entry const &, context>(head(*it1), context(tail(*it1)));
|
return head(*it);
|
||||||
--i;
|
--i;
|
||||||
it1 = &tail(*it1);
|
it = &tail(*it);
|
||||||
}
|
}
|
||||||
throw exception("unknown free variable");
|
throw exception("unknown free variable");
|
||||||
}
|
}
|
||||||
|
|
||||||
context_entry const & context::lookup(unsigned i) const {
|
|
||||||
list<context_entry> const * it1 = &m_list;
|
|
||||||
while (*it1) {
|
|
||||||
if (i == 0)
|
|
||||||
return head(*it1);
|
|
||||||
--i;
|
|
||||||
it1 = &tail(*it1);
|
|
||||||
}
|
|
||||||
throw exception("unknown free variable");
|
|
||||||
}
|
|
||||||
|
|
||||||
optional<context_entry> context::find(unsigned i) const {
|
|
||||||
list<context_entry> const * it1 = &m_list;
|
|
||||||
while (*it1) {
|
|
||||||
if (i == 0)
|
|
||||||
return some(head(*it1));
|
|
||||||
--i;
|
|
||||||
it1 = &tail(*it1);
|
|
||||||
}
|
|
||||||
return optional<context_entry>();
|
|
||||||
}
|
|
||||||
|
|
||||||
list<context_entry> truncate_core(list<context_entry> const & l, unsigned s) {
|
|
||||||
if (s == 0) {
|
|
||||||
return list<context_entry>();
|
|
||||||
} else {
|
|
||||||
return cons(head(l), truncate_core(tail(l), s-1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
context context::truncate(unsigned s) const {
|
|
||||||
return context(truncate_core(m_list, s));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct remove_no_applicable {};
|
|
||||||
static list<context_entry> remove_core(list<context_entry> const & l, unsigned s, unsigned n, metavar_env const & menv) {
|
|
||||||
if (l) {
|
|
||||||
if (s == 0) {
|
|
||||||
if (n > 0) {
|
|
||||||
return remove_core(tail(l), 0, n-1, menv);
|
|
||||||
} else {
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (has_free_var(head(l), s-1, s+n-1, menv))
|
|
||||||
throw remove_no_applicable();
|
|
||||||
return cons(lower_free_vars(head(l), s+n-1, n, menv), remove_core(tail(l), s-1, n, menv));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
optional<context> context::remove(unsigned s, unsigned n, metavar_env const & menv) const {
|
|
||||||
try {
|
|
||||||
return some(context(remove_core(m_list, s, n, menv)));
|
|
||||||
} catch (remove_no_applicable&) {
|
|
||||||
return optional<context>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,93 +11,8 @@ Author: Leonardo de Moura
|
||||||
#include "kernel/expr.h"
|
#include "kernel/expr.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
/**
|
typedef list<std::pair<name, expr>> context;
|
||||||
\brief An element of the Lean context.
|
inline context extend(context const & c, name const & n, expr const & t) { return cons(mk_pair(n, t), c); }
|
||||||
\see context
|
std::pair<name, expr> const & lookup(context const & c, unsigned i);
|
||||||
*/
|
optional<std::pair<name, expr>> find(context const & c, unsigned i);
|
||||||
class context_entry {
|
|
||||||
name m_name;
|
|
||||||
optional<expr> m_domain;
|
|
||||||
optional<expr> m_body;
|
|
||||||
public:
|
|
||||||
context_entry(name const & n, optional<expr> const & d, expr const & b):m_name(n), m_domain(d), m_body(b) {}
|
|
||||||
context_entry(name const & n, expr const & d, optional<expr> const & b):m_name(n), m_domain(d), m_body(b) {}
|
|
||||||
context_entry(name const & n, expr const & d, expr const & b):m_name(n), m_domain(d), m_body(b) {}
|
|
||||||
context_entry(name const & n, expr const & d):m_name(n), m_domain(d) {}
|
|
||||||
name const & get_name() const { return m_name; }
|
|
||||||
optional<expr> const & get_domain() const { return m_domain; }
|
|
||||||
optional<expr> const & get_body() const { return m_body; }
|
|
||||||
friend bool operator==(context_entry const & e1, context_entry const & e2) { return e1.m_domain == e2.m_domain && e1.m_body == e2.m_body; }
|
|
||||||
friend bool operator!=(context_entry const & e1, context_entry const & e2) { return !(e1 == e2); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class metavar_env;
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief A context is essentially a mapping from free-variables to types (and definition/body).
|
|
||||||
*/
|
|
||||||
class context {
|
|
||||||
list<context_entry> m_list;
|
|
||||||
explicit context(list<context_entry> const & l):m_list(l) {}
|
|
||||||
public:
|
|
||||||
context() {}
|
|
||||||
context(context const & c, name const & n, optional<expr> const & d, expr const & b):m_list(context_entry(n, d, b), c.m_list) {}
|
|
||||||
context(context const & c, name const & n, expr const & d, optional<expr> const & b):m_list(context_entry(n, d, b), c.m_list) {}
|
|
||||||
context(context const & c, name const & n, expr const & d, expr const & b):m_list(context_entry(n, d, b), c.m_list) {}
|
|
||||||
context(context const & c, name const & n, expr const & d):m_list(context_entry(n, d), c.m_list) {}
|
|
||||||
context(context const & c, context_entry const & e):m_list(e, c.m_list) {}
|
|
||||||
context(unsigned sz, context_entry const * es):context(to_list(es, es + sz)) {}
|
|
||||||
context(std::initializer_list<std::pair<char const *, expr const &>> const & l);
|
|
||||||
context_entry const & lookup(unsigned vidx) const;
|
|
||||||
std::pair<context_entry const &, context> lookup_ext(unsigned vidx) const;
|
|
||||||
/** \brief Similar to lookup, but always succeed */
|
|
||||||
optional<context_entry> find(unsigned vidx) const;
|
|
||||||
bool empty() const { return is_nil(m_list); }
|
|
||||||
explicit operator bool() const { return !empty(); }
|
|
||||||
unsigned size() const { return length(m_list); }
|
|
||||||
typedef list<context_entry>::iterator iterator;
|
|
||||||
iterator begin() const { return m_list.begin(); }
|
|
||||||
iterator end() const { return m_list.end(); }
|
|
||||||
friend bool is_eqp(context const & c1, context const & c2) { return is_eqp(c1.m_list, c2.m_list); }
|
|
||||||
/**
|
|
||||||
\brief Return a new context where entries at positions >= s are removed.
|
|
||||||
*/
|
|
||||||
context truncate(unsigned s) const;
|
|
||||||
/**
|
|
||||||
\brief Return a new context where the entries at positions [s, s+n) were removed.
|
|
||||||
|
|
||||||
The free variables in entries [0, s) are lowered.
|
|
||||||
That is, if this context is of the form
|
|
||||||
[ce_m, ..., ce_{s+n}, ce_{s+n-1}, ..., ce_s, ce_{s-1}, ..., ce_0]
|
|
||||||
Then, the resultant context is of the form
|
|
||||||
[ce_m, ..., ce_{s+n}, lower(ce_{s-1}, n, n), ..., lower(ce_0, s+n-1, n)]
|
|
||||||
|
|
||||||
\pre size() >= s + n
|
|
||||||
|
|
||||||
If for some i in [0, s), has_free_var(ce_i, s - 1 - i, s + n - 1 - i), then return none.
|
|
||||||
That is, the lower operations must be valid.
|
|
||||||
*/
|
|
||||||
optional<context> remove(unsigned s, unsigned n, metavar_env const & menv) const;
|
|
||||||
friend bool operator==(context const & ctx1, context const & ctx2) { return ctx1.m_list == ctx2.m_list; }
|
|
||||||
friend bool operator!=(context const & ctx1, context const & ctx2) { return !(ctx1 == ctx2); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Return the context entry for the free variable with de
|
|
||||||
Bruijn index \c i, and the context for this entry.
|
|
||||||
*/
|
|
||||||
inline std::pair<context_entry const &, context> lookup_ext(context const & c, unsigned i) { return c.lookup_ext(i); }
|
|
||||||
/**
|
|
||||||
\brief Return the context entry for the free variable with de
|
|
||||||
Bruijn index \c i.
|
|
||||||
*/
|
|
||||||
inline context_entry const & lookup(context const & c, unsigned i) { return c.lookup(i); }
|
|
||||||
inline optional<context_entry> find(context const & c, unsigned i) { return c.find(i); }
|
|
||||||
inline context extend(context const & c, name const & n, optional<expr> const & d, expr const & b) { return context(c, n, d, b); }
|
|
||||||
inline context extend(context const & c, name const & n, expr const & d, optional<expr> const & b) { return context(c, n, d, b); }
|
|
||||||
inline context extend(context const & c, name const & n, expr const & d, expr const & b) { return context(c, n, d, b); }
|
|
||||||
inline context extend(context const & c, name const & n, expr const & d) { return context(c, n, d); }
|
|
||||||
inline bool empty(context const & c) { return c.empty(); }
|
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream & out, context const & ctx);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,7 @@ Author: Leonardo de Moura
|
||||||
#include "util/object_serializer.h"
|
#include "util/object_serializer.h"
|
||||||
#include "kernel/expr.h"
|
#include "kernel/expr.h"
|
||||||
#include "kernel/expr_eq_fn.h"
|
#include "kernel/expr_eq_fn.h"
|
||||||
// #include "kernel/free_vars.h"
|
#include "kernel/free_vars.h"
|
||||||
// #include "kernel/metavar.h"
|
|
||||||
// #include "kernel/max_sharing.h"
|
// #include "kernel/max_sharing.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
@ -336,24 +335,36 @@ expr update_mlocal(expr const & e, expr const & new_type) {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
bool is_atomic(expr const & e) {
|
||||||
|
switch (e.kind()) {
|
||||||
|
case expr_kind::Constant: case expr_kind::Sort:
|
||||||
|
case expr_kind::Macro: case expr_kind::Var:
|
||||||
|
return true;
|
||||||
|
case expr_kind::App: case expr_kind::Let:
|
||||||
|
case expr_kind::Meta: case expr_kind::Local:
|
||||||
|
case expr_kind::Lambda: case expr_kind::Pi: case expr_kind::Sigma:
|
||||||
|
case expr_kind::Pair: case expr_kind::Fst: case expr_kind::Snd:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
lean_unreachable(); // LCOV_EXCL_LINE
|
||||||
|
}
|
||||||
|
|
||||||
bool is_arrow(expr const & t) {
|
bool is_arrow(expr const & t) {
|
||||||
optional<bool> r = t.raw()->is_arrow();
|
optional<bool> r = t.raw()->is_arrow();
|
||||||
if (r) {
|
if (r) {
|
||||||
return *r;
|
return *r;
|
||||||
} else {
|
} else {
|
||||||
bool res = is_pi(t) && !has_free_var(abst_body(t), 0);
|
bool res = is_pi(t) && !has_free_var(binder_body(t), 0);
|
||||||
t.raw()->set_is_arrow(res);
|
t.raw()->set_is_arrow(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_cartesian(expr const & t) {
|
bool is_cartesian(expr const & t) {
|
||||||
return is_sigma(t) && !has_free_var(abst_body(t), 0);
|
return is_sigma(t) && !has_free_var(binder_body(t), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
expr copy(expr const & a) {
|
expr copy(expr const & a) {
|
||||||
switch (a.kind()) {
|
switch (a.kind()) {
|
||||||
case expr_kind::Var: return mk_var(var_idx(a));
|
case expr_kind::Var: return mk_var(var_idx(a));
|
||||||
|
|
|
@ -359,6 +359,10 @@ inline bool is_let(expr const & e) { return e.kind() == expr_kind::Let; }
|
||||||
inline bool is_binder(expr const & e) { return is_lambda(e) || is_pi(e) || is_sigma(e); }
|
inline bool is_binder(expr const & e) { return is_lambda(e) || is_pi(e) || is_sigma(e); }
|
||||||
inline bool is_proj(expr const & e) { return is_fst(e) || is_snd(e); }
|
inline bool is_proj(expr const & e) { return is_fst(e) || is_snd(e); }
|
||||||
inline bool is_mlocal(expr const & e) { return is_metavar(e) || is_local(e); }
|
inline bool is_mlocal(expr const & e) { return is_metavar(e) || is_local(e); }
|
||||||
|
|
||||||
|
bool is_atomic(expr const & e);
|
||||||
|
bool is_arrow(expr const & t);
|
||||||
|
bool is_cartesian(expr const & t);
|
||||||
// =======================================
|
// =======================================
|
||||||
|
|
||||||
// =======================================
|
// =======================================
|
||||||
|
|
161
src/kernel/formatter.cpp
Normal file
161
src/kernel/formatter.cpp
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
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 "kernel/formatter.h"
|
||||||
|
#include "kernel/context.h"
|
||||||
|
|
||||||
|
namespace lean {
|
||||||
|
/**
|
||||||
|
\brief Very basic printer for expressions.
|
||||||
|
It is mainly used when debugging code.
|
||||||
|
*/
|
||||||
|
struct print_expr_fn {
|
||||||
|
std::ostream & m_out;
|
||||||
|
|
||||||
|
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, context const & c) {
|
||||||
|
if (is_atomic(a)) {
|
||||||
|
print(a, c);
|
||||||
|
} else {
|
||||||
|
out() << "("; print(a, c); out() << ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_macro(expr const & a) {
|
||||||
|
to_macro(a).display(out());
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_sort(expr const & a) {
|
||||||
|
if (is_zero(sort_level(a))) {
|
||||||
|
out () << "Bool";
|
||||||
|
} else {
|
||||||
|
out() << "(Type " << sort_level(a) << ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_app(expr const & e, context const & c) {
|
||||||
|
expr const & f = app_fn(e);
|
||||||
|
if (is_app(f))
|
||||||
|
print(f, c);
|
||||||
|
else
|
||||||
|
print_child(f, c);
|
||||||
|
out() << " ";
|
||||||
|
print_child(app_arg(e), c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_arrow_body(expr const & a, context const & c) {
|
||||||
|
if (is_atomic(a) || is_arrow(a))
|
||||||
|
return print(a, c);
|
||||||
|
else
|
||||||
|
return print_child(a, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_pair(expr const & e, context const & c) {
|
||||||
|
out() << "pair ";
|
||||||
|
print_child(pair_first(e), c);
|
||||||
|
out() << " ";
|
||||||
|
print_child(pair_second(e), c);
|
||||||
|
out() << " ";
|
||||||
|
print_child(pair_type(e), c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_binder(char const * bname, expr const & e, context const & c) {
|
||||||
|
out() << bname << " " << binder_name(e) << " : ";
|
||||||
|
print_child(binder_domain(e), c);
|
||||||
|
out() << ", ";
|
||||||
|
print_child(binder_body(e), extend(c, binder_name(e), binder_domain(e)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(expr const & a, context const & c) {
|
||||||
|
switch (a.kind()) {
|
||||||
|
case expr_kind::Meta: case expr_kind::Local:
|
||||||
|
out() << mlocal_name(a);
|
||||||
|
break;
|
||||||
|
case expr_kind::Var: {
|
||||||
|
auto e = find(c, var_idx(a));
|
||||||
|
if (e)
|
||||||
|
out() << e->first << "#" << var_idx(a);
|
||||||
|
else
|
||||||
|
out() << "#" << var_idx(a);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case expr_kind::Constant:
|
||||||
|
out() << const_name(a);
|
||||||
|
break;
|
||||||
|
case expr_kind::App:
|
||||||
|
print_app(a, c);
|
||||||
|
break;
|
||||||
|
case expr_kind::Pair:
|
||||||
|
print_pair(a, c);
|
||||||
|
break;
|
||||||
|
case expr_kind::Fst: case expr_kind::Snd:
|
||||||
|
out() << (is_fst(a) ? "fst" : "snd") << " ";
|
||||||
|
print_child(proj_arg(a), c);
|
||||||
|
break;
|
||||||
|
case expr_kind::Sigma:
|
||||||
|
print_binder("sig", a, c);
|
||||||
|
break;
|
||||||
|
case expr_kind::Lambda:
|
||||||
|
print_binder("fun", a, c);
|
||||||
|
break;
|
||||||
|
case expr_kind::Pi:
|
||||||
|
if (!is_arrow(a)) {
|
||||||
|
print_binder("Pi", a, c);
|
||||||
|
} else {
|
||||||
|
print_child(binder_domain(a), c);
|
||||||
|
out() << " -> ";
|
||||||
|
print_arrow_body(binder_body(a), extend(c, binder_name(a), binder_domain(a)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case expr_kind::Let:
|
||||||
|
out() << "let " << let_name(a);
|
||||||
|
if (let_type(a)) {
|
||||||
|
out() << " : ";
|
||||||
|
print(*let_type(a), c);
|
||||||
|
}
|
||||||
|
out() << " := ";
|
||||||
|
print(let_value(a), c);
|
||||||
|
out() << " in ";
|
||||||
|
print_child(let_body(a), extend(c, let_name(a), let_value(a)));
|
||||||
|
break;
|
||||||
|
case expr_kind::Sort:
|
||||||
|
print_sort(a);
|
||||||
|
break;
|
||||||
|
case expr_kind::Macro:
|
||||||
|
print_macro(a);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print_expr_fn(std::ostream & out):m_out(out) {}
|
||||||
|
|
||||||
|
void operator()(expr const & e, context const & c) {
|
||||||
|
print(e, c);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream & operator<<(std::ostream & out, expr const & e) {
|
||||||
|
print_expr_fn pr(out);
|
||||||
|
pr(e, context());
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
class simple_formatter_cell : public formatter_cell {
|
||||||
|
public:
|
||||||
|
virtual format operator()(expr const & e, options const &) {
|
||||||
|
std::ostringstream s; s << e; return format(s.str());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
formatter mk_simple_formatter() {
|
||||||
|
return mk_formatter(simple_formatter_cell());
|
||||||
|
}
|
||||||
|
void print(lean::expr const & a) { std::cout << a << std::endl; }
|
||||||
|
}
|
|
@ -7,8 +7,7 @@ Author: Leonardo de Moura
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "util/sexpr/options.h"
|
#include "util/sexpr/options.h"
|
||||||
#include "kernel/context.h"
|
#include "kernel/expr.h"
|
||||||
#include "kernel/environment.h"
|
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
/**
|
/**
|
||||||
|
@ -19,16 +18,7 @@ public:
|
||||||
virtual ~formatter_cell() {}
|
virtual ~formatter_cell() {}
|
||||||
/** \brief Format the given expression. */
|
/** \brief Format the given expression. */
|
||||||
virtual format operator()(expr const & e, options const & opts) = 0;
|
virtual format operator()(expr const & e, options const & opts) = 0;
|
||||||
/** \brief Format the given context. */
|
#if 0
|
||||||
virtual format operator()(context const & c, options const & opts) = 0;
|
|
||||||
/**
|
|
||||||
\brief Format the given expression with respect to the given
|
|
||||||
context.
|
|
||||||
|
|
||||||
\remark If format_ctx == false, then the context is not formatted. It just provides names
|
|
||||||
for the free variables
|
|
||||||
*/
|
|
||||||
virtual format operator()(context const & c, expr const & e, bool format_ctx, options const & opts) = 0;
|
|
||||||
/** \brief Format the given object */
|
/** \brief Format the given object */
|
||||||
virtual format operator()(object const & obj, options const & opts) = 0;
|
virtual format operator()(object const & obj, options const & opts) = 0;
|
||||||
/** \brief Format the given environment */
|
/** \brief Format the given environment */
|
||||||
|
@ -39,6 +29,7 @@ public:
|
||||||
Not every formatter has an associated environment object.
|
Not every formatter has an associated environment object.
|
||||||
*/
|
*/
|
||||||
virtual optional<ro_environment> get_environment() const { return optional<ro_environment>(); }
|
virtual optional<ro_environment> get_environment() const { return optional<ro_environment>(); }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
\brief Smart-pointer for the actual formatter object (aka \c formatter_cell).
|
\brief Smart-pointer for the actual formatter object (aka \c formatter_cell).
|
||||||
|
@ -48,16 +39,21 @@ class formatter {
|
||||||
formatter(formatter_cell * c):m_cell(c) {}
|
formatter(formatter_cell * c):m_cell(c) {}
|
||||||
public:
|
public:
|
||||||
format operator()(expr const & e, options const & opts = options()) const { return (*m_cell)(e, opts); }
|
format operator()(expr const & e, options const & opts = options()) const { return (*m_cell)(e, opts); }
|
||||||
format operator()(context const & c, options const & opts = options()) const { return (*m_cell)(c, opts); }
|
#if 0
|
||||||
format operator()(context const & c, expr const & e, bool format_ctx = false, options const & opts = options()) const { return (*m_cell)(c, e, format_ctx, opts); }
|
|
||||||
format operator()(object const & obj, options const & opts = options()) const { return (*m_cell)(obj, opts); }
|
format operator()(object const & obj, options const & opts = options()) const { return (*m_cell)(obj, opts); }
|
||||||
format operator()(ro_environment const & env, options const & opts = options()) const { return (*m_cell)(env, opts); }
|
format operator()(ro_environment const & env, options const & opts = options()) const { return (*m_cell)(env, opts); }
|
||||||
optional<ro_environment> get_environment() { return m_cell->get_environment(); }
|
optional<ro_environment> get_environment() { return m_cell->get_environment(); }
|
||||||
|
#endif
|
||||||
template<typename FCell> friend formatter mk_formatter(FCell && fcell);
|
template<typename FCell> friend formatter mk_formatter(FCell && fcell);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename FCell> formatter mk_formatter(FCell && fcell) {
|
template<typename FCell> formatter mk_formatter(FCell && fcell) {
|
||||||
return formatter(new FCell(std::forward<FCell>(fcell)));
|
return formatter(new FCell(std::forward<FCell>(fcell)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream & operator<<(std::ostream & out, expr const & e);
|
||||||
|
/**
|
||||||
|
\brief Create a simple formatter object based on operator<<
|
||||||
|
*/
|
||||||
|
formatter mk_simple_formatter();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,16 +7,6 @@ Author: Leonardo de Moura
|
||||||
#include "kernel/replace_fn.h"
|
#include "kernel/replace_fn.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
bool replace_fn::is_atomic(expr const & e) {
|
|
||||||
switch (e.kind()) {
|
|
||||||
case expr_kind::Constant: case expr_kind::Sort:
|
|
||||||
case expr_kind::Macro: case expr_kind::Var:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void replace_fn::save_result(expr const & e, expr const & r, unsigned offset, bool shared) {
|
void replace_fn::save_result(expr const & e, expr const & r, unsigned offset, bool shared) {
|
||||||
if (shared)
|
if (shared)
|
||||||
m_cache.insert(std::make_pair(expr_cell_offset(e.raw(), offset), r));
|
m_cache.insert(std::make_pair(expr_cell_offset(e.raw(), offset), r));
|
||||||
|
|
|
@ -52,7 +52,6 @@ class replace_fn {
|
||||||
frame_stack m_fs;
|
frame_stack m_fs;
|
||||||
result_stack m_rs;
|
result_stack m_rs;
|
||||||
|
|
||||||
static bool is_atomic(expr const & e);
|
|
||||||
void save_result(expr const & e, expr const & r, unsigned offset, bool shared);
|
void save_result(expr const & e, expr const & r, unsigned offset, bool shared);
|
||||||
bool visit(expr const & e, unsigned offset);
|
bool visit(expr const & e, unsigned offset);
|
||||||
bool check_index(frame & f, unsigned idx);
|
bool check_index(frame & f, unsigned idx);
|
||||||
|
|
Loading…
Reference in a new issue