refactor(*): add abstract_type_context class
This commit is contained in:
parent
5a4dd3f237
commit
7d61f640f6
60 changed files with 407 additions and 761 deletions
|
@ -5,6 +5,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#include "kernel/kernel_exception.h"
|
||||
#include "kernel/type_checker.h"
|
||||
#include "library/unifier.h"
|
||||
#include "library/print.h"
|
||||
#include "library/tactic/tactic.h"
|
||||
|
@ -52,7 +53,8 @@ char const * lean_exception_get_detailed_message(lean_exception e) {
|
|||
ios.set_regular_channel(out);
|
||||
ios.set_diagnostic_channel(out);
|
||||
environment env;
|
||||
io_state_stream ioss(env, ios);
|
||||
type_checker tc(env);
|
||||
io_state_stream ioss(env, ios, tc.get_type_context());
|
||||
display_error(ioss, nullptr, *lean::to_exception(e));
|
||||
return mk_string(static_cast<string_output_channel const *>(out.get())->str());
|
||||
} catch (...) {
|
||||
|
|
|
@ -96,7 +96,8 @@ lean_bool lean_expr_to_pp_string(lean_env env, lean_ios ios, lean_expr e, char c
|
|||
check_nonnull(ios);
|
||||
check_nonnull(e);
|
||||
options const & o = to_io_state_ref(ios).get_options();
|
||||
formatter fmt = to_io_state_ref(ios).get_formatter_factory()(to_env_ref(env), o);
|
||||
type_checker tc(to_env_ref(env));
|
||||
formatter fmt = to_io_state_ref(ios).get_formatter_factory()(to_env_ref(env), o, tc.get_type_context());
|
||||
std::ostringstream out;
|
||||
out << mk_pair(fmt(to_expr_ref(e)), o);
|
||||
*r = mk_string(out.str());
|
||||
|
@ -112,7 +113,8 @@ lean_bool lean_exception_to_pp_string(lean_env env, lean_ios ios, lean_exception
|
|||
std::shared_ptr<output_channel> aux(new string_output_channel());
|
||||
new_ios.set_regular_channel(aux);
|
||||
new_ios.set_diagnostic_channel(aux);
|
||||
io_state_stream ioss(to_env_ref(env), new_ios);
|
||||
type_checker tc(to_env_ref(env));
|
||||
io_state_stream ioss(to_env_ref(env), new_ios, tc.get_type_context());
|
||||
throwable * _e = to_exception(e);
|
||||
display_error(ioss, nullptr, *_e);
|
||||
*r = mk_string(static_cast<string_output_channel const *>(aux.get())->str());
|
||||
|
|
|
@ -27,7 +27,6 @@ Author: Leonardo de Moura
|
|||
#include "library/abstract_expr_manager.h"
|
||||
#include "library/defeq_simp_lemmas.h"
|
||||
#include "library/defeq_simplifier.h"
|
||||
#include "library/definitional/projection.h"
|
||||
#include "library/blast/blast.h"
|
||||
#include "library/blast/simplifier/simplifier.h"
|
||||
#include "compiler/preprocess_rec.h"
|
||||
|
@ -121,19 +120,19 @@ environment check_cmd(parser & p) {
|
|||
e = expand_abbreviations(p.env(), e);
|
||||
auto tc = mk_type_checker(p.env());
|
||||
expr type = tc->check(e, ls).first;
|
||||
auto reg = p.regular_stream();
|
||||
formatter fmt = reg.get_formatter();
|
||||
options opts = p.ios().get_options();
|
||||
opts = opts.update_if_undef(get_pp_metavar_args_name(), true);
|
||||
fmt = fmt.update_options(opts);
|
||||
io_state new_ios(p.ios(), opts);
|
||||
auto out = regular(p.env(), new_ios, tc->get_type_context());
|
||||
formatter fmt = out.get_formatter();
|
||||
unsigned indent = get_pp_indent(opts);
|
||||
format r = group(fmt(e) + space() + colon() + nest(indent, line() + fmt(type)));
|
||||
flycheck_information info(p.regular_stream());
|
||||
flycheck_information info(p.ios());
|
||||
if (info.enabled()) {
|
||||
p.display_information_pos(p.cmd_pos());
|
||||
p.regular_stream() << "check result:\n";
|
||||
out << "check result:\n";
|
||||
}
|
||||
reg << mk_pair(r, opts) << endl;
|
||||
out << mk_pair(r, opts) << endl;
|
||||
return p.env();
|
||||
}
|
||||
|
||||
|
@ -155,19 +154,21 @@ environment eval_cmd(parser & p) {
|
|||
bool eval_nested_prop = false;
|
||||
r = normalize(tc, ls, e, eta, eval_nested_prop);
|
||||
}
|
||||
flycheck_information info(p.regular_stream());
|
||||
flycheck_information info(p.ios());
|
||||
if (info.enabled()) {
|
||||
p.display_information_pos(p.cmd_pos());
|
||||
p.regular_stream() << "eval result:\n";
|
||||
p.ios().get_regular_stream() << "eval result:\n";
|
||||
}
|
||||
p.regular_stream() << r << endl;
|
||||
default_type_context tc(p.env(), p.get_options());
|
||||
auto out = regular(p.env(), p.ios(), tc);
|
||||
out << r << endl;
|
||||
return p.env();
|
||||
}
|
||||
|
||||
environment exit_cmd(parser & p) {
|
||||
flycheck_warning wrn(p.regular_stream());
|
||||
flycheck_warning wrn(p.ios());
|
||||
p.display_warning_pos(p.cmd_pos());
|
||||
p.regular_stream() << " using 'exit' to interrupt Lean" << endl;
|
||||
p.ios().get_regular_stream() << " using 'exit' to interrupt Lean" << std::endl;
|
||||
throw interrupt_parser();
|
||||
}
|
||||
|
||||
|
@ -428,40 +429,6 @@ static environment erase_cache_cmd(parser & p) {
|
|||
return p.env();
|
||||
}
|
||||
|
||||
static environment projections_cmd(parser & p) {
|
||||
name n = p.check_id_next("invalid #projections command, identifier expected");
|
||||
if (p.curr_is_token(get_dcolon_tk())) {
|
||||
p.next();
|
||||
buffer<name> proj_names;
|
||||
while (p.curr_is_identifier()) {
|
||||
proj_names.push_back(n + p.get_name_val());
|
||||
p.next();
|
||||
}
|
||||
return mk_projections(p.env(), n, proj_names);
|
||||
} else {
|
||||
return mk_projections(p.env(), n);
|
||||
}
|
||||
}
|
||||
|
||||
static environment telescope_eq_cmd(parser & p) {
|
||||
expr e; level_param_names ls;
|
||||
std::tie(e, ls) = parse_local_expr(p);
|
||||
buffer<expr> t;
|
||||
while (is_pi(e)) {
|
||||
expr local = mk_local(mk_fresh_name(), binding_name(e), binding_domain(e), binder_info());
|
||||
t.push_back(local);
|
||||
e = instantiate(binding_body(e), local);
|
||||
}
|
||||
auto tc = mk_type_checker(p.env());
|
||||
buffer<expr> eqs;
|
||||
mk_telescopic_eq(*tc, t, eqs);
|
||||
for (expr const & eq : eqs) {
|
||||
regular(p.env(), p.ios()) << local_pp_name(eq) << " : " << mlocal_type(eq) << "\n";
|
||||
tc->check(mlocal_type(eq), ls);
|
||||
}
|
||||
return p.env();
|
||||
}
|
||||
|
||||
static environment local_cmd(parser & p) {
|
||||
if (p.curr_is_token_or_id(get_attribute_tk())) {
|
||||
p.next();
|
||||
|
@ -475,18 +442,18 @@ static environment local_cmd(parser & p) {
|
|||
}
|
||||
|
||||
static environment help_cmd(parser & p) {
|
||||
flycheck_information info(p.regular_stream());
|
||||
flycheck_information info(p.ios());
|
||||
if (info.enabled()) {
|
||||
p.display_information_pos(p.cmd_pos());
|
||||
p.regular_stream() << "help result:\n";
|
||||
p.ios().get_regular_stream() << "help result:\n";
|
||||
}
|
||||
if (p.curr_is_token_or_id(get_options_tk())) {
|
||||
p.next();
|
||||
for (auto odecl : get_option_declarations()) {
|
||||
auto opt = odecl.second;
|
||||
regular(p.env(), p.ios())
|
||||
p.ios().get_regular_stream()
|
||||
<< " " << opt.get_name() << " (" << opt.kind() << ") "
|
||||
<< opt.get_description() << " (default: " << opt.get_default_value() << ")" << endl;
|
||||
<< opt.get_description() << " (default: " << opt.get_default_value() << ")" << std::endl;
|
||||
}
|
||||
} else if (p.curr_is_token_or_id(get_commands_tk())) {
|
||||
p.next();
|
||||
|
@ -497,11 +464,11 @@ static environment help_cmd(parser & p) {
|
|||
});
|
||||
std::sort(ns.begin(), ns.end());
|
||||
for (name const & n : ns) {
|
||||
regular(p.env(), p.ios())
|
||||
<< " " << n << ": " << cmds.find(n)->get_descr() << endl;
|
||||
p.ios().get_regular_stream()
|
||||
<< " " << n << ": " << cmds.find(n)->get_descr() << std::endl;
|
||||
};
|
||||
} else {
|
||||
p.regular_stream()
|
||||
p.ios().get_regular_stream()
|
||||
<< "help options : describe available options\n"
|
||||
<< "help commands : describe available commands\n";
|
||||
}
|
||||
|
@ -528,35 +495,11 @@ static environment compile_cmd(parser & p) {
|
|||
return p.env();
|
||||
}
|
||||
|
||||
static environment accessible_cmd(parser & p) {
|
||||
environment const & env = p.env();
|
||||
unsigned total = 0;
|
||||
unsigned accessible = 0;
|
||||
unsigned accessible_theorems = 0;
|
||||
env.for_each_declaration([&](declaration const & d) {
|
||||
name const & n = d.get_name();
|
||||
total++;
|
||||
if ((d.is_theorem() || d.is_definition()) &&
|
||||
!is_instance(env, n) && !is_simp_lemma(env, n) && !is_congr_lemma(env, n) &&
|
||||
!is_user_defined_recursor(env, n) && !is_aux_recursor(env, n) &&
|
||||
!is_projection(env, n) && !is_private(env, n) &&
|
||||
!is_user_defined_recursor(env, n) && !is_aux_recursor(env, n) &&
|
||||
!is_subst_relation(env, n) && !is_trans_relation(env, n) &&
|
||||
!is_symm_relation(env, n) && !is_refl_relation(env, n)) {
|
||||
accessible++;
|
||||
if (d.is_theorem())
|
||||
accessible_theorems++;
|
||||
}
|
||||
});
|
||||
p.regular_stream() << "total: " << total << ", accessible: " << accessible << ", accessible theorems: " << accessible_theorems << "\n";
|
||||
return env;
|
||||
}
|
||||
|
||||
static void check_expr_and_print(parser & p, expr const & e) {
|
||||
environment const & env = p.env();
|
||||
type_checker tc(env);
|
||||
expr t = tc.check_ignore_undefined_universes(e).first;
|
||||
p.regular_stream() << e << " : " << t << "\n";
|
||||
regular(env, p.ios(), tc.get_type_context()) << e << " : " << t << "\n";
|
||||
}
|
||||
|
||||
static environment app_builder_cmd(parser & p) {
|
||||
|
@ -607,130 +550,6 @@ static environment app_builder_cmd(parser & p) {
|
|||
return env;
|
||||
}
|
||||
|
||||
static environment refl_cmd(parser & p) {
|
||||
environment const & env = p.env();
|
||||
auto pos = p.pos();
|
||||
app_builder b(env);
|
||||
name relname = p.check_constant_next("invalid #refl command, constant expected");
|
||||
expr e; level_param_names ls;
|
||||
std::tie(e, ls) = parse_local_expr(p);
|
||||
try {
|
||||
expr r = b.mk_refl(relname, e);
|
||||
check_expr_and_print(p, r);
|
||||
} catch (app_builder_exception &) {
|
||||
throw parser_error(sstream() << "failed to build refl proof", pos);
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
static environment symm_cmd(parser & p) {
|
||||
environment const & env = p.env();
|
||||
auto pos = p.pos();
|
||||
app_builder b(env);
|
||||
name relname = p.check_constant_next("invalid #symm command, constant expected");
|
||||
expr e; level_param_names ls;
|
||||
std::tie(e, ls) = parse_local_expr(p);
|
||||
try {
|
||||
expr r = b.mk_symm(relname, e);
|
||||
check_expr_and_print(p, r);
|
||||
} catch (app_builder_exception &) {
|
||||
throw parser_error(sstream() << "failed to build symm proof", pos);
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
static environment trans_cmd(parser & p) {
|
||||
environment const & env = p.env();
|
||||
auto pos = p.pos();
|
||||
app_builder b(env);
|
||||
name relname = p.check_constant_next("invalid #trans command, constant expected");
|
||||
expr H1, H2; level_param_names ls;
|
||||
std::tie(H1, ls) = parse_local_expr(p);
|
||||
p.check_token_next(get_comma_tk(), "invalid #trans command, ',' expected");
|
||||
std::tie(H2, ls) = parse_local_expr(p);
|
||||
try {
|
||||
expr r = b.mk_trans(relname, H1, H2);
|
||||
check_expr_and_print(p, r);
|
||||
} catch (app_builder_exception &) {
|
||||
throw parser_error(sstream() << "failed to build trans proof", pos);
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
enum class congr_kind { Simp, Default, Rel };
|
||||
|
||||
static environment congr_cmd_core(parser & p, congr_kind kind) {
|
||||
environment const & env = p.env();
|
||||
auto pos = p.pos();
|
||||
expr e; level_param_names ls;
|
||||
std::tie(e, ls) = parse_local_expr(p);
|
||||
tmp_type_context ctx(env, p.get_options());
|
||||
app_builder b(ctx);
|
||||
fun_info_manager infom(ctx);
|
||||
congr_lemma_manager cm(b, infom);
|
||||
optional<congr_lemma> r;
|
||||
switch (kind) {
|
||||
case congr_kind::Simp: r = cm.mk_congr_simp(e); break;
|
||||
case congr_kind::Default: r = cm.mk_congr(e); break;
|
||||
case congr_kind::Rel: r = cm.mk_rel_iff_congr(e); break;
|
||||
}
|
||||
if (!r)
|
||||
throw parser_error("failed to generated congruence lemma", pos);
|
||||
auto out = p.regular_stream();
|
||||
out << "[";
|
||||
bool first = true;
|
||||
for (auto k : r->get_arg_kinds()) {
|
||||
if (!first) out << ", "; else first = false;
|
||||
switch (k) {
|
||||
case congr_arg_kind::Fixed: out << "fixed"; break;
|
||||
case congr_arg_kind::FixedNoParam: out << "fixed-noparm"; break;
|
||||
case congr_arg_kind::Eq: out << "eq"; break;
|
||||
case congr_arg_kind::HEq: out << "heq"; break;
|
||||
case congr_arg_kind::Cast: out << "cast"; break;
|
||||
}
|
||||
}
|
||||
out << "]\n";
|
||||
out << r->get_proof() << "\n:\n" << r->get_type() << "\n";;
|
||||
type_checker tc(env);
|
||||
expr type = tc.check(r->get_proof(), ls).first;
|
||||
if (!tc.is_def_eq(type, r->get_type()).first)
|
||||
throw parser_error("congruence lemma reported type does not match given type", pos);
|
||||
return env;
|
||||
}
|
||||
|
||||
static environment congr_simp_cmd(parser & p) {
|
||||
return congr_cmd_core(p, congr_kind::Simp);
|
||||
}
|
||||
|
||||
static environment congr_cmd(parser & p) {
|
||||
return congr_cmd_core(p, congr_kind::Default);
|
||||
}
|
||||
|
||||
static environment congr_rel_cmd(parser & p) {
|
||||
return congr_cmd_core(p, congr_kind::Rel);
|
||||
}
|
||||
|
||||
static environment hcongr_cmd(parser & p) {
|
||||
environment const & env = p.env();
|
||||
auto pos = p.pos();
|
||||
expr e; level_param_names ls;
|
||||
std::tie(e, ls) = parse_local_expr(p);
|
||||
tmp_type_context ctx(env, p.get_options());
|
||||
app_builder b(ctx);
|
||||
fun_info_manager infom(ctx);
|
||||
congr_lemma_manager cm(b, infom);
|
||||
optional<congr_lemma> r = cm.mk_hcongr(e);
|
||||
if (!r)
|
||||
throw parser_error("failed to generated heterogeneous congruence lemma", pos);
|
||||
auto out = p.regular_stream();
|
||||
out << r->get_proof() << "\n:\n" << r->get_type() << "\n";;
|
||||
type_checker tc(env);
|
||||
expr type = tc.check(r->get_proof(), ls).first;
|
||||
if (!tc.is_def_eq(type, r->get_type()).first)
|
||||
throw parser_error("heterogeneous congruence lemma reported type does not match given type", pos);
|
||||
return env;
|
||||
}
|
||||
|
||||
static environment simplify_cmd(parser & p) {
|
||||
name rel = p.check_constant_next("invalid #simplify command, constant expected");
|
||||
name ns = p.check_id_next("invalid #simplify command, id expected");
|
||||
|
@ -749,23 +568,25 @@ static environment simplify_cmd(parser & p) {
|
|||
}
|
||||
|
||||
blast::simp::result r = blast::simplify(rel, e, srss);
|
||||
type_checker tc(p.env());
|
||||
auto out = regular(p.env(), p.ios(), tc.get_type_context());
|
||||
|
||||
flycheck_information info(p.regular_stream());
|
||||
flycheck_information info(p.ios());
|
||||
if (info.enabled()) {
|
||||
p.display_information_pos(p.cmd_pos());
|
||||
p.regular_stream() << "simplify result:\n";
|
||||
out << "simplify result:\n";
|
||||
}
|
||||
|
||||
if (!r.has_proof()) {
|
||||
p.regular_stream() << "(refl): " << r.get_new() << endl;
|
||||
out << "(refl): " << r.get_new() << endl;
|
||||
} else {
|
||||
auto tc = mk_type_checker(p.env());
|
||||
|
||||
expr pf_type = tc->check(r.get_proof(), ls).first;
|
||||
|
||||
if (o == 0) p.regular_stream() << r.get_new() << endl;
|
||||
else if (o == 1) p.regular_stream() << r.get_proof() << endl;
|
||||
else p.regular_stream() << pf_type << endl;
|
||||
if (o == 0) out << r.get_new() << endl;
|
||||
else if (o == 1) out << r.get_proof() << endl;
|
||||
else out << pf_type << endl;
|
||||
}
|
||||
|
||||
return p.env();
|
||||
|
@ -777,7 +598,8 @@ static environment normalizer_cmd(parser & p) {
|
|||
std::tie(e, ls) = parse_local_expr(p);
|
||||
blast::scope_debug scope(p.env(), p.ios());
|
||||
expr r = blast::normalize(e);
|
||||
p.regular_stream() << r << endl;
|
||||
type_checker tc(env);
|
||||
regular(env, p.ios(), tc.get_type_context()) << r << endl;
|
||||
return env;
|
||||
}
|
||||
|
||||
|
@ -790,11 +612,11 @@ static environment unify_cmd(parser & p) {
|
|||
std::tie(e2, ls2) = parse_local_expr(p);
|
||||
default_type_context ctx(env, p.get_options());
|
||||
bool success = ctx.is_def_eq(e1, e2);
|
||||
flycheck_information info(p.regular_stream());
|
||||
flycheck_information info(p.ios());
|
||||
if (info.enabled()) {
|
||||
p.display_information_pos(p.cmd_pos());
|
||||
}
|
||||
p.regular_stream() << (success ? "success" : "fail") << endl;
|
||||
p.ios().get_regular_stream() << (success ? "success" : "fail") << std::endl;
|
||||
return env;
|
||||
}
|
||||
|
||||
|
@ -820,13 +642,14 @@ static environment defeq_simplify_cmd(parser & p) {
|
|||
if (!tc->is_def_eq(e, e_simp).first) {
|
||||
throw parser_error("defeq_simplify result not definitionally equal to input expression", pos);
|
||||
}
|
||||
flycheck_information info(p.regular_stream());
|
||||
flycheck_information info(p.ios());
|
||||
auto out = regular(p.env(), p.ios(), tc->get_type_context());
|
||||
if (info.enabled()) {
|
||||
p.display_information_pos(p.cmd_pos());
|
||||
p.regular_stream() << "defeq_simplify result:\n";
|
||||
out << "defeq_simplify result:\n";
|
||||
}
|
||||
|
||||
p.regular_stream() << e_simp << endl;
|
||||
out << e_simp << endl;
|
||||
return env;
|
||||
}
|
||||
|
||||
|
@ -838,23 +661,23 @@ static environment abstract_expr_cmd(parser & p) {
|
|||
congr_lemma_manager congr_lemma(builder, fun_info);
|
||||
abstract_expr_manager ae_manager(congr_lemma);
|
||||
|
||||
flycheck_information info(p.regular_stream());
|
||||
std::ostream & out = p.ios().get_regular_stream();
|
||||
flycheck_information info(p.ios());
|
||||
if (info.enabled()) p.display_information_pos(p.cmd_pos());
|
||||
|
||||
expr e, a, b;
|
||||
level_param_names ls, ls1, ls2;
|
||||
if (o == 0) {
|
||||
// hash
|
||||
if (info.enabled()) p.regular_stream() << "abstract hash: " << endl;
|
||||
if (info.enabled()) out << "abstract hash: " << std::endl;
|
||||
std::tie(e, ls) = parse_local_expr(p);
|
||||
p.regular_stream() << ae_manager.hash(e) << endl;
|
||||
out << ae_manager.hash(e) << std::endl;
|
||||
} else {
|
||||
// is_equal
|
||||
if (info.enabled()) p.regular_stream() << "abstract is_equal: " << endl;
|
||||
if (info.enabled()) out << "abstract is_equal: " << std::endl;
|
||||
std::tie(a, ls1) = parse_local_expr(p);
|
||||
p.check_token_next(get_comma_tk(), "invalid #abstract_expr command, ',' expected");
|
||||
std::tie(b, ls2) = parse_local_expr(p);
|
||||
p.regular_stream() << ae_manager.is_equal(a, b) << endl;
|
||||
out << ae_manager.is_equal(a, b) << std::endl;
|
||||
}
|
||||
return p.env();
|
||||
}
|
||||
|
@ -880,20 +703,8 @@ void init_cmd_table(cmd_table & r) {
|
|||
add_cmd(r, cmd_info("init_quotient", "initialize quotient type computational rules", init_quotient_cmd));
|
||||
add_cmd(r, cmd_info("init_hits", "initialize builtin HITs", init_hits_cmd));
|
||||
add_cmd(r, cmd_info("#erase_cache", "erase cached definition (for debugging purposes)", erase_cache_cmd));
|
||||
add_cmd(r, cmd_info("#projections", "generate projections for inductive datatype (for debugging purposes)", projections_cmd));
|
||||
add_cmd(r, cmd_info("#telescope_eq", "(for debugging purposes)", telescope_eq_cmd));
|
||||
add_cmd(r, cmd_info("#app_builder", "(for debugging purposes)", app_builder_cmd));
|
||||
add_cmd(r, cmd_info("#refl", "(for debugging purposes)", refl_cmd));
|
||||
add_cmd(r, cmd_info("#trans", "(for debugging purposes)", trans_cmd));
|
||||
add_cmd(r, cmd_info("#symm", "(for debugging purposes)", symm_cmd));
|
||||
add_cmd(r, cmd_info("#compile", "(for debugging purposes)", compile_cmd));
|
||||
add_cmd(r, cmd_info("#congr", "(for debugging purposes)", congr_cmd));
|
||||
add_cmd(r, cmd_info("#hcongr", "(for debugging purposes)", hcongr_cmd));
|
||||
add_cmd(r, cmd_info("#congr_simp", "(for debugging purposes)", congr_simp_cmd));
|
||||
add_cmd(r, cmd_info("#congr_rel", "(for debugging purposes)", congr_rel_cmd));
|
||||
add_cmd(r, cmd_info("#normalizer", "(for debugging purposes)", normalizer_cmd));
|
||||
add_cmd(r, cmd_info("#unify", "(for debugging purposes)", unify_cmd));
|
||||
add_cmd(r, cmd_info("#accessible", "(for debugging purposes) display number of accessible declarations for blast tactic", accessible_cmd));
|
||||
add_cmd(r, cmd_info("#simplify", "(for debugging purposes) simplify given expression", simplify_cmd));
|
||||
add_cmd(r, cmd_info("#defeq_simplify", "(for debugging purposes) defeq-simplify given expression", defeq_simplify_cmd));
|
||||
add_cmd(r, cmd_info("#abstract_expr", "(for debugging purposes) call abstract expr methods", abstract_expr_cmd));
|
||||
|
|
|
@ -880,7 +880,7 @@ class definition_cmd_fn {
|
|||
std::ostringstream msg;
|
||||
display_pos(msg);
|
||||
msg << " type checking time for " << m_name;
|
||||
timeit timer(m_p.diagnostic_stream().get_stream(), msg.str().c_str(), LEAN_PROFILE_THRESHOLD);
|
||||
timeit timer(m_p.ios().get_diagnostic_stream(), msg.str().c_str(), LEAN_PROFILE_THRESHOLD);
|
||||
return ::lean::check(m_env, d);
|
||||
} else {
|
||||
return ::lean::check(m_env, d);
|
||||
|
@ -1036,7 +1036,7 @@ class definition_cmd_fn {
|
|||
std::ostringstream msg;
|
||||
display_pos(msg);
|
||||
msg << " type elaboration time for " << m_name;
|
||||
timeit timer(m_p.diagnostic_stream().get_stream(), msg.str().c_str(), LEAN_PROFILE_THRESHOLD);
|
||||
timeit timer(m_p.ios().get_diagnostic_stream(), msg.str().c_str(), LEAN_PROFILE_THRESHOLD);
|
||||
return m_p.elaborate_type(e, list<expr>(), clear_pre_info);
|
||||
} else {
|
||||
return m_p.elaborate_type(e, list<expr>(), clear_pre_info);
|
||||
|
@ -1049,7 +1049,7 @@ class definition_cmd_fn {
|
|||
std::ostringstream msg;
|
||||
display_pos(msg);
|
||||
msg << " elaboration time for " << m_name;
|
||||
timeit timer(m_p.diagnostic_stream().get_stream(), msg.str().c_str(), LEAN_PROFILE_THRESHOLD);
|
||||
timeit timer(m_p.ios().get_diagnostic_stream(), msg.str().c_str(), LEAN_PROFILE_THRESHOLD);
|
||||
return m_p.elaborate_definition(def_name, type, value);
|
||||
} else {
|
||||
return m_p.elaborate_definition(def_name, type, value);
|
||||
|
|
|
@ -312,9 +312,9 @@ void elaborator::instantiate_info(substitution s) {
|
|||
expr meta_type = s.instantiate(type_checker(env()).infer(meta).first);
|
||||
goal g(meta, meta_type);
|
||||
proof_state ps(goals(g), s, constraints());
|
||||
auto out = regular(env(), ios());
|
||||
auto out = regular(env(), ios(), m_tc->get_type_context());
|
||||
print_lean_info_header(out.get_stream());
|
||||
out << ps.pp(env(), ios()) << endl;
|
||||
out << ps.pp(out.get_formatter()) << endl;
|
||||
print_lean_info_footer(out.get_stream());
|
||||
}
|
||||
if (infom()) {
|
||||
|
@ -1886,11 +1886,11 @@ void elaborator::display_unsolved_proof_state(expr const & mvar, proof_state con
|
|||
lean_assert(is_metavar(mvar));
|
||||
if (!m_displayed_errors.contains(mlocal_name(mvar))) {
|
||||
m_displayed_errors.insert(mlocal_name(mvar));
|
||||
auto out = regular(env(), ios());
|
||||
flycheck_error err(out);
|
||||
auto out = regular(env(), ios(), m_tc->get_type_context());
|
||||
flycheck_error err(ios());
|
||||
if (!err.enabled() || save_error(pip(), pos)) {
|
||||
display_error_pos(out, pip(), pos);
|
||||
out << " " << msg << "\n" << ps.pp(env(), ios()) << endl;
|
||||
display_error_pos(out.get_stream(), out.get_options(), pip(), pos);
|
||||
out << " " << msg << "\n" << ps.pp(out.get_formatter()) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1928,8 +1928,8 @@ optional<tactic> elaborator::pre_tactic_to_tactic(expr const & pre_tac) {
|
|||
};
|
||||
return optional<tactic>(expr_to_tactic(env(), fn, pre_tac, pip()));
|
||||
} catch (expr_to_tactic_exception & ex) {
|
||||
auto out = regular(env(), ios());
|
||||
flycheck_error err(out);
|
||||
auto out = regular(env(), ios(), m_tc->get_type_context());
|
||||
flycheck_error err(ios());
|
||||
if (!err.enabled() || save_error(pip(), ex.get_expr())) {
|
||||
display_error_pos(out, pip(), ex.get_expr());
|
||||
out << " " << ex.what();
|
||||
|
@ -1941,8 +1941,8 @@ optional<tactic> elaborator::pre_tactic_to_tactic(expr const & pre_tac) {
|
|||
}
|
||||
|
||||
void elaborator::display_tactic_exception(tactic_exception const & ex, proof_state const & ps, expr const & pre_tac) {
|
||||
auto out = regular(env(), ios());
|
||||
flycheck_error err(out);
|
||||
auto out = regular(env(), ios(), m_tc->get_type_context());
|
||||
flycheck_error err(ios());
|
||||
if (optional<expr> const & e = ex.get_main_expr()) {
|
||||
if (err.enabled() && !save_error(pip(), *e))
|
||||
return;
|
||||
|
@ -1954,9 +1954,9 @@ void elaborator::display_tactic_exception(tactic_exception const & ex, proof_sta
|
|||
}
|
||||
out << ex.pp(out.get_formatter()) << "\nproof state:\n";
|
||||
if (auto curr_ps = ex.get_proof_state())
|
||||
out << curr_ps->pp(env(), ios()) << "\n";
|
||||
out << curr_ps->pp(out.get_formatter()) << "\n";
|
||||
else
|
||||
out << ps.pp(env(), ios()) << "\n";
|
||||
out << ps.pp(out.get_formatter()) << "\n";
|
||||
}
|
||||
|
||||
void elaborator::display_unsolved_subgoals(expr const & mvar, proof_state const & ps, expr const & pos) {
|
||||
|
@ -2049,10 +2049,10 @@ void elaborator::show_goal(proof_state const & ps, expr const & start, expr cons
|
|||
if (curr_pos->first < line || (curr_pos->first == line && curr_pos->second < col))
|
||||
return;
|
||||
m_ctx.reset_show_goal_at();
|
||||
auto out = regular(env(), ios());
|
||||
auto out = regular(env(), ios(), m_tc->get_type_context());
|
||||
print_lean_info_header(out.get_stream());
|
||||
out << "position " << curr_pos->first << ":" << curr_pos->second << "\n";
|
||||
out << ps.pp(env(), ios()) << "\n";
|
||||
out << ps.pp(out.get_formatter()) << "\n";
|
||||
print_lean_info_footer(out.get_stream());
|
||||
}
|
||||
|
||||
|
@ -2088,11 +2088,11 @@ bool elaborator::try_using_begin_end(substitution & subst, expr const & mvar, pr
|
|||
}
|
||||
if (m_ctx.m_flycheck_goals) {
|
||||
if (auto p = pip()->get_pos_info(ptac)) {
|
||||
auto out = regular(env(), ios());
|
||||
flycheck_information info(out);
|
||||
auto out = regular(env(), ios(), m_tc->get_type_context());
|
||||
flycheck_information info(ios());
|
||||
if (info.enabled()) {
|
||||
display_information_pos(out, pip()->get_file_name(), p->first, p->second);
|
||||
out << " proof state:\n" << ps.pp(env(), ios()) << "\n";
|
||||
out << " proof state:\n" << ps.pp(out.get_formatter()) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2103,12 +2103,12 @@ bool elaborator::try_using_begin_end(substitution & subst, expr const & mvar, pr
|
|||
} catch (exception &) {
|
||||
throw;
|
||||
} catch (throwable & ex) {
|
||||
auto out = regular(env(), ios());
|
||||
flycheck_error err(out);
|
||||
auto out = regular(env(), ios(), m_tc->get_type_context());
|
||||
flycheck_error err(ios());
|
||||
if (!err.enabled() || save_error(pip(), ptac)) {
|
||||
display_error_pos(out, pip(), ptac);
|
||||
out << ex.what() << "\nproof state:\n";
|
||||
out << ps.pp(env(), ios()) << "\n";
|
||||
out << ps.pp(out.get_formatter()) << "\n";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -107,12 +107,14 @@ environment find_cmd(parser & p) {
|
|||
buffer<std::string> pos_names, neg_names;
|
||||
parse_filters(p, pos_names, neg_names);
|
||||
environment env = p.env();
|
||||
auto tc = mk_opaque_type_checker(env);
|
||||
flycheck_information info(p.regular_stream());
|
||||
// TODO(Leo): replace with type_context
|
||||
auto tc = mk_opaque_type_checker(env);
|
||||
auto out = regular(env, p.ios(), tc->get_type_context());
|
||||
flycheck_information info(p.ios());
|
||||
if (info.enabled()) {
|
||||
p.display_information_pos(p.cmd_pos());
|
||||
}
|
||||
p.regular_stream() << "find_decl result:\n";
|
||||
out << "find_decl result:\n";
|
||||
|
||||
unsigned max_steps = get_find_max_steps(p.get_options());
|
||||
bool cheap = !get_find_expensive(p.get_options());
|
||||
|
@ -124,11 +126,11 @@ environment find_cmd(parser & p) {
|
|||
[&](std::string const & neg) { return !is_part_of(neg, d.get_name()); }) &&
|
||||
match_pattern(*tc.get(), e, d, max_steps, cheap)) {
|
||||
found = true;
|
||||
p.regular_stream() << " " << get_decl_short_name(d.get_name(), env) << " : " << d.get_type() << endl;
|
||||
out << " " << get_decl_short_name(d.get_name(), env) << " : " << d.get_type() << endl;
|
||||
}
|
||||
});
|
||||
if (!found)
|
||||
p.regular_stream() << "no matches\n";
|
||||
out << "no matches\n";
|
||||
return env;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ Author: Leonardo de Moura
|
|||
#include "library/choice.h"
|
||||
#include "library/scoped_ext.h"
|
||||
#include "library/pp_options.h"
|
||||
#include "library/type_context.h"
|
||||
#include "library/tactic/proof_state.h"
|
||||
#include "library/tactic/expr_to_tactic.h"
|
||||
#include "frontends/lean/info_manager.h"
|
||||
|
@ -628,7 +629,8 @@ struct info_manager::imp {
|
|||
void display_core(environment const & env, options const & o, io_state const & ios, unsigned line,
|
||||
optional<unsigned> const & col) {
|
||||
m_line_data[line].for_each([&](info_data const & d) {
|
||||
io_state_stream out = regular(env, ios).update_options(o);
|
||||
default_type_context tc(env, o);
|
||||
io_state_stream out = regular(env, ios, tc).update_options(o);
|
||||
if ((!col && d.is_cheap()) || (col && d.get_column() == *col))
|
||||
d.display(out, line);
|
||||
});
|
||||
|
|
|
@ -41,6 +41,7 @@ Author: Leonardo de Moura
|
|||
#include "library/pp_options.h"
|
||||
#include "library/noncomputable.h"
|
||||
#include "library/error_handling.h"
|
||||
#include "library/type_context.h"
|
||||
#include "library/tactic/expr_to_tactic.h"
|
||||
#include "library/tactic/location.h"
|
||||
#include "frontends/lean/tokens.h"
|
||||
|
@ -181,7 +182,7 @@ void parser::scan() {
|
|||
if (curr_is_identifier()) {
|
||||
name const & id = get_name_val();
|
||||
if (p.second <= m_info_at_col && m_info_at_col < p.second + id.utf8_size()) {
|
||||
print_lean_info_header(regular_stream().get_stream());
|
||||
print_lean_info_header(m_ios.get_regular_stream());
|
||||
bool ok = true;
|
||||
try {
|
||||
bool show_value = false;
|
||||
|
@ -190,26 +191,26 @@ void parser::scan() {
|
|||
ok = false;
|
||||
}
|
||||
if (!ok)
|
||||
regular_stream() << "unknown identifier '" << id << "'\n";
|
||||
print_lean_info_footer(regular_stream().get_stream());
|
||||
m_ios.get_regular_stream() << "unknown identifier '" << id << "'\n";
|
||||
print_lean_info_footer(m_ios.get_regular_stream());
|
||||
m_info_at = false;
|
||||
}
|
||||
} else if (curr_is_keyword()) {
|
||||
name const & tk = get_token_info().token();
|
||||
if (p.second <= m_info_at_col && m_info_at_col < p.second + tk.utf8_size()) {
|
||||
print_lean_info_header(regular_stream().get_stream());
|
||||
print_lean_info_header(m_ios.get_regular_stream());
|
||||
try {
|
||||
print_token_info(*this, tk);
|
||||
} catch (exception &) {}
|
||||
print_lean_info_footer(regular_stream().get_stream());
|
||||
print_lean_info_footer(m_ios.get_regular_stream());
|
||||
m_info_at = false;
|
||||
}
|
||||
} else if (curr_is_command()) {
|
||||
name const & tk = get_token_info().token();
|
||||
if (p.second <= m_info_at_col && m_info_at_col < p.second + tk.utf8_size()) {
|
||||
print_lean_info_header(regular_stream().get_stream());
|
||||
regular_stream() << "'" << tk << "' is a command\n";
|
||||
print_lean_info_footer(regular_stream().get_stream());
|
||||
print_lean_info_header(m_ios.get_regular_stream());
|
||||
m_ios.get_regular_stream() << "'" << tk << "' is a command\n";
|
||||
print_lean_info_footer(m_ios.get_regular_stream());
|
||||
m_info_at = false;
|
||||
}
|
||||
}
|
||||
|
@ -274,9 +275,9 @@ expr parser::mk_sorry(pos_info const & p) {
|
|||
// TODO(Leo): remove the #ifdef.
|
||||
// The compilation option LEAN_IGNORE_SORRY is a temporary hack for the nightly builds
|
||||
// We use it to avoid a buch of warnings on cdash.
|
||||
flycheck_warning wrn(regular_stream());
|
||||
flycheck_warning wrn(m_ios);
|
||||
display_warning_pos(p.first, p.second);
|
||||
regular_stream() << " using 'sorry'" << endl;
|
||||
m_ios.get_regular_stream() << " using 'sorry'" << std::endl;
|
||||
#endif
|
||||
}
|
||||
return save_pos(::lean::mk_sorry(), p);
|
||||
|
@ -322,30 +323,36 @@ void parser::updt_options() {
|
|||
}
|
||||
|
||||
void parser::display_warning_pos(unsigned line, unsigned pos) {
|
||||
::lean::display_warning_pos(regular_stream(), get_stream_name().c_str(), line, pos);
|
||||
default_type_context tc(env(), get_options());
|
||||
auto out = regular(env(), ios(), tc);
|
||||
::lean::display_warning_pos(out, get_stream_name().c_str(), line, pos);
|
||||
}
|
||||
void parser::display_warning_pos(pos_info p) { display_warning_pos(p.first, p.second); }
|
||||
|
||||
void parser::display_information_pos(pos_info pos) {
|
||||
::lean::display_information_pos(regular_stream(), get_stream_name().c_str(), pos.first, pos.second);
|
||||
::lean::display_information_pos(ios().get_regular_stream(), get_options(),
|
||||
get_stream_name().c_str(), pos.first, pos.second);
|
||||
}
|
||||
|
||||
void parser::display_error_pos(unsigned line, unsigned pos) {
|
||||
::lean::display_error_pos(regular_stream(), get_stream_name().c_str(), line, pos);
|
||||
::lean::display_error_pos(ios().get_regular_stream(), get_options(),
|
||||
get_stream_name().c_str(), line, pos);
|
||||
}
|
||||
void parser::display_error_pos(pos_info p) { display_error_pos(p.first, p.second); }
|
||||
|
||||
void parser::display_error(char const * msg, unsigned line, unsigned pos) {
|
||||
flycheck_error err(regular_stream());
|
||||
flycheck_error err(ios());
|
||||
display_error_pos(line, pos);
|
||||
regular_stream() << " " << msg << endl;
|
||||
ios().get_regular_stream() << " " << msg << std::endl;
|
||||
}
|
||||
|
||||
void parser::display_error(char const * msg, pos_info p) { display_error(msg, p.first, p.second); }
|
||||
|
||||
void parser::display_error(throwable const & ex) {
|
||||
default_type_context tc(env(), get_options());
|
||||
auto out = regular(env(), ios(), tc);
|
||||
parser_pos_provider pos_provider(m_pos_table, get_stream_name(), m_last_cmd_pos);
|
||||
::lean::display_error(regular_stream(), &pos_provider, ex);
|
||||
::lean::display_error(out, &pos_provider, ex);
|
||||
}
|
||||
|
||||
void parser::throw_parser_exception(char const * msg, pos_info p) {
|
||||
|
@ -373,7 +380,7 @@ void parser::protected_call(std::function<void()> && f, std::function<void()> &&
|
|||
ex.get_exception().rethrow();
|
||||
}
|
||||
} catch (parser_exception & ex) {
|
||||
CATCH(flycheck_error err(regular_stream()); regular_stream() << ex.what() << endl,
|
||||
CATCH(flycheck_error err(ios()); ios().get_regular_stream() << ex.what() << std::endl,
|
||||
throw);
|
||||
} catch (parser_error & ex) {
|
||||
CATCH(display_error(ex.what(), ex.m_pos),
|
||||
|
@ -382,7 +389,7 @@ void parser::protected_call(std::function<void()> && f, std::function<void()> &&
|
|||
save_pre_info_data();
|
||||
reset_interrupt();
|
||||
if (m_verbose)
|
||||
regular_stream() << "!!!Interrupted!!!" << endl;
|
||||
ios().get_regular_stream() << "!!!Interrupted!!!" << std::endl;
|
||||
sync();
|
||||
if (m_use_exceptions || m_info_manager)
|
||||
throw;
|
||||
|
@ -2034,13 +2041,35 @@ expr parser::parse_tactic(unsigned rbp) {
|
|||
return left;
|
||||
}
|
||||
|
||||
/** \brief Helper class for creating type context only if needed */
|
||||
class lazy_type_context : public abstract_type_context {
|
||||
environment const & m_env;
|
||||
options const & m_opts;
|
||||
std::unique_ptr<default_type_context> m_ctx;
|
||||
default_type_context & ctx() {
|
||||
if (!m_ctx)
|
||||
m_ctx.reset(new default_type_context(m_env, m_opts));
|
||||
return *m_ctx;
|
||||
}
|
||||
public:
|
||||
lazy_type_context(environment const & env, options const & opts):m_env(env), m_opts(opts) {}
|
||||
virtual ~lazy_type_context() {}
|
||||
virtual environment const & env() const override { return const_cast<lazy_type_context*>(this)->ctx().env(); }
|
||||
virtual expr whnf(expr const & e) override { return ctx().whnf(e); }
|
||||
virtual bool is_def_eq(expr const & e1, expr const & e2) override { return ctx().is_def_eq(e1, e2); }
|
||||
virtual expr infer(expr const & e) override { return ctx().infer(e); }
|
||||
virtual expr check(expr const & e) override { return ctx().check(e); }
|
||||
virtual optional<expr> is_stuck(expr const & e) override { return ctx().is_stuck(e); }
|
||||
};
|
||||
|
||||
void parser::parse_command() {
|
||||
lean_assert(curr() == scanner::token_kind::CommandKeyword);
|
||||
m_last_cmd_pos = pos();
|
||||
name const & cmd_name = get_token_info().value();
|
||||
m_cmd_token = get_token_info().token();
|
||||
if (auto it = cmds().find(cmd_name)) {
|
||||
scope_trace_env scope(m_env, m_ios);
|
||||
lazy_type_context tc(m_env, get_options());
|
||||
scope_trace_env scope(m_env, m_ios, tc);
|
||||
if (is_notation_cmd(cmd_name)) {
|
||||
in_notation_ctx ctx(*this);
|
||||
next();
|
||||
|
@ -2082,9 +2111,9 @@ void parser::parse_imports() {
|
|||
} else {
|
||||
m_found_errors = true;
|
||||
if (!m_use_exceptions && m_show_errors) {
|
||||
flycheck_error err(regular_stream());
|
||||
flycheck_error err(ios());
|
||||
display_error_pos(pos());
|
||||
regular_stream() << " invalid import, unknown module '" << f << "'" << endl;
|
||||
ios().get_regular_stream() << " invalid import, unknown module '" << f << "'" << std::endl;
|
||||
}
|
||||
if (m_use_exceptions)
|
||||
throw parser_error(sstream() << "invalid import, unknown module '" << f << "'", pos());
|
||||
|
@ -2160,9 +2189,9 @@ bool parser::parse_commands() {
|
|||
// TODO(Leo): remove the #ifdef.
|
||||
// The compilation option LEAN_IGNORE_SORRY is a temporary hack for the nightly builds
|
||||
// We use it to avoid a buch of warnings on cdash.
|
||||
flycheck_warning wrn(regular_stream());
|
||||
flycheck_warning wrn(ios());
|
||||
display_warning_pos(pos());
|
||||
regular_stream() << " imported file uses 'sorry'" << endl;
|
||||
ios().get_regular_stream() << " imported file uses 'sorry'" << std::endl;
|
||||
#endif
|
||||
}
|
||||
while (!done) {
|
||||
|
|
|
@ -377,9 +377,6 @@ public:
|
|||
token_info const & get_token_info() const { return m_scanner.get_token_info(); }
|
||||
std::string const & get_stream_name() const { return m_scanner.get_stream_name(); }
|
||||
|
||||
io_state_stream regular_stream() const { return regular(env(), ios()); }
|
||||
io_state_stream diagnostic_stream() const { return diagnostic(env(), ios()); }
|
||||
|
||||
unsigned get_small_nat();
|
||||
unsigned parse_small_nat();
|
||||
double parse_double();
|
||||
|
|
|
@ -1380,7 +1380,7 @@ format pretty_fn::operator()(expr const & e) {
|
|||
}
|
||||
|
||||
formatter_factory mk_pretty_formatter_factory() {
|
||||
return [](environment const & env, options const & o) { // NOLINT
|
||||
return [](environment const & env, options const & o, abstract_type_context &) { // NOLINT
|
||||
auto fn_ptr = std::make_shared<pretty_fn>(env, o);
|
||||
return formatter(o, [=](expr const & e, options const & new_o) {
|
||||
fn_ptr->set_options(new_o);
|
||||
|
@ -1399,18 +1399,22 @@ static options mk_options(bool detail) {
|
|||
}
|
||||
|
||||
static void pp_core(environment const & env, expr const & e, bool detail) {
|
||||
type_checker tc(env);
|
||||
io_state ios(mk_pretty_formatter_factory(), mk_options(detail));
|
||||
regular(env, ios) << e << "\n";
|
||||
regular(env, ios, tc.get_type_context()) << e << "\n";
|
||||
}
|
||||
|
||||
static void pp_core(environment const & env, goal const & g, bool detail) {
|
||||
type_checker tc(env);
|
||||
io_state ios(mk_pretty_formatter_factory(), mk_options(detail));
|
||||
regular(env, ios) << g << "\n";
|
||||
regular(env, ios, tc.get_type_context()) << g << "\n";
|
||||
}
|
||||
|
||||
static void pp_core(environment const & env, proof_state const & s, bool detail) {
|
||||
type_checker tc(env);
|
||||
io_state ios(mk_pretty_formatter_factory(), mk_options(detail));
|
||||
regular(env, ios) << s.pp(env, ios) << "\n";
|
||||
auto out = regular(env, ios, tc.get_type_context());
|
||||
out << s.pp(out.get_formatter()) << "\n";
|
||||
}
|
||||
}
|
||||
// for debugging purposes
|
||||
|
|
|
@ -43,21 +43,20 @@ Author: Leonardo de Moura
|
|||
namespace lean {
|
||||
static void print_coercions(parser & p, optional<name> const & C) {
|
||||
environment const & env = p.env();
|
||||
options opts = p.regular_stream().get_options();
|
||||
opts = opts.update(get_pp_coercions_name(), true);
|
||||
io_state_stream out = p.regular_stream().update_options(opts);
|
||||
options opts = p.get_options();
|
||||
std::ostream & out = p.ios().get_regular_stream();
|
||||
char const * arrow = get_pp_unicode(opts) ? "↣" : ">->";
|
||||
for_each_coercion_user(env, [&](name const & C1, name const & c, name const & D) {
|
||||
if (!C || *C == C1)
|
||||
out << C1 << " " << arrow << " " << D << " : " << c << endl;
|
||||
out << C1 << " " << arrow << " " << D << " : " << c << std::endl;
|
||||
});
|
||||
for_each_coercion_sort(env, [&](name const & C1, name const & c) {
|
||||
if (!C || *C == C1)
|
||||
out << C1 << " " << arrow << " [sort-class] : " << c << endl;
|
||||
out << C1 << " " << arrow << " [sort-class] : " << c << std::endl;
|
||||
});
|
||||
for_each_coercion_fun(env, [&](name const & C1, name const & c) {
|
||||
if (!C || *C == C1)
|
||||
out << C1 << " " << arrow << " [fun-class] : " << c << endl;
|
||||
out << C1 << " " << arrow << " [fun-class] : " << c << std::endl;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -102,20 +101,24 @@ static environment print_axioms(parser & p) {
|
|||
if (p.curr_is_identifier()) {
|
||||
name c = p.check_constant_next("invalid 'print axioms', constant expected");
|
||||
environment new_env = p.reveal_all_theorems();
|
||||
print_axioms_deps(p.env(), p.regular_stream())(c);
|
||||
default_type_context tc(new_env, p.get_options());
|
||||
auto out = regular(new_env, p.ios(), tc);
|
||||
print_axioms_deps(p.env(), out)(c);
|
||||
return new_env;
|
||||
} else {
|
||||
bool has_axioms = false;
|
||||
environment const & env = p.env();
|
||||
default_type_context tc(env, p.get_options());
|
||||
auto out = regular(env, p.ios(), tc);
|
||||
env.for_each_declaration([&](declaration const & d) {
|
||||
name const & n = d.get_name();
|
||||
if (!d.is_definition() && !env.is_builtin(n) && !p.in_theorem_queue(n)) {
|
||||
p.regular_stream() << n << " : " << d.get_type() << endl;
|
||||
out << n << " : " << d.get_type() << endl;
|
||||
has_axioms = true;
|
||||
}
|
||||
});
|
||||
if (!has_axioms)
|
||||
p.regular_stream() << "no axioms" << endl;
|
||||
out << "no axioms" << endl;
|
||||
return p.env();
|
||||
}
|
||||
}
|
||||
|
@ -124,6 +127,8 @@ static void print_prefix(parser & p) {
|
|||
name prefix = p.check_id_next("invalid 'print prefix' command, identifier expected");
|
||||
environment const & env = p.env();
|
||||
buffer<declaration> to_print;
|
||||
default_type_context tc(env, p.get_options());
|
||||
auto out = regular(env, p.ios(), tc);
|
||||
env.for_each_declaration([&](declaration const & d) {
|
||||
if (is_prefix_of(prefix, d.get_name())) {
|
||||
to_print.push_back(d);
|
||||
|
@ -131,10 +136,10 @@ static void print_prefix(parser & p) {
|
|||
});
|
||||
std::sort(to_print.begin(), to_print.end(), [](declaration const & d1, declaration const & d2) { return d1.get_name() < d2.get_name(); });
|
||||
for (declaration const & d : to_print) {
|
||||
p.regular_stream() << d.get_name() << " : " << d.get_type() << endl;
|
||||
out << d.get_name() << " : " << d.get_type() << endl;
|
||||
}
|
||||
if (to_print.empty())
|
||||
p.regular_stream() << "no declaration starting with prefix '" << prefix << "'" << endl;
|
||||
out << "no declaration starting with prefix '" << prefix << "'" << endl;
|
||||
}
|
||||
|
||||
static void print_fields(parser const & p, name const & S, pos_info const & pos) {
|
||||
|
@ -143,9 +148,11 @@ static void print_fields(parser const & p, name const & S, pos_info const & pos)
|
|||
throw parser_error(sstream() << "invalid 'print fields' command, '" << S << "' is not a structure", pos);
|
||||
buffer<name> field_names;
|
||||
get_structure_fields(env, S, field_names);
|
||||
default_type_context tc(env, p.get_options());
|
||||
auto out = regular(env, p.ios(), tc);
|
||||
for (name const & field_name : field_names) {
|
||||
declaration d = env.get(field_name);
|
||||
p.regular_stream() << d.get_name() << " : " << d.get_type() << endl;
|
||||
out << d.get_name() << " : " << d.get_type() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,10 +178,11 @@ static bool print_parse_table(parser const & p, parse_table const & t, bool nud,
|
|||
os = os.update(get_pp_notation_name(), false);
|
||||
os = os.update(get_pp_preterm_name(), true);
|
||||
ios.set_options(os);
|
||||
default_type_context tc(p.env(), p.get_options());
|
||||
io_state_stream out = regular(p.env(), ios, tc);
|
||||
optional<token_table> tt(get_token_table(p.env()));
|
||||
t.for_each([&](unsigned num, notation::transition const * ts, list<notation::accepting> const & overloads) {
|
||||
if (uses_some_token(num, ts, tokens)) {
|
||||
io_state_stream out = regular(p.env(), ios);
|
||||
if (tactic_table)
|
||||
out << "tactic notation ";
|
||||
found = true;
|
||||
|
@ -196,14 +204,14 @@ static void print_notation(parser & p) {
|
|||
if (print_parse_table(p, get_led_table(p.env()), false, tokens))
|
||||
found = true;
|
||||
if (!found)
|
||||
p.regular_stream() << "no notation" << endl;
|
||||
p.ios().get_regular_stream() << "no notation" << std::endl;
|
||||
}
|
||||
|
||||
static void print_metaclasses(parser const & p) {
|
||||
buffer<name> c;
|
||||
get_metaclasses(c);
|
||||
for (name const & n : c)
|
||||
p.regular_stream() << "[" << n << "]" << endl;
|
||||
p.ios().get_regular_stream() << "[" << n << "]" << std::endl;
|
||||
}
|
||||
|
||||
static void print_patterns(parser & p, name const & n) {
|
||||
|
@ -213,10 +221,11 @@ static void print_patterns(parser & p, name const & n) {
|
|||
blast::scope_debug scope(p.env(), p.ios());
|
||||
auto hi = blast::mk_hi_lemma(n, LEAN_DEFAULT_PRIORITY);
|
||||
if (hi.m_multi_patterns) {
|
||||
io_state_stream _out = p.regular_stream();
|
||||
options opts = _out.get_options();
|
||||
options opts = p.get_options();
|
||||
opts = opts.update_if_undef(get_pp_metavar_args_name(), true);
|
||||
io_state_stream out = _out.update_options(opts);
|
||||
io_state new_ios(p.ios(), opts);
|
||||
default_type_context tc(p.env(), opts);
|
||||
io_state_stream out = regular(p.env(), new_ios, tc);
|
||||
out << "(multi-)patterns:\n";
|
||||
if (!is_nil(hi.m_mvars)) {
|
||||
expr m = head(hi.m_mvars);
|
||||
|
@ -252,21 +261,22 @@ static name to_user_name(environment const & env, name const & n) {
|
|||
static void print_definition(parser const & p, name const & n, pos_info const & pos) {
|
||||
environment const & env = p.env();
|
||||
declaration d = env.get(n);
|
||||
io_state_stream out = p.regular_stream();
|
||||
options opts = out.get_options();
|
||||
options opts = p.get_options();
|
||||
opts = opts.update_if_undef(get_pp_beta_name(), false);
|
||||
io_state_stream new_out = out.update_options(opts);
|
||||
io_state ios(p.ios(), opts);
|
||||
default_type_context tc(env, opts);
|
||||
io_state_stream out = regular(env, ios, tc);
|
||||
if (d.is_axiom())
|
||||
throw parser_error(sstream() << "invalid 'print definition', theorem '" << to_user_name(env, n)
|
||||
<< "' is not available (suggestion: use command 'reveal " << to_user_name(env, n) << "')", pos);
|
||||
if (!d.is_definition())
|
||||
throw parser_error(sstream() << "invalid 'print definition', '" << to_user_name(env, n) << "' is not a definition", pos);
|
||||
new_out << d.get_value() << endl;
|
||||
out << d.get_value() << endl;
|
||||
}
|
||||
|
||||
static void print_attributes(parser const & p, name const & n) {
|
||||
environment const & env = p.env();
|
||||
io_state_stream out = p.regular_stream();
|
||||
std::ostream & out = p.ios().get_regular_stream();
|
||||
buffer<char const *> attrs;
|
||||
get_attributes(attrs);
|
||||
for (char const * attr : attrs) {
|
||||
|
@ -301,7 +311,8 @@ static void print_attributes(parser const & p, name const & n) {
|
|||
|
||||
static void print_inductive(parser const & p, name const & n, pos_info const & pos) {
|
||||
environment const & env = p.env();
|
||||
io_state_stream out = p.regular_stream();
|
||||
type_checker tc(env);
|
||||
io_state_stream out = regular(env, p.ios(), tc.get_type_context());
|
||||
if (auto idecls = inductive::is_inductive_decl(env, n)) {
|
||||
level_param_names ls; unsigned nparams; list<inductive::inductive_decl> dlist;
|
||||
std::tie(ls, nparams, dlist) = *idecls;
|
||||
|
@ -330,7 +341,7 @@ static void print_inductive(parser const & p, name const & n, pos_info const & p
|
|||
|
||||
static void print_recursor_info(parser & p) {
|
||||
name c = p.check_constant_next("invalid 'print [recursor]', constant expected");
|
||||
auto out = p.regular_stream();
|
||||
std::ostream & out = p.ios().get_regular_stream();
|
||||
recursor_info info = get_recursor_info(p.env(), c);
|
||||
out << "recursor information\n"
|
||||
<< " num. parameters: " << info.get_num_params() << "\n"
|
||||
|
@ -368,7 +379,8 @@ static void print_recursor_info(parser & p) {
|
|||
}
|
||||
|
||||
static bool print_constant(parser const & p, char const * kind, declaration const & d, bool is_def = false) {
|
||||
io_state_stream out = p.regular_stream();
|
||||
type_checker tc(p.env());
|
||||
auto out = regular(p.env(), p.ios(), tc.get_type_context());
|
||||
if (d.is_definition() && is_marked_noncomputable(p.env(), d.get_name()))
|
||||
out << "noncomputable ";
|
||||
if (is_protected(p.env(), d.get_name()))
|
||||
|
@ -386,7 +398,8 @@ bool print_id_info(parser & p, name const & id, bool show_value, pos_info const
|
|||
// declarations
|
||||
try {
|
||||
environment const & env = p.env();
|
||||
io_state_stream out = p.regular_stream();
|
||||
type_checker tc(env);
|
||||
auto out = regular(env, p.ios(), tc.get_type_context());
|
||||
try {
|
||||
list<name> cs = p.to_constants(id, "", pos);
|
||||
bool first = true;
|
||||
|
@ -502,14 +515,15 @@ static void print_reducible_info(parser & p, reducible_status s1) {
|
|||
if (s1 == s2)
|
||||
r.push_back(n);
|
||||
});
|
||||
io_state_stream out = p.regular_stream();
|
||||
std::ostream & out = p.ios().get_regular_stream();
|
||||
std::sort(r.begin(), r.end());
|
||||
for (name const & n : r)
|
||||
out << n << "\n";
|
||||
}
|
||||
|
||||
static void print_unification_hints(parser & p) {
|
||||
io_state_stream out = p.regular_stream();
|
||||
type_checker tc(p.env());
|
||||
auto out = regular(p.env(), p.ios(), tc.get_type_context());
|
||||
unification_hints hints;
|
||||
name ns;
|
||||
if (p.curr_is_identifier()) {
|
||||
|
@ -526,7 +540,8 @@ static void print_unification_hints(parser & p) {
|
|||
}
|
||||
|
||||
static void print_defeq_lemmas(parser & p) {
|
||||
io_state_stream out = p.regular_stream();
|
||||
type_checker tc(p.env());
|
||||
auto out = regular(p.env(), p.ios(), tc.get_type_context());
|
||||
defeq_simp_lemmas lemmas;
|
||||
name ns;
|
||||
if (p.curr_is_identifier()) {
|
||||
|
@ -543,7 +558,8 @@ static void print_defeq_lemmas(parser & p) {
|
|||
}
|
||||
|
||||
static void print_simp_rules(parser & p) {
|
||||
io_state_stream out = p.regular_stream();
|
||||
type_checker tc(p.env());
|
||||
auto out = regular(p.env(), p.ios(), tc.get_type_context());
|
||||
blast::scope_debug scope(p.env(), p.ios());
|
||||
blast::simp_lemmas s;
|
||||
name ns;
|
||||
|
@ -561,14 +577,16 @@ static void print_simp_rules(parser & p) {
|
|||
}
|
||||
|
||||
static void print_congr_rules(parser & p) {
|
||||
io_state_stream out = p.regular_stream();
|
||||
type_checker tc(p.env());
|
||||
auto out = regular(p.env(), p.ios(), tc.get_type_context());
|
||||
blast::scope_debug scope(p.env(), p.ios());
|
||||
blast::simp_lemmas s = blast::get_simp_lemmas();
|
||||
out << s.pp_congr(out.get_formatter());
|
||||
}
|
||||
|
||||
static void print_light_rules(parser & p) {
|
||||
io_state_stream out = p.regular_stream();
|
||||
type_checker tc(p.env());
|
||||
auto out = regular(p.env(), p.ios(), tc.get_type_context());
|
||||
light_rule_set lrs = get_light_rule_set(p.env());
|
||||
out << lrs;
|
||||
}
|
||||
|
@ -577,31 +595,29 @@ static void print_elim_lemmas(parser & p) {
|
|||
buffer<name> lemmas;
|
||||
get_elim_lemmas(p.env(), lemmas);
|
||||
for (auto n : lemmas)
|
||||
p.regular_stream() << n << "\n";
|
||||
p.ios().get_regular_stream() << n << "\n";
|
||||
}
|
||||
|
||||
static void print_intro_lemmas(parser & p) {
|
||||
io_state_stream out = p.regular_stream();
|
||||
buffer<name> lemmas;
|
||||
get_intro_lemmas(p.env(), lemmas);
|
||||
for (auto n : lemmas)
|
||||
out << n << "\n";
|
||||
p.ios().get_regular_stream() << n << "\n";
|
||||
}
|
||||
|
||||
static void print_backward_lemmas(parser & p) {
|
||||
io_state_stream out = p.regular_stream();
|
||||
buffer<name> lemmas;
|
||||
get_backward_lemmas(p.env(), lemmas);
|
||||
for (auto n : lemmas)
|
||||
out << n << "\n";
|
||||
p.ios().get_regular_stream() << n << "\n";
|
||||
}
|
||||
|
||||
static void print_no_patterns(parser & p) {
|
||||
io_state_stream out = p.regular_stream();
|
||||
auto s = get_no_patterns(p.env());
|
||||
buffer<name> ns;
|
||||
s.to_buffer(ns);
|
||||
std::sort(ns.begin(), ns.end());
|
||||
std::ostream & out = p.ios().get_regular_stream();
|
||||
for (unsigned i = 0; i < ns.size(); i++) {
|
||||
if (i > 0) out << ", ";
|
||||
out << ns[i];
|
||||
|
@ -610,7 +626,7 @@ static void print_no_patterns(parser & p) {
|
|||
}
|
||||
|
||||
static void print_aliases(parser const & p) {
|
||||
io_state_stream out = p.regular_stream();
|
||||
std::ostream & out = p.ios().get_regular_stream();
|
||||
for_each_expr_alias(p.env(), [&](name const & n, list<name> const & as) {
|
||||
out << n << " -> {";
|
||||
bool first = true;
|
||||
|
@ -623,18 +639,20 @@ static void print_aliases(parser const & p) {
|
|||
}
|
||||
|
||||
environment print_cmd(parser & p) {
|
||||
flycheck_information info(p.regular_stream());
|
||||
flycheck_information info(p.ios());
|
||||
environment const & env = p.env();
|
||||
type_checker tc(env);
|
||||
auto out = regular(env, p.ios(), tc.get_type_context());
|
||||
if (info.enabled()) {
|
||||
p.display_information_pos(p.cmd_pos());
|
||||
p.regular_stream() << "print result:\n";
|
||||
out << "print result:\n";
|
||||
}
|
||||
if (p.curr() == scanner::token_kind::String) {
|
||||
p.regular_stream() << p.get_str_val() << endl;
|
||||
out << p.get_str_val() << endl;
|
||||
p.next();
|
||||
} else if (p.curr_is_token_or_id(get_raw_tk())) {
|
||||
p.next();
|
||||
expr e = p.parse_expr();
|
||||
io_state_stream out = p.regular_stream();
|
||||
options opts = out.get_options();
|
||||
opts = opts.update(get_pp_notation_name(), false);
|
||||
out.update_options(opts) << e << endl;
|
||||
|
@ -649,10 +667,10 @@ environment print_cmd(parser & p) {
|
|||
print_reducible_info(p, reducible_status::Irreducible);
|
||||
} else if (p.curr_is_token_or_id(get_options_tk())) {
|
||||
p.next();
|
||||
p.regular_stream() << p.ios().get_options() << endl;
|
||||
out << p.ios().get_options() << endl;
|
||||
} else if (p.curr_is_token_or_id(get_trust_tk())) {
|
||||
p.next();
|
||||
p.regular_stream() << "trust level: " << p.env().trust_lvl() << endl;
|
||||
out << "trust level: " << p.env().trust_lvl() << endl;
|
||||
} else if (p.curr_is_token_or_id(get_definition_tk())) {
|
||||
p.next();
|
||||
auto pos = p.pos();
|
||||
|
@ -663,7 +681,7 @@ environment print_cmd(parser & p) {
|
|||
if (first)
|
||||
first = false;
|
||||
else
|
||||
p.regular_stream() << "\n";
|
||||
out << "\n";
|
||||
declaration const & d = p.env().get(c);
|
||||
if (d.is_theorem()) {
|
||||
print_constant(p, "theorem", d);
|
||||
|
@ -678,14 +696,13 @@ environment print_cmd(parser & p) {
|
|||
} else if (p.curr_is_token_or_id(get_instances_tk())) {
|
||||
p.next();
|
||||
name c = p.check_constant_next("invalid 'print instances', constant expected");
|
||||
environment const & env = p.env();
|
||||
for (name const & i : get_class_instances(env, c)) {
|
||||
p.regular_stream() << i << " : " << env.get(i).get_type() << endl;
|
||||
out << i << " : " << env.get(i).get_type() << endl;
|
||||
}
|
||||
if (list<name> derived_insts = get_class_derived_trans_instances(env, c)) {
|
||||
p.regular_stream() << "Derived transitive instances:\n";
|
||||
out << "Derived transitive instances:\n";
|
||||
for (name const & i : derived_insts) {
|
||||
p.regular_stream() << i << " : " << env.get(i).get_type() << endl;
|
||||
out << i << " : " << env.get(i).get_type() << endl;
|
||||
}
|
||||
}
|
||||
} else if (p.curr_is_token_or_id(get_classes_tk())) {
|
||||
|
@ -695,7 +712,7 @@ environment print_cmd(parser & p) {
|
|||
get_classes(env, classes);
|
||||
std::sort(classes.begin(), classes.end());
|
||||
for (name const & c : classes) {
|
||||
p.regular_stream() << c << " : " << env.get(c).get_type() << endl;
|
||||
out << c << " : " << env.get(c).get_type() << endl;
|
||||
}
|
||||
} else if (p.curr_is_token_or_id(get_prefix_tk())) {
|
||||
p.next();
|
||||
|
|
|
@ -560,7 +560,8 @@ void server::show(bool valid) {
|
|||
|
||||
void server::display_decl(name const & short_name, name const & long_name, environment const & env, options const & o) {
|
||||
declaration const & d = env.get(long_name);
|
||||
io_state_stream out = regular(env, m_ios).update_options(o);
|
||||
type_checker tc(env);
|
||||
io_state_stream out = regular(env, m_ios, tc.get_type_context()).update_options(o);
|
||||
expr type = d.get_type();
|
||||
if (LEAN_FIND_CONSUME_IMPLICIT) {
|
||||
while (true) {
|
||||
|
|
|
@ -119,7 +119,7 @@ void init_token_table(token_table & t) {
|
|||
"add_begin_end_tactic", "set_begin_end_tactic", "instance", "class",
|
||||
"multiple_instances", "find_decl", "attribute", "persistent",
|
||||
"include", "omit", "migrate", "init_quotient", "init_hits", "#erase_cache", "#projections", "#telescope_eq",
|
||||
"#compile", "#accessible", "#decl_stats", "#relevant_thms", "#simplify", "#app_builder", "#refl", "#symm",
|
||||
"#compile", "#decl_stats", "#relevant_thms", "#simplify", "#app_builder", "#refl", "#symm",
|
||||
"#trans", "#congr", "#hcongr", "#congr_simp", "#congr_rel", "#normalizer", "#abstract_expr", "#unify",
|
||||
"#defeq_simplify", nullptr};
|
||||
|
||||
|
|
30
src/kernel/abstract_type_context.h
Normal file
30
src/kernel/abstract_type_context.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Copyright (c) 2016 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/expr.h"
|
||||
|
||||
namespace lean {
|
||||
/** \brief This is a basic API for implementing macro definitions,
|
||||
kernel extensions, formatters, etc.
|
||||
|
||||
\remark This class will eventually replace the class extension_context.
|
||||
|
||||
\remark This class is already using the Lean 0.3 approach where
|
||||
constraint_seq is not used. */
|
||||
class abstract_type_context {
|
||||
public:
|
||||
virtual ~abstract_type_context() {}
|
||||
virtual environment const & env() const = 0;
|
||||
virtual expr whnf(expr const & e) = 0;
|
||||
virtual bool is_def_eq(expr const & e1, expr const & e2) = 0;
|
||||
virtual expr infer(expr const & e) = 0;
|
||||
/** \brief Simular to \c infer, but also performs type checking.
|
||||
\remark Default implementation just invokes \c infer. */
|
||||
virtual expr check(expr const & e) { return infer(e); }
|
||||
virtual optional<expr> is_stuck(expr const &) { return none_expr(); }
|
||||
};
|
||||
}
|
|
@ -12,6 +12,7 @@ Author: Leonardo de Moura
|
|||
namespace lean {
|
||||
class expr;
|
||||
class environment;
|
||||
class abstract_type_context;
|
||||
|
||||
name const & get_formatter_hide_full_terms_name();
|
||||
bool get_formatter_hide_full_terms(options const & opts);
|
||||
|
@ -26,7 +27,7 @@ public:
|
|||
formatter update_options(options const & o) const { return formatter(o, m_fn); }
|
||||
};
|
||||
|
||||
typedef std::function<formatter(environment const &, options const &)> formatter_factory;
|
||||
typedef std::function<formatter(environment const &, options const &, abstract_type_context &)> formatter_factory;
|
||||
|
||||
std::ostream & operator<<(std::ostream & out, expr const & e);
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ expr mk_pi_for(expr const & meta) {
|
|||
|
||||
optional<expr> type_checker::expand_macro(expr const & m) {
|
||||
lean_assert(is_macro(m));
|
||||
return macro_def(m).expand(m, m_tc_ctx);
|
||||
return macro_def(m).expand(m, m_old_tc_ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,7 +190,7 @@ expr type_checker::infer_constant(expr const & e, bool infer_only) {
|
|||
|
||||
pair<expr, constraint_seq> type_checker::infer_macro(expr const & e, bool infer_only) {
|
||||
auto def = macro_def(e);
|
||||
pair<expr, constraint_seq> tcs = def.check_type(e, m_tc_ctx, infer_only);
|
||||
pair<expr, constraint_seq> tcs = def.check_type(e, m_old_tc_ctx, infer_only);
|
||||
expr t = tcs.first;
|
||||
constraint_seq cs = tcs.second;
|
||||
if (!infer_only && def.trust_level() >= m_env.trust_lvl()) {
|
||||
|
@ -422,7 +422,7 @@ bool type_checker::is_opaque(expr const & c) const {
|
|||
}
|
||||
|
||||
type_checker::type_checker(environment const & env, std::unique_ptr<converter> && conv, bool memoize):
|
||||
m_env(env), m_conv(std::move(conv)), m_tc_ctx(*this),
|
||||
m_env(env), m_conv(std::move(conv)), m_old_tc_ctx(*this), m_tc_ctx(*this),
|
||||
m_memoize(memoize), m_params(nullptr) {
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ Author: Leonardo de Moura
|
|||
#include "kernel/justification.h"
|
||||
#include "kernel/converter.h"
|
||||
#include "kernel/expr_maps.h"
|
||||
#include "kernel/abstract_type_context.h"
|
||||
|
||||
namespace lean {
|
||||
/** \brief Return the "arity" of the given type. The arity is the number of nested pi-expressions. */
|
||||
|
@ -69,11 +70,12 @@ expr mk_pi_for(expr const & meta);
|
|||
class type_checker {
|
||||
typedef expr_bi_struct_map<pair<expr, constraint_seq>> cache;
|
||||
|
||||
/** \brief Interface type_checker <-> macro & normalizer_extension */
|
||||
class type_checker_context : public extension_context {
|
||||
/** \brief Interface type_checker <-> macro & normalizer_extension
|
||||
TODO(Leo): delete this class. It will be subsumed by type_checker_context. */
|
||||
class old_type_checker_context : public extension_context {
|
||||
type_checker & m_tc;
|
||||
public:
|
||||
type_checker_context(type_checker & tc):m_tc(tc) {}
|
||||
old_type_checker_context(type_checker & tc):m_tc(tc) {}
|
||||
virtual environment const & env() const { return m_tc.m_env; }
|
||||
virtual pair<expr, constraint_seq> whnf(expr const & e) { return m_tc.whnf(e); }
|
||||
virtual pair<bool, constraint_seq> is_def_eq(expr const & e1, expr const & e2, delayed_justification & j) {
|
||||
|
@ -85,6 +87,21 @@ class type_checker {
|
|||
virtual optional<expr> is_stuck(expr const & e) { return m_tc.is_stuck(e); }
|
||||
};
|
||||
|
||||
class type_checker_context : public abstract_type_context {
|
||||
type_checker & m_tc;
|
||||
public:
|
||||
type_checker_context(type_checker & tc):m_tc(tc) {}
|
||||
virtual environment const & env() const { return m_tc.m_env; }
|
||||
virtual expr whnf(expr const & e) { return m_tc.whnf(e).first; }
|
||||
virtual bool is_def_eq(expr const & e1, expr const & e2) {
|
||||
no_delayed_justification j;
|
||||
return m_tc.is_def_eq(e1, e2, j).first;
|
||||
}
|
||||
virtual expr infer(expr const & e) { return m_tc.infer_type_core(e, true).first; }
|
||||
virtual expr check(expr const & e) { return m_tc.infer_type_core(e, false).first; }
|
||||
virtual optional<expr> is_stuck(expr const & e) { return m_tc.is_stuck(e); }
|
||||
};
|
||||
|
||||
environment m_env;
|
||||
std::unique_ptr<converter> m_conv;
|
||||
// In the type checker cache, we must take into account binder information.
|
||||
|
@ -92,6 +109,7 @@ class type_checker {
|
|||
// The type of (lambda x : A, t) is (Pi x : A, typeof(t))
|
||||
// The type of (lambda {x : A}, t) is (Pi {x : A}, typeof(t))
|
||||
cache m_infer_type_cache[2];
|
||||
old_type_checker_context m_old_tc_ctx;
|
||||
type_checker_context m_tc_ctx;
|
||||
bool m_memoize;
|
||||
// temp flag
|
||||
|
@ -112,7 +130,7 @@ class type_checker {
|
|||
pair<expr, constraint_seq> infer_type(expr const & e);
|
||||
expr infer_type_core(expr const & e, bool infer_only, constraint_seq & cs);
|
||||
|
||||
extension_context & get_extension() { return m_tc_ctx; }
|
||||
extension_context & get_extension() { return m_old_tc_ctx; }
|
||||
constraint mk_eq_cnstr(expr const & lhs, expr const & rhs, justification const & j);
|
||||
public:
|
||||
/**
|
||||
|
@ -126,6 +144,9 @@ public:
|
|||
~type_checker();
|
||||
|
||||
environment const & env() const { return m_env; }
|
||||
|
||||
abstract_type_context & get_type_context() { return m_tc_ctx; }
|
||||
|
||||
/**
|
||||
\brief Return the type of \c t.
|
||||
|
||||
|
|
|
@ -1368,7 +1368,7 @@ pair<expr, constraint_seq> blast_goal(environment const & env, io_state const &
|
|||
blast::scope_blastenv scope2(b);
|
||||
blast::scope_congruence_closure scope3;
|
||||
blast::scope_config scope4(ios.get_options());
|
||||
scope_trace_env scope5(env, ios);
|
||||
scope_trace_env scope5(env, ios, blast::get_type_context());
|
||||
blast::scope_simp scope6;
|
||||
return b(g);
|
||||
}
|
||||
|
|
|
@ -718,7 +718,7 @@ result simplifier::try_congr(expr const & e, user_congr_lemma const & cr) {
|
|||
lean_trace(name({"simplifier", "congruence"}),
|
||||
expr new_lhs = tmp_tctx->instantiate_uvars_mvars(cr.get_lhs());
|
||||
expr new_rhs = tmp_tctx->instantiate_uvars_mvars(cr.get_rhs());
|
||||
diagnostic(env(), ios())
|
||||
diagnostic(env(), ios(), get_type_context())
|
||||
<< "(" << cr.get_id() << ") "
|
||||
<< "[" << ppb(new_lhs) << " =?= " << ppb(new_rhs) << "]\n";);
|
||||
|
||||
|
@ -1081,7 +1081,7 @@ result simplifier::fuse(expr const & e) {
|
|||
get_simp_lemmas(g_ac_key));
|
||||
|
||||
if (!pf_1_3) {
|
||||
diagnostic(env(), ios()) << ppb(e) << "\n\n =?=\n\n" << ppb(e_grp) << "\n";
|
||||
diagnostic(env(), ios(), get_type_context()) << ppb(e) << "\n\n =?=\n\n" << ppb(e_grp) << "\n";
|
||||
throw blast_exception("Failed to prove (1) == (3) during fusion", e);
|
||||
}
|
||||
|
||||
|
@ -1090,7 +1090,7 @@ result simplifier::fuse(expr const & e) {
|
|||
get_simp_lemmas(g_som_key));
|
||||
|
||||
if (!pf_4_5) {
|
||||
diagnostic(env(), ios()) << ppb(e_grp_ls) << "\n\n =?=\n\n" << ppb(e_fused_ls) << "\n";
|
||||
diagnostic(env(), ios(), get_type_context()) << ppb(e_grp_ls) << "\n\n =?=\n\n" << ppb(e_fused_ls) << "\n";
|
||||
throw blast_exception("Failed to prove (4) == (5) during fusion", e);
|
||||
}
|
||||
|
||||
|
|
|
@ -311,7 +311,7 @@ void state::display(io_state_stream const & ios, bool include_inactive) const {
|
|||
}
|
||||
|
||||
void state::display(environment const & env, io_state const & ios, bool include_inactive) const {
|
||||
formatter fmt = ios.get_formatter_factory()(env, ios.get_options());
|
||||
formatter fmt = ios.get_formatter_factory()(env, ios.get_options(), get_type_context());
|
||||
auto & out = ios.get_diagnostic_channel();
|
||||
out << mk_pair(to_goal(include_inactive).pp(fmt), ios.get_options()) << "\n";
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ void trace_curr_state() {
|
|||
if (lean_is_trace_enabled(name({"blast", "state"}))) {
|
||||
std::shared_ptr<output_channel> out(new string_output_channel());
|
||||
io_state tmp(ios(), out, out);
|
||||
io_state_stream strm(env(), tmp);
|
||||
io_state_stream strm(env(), tmp, get_type_context());
|
||||
curr_state().display(strm);
|
||||
std::string new_str = static_cast<string_output_channel*>(out.get())->str();
|
||||
if (get_state_str() == new_str)
|
||||
|
|
|
@ -324,7 +324,7 @@ struct class_instance_elaborator : public choice_iterator {
|
|||
void trace(expr const & t, expr const & r) {
|
||||
if (!m_C->trace_instances())
|
||||
return;
|
||||
auto out = diagnostic(m_C->env(), m_C->ios());
|
||||
auto out = diagnostic(m_C->env(), m_C->ios(), m_C->m_tc->get_type_context());
|
||||
if (!m_displayed_trace_header && m_depth == 0) {
|
||||
if (auto fname = m_C->get_file_name()) {
|
||||
out << fname << ":";
|
||||
|
|
|
@ -324,7 +324,7 @@ class equation_compiler_fn {
|
|||
|
||||
environment const & env() const { return m_tc.env(); }
|
||||
io_state const & ios() const { return m_ios; }
|
||||
io_state_stream out() const { return regular(env(), ios()); }
|
||||
io_state_stream out() const { return regular(env(), ios(), m_tc.get_type_context()); }
|
||||
expr whnf(expr const & e) { return m_tc.whnf(e).first; }
|
||||
expr infer_type(expr const & e) { return m_tc.infer(e).first; }
|
||||
bool is_def_eq(expr const & e1, expr const & e2) { return m_tc.is_def_eq(e1, e2).first; }
|
||||
|
|
|
@ -40,28 +40,44 @@ void display_pos(io_state_stream const & ios, char const * strm_name, unsigned l
|
|||
display_pos(ios.get_stream(), ios.get_options(), strm_name, line, pos);
|
||||
}
|
||||
|
||||
void display_error_pos(std::ostream & out, options const & o, char const * strm_name, unsigned line, unsigned pos) {
|
||||
display_pos(out, o, strm_name, line, pos);
|
||||
out << " error:";
|
||||
}
|
||||
|
||||
void display_error_pos(io_state_stream const & ios, char const * strm_name, unsigned line, unsigned pos) {
|
||||
display_pos(ios, strm_name, line, pos);
|
||||
ios << " error:";
|
||||
display_error_pos(ios.get_stream(), ios.get_options(), strm_name, line, pos);
|
||||
}
|
||||
|
||||
void display_warning_pos(std::ostream & out, options const & o, char const * strm_name, unsigned line, unsigned pos) {
|
||||
display_pos(out, o, strm_name, line, pos);
|
||||
out << " warning:";
|
||||
}
|
||||
|
||||
void display_warning_pos(io_state_stream const & ios, char const * strm_name, unsigned line, unsigned pos) {
|
||||
display_pos(ios, strm_name, line, pos);
|
||||
ios << " warning:";
|
||||
display_warning_pos(ios.get_stream(), ios.get_options(), strm_name, line, pos);
|
||||
}
|
||||
|
||||
void display_information_pos(std::ostream & out, options const & o, char const * strm_name, unsigned line, unsigned pos) {
|
||||
display_pos(out, o, strm_name, line, pos);
|
||||
out << " information:";
|
||||
}
|
||||
|
||||
void display_information_pos(io_state_stream const & ios, char const * strm_name, unsigned line, unsigned pos) {
|
||||
display_pos(ios, strm_name, line, pos);
|
||||
ios << " information:";
|
||||
display_information_pos(ios.get_stream(), ios.get_options(), strm_name, line, pos);
|
||||
}
|
||||
|
||||
void display_error_pos(std::ostream & out, options const & o, pos_info_provider const * p, expr const & e) {
|
||||
if (p) {
|
||||
auto pos = p->get_pos_info_or_some(e);
|
||||
display_error_pos(out, o, p->get_file_name(), pos.first, pos.second);
|
||||
} else {
|
||||
out << "error:";
|
||||
}
|
||||
}
|
||||
|
||||
void display_error_pos(io_state_stream const & ios, pos_info_provider const * p, expr const & e) {
|
||||
if (p) {
|
||||
auto pos = p->get_pos_info_or_some(e);
|
||||
display_error_pos(ios, p->get_file_name(), pos.first, pos.second);
|
||||
} else {
|
||||
ios << "error:";
|
||||
}
|
||||
display_error_pos(ios.get_stream(), ios.get_options(), p, e);
|
||||
}
|
||||
|
||||
void display_error_pos(io_state_stream const & ios, pos_info_provider const * p, optional<expr> const & e) {
|
||||
|
@ -91,7 +107,7 @@ static void display_error(io_state_stream const & ios, pos_info_provider const *
|
|||
}
|
||||
|
||||
void display_error(io_state_stream const & ios, pos_info_provider const * p, throwable const & ex) {
|
||||
flycheck_error err(ios);
|
||||
flycheck_error err(ios.get_stream(), ios.get_options());
|
||||
if (auto k_ex = dynamic_cast<ext_exception const *>(&ex)) {
|
||||
display_error(ios, p, *k_ex);
|
||||
} else if (auto e_ex = dynamic_cast<unifier_exception const *>(&ex)) {
|
||||
|
|
|
@ -17,11 +17,15 @@ void display_pos(io_state_stream const & ios, char const * strm_name, unsigned l
|
|||
\brief Display position information associated with \c e (IF avaiable).
|
||||
If it is not available, it just displays "error:"
|
||||
*/
|
||||
void display_error_pos(std::ostream & out, options const & o, pos_info_provider const * p, expr const & e);
|
||||
void display_error_pos(io_state_stream const & ios, pos_info_provider const * p, expr const & e);
|
||||
/** \brief Display position information + "error:" */
|
||||
void display_error_pos(std::ostream & out, options const & o, char const * strm_name, unsigned line, unsigned pos);
|
||||
void display_error_pos(io_state_stream const & ios, char const * strm_name, unsigned line, unsigned pos);
|
||||
/** \brief Similar to #display_error_pos, but displays a "warning:" */
|
||||
void display_warning_pos(std::ostream & out, options const & o, char const * strm_name, unsigned line, unsigned pos);
|
||||
void display_warning_pos(io_state_stream const & ios, char const * strm_name, unsigned line, unsigned pos);
|
||||
void display_information_pos(std::ostream & out, options const & o, char const * strm_name, unsigned line, unsigned pos);
|
||||
void display_information_pos(io_state_stream const & ios, char const * strm_name, unsigned line, unsigned pos);
|
||||
/**
|
||||
\brief Display exception in the regular stream of \c ios, using the configuration options and formatter from \c ios.
|
||||
|
|
|
@ -7,12 +7,12 @@ Author: Leonardo de Moura
|
|||
#include "library/flycheck.h"
|
||||
|
||||
namespace lean {
|
||||
flycheck_scope::flycheck_scope(io_state_stream const & ios, char const * kind):
|
||||
m_ios(ios),
|
||||
m_flycheck(m_ios.get_options().get_bool("flycheck", false)) {
|
||||
if (m_flycheck) m_ios << "FLYCHECK_BEGIN " << kind << endl;
|
||||
flycheck_scope::flycheck_scope(std::ostream & out, options const & o, char const * kind):
|
||||
m_out(out),
|
||||
m_flycheck(o.get_bool("flycheck", false)) {
|
||||
if (m_flycheck) m_out << "FLYCHECK_BEGIN " << kind << std::endl;
|
||||
}
|
||||
flycheck_scope::~flycheck_scope() {
|
||||
if (m_flycheck) m_ios << "FLYCHECK_END" << endl;
|
||||
if (m_flycheck) m_out << "FLYCHECK_END" << std::endl;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,28 +5,35 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Author: Leonardo de Moura
|
||||
*/
|
||||
#pragma once
|
||||
#include "library/io_state_stream.h"
|
||||
#include <iostream>
|
||||
#include "util/sexpr/options.h"
|
||||
#include "library/io_state.h"
|
||||
|
||||
namespace lean {
|
||||
/** \brief Auxiliary object for "inserting" delimiters for flycheck */
|
||||
class flycheck_scope {
|
||||
io_state_stream m_ios;
|
||||
std::ostream & m_out;
|
||||
bool m_flycheck;
|
||||
public:
|
||||
flycheck_scope(io_state_stream const & ios, char const * kind);
|
||||
flycheck_scope(std::ostream & out, options const & o, char const * kind);
|
||||
flycheck_scope(io_state const & ios, char const * kind):
|
||||
flycheck_scope(ios.get_regular_stream(), ios.get_options(), kind) {}
|
||||
~flycheck_scope();
|
||||
bool enabled() const { return m_flycheck; }
|
||||
};
|
||||
|
||||
struct flycheck_error : public flycheck_scope {
|
||||
flycheck_error(io_state_stream const & ios):flycheck_scope(ios, "ERROR") {}
|
||||
flycheck_error(std::ostream & out, options const & o):flycheck_scope(out, o, "ERROR") {}
|
||||
flycheck_error(io_state const & ios):flycheck_scope(ios, "ERROR") {}
|
||||
};
|
||||
|
||||
struct flycheck_warning : public flycheck_scope {
|
||||
flycheck_warning(io_state_stream const & ios):flycheck_scope(ios, "WARNING") {}
|
||||
flycheck_warning(std::ostream & out, options const & o):flycheck_scope(out, o, "WARNING") {}
|
||||
flycheck_warning(io_state const & ios):flycheck_scope(ios, "WARNING") {}
|
||||
};
|
||||
|
||||
struct flycheck_information : public flycheck_scope {
|
||||
flycheck_information(io_state_stream const & ios):flycheck_scope(ios, "INFORMATION") {}
|
||||
flycheck_information(std::ostream & out, options const & o):flycheck_scope(out, o, "INFORMATION") {}
|
||||
flycheck_information(io_state const & ios):flycheck_scope(ios, "INFORMATION") {}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ public:
|
|||
formatter_factory const & get_formatter_factory() const { return m_formatter_factory; }
|
||||
output_channel & get_regular_channel() const { return *m_regular_channel; }
|
||||
output_channel & get_diagnostic_channel() const { return *m_diagnostic_channel; }
|
||||
std::ostream & get_regular_stream() const { return m_regular_channel->get_stream(); }
|
||||
std::ostream & get_diagnostic_stream() const { return m_diagnostic_channel->get_stream(); }
|
||||
|
||||
void set_regular_channel(std::shared_ptr<output_channel> const & out);
|
||||
void set_diagnostic_channel(std::shared_ptr<output_channel> const & out);
|
||||
|
|
|
@ -7,6 +7,7 @@ Author: Leonardo de Moura
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include "kernel/ext_exception.h"
|
||||
#include "kernel/abstract_type_context.h"
|
||||
#include "library/generic_exception.h"
|
||||
#include "library/io_state.h"
|
||||
|
||||
|
@ -19,8 +20,8 @@ protected:
|
|||
output_channel & m_stream;
|
||||
io_state_stream(environment const & env, formatter const & fmt, output_channel & s):m_env(env), m_formatter(fmt), m_stream(s) {}
|
||||
public:
|
||||
io_state_stream(environment const & env, io_state const & ios, bool regular = true):
|
||||
m_env(env), m_formatter(ios.get_formatter_factory()(env, ios.get_options())),
|
||||
io_state_stream(environment const & env, io_state const & ios, abstract_type_context & ctx, bool regular = true):
|
||||
m_env(env), m_formatter(ios.get_formatter_factory()(env, ios.get_options(), ctx)),
|
||||
m_stream(regular ? ios.get_regular_channel() : ios.get_diagnostic_channel()) {}
|
||||
std::ostream & get_stream() const { return m_stream.get_stream(); }
|
||||
void flush() { get_stream().flush(); }
|
||||
|
@ -30,8 +31,12 @@ public:
|
|||
io_state_stream update_options(options const & o) const { return io_state_stream(m_env, m_formatter.update_options(o), m_stream); }
|
||||
};
|
||||
|
||||
inline io_state_stream regular(environment const & env, io_state const & ios) { return io_state_stream(env, ios, true); }
|
||||
inline io_state_stream diagnostic(environment const & env, io_state const & ios) { return io_state_stream(env, ios, false); }
|
||||
inline io_state_stream regular(environment const & env, io_state const & ios, abstract_type_context & ctx) {
|
||||
return io_state_stream(env, ios, ctx, true);
|
||||
}
|
||||
inline io_state_stream diagnostic(environment const & env, io_state const & ios, abstract_type_context & ctx) {
|
||||
return io_state_stream(env, ios, ctx, false);
|
||||
}
|
||||
|
||||
// hack for using std::endl with channels
|
||||
struct endl_class { endl_class() {} };
|
||||
|
|
|
@ -246,7 +246,7 @@ struct print_expr_fn {
|
|||
};
|
||||
|
||||
formatter_factory mk_print_formatter_factory() {
|
||||
return [](environment const & env, options const & o) { // NOLINT
|
||||
return [](environment const & env, options const & o, abstract_type_context &) { // NOLINT
|
||||
return formatter(o, [=](expr const & e, options const &) {
|
||||
std::ostringstream s;
|
||||
print_expr_fn pr(s, env.prop_proof_irrel());
|
||||
|
|
|
@ -24,8 +24,8 @@ tactic check_expr_tactic(elaborate_fn const & elab, expr const & e,
|
|||
expr new_e = std::get<0>(elab(g, ios.get_options(), e, none_expr(), s.get_subst(), false));
|
||||
auto tc = mk_type_checker(env);
|
||||
expr new_t = tc->infer(new_e).first;
|
||||
auto out = regular(env, ios);
|
||||
flycheck_information info(out);
|
||||
auto out = regular(env, ios, tc->get_type_context());
|
||||
flycheck_information info(out.get_stream(), out.get_options());
|
||||
if (info.enabled()) {
|
||||
out << fname << ":" << pos.first << ":" << pos.second << ": information: ";
|
||||
out << "check result:\n";
|
||||
|
|
|
@ -70,7 +70,8 @@ tactic contradiction_tactic() {
|
|||
}
|
||||
}
|
||||
} catch (kernel_exception & ex) {
|
||||
regular(env, ios) << ex << "\n";
|
||||
// TODO(Leo)
|
||||
// regular(env, ios) << ex << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,11 +62,6 @@ format proof_state::pp(formatter const & fmt) const {
|
|||
return pp_core([&]() { return fmt; }, fmt.get_options());
|
||||
}
|
||||
|
||||
format proof_state::pp(environment const & env, io_state const & ios) const {
|
||||
return pp_core([&]() { return ios.get_formatter_factory()(env, ios.get_options()); },
|
||||
ios.get_options());
|
||||
}
|
||||
|
||||
goals map_goals(proof_state const & s, std::function<optional<goal>(goal const & g)> f) {
|
||||
return map_filter<goal>(s.get_goals(), [=](goal const & in, goal & out) -> bool {
|
||||
check_interrupted();
|
||||
|
|
|
@ -55,12 +55,6 @@ public:
|
|||
/** \brief Return true iff this state does not have any goals left */
|
||||
bool is_final_state() const { return empty(m_goals); }
|
||||
|
||||
/** \remark This pretty printing method creates a fresh formatter object for each goal.
|
||||
Some format objects "purify" local constant names by renaming.
|
||||
The local constants in different goals are independent of each other.
|
||||
So, this trick/hack avoids "unwanted purification".
|
||||
*/
|
||||
format pp(environment const & env, io_state const & ios) const;
|
||||
format pp(formatter const & fmt) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -1283,7 +1283,7 @@ class rewrite_fn {
|
|||
return unify_result();
|
||||
}
|
||||
} catch (kernel_exception & ex) {
|
||||
regular(m_env, m_ios) << ">> " << ex << "\n";
|
||||
regular(m_env, m_ios, m_tc->get_type_context()) << ">> " << ex << "\n";
|
||||
add_target_failure(orig_elem, t, ex.what());
|
||||
return unify_result();
|
||||
} catch (exception & ex) {
|
||||
|
|
|
@ -32,8 +32,10 @@ tactic trace_tactic(char const * msg) {
|
|||
|
||||
tactic trace_state_tactic(std::string const & fname, pair<unsigned, unsigned> const & pos) {
|
||||
return tactic1([=](environment const & env, io_state const & ios, proof_state const & s) -> proof_state {
|
||||
diagnostic(env, ios) << fname << ":" << pos.first << ":" << pos.second << ": proof state\n"
|
||||
<< s.pp(env, ios) << endl;
|
||||
type_checker tc(env);
|
||||
auto out = diagnostic(env, ios, tc.get_type_context());
|
||||
out << fname << ":" << pos.first << ":" << pos.second << ": proof state\n"
|
||||
<< s.pp(out.get_formatter()) << endl;
|
||||
ios.get_diagnostic_channel().get_stream().flush();
|
||||
return s;
|
||||
});
|
||||
|
@ -41,7 +43,9 @@ tactic trace_state_tactic(std::string const & fname, pair<unsigned, unsigned> co
|
|||
|
||||
tactic trace_state_tactic() {
|
||||
return tactic1([=](environment const & env, io_state const & ios, proof_state const & s) -> proof_state {
|
||||
diagnostic(env, ios) << "proof state\n" << s.pp(env, ios) << endl;
|
||||
type_checker tc(env);
|
||||
auto out = diagnostic(env, ios, tc.get_type_context());
|
||||
out << "proof state\n" << s.pp(out.get_formatter()) << endl;
|
||||
ios.get_diagnostic_channel().get_stream().flush();
|
||||
return s;
|
||||
});
|
||||
|
|
|
@ -7,6 +7,7 @@ Author: Leonardo de Moura
|
|||
#include <vector>
|
||||
#include "util/sexpr/option_declarations.h"
|
||||
#include "kernel/environment.h"
|
||||
#include "kernel/type_checker.h"
|
||||
#include "library/io_state.h"
|
||||
#include "library/trace.h"
|
||||
|
||||
|
@ -16,8 +17,9 @@ static name_map<name_set> * g_trace_aliases = nullptr;
|
|||
MK_THREAD_LOCAL_GET_DEF(std::vector<name>, get_enabled_trace_classes);
|
||||
MK_THREAD_LOCAL_GET_DEF(std::vector<name>, get_disabled_trace_classes);
|
||||
MK_THREAD_LOCAL_GET_DEF(environment, get_dummy_env);
|
||||
LEAN_THREAD_PTR(environment, g_env);
|
||||
LEAN_THREAD_PTR(io_state, g_ios);
|
||||
LEAN_THREAD_PTR(environment, g_env);
|
||||
LEAN_THREAD_PTR(io_state, g_ios);
|
||||
LEAN_THREAD_PTR(abstract_type_context, g_ctx);
|
||||
LEAN_THREAD_VALUE(unsigned, g_depth, 0);
|
||||
|
||||
void register_trace_class(name const & n) {
|
||||
|
@ -44,7 +46,6 @@ static void update_class(std::vector<name> & cs, name const & c) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void enable_trace_class(name const & c) {
|
||||
update_class(get_enabled_trace_classes(), c);
|
||||
}
|
||||
|
@ -90,13 +91,15 @@ bool is_trace_class_enabled(name const & n) {
|
|||
return is_trace_class_set(get_enabled_trace_classes(), n);
|
||||
}
|
||||
|
||||
scope_trace_env::scope_trace_env(environment const & env, io_state const & ios) {
|
||||
scope_trace_env::scope_trace_env(environment const & env, io_state const & ios, abstract_type_context & ctx) {
|
||||
m_enable_sz = get_enabled_trace_classes().size();
|
||||
m_disable_sz = get_disabled_trace_classes().size();
|
||||
m_old_env = g_env;
|
||||
m_old_ios = g_ios;
|
||||
m_old_ctx = g_ctx;
|
||||
g_env = const_cast<environment*>(&env);
|
||||
g_ios = const_cast<io_state*>(&ios);
|
||||
g_ctx = &ctx;
|
||||
options const & opts = ios.get_options();
|
||||
name trace("trace");
|
||||
opts.for_each([&](name const & n) {
|
||||
|
@ -113,6 +116,7 @@ scope_trace_env::scope_trace_env(environment const & env, io_state const & ios)
|
|||
scope_trace_env::~scope_trace_env() {
|
||||
g_env = const_cast<environment*>(m_old_env);
|
||||
g_ios = const_cast<io_state*>(m_old_ios);
|
||||
g_ctx = m_old_ctx;
|
||||
get_enabled_trace_classes().resize(m_enable_sz);
|
||||
get_disabled_trace_classes().resize(m_disable_sz);
|
||||
}
|
||||
|
@ -154,6 +158,7 @@ struct silent_ios_helper {
|
|||
};
|
||||
|
||||
MK_THREAD_LOCAL_GET_DEF(silent_ios_helper, get_silent_ios_helper);
|
||||
MK_THREAD_LOCAL_GET(type_checker, get_dummy_tc, get_dummy_env());
|
||||
|
||||
scope_trace_silent::scope_trace_silent(bool flag) {
|
||||
m_old_ios = g_ios;
|
||||
|
@ -167,9 +172,9 @@ scope_trace_silent::~scope_trace_silent() {
|
|||
|
||||
io_state_stream tout() {
|
||||
if (g_env) {
|
||||
return diagnostic(*g_env, *g_ios);
|
||||
return diagnostic(*g_env, *g_ios, *g_ctx);
|
||||
} else {
|
||||
return diagnostic(get_dummy_env(), get_silent_ios_helper().m_ios);
|
||||
return diagnostic(get_dummy_env(), get_silent_ios_helper().m_ios, get_dummy_tc().get_type_context());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,12 +17,13 @@ bool is_trace_class_enabled(name const & n);
|
|||
#define lean_is_trace_enabled(CName) (::lean::is_trace_enabled() && ::lean::is_trace_class_enabled(CName))
|
||||
|
||||
class scope_trace_env {
|
||||
unsigned m_enable_sz;
|
||||
unsigned m_disable_sz;
|
||||
environment const * m_old_env;
|
||||
io_state const * m_old_ios;
|
||||
unsigned m_enable_sz;
|
||||
unsigned m_disable_sz;
|
||||
environment const * m_old_env;
|
||||
io_state const * m_old_ios;
|
||||
abstract_type_context * m_old_ctx;
|
||||
public:
|
||||
scope_trace_env(environment const & env, io_state const & ios);
|
||||
scope_trace_env(environment const & env, io_state const & ios, abstract_type_context & ctx);
|
||||
~scope_trace_env();
|
||||
};
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ Author: Leonardo de Moura
|
|||
#include "util/fresh_name.h"
|
||||
#include "util/scoped_map.h"
|
||||
#include "kernel/environment.h"
|
||||
#include "kernel/abstract_type_context.h"
|
||||
#include "library/io_state.h"
|
||||
#include "library/io_state_stream.h"
|
||||
#include "library/projection.h"
|
||||
|
@ -107,7 +108,7 @@ bool get_class_trans_instances(options const & o);
|
|||
2- (all temporary local constants created by auxiliary procedure) Example: simplifier goes inside of a lambda.
|
||||
3- (all internal local constants created by type_context) Example: when processing is_def_eq.
|
||||
*/
|
||||
class type_context {
|
||||
class type_context : public abstract_type_context {
|
||||
struct ext_ctx;
|
||||
friend struct ext_ctx;
|
||||
environment m_env;
|
||||
|
|
|
@ -1269,7 +1269,7 @@ struct unifier_fn {
|
|||
void display(std::ostream & out, justification const & j, unsigned indent = 0) {
|
||||
for (unsigned i = 0; i < indent; i++)
|
||||
out << " ";
|
||||
out << j.pp(mk_print_formatter_factory()(m_env, options()), nullptr, m_subst) << "\n";
|
||||
out << j.pp(mk_print_formatter_factory()(m_env, options(), m_tc->get_type_context()), nullptr, m_subst) << "\n";
|
||||
if (j.is_composite()) {
|
||||
display(out, composite_child1(j), indent+2);
|
||||
display(out, composite_child2(j), indent+2);
|
||||
|
|
|
@ -7,6 +7,7 @@ Author: Leonardo de Moura
|
|||
#include <string>
|
||||
#include "library/module.h"
|
||||
#include "library/standard_kernel.h"
|
||||
#include "library/type_context.h"
|
||||
#include "library/error_handling.h"
|
||||
#include "frontends/lean/pp.h"
|
||||
#include "frontends/lean/parser.h"
|
||||
|
@ -36,7 +37,9 @@ public:
|
|||
env = import_modules(env, base, 1, &mod, num_threads, keep_proofs, ios);
|
||||
} catch (lean::exception & ex) {
|
||||
simple_pos_info_provider pp("import_module");
|
||||
lean::display_error(diagnostic(env, ios), &pp, ex);
|
||||
default_type_context tc(env, ios.get_options());
|
||||
auto out = diagnostic(env, ios, tc);
|
||||
lean::display_error(out, &pp, ex);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -53,7 +56,9 @@ public:
|
|||
} catch (lean::exception & ex) {
|
||||
simple_pos_info_provider pp(input_filename.c_str());
|
||||
ok = false;
|
||||
lean::display_error(diagnostic(env, ios), &pp, ex);
|
||||
default_type_context tc(env, ios.get_options());
|
||||
auto out = diagnostic(env, ios, tc);
|
||||
lean::display_error(out, &pp, ex);
|
||||
}
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
|
|
@ -23,11 +23,13 @@ Author: Leonardo de Moura
|
|||
#include "util/sexpr/option_declarations.h"
|
||||
#include "kernel/environment.h"
|
||||
#include "kernel/kernel_exception.h"
|
||||
#include "kernel/type_checker.h"
|
||||
#include "kernel/formatter.h"
|
||||
#include "library/standard_kernel.h"
|
||||
#include "library/hott_kernel.h"
|
||||
#include "library/module.h"
|
||||
#include "library/flycheck.h"
|
||||
#include "library/type_context.h"
|
||||
#include "library/io_state_stream.h"
|
||||
#include "library/definition_cache.h"
|
||||
#include "library/declaration_index.h"
|
||||
|
@ -63,6 +65,8 @@ using lean::module_name;
|
|||
using lean::simple_pos_info_provider;
|
||||
using lean::shared_file_lock;
|
||||
using lean::exclusive_file_lock;
|
||||
using lean::default_type_context;
|
||||
using lean::type_checker;
|
||||
|
||||
enum class input_kind { Unspecified, Lean, HLean, Trace };
|
||||
|
||||
|
@ -452,15 +456,15 @@ int main(int argc, char ** argv) {
|
|||
cache.load(in);
|
||||
} catch (lean::throwable & ex) {
|
||||
cache_ptr = nullptr;
|
||||
auto out = regular(env, ios);
|
||||
// I'm using flycheck_error instead off flycheck_warning because
|
||||
// the :error-patterns at lean-flycheck.el do not work after
|
||||
// I add a rule for FLYCHECK_WARNING.
|
||||
// Same for display_error_pos vs display_warning_pos.
|
||||
lean::flycheck_error warn(out);
|
||||
lean::flycheck_error warn(ios);
|
||||
if (optind < argc)
|
||||
display_error_pos(out, argv[optind], 1, 0);
|
||||
out << "failed to load cache file '" << cache_name << "', "
|
||||
display_error_pos(ios.get_regular_stream(), ios.get_options(), argv[optind], 1, 0);
|
||||
ios.get_regular_stream()
|
||||
<< "failed to load cache file '" << cache_name << "', "
|
||||
<< ex.what() << ". cache is going to be ignored\n";
|
||||
}
|
||||
}
|
||||
|
@ -503,7 +507,9 @@ int main(int argc, char ** argv) {
|
|||
} catch (lean::exception & ex) {
|
||||
simple_pos_info_provider pp(argv[i]);
|
||||
ok = false;
|
||||
lean::display_error(diagnostic(env, ios), &pp, ex);
|
||||
default_type_context tc(env, ios.get_options());
|
||||
auto out = diagnostic(env, ios, tc);
|
||||
lean::display_error(out, &pp, ex);
|
||||
}
|
||||
}
|
||||
if (ok && server && (default_k == input_kind::Lean || default_k == input_kind::HLean)) {
|
||||
|
@ -522,7 +528,9 @@ int main(int argc, char ** argv) {
|
|||
exclusive_file_lock index_lock(index_name);
|
||||
std::shared_ptr<lean::file_output_channel> out(new lean::file_output_channel(index_name.c_str()));
|
||||
ios.set_regular_channel(out);
|
||||
index.save(regular(env, ios));
|
||||
type_checker tc(env);
|
||||
auto strm = regular(env, ios, tc.get_type_context());
|
||||
index.save(strm);
|
||||
}
|
||||
if (export_objects && ok) {
|
||||
exclusive_file_lock output_lock(output);
|
||||
|
@ -541,7 +549,9 @@ int main(int argc, char ** argv) {
|
|||
}
|
||||
return ok ? 0 : 1;
|
||||
} catch (lean::throwable & ex) {
|
||||
lean::display_error(diagnostic(env, ios), nullptr, ex);
|
||||
default_type_context tc(env, ios.get_options());
|
||||
auto out = diagnostic(env, ios, tc);
|
||||
lean::display_error(out, nullptr, ex);
|
||||
} catch (std::bad_alloc & ex) {
|
||||
std::cerr << "out of memory" << std::endl;
|
||||
return 1;
|
||||
|
|
|
@ -23,10 +23,6 @@ static environment add_decl(environment const & env, declaration const & d) {
|
|||
return env.add(cd);
|
||||
}
|
||||
|
||||
formatter mk_formatter(environment const & env) {
|
||||
return mk_print_formatter_factory()(env, options());
|
||||
}
|
||||
|
||||
static void tst1() {
|
||||
environment env1;
|
||||
auto env2 = add_decl(env1, mk_definition("Prop", level_param_names(), mk_Type(), mk_Prop()));
|
||||
|
@ -37,31 +33,31 @@ static void tst1() {
|
|||
auto env3 = add_decl(env2, mk_definition("Prop", level_param_names(), mk_Type(), mk_Prop()));
|
||||
lean_unreachable();
|
||||
} catch (kernel_exception & ex) {
|
||||
std::cout << "expected error: " << ex.pp(mk_formatter(ex.get_environment())) << "\n";
|
||||
std::cout << "expected error: " << ex.what() << "\n";
|
||||
}
|
||||
try {
|
||||
auto env4 = add_decl(env2, mk_definition("BuggyProp", level_param_names(), mk_Prop(), mk_Prop()));
|
||||
lean_unreachable();
|
||||
} catch (kernel_exception & ex) {
|
||||
std::cout << "expected error: " << ex.pp(mk_formatter(ex.get_environment())) << "\n";
|
||||
std::cout << "expected error: " << ex.what() << "\n";
|
||||
}
|
||||
try {
|
||||
auto env5 = add_decl(env2, mk_definition("Type1", level_param_names(), mk_metavar("T", mk_sort(mk_meta_univ("l"))), mk_Type()));
|
||||
lean_unreachable();
|
||||
} catch (kernel_exception & ex) {
|
||||
std::cout << "expected error: " << ex.pp(mk_formatter(ex.get_environment())) << "\n";
|
||||
std::cout << "expected error: " << ex.what() << "\n";
|
||||
}
|
||||
try {
|
||||
auto env6 = add_decl(env2, mk_definition("Type1", level_param_names(), mk_Type(), mk_metavar("T", mk_sort(mk_meta_univ("l")))));
|
||||
lean_unreachable();
|
||||
} catch (kernel_exception & ex) {
|
||||
std::cout << "expected error: " << ex.pp(mk_formatter(ex.get_environment())) << "\n";
|
||||
std::cout << "expected error: " << ex.what() << "\n";
|
||||
}
|
||||
try {
|
||||
auto env7 = add_decl(env2, mk_definition("foo", level_param_names(), mk_Type() >> mk_Type(), mk_Prop()));
|
||||
lean_unreachable();
|
||||
} catch (kernel_exception & ex) {
|
||||
std::cout << "expected error: " << ex.pp(mk_formatter(ex.get_environment())) << "\n";
|
||||
std::cout << "expected error: " << ex.what() << "\n";
|
||||
}
|
||||
expr Type = mk_Type();
|
||||
expr A = Local("A", Type);
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
import data.list
|
||||
|
||||
#congr_simp @add
|
||||
#congr_simp @ite
|
||||
#congr_simp @perm
|
||||
|
||||
|
||||
section
|
||||
variables p : nat → Prop
|
||||
variables q : nat → nat → Prop
|
||||
variables f : Π (x y : nat), p x → q x y → nat
|
||||
|
||||
#congr_simp f
|
||||
end
|
||||
|
||||
constant p : Π {A : Type}, A → Prop
|
||||
constant q : Π {A : Type} (n m : A), p n → p m → Prop
|
||||
constant r : Π {A : Type} (n m : A) (H₁ : p n) (H₂ : p m), q n m H₁ H₂ → Prop
|
||||
constant h : Π (A : Type) (n m : A)
|
||||
(H₁ : p n) (H₂ : p m) (H₃ : q n n H₁ H₁) (H₄ : q n m H₁ H₂)
|
||||
(H₅ : r n m H₁ H₂ H₄) (H₆ : r n n H₁ H₁ H₃), A
|
||||
|
||||
#congr_simp h
|
|
@ -1,39 +0,0 @@
|
|||
[fixed, fixed, eq, eq]
|
||||
λ (A : Type) (s : has_add A) (a a_1 : A) (e_3 : a = a_1) (a_2 a_3 : A) (e_4 : a_2 = a_3), congr (congr_arg add e_3) e_4
|
||||
:
|
||||
∀ (A : Type) (s : has_add A) (a a_1 : A), a = a_1 → (∀ (a_2 a_3 : A), a_2 = a_3 → a + a_2 = a_1 + a_3)
|
||||
[eq, cast, fixed, eq, eq]
|
||||
λ (c c_1 : Prop) (e_1 : c = c_1) (H : decidable c) (A : Type) (t t_1 : A) (e_4 : t = t_1) (e e_2 : A) (e_5 : e = e_2),
|
||||
eq.drec (eq.drec (eq.drec (eq.refl (ite c t e)) e_5) e_4) e_1
|
||||
:
|
||||
∀ (c c_1 : Prop) (e_1 : c = c_1) (H : decidable c) (A : Type) (t t_1 : A),
|
||||
t = t_1 → (∀ (e e_2 : A), e = e_2 → ite c t e = ite c_1 t_1 e_2)
|
||||
[fixed, eq, eq]
|
||||
λ (A : Type) (a a_1 : list A) (e_2 : a = a_1) (a_2 a_3 : list A) (e_3 : a_2 = a_3), congr (congr_arg perm e_2) e_3
|
||||
:
|
||||
∀ (A : Type) (a a_1 : list A), a = a_1 → (∀ (a_2 a_3 : list A), a_2 = a_3 → perm a a_2 = perm a_1 a_3)
|
||||
[eq, eq, cast, cast]
|
||||
λ (x x_1 : ℕ) (e_1 : x = x_1) (y y_1 : ℕ) (e_2 : y = y_1) (a : p x) (a_1 : q x y),
|
||||
eq.drec (eq.drec (eq.refl (f x y (eq.rec a (eq.refl x)) (eq.rec (eq.rec a_1 (eq.refl y)) (eq.refl x)))) e_2) e_1
|
||||
:
|
||||
∀ (x x_1 : ℕ) (e_1 : x = x_1) (y y_1 : ℕ) (e_2 : y = y_1) (a : p x) (a_1 : q x y),
|
||||
f x y a a_1 = f x_1 y_1 (eq.rec a e_1) (eq.rec (eq.rec a_1 e_2) e_1)
|
||||
[fixed, eq, eq, cast, cast, cast, cast, cast, cast]
|
||||
λ (A : Type) (n n_1 : A) (e_2 : n = n_1) (m m_1 : A) (e_3 : m = m_1) (H₁ : p n) (H₂ : p m) (H₃ : q n n H₁ H₁)
|
||||
(H₄ : q n m H₁ H₂) (H₅ : r n m H₁ H₂ H₄) (H₆ : r n n H₁ H₁ H₃),
|
||||
eq.drec
|
||||
(eq.drec
|
||||
(eq.refl
|
||||
(h A n m (eq.rec H₁ (eq.refl n)) (eq.rec H₂ (eq.refl m)) (eq.drec H₃ (eq.refl n))
|
||||
(eq.drec (eq.drec H₄ (eq.refl m)) (eq.refl n))
|
||||
(eq.drec (eq.drec H₅ (eq.refl m)) (eq.refl n))
|
||||
(eq.drec H₆ (eq.refl n))))
|
||||
e_3)
|
||||
e_2
|
||||
:
|
||||
∀ (A : Type) (n n_1 : A) (e_2 : n = n_1) (m m_1 : A) (e_3 : m = m_1) (H₁ : p n) (H₂ : p m)
|
||||
(H₃ : q n n H₁ H₁) (H₄ : q n m H₁ H₂) (H₅ : r n m H₁ H₂ H₄) (H₆ : r n n H₁ H₁ H₃),
|
||||
h A n m H₁ H₂ H₃ H₄ H₅ H₆ = h A n_1 m_1 (eq.rec H₁ e_2) (eq.rec H₂ e_3) (eq.drec H₃ e_2)
|
||||
(eq.drec (eq.drec H₄ e_3) e_2)
|
||||
(eq.drec (eq.drec H₅ e_3) e_2)
|
||||
(eq.drec H₆ e_2)
|
|
@ -1,23 +0,0 @@
|
|||
import data.list
|
||||
|
||||
#congr @add
|
||||
#congr @perm
|
||||
|
||||
section
|
||||
variables p : nat → Prop
|
||||
variables q : nat → nat → Prop
|
||||
variables f : Π (x y : nat), p x → q x y → nat
|
||||
|
||||
#congr f
|
||||
end
|
||||
|
||||
constant p : Π {A : Type}, A → Prop
|
||||
constant q : Π {A : Type} (n m : A), p n → p m → Prop
|
||||
constant r : Π {A : Type} (n m : A) (H₁ : p n) (H₂ : p m), q n m H₁ H₂ → Prop
|
||||
constant h : Π (A : Type) (n m : A)
|
||||
(H₁ : p n) (H₂ : p m) (H₃ : q n n H₁ H₁) (H₄ : q n m H₁ H₂)
|
||||
(H₅ : r n m H₁ H₂ H₄) (H₆ : r n n H₁ H₁ H₃), A
|
||||
|
||||
#congr h
|
||||
|
||||
#congr @ite
|
|
@ -1,50 +0,0 @@
|
|||
[fixed, fixed, eq, eq]
|
||||
λ (A : Type) (s : has_add A) (a a_1 : A) (e_3 : a = a_1) (a_2 a_3 : A) (e_4 : a_2 = a_3), congr (congr_arg add e_3) e_4
|
||||
:
|
||||
∀ (A : Type) (s : has_add A) (a a_1 : A), a = a_1 → (∀ (a_2 a_3 : A), a_2 = a_3 → a + a_2 = a_1 + a_3)
|
||||
[fixed, eq, eq]
|
||||
λ (A : Type) (a a_1 : list A) (e_2 : a = a_1) (a_2 a_3 : list A) (e_3 : a_2 = a_3), congr (congr_arg perm e_2) e_3
|
||||
:
|
||||
∀ (A : Type) (a a_1 : list A), a = a_1 → (∀ (a_2 a_3 : list A), a_2 = a_3 → perm a a_2 = perm a_1 a_3)
|
||||
[eq, eq, cast, cast]
|
||||
λ (x x_1 : ℕ) (e_1 : x = x_1) (y y_1 : ℕ) (e_2 : y = y_1) (a : p x) (a_1 : p x_1) (a_1 : q x y) (a_2 : q x_1 y_1),
|
||||
eq.drec (eq.drec (eq.refl (f x y (eq.rec a (eq.refl x)) (eq.rec (eq.rec a_1 (eq.refl y)) (eq.refl x)))) e_2) e_1
|
||||
:
|
||||
∀ (x x_1 : ℕ),
|
||||
x = x_1 →
|
||||
(∀ (y y_1 : ℕ),
|
||||
y = y_1 → (∀ (a : p x) (a_1 : p x_1) (a_2 : q x y) (a_3 : q x_1 y_1), f x y a a_2 = f x_1 y_1 a_1 a_3))
|
||||
[fixed, eq, eq, cast, cast, cast, cast, cast, cast]
|
||||
λ (A : Type) (n n_1 : A) (e_2 : n = n_1) (m m_1 : A) (e_3 : m = m_1) (H₁ : p n) (H₁_1 : p n_1) (H₂ : p m)
|
||||
(H₂_1 : p m_1) (H₃ : q n n H₁ H₁) (H₃_1 : q n_1 n_1 H₁_1 H₁_1) (H₄ : q n m H₁ H₂)
|
||||
(H₄_1 : q n_1 m_1 H₁_1 H₂_1) (H₅ : r n m H₁ H₂ H₄) (H₅_1 : r n_1 m_1 H₁_1 H₂_1 H₄_1)
|
||||
(H₆ : r n n H₁ H₁ H₃) (H₆_1 : r n_1 n_1 H₁_1 H₁_1 H₃_1),
|
||||
eq.drec
|
||||
(eq.drec
|
||||
(eq.refl
|
||||
(h A n m (eq.rec H₁ (eq.refl n)) (eq.rec H₂ (eq.refl m)) (eq.drec H₃ (eq.refl n))
|
||||
(eq.drec (eq.drec H₄ (eq.refl m)) (eq.refl n))
|
||||
(eq.drec (eq.drec H₅ (eq.refl m)) (eq.refl n))
|
||||
(eq.drec H₆ (eq.refl n))))
|
||||
e_3)
|
||||
e_2
|
||||
:
|
||||
∀ (A : Type) (n n_1 : A),
|
||||
n = n_1 →
|
||||
(∀ (m m_1 : A),
|
||||
m = m_1 →
|
||||
(∀ (H₁ : p n) (H₁_1 : p n_1) (H₂ : p m) (H₂_1 : p m_1) (H₃ : q n n H₁ H₁)
|
||||
(H₃_1 : q n_1 n_1 H₁_1 H₁_1) (H₄ : q n m H₁ H₂) (H₄_1 : q n_1 m_1 H₁_1 H₂_1)
|
||||
(H₅ : r n m H₁ H₂ H₄) (H₅_1 : r n_1 m_1 H₁_1 H₂_1 H₄_1) (H₆ : r n n H₁ H₁ H₃)
|
||||
(H₆_1 : r n_1 n_1 H₁_1 H₁_1 H₃_1),
|
||||
h A n m H₁ H₂ H₃ H₄ H₅ H₆ = h A n_1 m_1 H₁_1 H₂_1 H₃_1 H₄_1 H₅_1 H₆_1))
|
||||
[eq, cast, fixed, eq, eq]
|
||||
λ (c c_1 : Prop) (e_1 : c = c_1) (H : decidable c) (H_1 : decidable c_1) (A : Type) (t t_1 : A) (e_4 : t = t_1)
|
||||
(e e_2 : A) (e_5 : e = e_2),
|
||||
eq.trans (eq.drec (eq.drec (eq.drec (eq.refl (ite c t e)) e_5) e_4) e_1)
|
||||
(congr_fun (congr_fun (congr_fun (congr (eq.refl (ite c_1)) (subsingleton.elim (eq.rec H e_1) H_1)) A) t_1) e_2)
|
||||
:
|
||||
∀ (c c_1 : Prop),
|
||||
c = c_1 →
|
||||
(∀ (H : decidable c) (H_1 : decidable c_1) (A : Type) (t t_1 : A),
|
||||
t = t_1 → (∀ (e e_1 : A), e = e_1 → ite c t e = ite c_1 t_1 e_1))
|
|
@ -1,6 +0,0 @@
|
|||
constant P : Type₁
|
||||
constant P_sub : subsingleton P
|
||||
attribute P_sub [instance]
|
||||
constant q : P → Prop
|
||||
|
||||
#congr q
|
|
@ -1,4 +0,0 @@
|
|||
[cast]
|
||||
λ (a a_1 : P), eq.trans (eq.refl (q a)) (congr (eq.refl q) (subsingleton.elim a a_1))
|
||||
:
|
||||
∀ (a a_1 : P), q a = q a_1
|
|
@ -1,7 +0,0 @@
|
|||
import data.list
|
||||
open perm
|
||||
|
||||
#congr_rel @eq
|
||||
#congr_rel @iff
|
||||
#congr_rel @perm
|
||||
#congr_rel @heq
|
|
@ -1,24 +0,0 @@
|
|||
[fixed, eq, eq]
|
||||
λ (A : Type) (a a_1 : A) (H1 : a = a_1) (a_2 a_3 : A) (H2 : a_2 = a_3),
|
||||
iff.intro (λ (x : a = a_2), eq.trans (eq.symm H1) (eq.trans x H2))
|
||||
(λ (x : a_1 = a_3), eq.trans H1 (eq.trans x (eq.symm H2)))
|
||||
:
|
||||
∀ (A : Type) (a a_1 : A), a = a_1 → (∀ (a_2 a_3 : A), a_2 = a_3 → (a = a_2 ↔ a_1 = a_3))
|
||||
[eq, eq]
|
||||
λ (a a_1 : Prop) (H1 : a ↔ a_1) (b b_1 : Prop) (H2 : b ↔ b_1),
|
||||
iff.intro (λ (x : a ↔ b), iff.trans (iff.symm H1) (iff.trans x H2))
|
||||
(λ (x : a_1 ↔ b_1), iff.trans H1 (iff.trans x (iff.symm H2)))
|
||||
:
|
||||
∀ (a a_1 : Prop), (a ↔ a_1) → (∀ (b b_1 : Prop), (b ↔ b_1) → (a ↔ b ↔ (a_1 ↔ b_1)))
|
||||
[fixed, eq, eq]
|
||||
λ (A : Type) (a a_1 : list A) (H1 : a ~ a_1) (a_2 a_3 : list A) (H2 : a_2 ~ a_3),
|
||||
iff.intro (λ (x : a ~ a_2), trans (perm.symm H1) (trans x H2))
|
||||
(λ (x : a_1 ~ a_3), trans H1 (trans x (perm.symm H2)))
|
||||
:
|
||||
∀ (A : Type) (a a_1 : list A), a ~ a_1 → (∀ (a_2 a_3 : list A), a_2 ~ a_3 → (a ~ a_2 ↔ a_1 ~ a_3))
|
||||
[fixed, eq, fixed, eq]
|
||||
λ (A : Type) (a a_1 : A) (H1 : a == a_1) (B : Type) (a_2 a_3 : B) (H2 : a_2 == a_3),
|
||||
iff.intro (λ (x : a == a_2), heq.trans (heq.symm H1) (heq.trans x H2))
|
||||
(λ (x : a_1 == a_3), heq.trans H1 (heq.trans x (heq.symm H2)))
|
||||
:
|
||||
∀ (A : Type) (a a_1 : A), a == a_1 → (∀ (B : Type) (a_2 a_3 : B), a_2 == a_3 → (a == a_2 ↔ a_1 == a_3))
|
|
@ -1,16 +0,0 @@
|
|||
-- check @eq.rec
|
||||
-- universe variable l_1
|
||||
-- variables {A A' : Type.{l_1}} {e_1 : A = A'} {a : A}
|
||||
-- check @eq.rec.{l_1 l_1+1} Type.{l_1} A (fun (A' : Type.{l_1}) (e_1 : A = A'), A') a A' e_1
|
||||
open nat
|
||||
|
||||
inductive vec (A : Type) : nat → Type :=
|
||||
| nil {} : vec A zero
|
||||
| cons : Π {n}, A → vec A n → vec A (succ n)
|
||||
|
||||
structure S (A : Type) (a : A) (n : nat) (v : vec A n) :=
|
||||
mk :: (fa : A)
|
||||
|
||||
set_option pp.implicit true
|
||||
|
||||
#telescope_eq Π (A : Type) (a : A) (b : A) (c : nat) (d : vec A c) (e : S A a c d), nat
|
|
@ -1,25 +0,0 @@
|
|||
import logic
|
||||
|
||||
inductive vector (T : Type) : nat → Type :=
|
||||
| nil {} : vector T nat.zero
|
||||
| cons : T → ∀{n}, vector T n → vector T (nat.succ n)
|
||||
|
||||
#projections or
|
||||
#projections and
|
||||
#projections eq.refl
|
||||
#projections eq
|
||||
#projections vector
|
||||
|
||||
inductive point :=
|
||||
mk : nat → nat → point
|
||||
|
||||
#projections point :: x y z
|
||||
|
||||
#projections point :: x y
|
||||
|
||||
#projections point :: x y
|
||||
|
||||
inductive funny : nat → Type :=
|
||||
mk : Π (a : nat), funny a
|
||||
|
||||
#projections funny
|
|
@ -1,7 +0,0 @@
|
|||
proj.lean:7:0: error: projection generation, 'or' does not have a single constructor
|
||||
proj.lean:9:0: error: projection generation, 'eq.refl' is not an inductive datatype
|
||||
proj.lean:10:0: error: projection generation, 'eq' is an indexed inductive datatype family
|
||||
proj.lean:11:0: error: projection generation, 'vector' is an indexed inductive datatype family
|
||||
proj.lean:16:0: error: generating projection 'point.z', 'point' does not have sufficient data
|
||||
proj.lean:20:0: error: invalid object declaration, environment already has an object named 'point.x'
|
||||
proj.lean:25:0: error: projection generation, 'funny' is an indexed inductive datatype family
|
|
@ -1,24 +0,0 @@
|
|||
import algebra.ring
|
||||
|
||||
variables a b c : nat
|
||||
variables H1 : a = b
|
||||
variables H2 : b = c
|
||||
set_option pp.all true
|
||||
|
||||
#app_builder eq.refl a
|
||||
#app_builder eq.trans H1, H2
|
||||
#app_builder eq.symm H1
|
||||
|
||||
open algebra nat
|
||||
universe l
|
||||
constant A : Type.{l}
|
||||
constant s : comm_ring A
|
||||
attribute s [instance]
|
||||
variables x y : A
|
||||
|
||||
#app_builder eq.refl s
|
||||
#app_builder eq.refl x
|
||||
#app_builder add x, y
|
||||
#app_builder add a, b
|
||||
#app_builder mul a, b
|
||||
#app_builder sub x, y
|
|
@ -1,24 +0,0 @@
|
|||
import data.list
|
||||
open perm
|
||||
variables a b c : nat
|
||||
variables H1 : a = b
|
||||
variables H2 : b = c
|
||||
set_option pp.all true
|
||||
variables p q r : Prop
|
||||
variables l1 l2 l3 : list nat
|
||||
variables H3 : p ↔ q
|
||||
variables H4 : q ↔ r
|
||||
variables H5 : l1 ~ l2
|
||||
variables H6 : l2 ~ l3
|
||||
|
||||
#refl eq a
|
||||
#refl iff p
|
||||
#refl perm l1
|
||||
|
||||
#symm eq H1
|
||||
#symm iff H3
|
||||
#symm perm H5
|
||||
|
||||
#trans eq H1, H2
|
||||
#trans iff H3, H4
|
||||
#trans perm H5, H6
|
|
@ -1,7 +0,0 @@
|
|||
constant f : ∀ (A : Type) (a b c : A), a = c → A
|
||||
|
||||
variables a b c : nat
|
||||
variables H : a = b
|
||||
|
||||
#app_builder f [false, false, true, false, true] c, H
|
||||
#app_builder f [false, true, true, false, true] a, c, H
|
|
@ -1,16 +0,0 @@
|
|||
import data.list
|
||||
|
||||
constants f : nat → nat → nat
|
||||
constants a b : nat
|
||||
axiom H2 : a = b
|
||||
set_option pp.all true
|
||||
|
||||
#app_builder congr (eq.refl (f a)), H2
|
||||
|
||||
constants g : ∀ {A :Type}, A → A → A
|
||||
variables A : Type
|
||||
variables l₁ l₂ l₃: list A
|
||||
variables H : l₂ = l₃
|
||||
|
||||
#app_builder congr (eq.refl (g l₁)), H
|
||||
#app_builder congr_arg (g l₁), H
|
|
@ -1,6 +0,0 @@
|
|||
import data.tuple
|
||||
|
||||
#hcongr @tuple.append
|
||||
#hcongr @add
|
||||
#hcongr @list.ith
|
||||
#hcongr (@list.ith nat)
|
|
@ -1,18 +0,0 @@
|
|||
import logic.eq
|
||||
|
||||
inductive sigma2 {A : Type} (B : A → Type) :=
|
||||
mk : Π (a : A), B a → sigma2 B
|
||||
|
||||
#projections sigma2 :: proj1 proj2
|
||||
|
||||
check sigma2.proj1
|
||||
check sigma2.proj2
|
||||
|
||||
variables {A : Type} {B : A → Type}
|
||||
variables (a : A) (b : B a)
|
||||
|
||||
theorem tst1 : sigma2.proj1 (sigma2.mk a b) = a :=
|
||||
rfl
|
||||
|
||||
theorem tst2 : sigma2.proj2 (sigma2.mk a b) = b :=
|
||||
rfl
|
Loading…
Reference in a new issue