class_instance_context(environment const & env, io_state const & ios, name const & prefix, bool relax, bool use_local_instances): m_ios(ios), m_ngen(prefix), m_relax(relax), m_use_local_instances(use_local_instances) { m_fname = nullptr; m_trace_instances = get_class_trace_instances(ios.get_options()); m_max_depth = get_class_instance_max_depth(ios.get_options()); m_conservative = get_class_conservative(ios.get_options()); if (m_conservative) m_tc = mk_type_checker(env, m_ngen.mk_child(), false, UnfoldReducible); else m_tc = mk_type_checker(env, m_ngen.mk_child(), m_relax); options opts = m_ios.get_options(); opts = opts.update_if_undef(get_pp_purify_metavars_name(), false); opts = opts.update_if_undef(get_pp_implicit_name(), true); m_ios.set_options(opts); }
elaborator_context::elaborator_context(environment const & env, io_state const & ios, local_decls<level> const & lls, pos_info_provider const * pp, info_manager * info, bool check_unassigned): m_env(env), m_ios(ios), m_lls(lls), m_pos_provider(pp), m_info_manager(info), m_check_unassigned(check_unassigned) { m_use_local_instances = get_elaborator_local_instances(ios.get_options()); m_ignore_instances = get_elaborator_ignore_instances(ios.get_options()); m_flycheck_goals = get_elaborator_flycheck_goals(ios.get_options()); m_fail_missing_field = get_elaborator_fail_missing_field(ios.get_options()); m_lift_coercions = get_elaborator_lift_coercions(ios.get_options()); init_options(ios.get_options()); }
scope_trace_env::scope_trace_env(environment const & env, io_state const & ios) { 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; g_env = const_cast<environment*>(&env); g_ios = const_cast<io_state*>(&ios); options const & opts = ios.get_options(); name trace("trace"); opts.for_each([&](name const & n) { if (is_prefix_of(trace, n)) { name cls = n.replace_prefix(trace, name()); if (opts.get_bool(n, false)) enable_trace_class(cls); else disable_trace_class(cls); } }); }
server::worker::worker(environment const & env, io_state const & ios, definition_cache & cache, optional<std::string> const & base_dir): m_empty_snapshot(env, ios.get_options()), m_cache(cache), m_base_dir(base_dir), m_todo_line_num(0), m_todo_options(ios.get_options()), m_terminate(false), m_thread([=]() { io_state _ios(ios); while (!m_terminate) { file_ptr todo_file; unsigned todo_line_num = 0; options todo_options; // wait for next task while (!m_terminate) { unique_lock<mutex> lk(m_todo_mutex); if (m_todo_file) { todo_file = m_todo_file; todo_line_num = m_todo_line_num; todo_options = m_todo_options; break; } else { m_todo_cv.wait(lk); } } // extract block of code and snapshot from todo_file reset_interrupt(); bool worker_interrupted = false; if (m_terminate) break; DIAG(std::cerr << "processing '" << todo_file->get_fname() << "'\n";) std::string block; unsigned num_lines; snapshot s; { lean_assert(todo_file); lock_guard<mutex> lk(todo_file->m_lines_mutex); unsigned i = todo_file->find(todo_line_num); todo_file->m_snapshots.resize(i); s = i == 0 ? m_empty_snapshot : todo_file->m_snapshots[i-1]; if (direct_imports_have_changed(s.m_env)) s = m_empty_snapshot; lean_assert(s.m_line > 0); todo_file->m_info.start_from(s.m_line); todo_file->m_info.save_environment_options(s.m_line, 0, s.m_env, s.m_options); num_lines = todo_file->copy_to(block, s.m_line - 1); } if (m_terminate) break; // parse block of code with respect to snapshot try { std::istringstream strm(block); #if defined(LEAN_SERVER_DIAGNOSTIC) std::shared_ptr<output_channel> out1(new stderr_channel()); std::shared_ptr<output_channel> out2(new stderr_channel()); #else std::shared_ptr<output_channel> out1(new string_output_channel()); std::shared_ptr<output_channel> out2(new string_output_channel()); #endif io_state tmp_ios(_ios, out1, out2); tmp_ios.set_options(join(s.m_options, _ios.get_options())); bool use_exceptions = false; unsigned num_threads = 1; parser p(s.m_env, tmp_ios, strm, todo_file->m_fname.c_str(), m_base_dir, use_exceptions, num_threads, &s, &todo_file->m_snapshots, &todo_file->m_info); p.set_cache(&m_cache); p(); } catch (interrupted &) { worker_interrupted = true; } catch (throwable & ex) { DIAG(std::cerr << "worker exception: " << ex.what() << "\n";) } if (!m_terminate && !worker_interrupted) { DIAG(std::cerr << "finished '" << todo_file->get_fname() << "'\n";) unique_lock<mutex> lk(m_todo_mutex); if (m_todo_file == todo_file && m_last_file == todo_file && m_todo_line_num == todo_line_num) { m_todo_line_num = num_lines + 1; m_todo_file = nullptr; m_todo_cv.notify_all(); } }
static proof_state_seq apply_tactic_core(environment const & env, io_state const & ios, proof_state const & s, expr const & _e, buffer<constraint> & cs, add_meta_kind add_meta, subgoals_action_kind subgoals_action, optional<unifier_kind> const & uk = optional<unifier_kind>()) { goals const & gs = s.get_goals(); if (empty(gs)) { throw_no_goal_if_enabled(s); return proof_state_seq(); } bool class_inst = get_apply_class_instance(ios.get_options()); name_generator ngen = s.get_ngen(); std::shared_ptr<type_checker> tc(mk_type_checker(env, ngen.mk_child())); goal g = head(gs); goals tail_gs = tail(gs); expr t = g.get_type(); expr e = _e; auto e_t_cs = tc->infer(e); e_t_cs.second.linearize(cs); expr e_t = e_t_cs.first; buffer<expr> metas; local_context ctx; bool initialized_ctx = false; unifier_config cfg(ios.get_options()); if (uk) cfg.m_kind = *uk; if (add_meta != DoNotAdd) { unsigned num_e_t = get_expect_num_args(*tc, e_t); if (add_meta == AddDiff) { unsigned num_t = get_expect_num_args(*tc, t); if (num_t <= num_e_t) num_e_t -= num_t; else num_e_t = 0; } else { lean_assert(add_meta == AddAll); } for (unsigned i = 0; i < num_e_t; i++) { auto e_t_cs = tc->whnf(e_t); e_t_cs.second.linearize(cs); e_t = e_t_cs.first; expr meta; if (class_inst && binding_info(e_t).is_inst_implicit()) { if (!initialized_ctx) { ctx = g.to_local_context(); initialized_ctx = true; } bool use_local_insts = true; bool is_strict = false; auto mc = mk_class_instance_elaborator( env, ios, ctx, ngen.next(), optional<name>(), use_local_insts, is_strict, some_expr(head_beta_reduce(binding_domain(e_t))), e.get_tag(), cfg, nullptr); meta = mc.first; cs.push_back(mc.second); } else { meta = g.mk_meta(ngen.next(), head_beta_reduce(binding_domain(e_t))); } e = mk_app(e, meta); e_t = instantiate(binding_body(e_t), meta); metas.push_back(meta); } } metavar_closure cls(t); cls.mk_constraints(s.get_subst(), justification()); pair<bool, constraint_seq> dcs = tc->is_def_eq(t, e_t); if (!dcs.first) { throw_tactic_exception_if_enabled(s, [=](formatter const & fmt) { format r = format("invalid 'apply' tactic, failed to unify"); r += pp_indent_expr(fmt, t); r += compose(line(), format("with")); r += pp_indent_expr(fmt, e_t); return r; }); return proof_state_seq(); } dcs.second.linearize(cs); unify_result_seq rseq = unify(env, cs.size(), cs.data(), ngen.mk_child(), s.get_subst(), cfg); list<expr> meta_lst = to_list(metas.begin(), metas.end()); return map2<proof_state>(rseq, [=](pair<substitution, constraints> const & p) -> proof_state { substitution const & subst = p.first; constraints const & postponed = p.second; name_generator new_ngen(ngen); substitution new_subst = subst; expr new_e = new_subst.instantiate_all(e); assign(new_subst, g, new_e); goals new_gs = tail_gs; if (subgoals_action != IgnoreSubgoals) { buffer<expr> metas; for (auto m : meta_lst) { if (!new_subst.is_assigned(get_app_fn(m))) metas.push_back(m); } if (subgoals_action == AddRevSubgoals) { for (unsigned i = 0; i < metas.size(); i++) new_gs = cons(goal(metas[i], new_subst.instantiate_all(tc->infer(metas[i]).first)), new_gs); } else { lean_assert(subgoals_action == AddSubgoals || subgoals_action == AddAllSubgoals); if (subgoals_action == AddSubgoals) remove_redundant_metas(metas); unsigned i = metas.size(); while (i > 0) { --i; new_gs = cons(goal(metas[i], new_subst.instantiate_all(tc->infer(metas[i]).first)), new_gs); } } } return proof_state(s, new_gs, new_subst, new_ngen, postponed); }); }
elaborator_context::elaborator_context(environment const & env, io_state const & ios, local_decls<level> const & lls, pos_info_provider const * pp, info_manager * info, bool check_unassigned): m_env(env), m_ios(ios), m_lls(lls), m_pos_provider(pp), m_info_manager(info), m_check_unassigned(check_unassigned) { m_use_local_instances = get_elaborator_local_instances(ios.get_options()); }