optional<expr> unfold_step(type_context & ctx, expr const & e, name_set const & to_unfold, bool unfold_reducible) { if (!unfold_reducible && to_unfold.empty()) return none_expr(); if (!is_app(e) && !is_constant(e)) return none_expr(); expr const & fn = get_app_fn(e); if (!is_constant(fn)) return none_expr(); name const & fn_name = const_name(fn); bool in_to_unfold = to_unfold.contains(const_name(fn)); if (!in_to_unfold && !unfold_reducible) return none_expr(); if (is_projection(ctx.env(), const_name(fn))) { if (in_to_unfold) { type_context::transparency_scope scope(ctx, transparency_mode::Instances); return ctx.reduce_projection(e); } else { return none_expr(); } } else if (in_to_unfold) { return unfold_term(ctx.env(), e); } else if (unfold_reducible && is_reducible(ctx.env(), fn_name)) { type_context::transparency_scope scope(ctx, transparency_mode::Reducible); return unfold_term(ctx.env(), e); } else { return none_expr(); } }
expr collect(expr const & e) { return replace(e, [&](expr const & e, unsigned) { if (is_metavar(e)) { name const & id = mlocal_name(e); if (auto r = m_meta_to_param.find(id)) { return some_expr(*r); } else { expr type = m_ctx.infer(e); expr x = m_ctx.push_local("_x", type); m_meta_to_param.insert(id, x); m_meta_to_param_inv.insert(mlocal_name(x), e); m_params.push_back(x); return some_expr(x); } } else if (is_local(e)) { name const & id = mlocal_name(e); if (!m_found_local.contains(id)) { m_found_local.insert(id); m_params.push_back(e); } } else if (is_sort(e)) { return some_expr(update_sort(e, collect(sort_level(e)))); } else if (is_constant(e)) { return some_expr(update_constant(e, collect(const_levels(e)))); } return none_expr(); }); }
level collect(level const & l) { return replace(l, [&](level const & l) { if (is_meta(l)) { name const & id = meta_id(l); if (auto r = m_univ_meta_to_param.find(id)) { return some_level(*r); } else { name n = m_prefix.append_after(m_next_idx); m_next_idx++; level new_r = mk_param_univ(n); m_univ_meta_to_param.insert(id, new_r); m_univ_meta_to_param_inv.insert(n, l); m_level_params.push_back(n); return some_level(new_r); } } else if (is_param(l)) { name const & id = param_id(l); if (!m_found_univ_params.contains(id)) { m_found_univ_params.insert(id); m_level_params.push_back(id); } } return none_level(); }); }
// Check whether rhs is of the form (mvar l_1 ... l_n) where mvar is a metavariable, // and l_i's are local constants, and mvar does not occur in found_mvars. // If it is return true and update found_mvars static bool is_valid_congr_hyp_rhs(expr const & rhs, name_set & found_mvars) { buffer<expr> rhs_args; expr const & rhs_fn = get_app_args(rhs, rhs_args); if (!is_metavar(rhs_fn) || found_mvars.contains(mlocal_name(rhs_fn))) return false; for (expr const & arg : rhs_args) if (!is_local(arg)) return false; found_mvars.insert(mlocal_name(rhs_fn)); return true; }
// Return a new ls s.t. there is no conflict between the names in ls and globals. // Store the mapping between old and new names in param_name_map. static level_param_names sanitize_level_params(level_param_names const & ls, name_set const & globals, name_map<name> & param_name_map) { buffer<name> new_params; for (name const & n : ls) { if (globals.contains(n)) { unsigned i = 1; name new_n = n.append_after(i); while (globals.contains(new_n)) { i++; name new_n = n.append_after(i); } param_name_map.insert(n, new_n); new_params.push_back(new_n); } else { new_params.push_back(n); } } if (param_name_map.empty()) return ls; return to_list(new_params.begin(), new_params.end()); }
void simp_rule_set::erase_simp(name_set const & ids) { // This method is not very smart and doesn't use any indexing or caching. // So, it may be a bottleneck in the future buffer<simp_rule> to_delete; for_each_simp([&](simp_rule const & r) { if (ids.contains(r.get_id())) { to_delete.push_back(r); } }); for (simp_rule const & r : to_delete) { erase(r); } }
double get_thm_score(name const & n) const { name_set s = get_use_set(m_env, n); unsigned IR = 0; double M = 0.0; s.for_each([&](name const & F) { if (ignore_F(F)) return; if (m_relevant.contains(F)) { M += get_weight(F); } else { // std::cout << "IR: " << F << "\n"; IR++; } }); // std::cout << n << " M: " << M << " IR: " << IR << "\n"; if (M > 0.0) return M / (M + IR); else return 0.0; }
bool substitution::occurs_expr_core(name const & m, expr const & e, name_set & visited) const { bool found = false; for_each(e, [&](expr const & e, unsigned) { if (found || !has_expr_metavar(e)) return false; if (is_metavar(e)) { name const & n = mlocal_name(e); if (n == m) found = true; auto s = get_expr(e); if (!s || visited.contains(n)) return false; // do not visit type visited.insert(n); if (s && occurs_expr_core(m, *s, visited)) found = true; return false; // do not visit type } if (is_local(e)) return false; // do not visit type return true; }); return found; }
// Return true iff all metavariables in e are in found_mvars static bool only_found_mvars(expr const & e, name_set const & found_mvars) { return !find(e, [&](expr const & m, unsigned) { return is_metavar(m) && !found_mvars.contains(mlocal_name(m)); }); }