parent
741fca1e7b
commit
701b0ae66f
9 changed files with 377 additions and 14 deletions
|
@ -70,6 +70,9 @@ public:
|
|||
bool operator==(level const & l1, level const & l2);
|
||||
inline bool operator!=(level const & l1, level const & l2) { return !operator==(l1, l2); }
|
||||
|
||||
struct level_hash { unsigned operator()(level const & n) const { return n.hash(); } };
|
||||
struct level_eq { bool operator()(level const & n1, level const & n2) const { return n1 == n2; } };
|
||||
|
||||
SPECIALIZE_OPTIONAL_FOR_SMART_PTR(level)
|
||||
|
||||
inline optional<level> none_level() { return optional<level>(); }
|
||||
|
|
|
@ -12,6 +12,7 @@ add_library(library deep_copy.cpp expr_lt.cpp io_state.cpp occurs.cpp
|
|||
metavar_closure.cpp reducible.cpp init_module.cpp
|
||||
generic_exception.cpp fingerprint.cpp flycheck.cpp hott_kernel.cpp
|
||||
local_context.cpp choice_iterator.cpp pp_options.cpp unfold_macros.cpp
|
||||
app_builder.cpp projection.cpp abbreviation.cpp equivalence_manager.cpp)
|
||||
app_builder.cpp projection.cpp abbreviation.cpp equivalence_manager.cpp
|
||||
export.cpp)
|
||||
|
||||
target_link_libraries(library ${LEAN_LIBS})
|
||||
|
|
287
src/library/export.cpp
Normal file
287
src/library/export.cpp
Normal file
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include <unordered_map>
|
||||
#include "kernel/expr_maps.h"
|
||||
#include "kernel/inductive/inductive.h"
|
||||
#include "library/max_sharing.h"
|
||||
#include "library/module.h"
|
||||
#include "library/unfold_macros.h"
|
||||
|
||||
namespace lean {
|
||||
template<typename T>
|
||||
using level_map = typename std::unordered_map<level, T, level_hash, level_eq>;
|
||||
|
||||
template<typename T>
|
||||
using name_hmap = typename std::unordered_map<name, T, name_hash, name_eq>;
|
||||
|
||||
|
||||
class exporter {
|
||||
std::ostream & m_out;
|
||||
environment m_env;
|
||||
max_sharing_fn m_max_sharing;
|
||||
name_hmap<unsigned> m_name2idx;
|
||||
level_map<unsigned> m_level2idx;
|
||||
expr_bi_struct_map<unsigned> m_expr2idx;
|
||||
|
||||
unsigned export_name(name const & n) {
|
||||
auto it = m_name2idx.find(n);
|
||||
if (it != m_name2idx.end())
|
||||
return it->second;
|
||||
unsigned i;
|
||||
if (n.is_anonymous()) {
|
||||
i = m_name2idx.size();
|
||||
m_out << i << " n\n";
|
||||
} else if (n.is_string()) {
|
||||
unsigned p = export_name(n.get_prefix());
|
||||
i = m_name2idx.size();
|
||||
m_out << i << " s " << p << " " << n.get_string() << "\n";
|
||||
} else {
|
||||
unsigned p = export_name(n.get_prefix());
|
||||
i = m_name2idx.size();
|
||||
m_out << i << " i " << p << " " << n.get_numeral() << "\n";
|
||||
}
|
||||
m_name2idx.insert(mk_pair(n, i));
|
||||
return i;
|
||||
}
|
||||
|
||||
unsigned export_level(level const & l) {
|
||||
auto it = m_level2idx.find(l);
|
||||
if (it != m_level2idx.end())
|
||||
return it->second;
|
||||
unsigned i = 0;
|
||||
unsigned l1, l2, n;
|
||||
switch (l.kind()) {
|
||||
case level_kind::Zero:
|
||||
i = m_level2idx.size();
|
||||
m_out << i << " UZ\n";
|
||||
break;
|
||||
case level_kind::Succ:
|
||||
l1 = export_level(succ_of(l));
|
||||
i = m_level2idx.size();
|
||||
m_out << i << " US " << l1 << "\n";
|
||||
break;
|
||||
case level_kind::Max:
|
||||
l1 = export_level(max_lhs(l));
|
||||
l2 = export_level(max_rhs(l));
|
||||
i = m_level2idx.size();
|
||||
m_out << i << " UM " << l1 << " " << l2 << "\n";
|
||||
break;
|
||||
case level_kind::IMax:
|
||||
l1 = export_level(imax_lhs(l));
|
||||
l2 = export_level(imax_rhs(l));
|
||||
i = m_level2idx.size();
|
||||
m_out << i << " UIM " << l1 << " " << l2 << "\n";
|
||||
break;
|
||||
case level_kind::Param:
|
||||
n = export_name(param_id(l));
|
||||
i = m_level2idx.size();
|
||||
m_out << i << " UP " << n << "\n";
|
||||
break;
|
||||
case level_kind::Global:
|
||||
n = export_name(global_id(l));
|
||||
i = m_level2idx.size();
|
||||
m_out << i << " UG " << n << "\n";
|
||||
break;
|
||||
case level_kind::Meta:
|
||||
throw exception("invald 'export', universe meta-variables cannot be exported");
|
||||
}
|
||||
m_level2idx.insert(mk_pair(l, i));
|
||||
return i;
|
||||
}
|
||||
|
||||
void display_binder_info(binder_info const & bi) {
|
||||
if (bi.is_implicit())
|
||||
m_out << "I";
|
||||
else if (bi.is_strict_implicit())
|
||||
m_out << "S";
|
||||
else if (bi.is_inst_implicit())
|
||||
m_out << "C";
|
||||
else
|
||||
m_out << "D";
|
||||
}
|
||||
|
||||
unsigned export_binding(expr const & e, char const * k) {
|
||||
unsigned n = export_name(binding_name(e));
|
||||
unsigned e1 = export_expr(binding_domain(e));
|
||||
unsigned e2 = export_expr(binding_body(e));
|
||||
unsigned i = m_expr2idx.size();
|
||||
m_out << i << " " << k << " ";
|
||||
display_binder_info(binding_info(e));
|
||||
m_out << " " << n << " " << e1 << " " << e2 << "\n";
|
||||
return i;
|
||||
}
|
||||
|
||||
unsigned export_const(expr const & e) {
|
||||
buffer<unsigned> ls;
|
||||
unsigned n = export_name(const_name(e));
|
||||
for (level const & l : const_levels(e))
|
||||
ls.push_back(export_level(l));
|
||||
unsigned i = m_expr2idx.size();
|
||||
m_out << i << " C " << n;
|
||||
for (unsigned l : ls)
|
||||
m_out << " " << l;
|
||||
m_out << "\n";
|
||||
return i;
|
||||
}
|
||||
|
||||
unsigned export_expr(expr const & e) {
|
||||
auto it = m_expr2idx.find(e);
|
||||
if (it != m_expr2idx.end())
|
||||
return it->second;
|
||||
unsigned i = 0;
|
||||
unsigned l, e1, e2;
|
||||
switch (e.kind()) {
|
||||
case expr_kind::Var:
|
||||
i = m_expr2idx.size();
|
||||
m_out << i << " V " << var_idx(e) << "\n";
|
||||
break;
|
||||
case expr_kind::Sort:
|
||||
l = export_level(sort_level(e));
|
||||
i = m_expr2idx.size();
|
||||
m_out << i << " S " << l << "\n";
|
||||
break;
|
||||
case expr_kind::Constant:
|
||||
i = export_const(e);
|
||||
break;
|
||||
case expr_kind::App:
|
||||
e1 = export_expr(app_fn(e));
|
||||
e2 = export_expr(app_arg(e));
|
||||
i = m_expr2idx.size();
|
||||
m_out << i << " A " << e1 << " " << e2 << "\n";
|
||||
break;
|
||||
case expr_kind::Lambda:
|
||||
i = export_binding(e, "L");
|
||||
break;
|
||||
case expr_kind::Pi:
|
||||
i = export_binding(e, "P");
|
||||
break;
|
||||
case expr_kind::Meta:
|
||||
throw exception("invald 'export', meta-variables cannot be exported");
|
||||
case expr_kind::Local:
|
||||
throw exception("invald 'export', local constants cannot be exported");
|
||||
case expr_kind::Macro:
|
||||
throw exception("invald 'export', macros cannot be exported");
|
||||
}
|
||||
m_expr2idx.insert(mk_pair(e, i));
|
||||
return i;
|
||||
}
|
||||
|
||||
unsigned export_root_expr(expr const & e) {
|
||||
return export_expr(m_max_sharing(unfold_all_macros(m_env, e)));
|
||||
}
|
||||
|
||||
void export_definition(declaration const & d) {
|
||||
unsigned n = export_name(d.get_name());
|
||||
buffer<unsigned> ps;
|
||||
for (name const & p : d.get_univ_params())
|
||||
ps.push_back(export_name(p));
|
||||
unsigned t = export_root_expr(d.get_type());
|
||||
unsigned v = export_root_expr(d.get_value());
|
||||
m_out << "DEF " << n;
|
||||
for (unsigned p : ps)
|
||||
m_out << " " << p;
|
||||
m_out << " | " << t << " " << v << "\n";
|
||||
}
|
||||
|
||||
void export_axiom(declaration const & d) {
|
||||
unsigned n = export_name(d.get_name());
|
||||
buffer<unsigned> ps;
|
||||
for (name const & p : d.get_univ_params())
|
||||
ps.push_back(export_name(p));
|
||||
unsigned t = export_root_expr(d.get_type());
|
||||
m_out << "AX " << n;
|
||||
for (unsigned p : ps)
|
||||
m_out << " " << p;
|
||||
m_out << " | " << t << "\n";
|
||||
}
|
||||
|
||||
void export_inductive(name const & n) {
|
||||
std::tuple<level_param_names, unsigned, list<inductive::inductive_decl>> decls =
|
||||
*inductive::is_inductive_decl(m_env, n);
|
||||
for (name const & p : std::get<0>(decls))
|
||||
export_name(p);
|
||||
for (inductive::inductive_decl const & d : std::get<2>(decls)) {
|
||||
export_name(inductive::inductive_decl_name(d));
|
||||
export_expr(inductive::inductive_decl_type(d));
|
||||
for (inductive::intro_rule const & c : inductive::inductive_decl_intros(d)) {
|
||||
export_name(inductive::intro_rule_name(c));
|
||||
export_expr(inductive::intro_rule_type(c));
|
||||
}
|
||||
}
|
||||
m_out << "BIND " << std::get<1>(decls) << " " << length(std::get<2>(decls));
|
||||
for (name const & p : std::get<0>(decls))
|
||||
m_out << " " << export_name(p);
|
||||
m_out << "\n";
|
||||
for (inductive::inductive_decl const & d : std::get<2>(decls)) {
|
||||
m_out << "IND " << export_name(inductive::inductive_decl_name(d)) << " "
|
||||
<< export_expr(inductive::inductive_decl_type(d)) << "\n";
|
||||
for (inductive::intro_rule const & c : inductive::inductive_decl_intros(d)) {
|
||||
m_out << "INTRO " << export_name(inductive::intro_rule_name(c)) << " "
|
||||
<< export_expr(inductive::intro_rule_type(c)) << "\n";
|
||||
}
|
||||
}
|
||||
m_out << "EIND\n";
|
||||
}
|
||||
|
||||
void export_declaration(name const & n) {
|
||||
if (inductive::is_inductive_decl(m_env, n)) {
|
||||
export_inductive(n);
|
||||
} else {
|
||||
declaration const & d = m_env.get(n);
|
||||
if (d.is_definition())
|
||||
export_definition(d);
|
||||
else
|
||||
export_axiom(d);
|
||||
}
|
||||
}
|
||||
|
||||
void export_declarations() {
|
||||
buffer<name> ns;
|
||||
to_buffer(get_curr_module_decl_names(m_env), ns);
|
||||
std::reverse(ns.begin(), ns.end());
|
||||
for (name const & n : ns)
|
||||
export_declaration(n);
|
||||
}
|
||||
|
||||
void export_direct_imports() {
|
||||
buffer<module_name> imports;
|
||||
to_buffer(get_curr_module_imports(m_env), imports);
|
||||
std::reverse(imports.begin(), imports.end());
|
||||
for (module_name const & m : imports) {
|
||||
unsigned n = export_name(m.get_name());
|
||||
if (m.is_relative()) {
|
||||
m_out << "RI " << *m.get_k() << " " << n << "\n";
|
||||
} else {
|
||||
m_out << "DI " << n << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void export_global_universes() {
|
||||
buffer<name> ns;
|
||||
to_buffer(get_curr_module_univ_names(m_env), ns);
|
||||
std::reverse(ns.begin(), ns.end());
|
||||
for (name const & u : ns) {
|
||||
unsigned n = export_name(u);
|
||||
m_out << "UNI " << n << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
exporter(std::ostream & out, environment const & env):m_out(out), m_env(env) {}
|
||||
|
||||
void operator()() {
|
||||
export_direct_imports();
|
||||
export_global_universes();
|
||||
export_declarations();
|
||||
}
|
||||
};
|
||||
|
||||
void export_module_as_lowtext(std::ostream & out, environment const & env) {
|
||||
exporter(out, env)();
|
||||
}
|
||||
}
|
11
src/library/export.h
Normal file
11
src/library/export.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
Copyright (c) 2015 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/environment.h"
|
||||
namespace lean {
|
||||
void export_module_as_lowtext(std::ostream & out, environment const & env);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
||||
Copyright (c) 2014-2015 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
|
||||
Author: Leonardo de Moura
|
||||
|
@ -42,6 +42,8 @@ typedef pair<std::string, std::function<void(serializer &)>> writer;
|
|||
struct module_ext : public environment_extension {
|
||||
list<module_name> m_direct_imports;
|
||||
list<writer> m_writers;
|
||||
list<name> m_module_univs;
|
||||
list<name> m_module_decls;
|
||||
name_set m_module_defs;
|
||||
// auxiliary information for detecting whether
|
||||
// directly imported files have changed
|
||||
|
@ -68,6 +70,18 @@ list<module_name> get_direct_imports(environment const & env) {
|
|||
return get_extension(env).m_direct_imports;
|
||||
}
|
||||
|
||||
list<name> const & get_curr_module_decl_names(environment const & env) {
|
||||
return get_extension(env).m_module_decls;
|
||||
}
|
||||
|
||||
list<name> const & get_curr_module_univ_names(environment const & env) {
|
||||
return get_extension(env).m_module_univs;
|
||||
}
|
||||
|
||||
list<module_name> const & get_curr_module_imports(environment const & env) {
|
||||
return get_extension(env).m_direct_imports;
|
||||
}
|
||||
|
||||
bool direct_imports_have_changed(environment const & env) {
|
||||
module_ext const & ext = get_extension(env);
|
||||
std::string const & base = ext.m_base;
|
||||
|
@ -176,16 +190,22 @@ environment add(environment const & env, std::string const & k, std::function<vo
|
|||
|
||||
environment add_universe(environment const & env, name const & l) {
|
||||
environment new_env = env.add_universe(l);
|
||||
module_ext ext = get_extension(env);
|
||||
ext.m_module_univs = cons(l, ext.m_module_univs);
|
||||
new_env = update(new_env, ext);
|
||||
return add(new_env, *g_glvl_key, [=](serializer & s) { s << l; });
|
||||
}
|
||||
|
||||
environment update_module_defs(environment const & env, declaration const & d) {
|
||||
if (d.is_definition() && !d.is_theorem()) {
|
||||
module_ext ext = get_extension(env);
|
||||
ext.m_module_decls = cons(d.get_name(), ext.m_module_decls);
|
||||
ext.m_module_defs.insert(d.get_name());
|
||||
return update(env, ext);
|
||||
} else {
|
||||
return env;
|
||||
module_ext ext = get_extension(env);
|
||||
ext.m_module_decls = cons(d.get_name(), ext.m_module_decls);
|
||||
return update(env, ext);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,6 +258,9 @@ environment add_inductive(environment env,
|
|||
unsigned num_params,
|
||||
list<inductive::inductive_decl> const & decls) {
|
||||
environment new_env = inductive::add_inductive(env, level_params, num_params, decls);
|
||||
module_ext ext = get_extension(env);
|
||||
ext.m_module_decls = cons(inductive::inductive_decl_name(head(decls)), ext.m_module_decls);
|
||||
new_env = update(new_env, ext);
|
||||
return add(new_env, *g_inductive, [=](serializer & s) {
|
||||
s << inductive_decls(level_params, num_params, decls);
|
||||
});
|
||||
|
|
|
@ -31,6 +31,13 @@ public:
|
|||
optional<unsigned> const & get_k() const { return m_relative; }
|
||||
};
|
||||
|
||||
/** \brief Return the list of declarations performed in the current module */
|
||||
list<name> const & get_curr_module_decl_names(environment const & env);
|
||||
/** \brief Return the list of universes declared in the current module */
|
||||
list<name> const & get_curr_module_univ_names(environment const & env);
|
||||
/** \brief Return the list of modules directly imported by the current module */
|
||||
list<module_name> const & get_curr_module_imports(environment const & env);
|
||||
|
||||
/** \brief Return an environment based on \c env, where all modules in \c modules are imported.
|
||||
Modules included directly or indirectly by them are also imported.
|
||||
The environment \c env is usually an empty environment.
|
||||
|
|
|
@ -104,8 +104,8 @@ class unfold_untrusted_macros_fn {
|
|||
}
|
||||
|
||||
public:
|
||||
unfold_untrusted_macros_fn(environment const & env):
|
||||
m_tc(env), m_trust_lvl(env.trust_lvl()) {}
|
||||
unfold_untrusted_macros_fn(environment const & env, unsigned lvl):
|
||||
m_tc(env), m_trust_lvl(lvl) {}
|
||||
|
||||
expr operator()(expr const & e) { return visit(e); }
|
||||
};
|
||||
|
@ -116,28 +116,36 @@ bool contains_untrusted_macro(unsigned trust_lvl, expr const & e) {
|
|||
}));
|
||||
}
|
||||
|
||||
expr unfold_untrusted_macros(environment const & env, expr const & e) {
|
||||
if (contains_untrusted_macro(env.trust_lvl(), e)) {
|
||||
return unfold_untrusted_macros_fn(env)(e);
|
||||
expr unfold_untrusted_macros(environment const & env, expr const & e, unsigned trust_lvl) {
|
||||
if (contains_untrusted_macro(trust_lvl, e)) {
|
||||
return unfold_untrusted_macros_fn(env, trust_lvl)(e);
|
||||
} else {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
expr unfold_untrusted_macros(environment const & env, expr const & e) {
|
||||
return unfold_untrusted_macros(env, e, env.trust_lvl());
|
||||
}
|
||||
|
||||
expr unfold_all_macros(environment const & env, expr const & e) {
|
||||
return unfold_untrusted_macros(env, e, 0);
|
||||
}
|
||||
|
||||
bool contains_untrusted_macro(unsigned trust_lvl, declaration const & d) {
|
||||
if (contains_untrusted_macro(trust_lvl, d.get_type()))
|
||||
return true;
|
||||
return (d.is_definition() || d.is_theorem()) && contains_untrusted_macro(trust_lvl, d.get_value());
|
||||
}
|
||||
|
||||
declaration unfold_untrusted_macros(environment const & env, declaration const & d) {
|
||||
if (contains_untrusted_macro(env.trust_lvl(), d)) {
|
||||
expr new_t = unfold_untrusted_macros(env, d.get_type());
|
||||
declaration unfold_untrusted_macros(environment const & env, declaration const & d, unsigned trust_lvl) {
|
||||
if (contains_untrusted_macro(trust_lvl, d)) {
|
||||
expr new_t = unfold_untrusted_macros(env, d.get_type(), trust_lvl);
|
||||
if (d.is_theorem()) {
|
||||
expr new_v = unfold_untrusted_macros(env, d.get_value());
|
||||
expr new_v = unfold_untrusted_macros(env, d.get_value(), trust_lvl);
|
||||
return mk_theorem(d.get_name(), d.get_univ_params(), new_t, new_v, d.get_module_idx());
|
||||
} else if (d.is_definition()) {
|
||||
expr new_v = unfold_untrusted_macros(env, d.get_value());
|
||||
expr new_v = unfold_untrusted_macros(env, d.get_value(), trust_lvl);
|
||||
return mk_definition(d.get_name(), d.get_univ_params(), new_t, new_v,
|
||||
d.is_opaque(), d.get_weight(), d.get_module_idx(), d.use_conv_opt());
|
||||
} else if (d.is_axiom()) {
|
||||
|
@ -151,4 +159,12 @@ declaration unfold_untrusted_macros(environment const & env, declaration const &
|
|||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
declaration unfold_untrusted_macros(environment const & env, declaration const & d) {
|
||||
return unfold_untrusted_macros(env, d, env.trust_lvl());
|
||||
}
|
||||
|
||||
declaration unfold_all_macros(environment const & env, declaration const & d) {
|
||||
return unfold_untrusted_macros(env, d, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,4 +18,8 @@ namespace lean {
|
|||
expr unfold_untrusted_macros(environment const & env, expr const & e);
|
||||
|
||||
declaration unfold_untrusted_macros(environment const & env, declaration const & d);
|
||||
|
||||
expr unfold_all_macros(environment const & env, expr const & e);
|
||||
|
||||
declaration unfold_all_macros(environment const & env, declaration const & d);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ Author: Leonardo de Moura
|
|||
#include "library/io_state_stream.h"
|
||||
#include "library/definition_cache.h"
|
||||
#include "library/declaration_index.h"
|
||||
#include "library/export.h"
|
||||
#include "library/error_handling/error_handling.h"
|
||||
#include "frontends/lean/parser.h"
|
||||
#include "frontends/lean/pp.h"
|
||||
|
@ -125,6 +126,7 @@ static void display_help(std::ostream & out) {
|
|||
std::cout << " --line=value line number for query\n";
|
||||
std::cout << " --col=value column number for query\n";
|
||||
std::cout << " --goal display goal at close to given position\n";
|
||||
std::cout << " --export=file -E export final environment as textual low-level file\n";
|
||||
}
|
||||
|
||||
static char const * get_file_extension(char const * fname) {
|
||||
|
@ -152,6 +154,7 @@ static struct option g_long_options[] = {
|
|||
{"luahook", required_argument, 0, 'k'},
|
||||
{"githash", no_argument, 0, 'g'},
|
||||
{"output", required_argument, 0, 'o'},
|
||||
{"export", required_argument, 0, 'E'},
|
||||
{"memory", required_argument, 0, 'M'},
|
||||
{"trust", required_argument, 0, 't'},
|
||||
{"discard", no_argument, 0, 'r'},
|
||||
|
@ -175,7 +178,7 @@ static struct option g_long_options[] = {
|
|||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
#define OPT_STR "PHRXFdD:qrlupgvhk:012t:012o:c:i:L:012O:012G"
|
||||
#define OPT_STR "PHRXFdD:qrlupgvhk:012t:012o:E:c:i:L:012O:012G"
|
||||
|
||||
#if defined(LEAN_TRACK_MEMORY)
|
||||
#define OPT_STR2 OPT_STR "M:012"
|
||||
|
@ -336,6 +339,7 @@ int main(int argc, char ** argv) {
|
|||
std::string index_name;
|
||||
optional<unsigned> line;
|
||||
optional<unsigned> column;
|
||||
optional<std::string> export_txt;
|
||||
bool show_goal = false;
|
||||
input_kind default_k = input_kind::Unspecified;
|
||||
while (true) {
|
||||
|
@ -435,6 +439,9 @@ int main(int argc, char ** argv) {
|
|||
case 'G':
|
||||
show_goal = true;
|
||||
break;
|
||||
case 'E':
|
||||
export_txt = std::string(optarg);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Unknown command line option\n";
|
||||
display_help(std::cerr);
|
||||
|
@ -574,6 +581,10 @@ int main(int argc, char ** argv) {
|
|||
std::ofstream out(output, std::ofstream::binary);
|
||||
export_module(out, env);
|
||||
}
|
||||
if (export_txt) {
|
||||
std::ofstream out(*export_txt);
|
||||
export_module_as_lowtext(out, env);
|
||||
}
|
||||
return ok ? 0 : 1;
|
||||
} catch (lean::throwable & ex) {
|
||||
lean::display_error(diagnostic(env, ios), nullptr, ex);
|
||||
|
|
Loading…
Reference in a new issue