void get_structure_instance_info(expr const & e, name & struct_name, optional<expr> & source, buffer<name> & field_names, buffer<expr> & field_values) { lean_assert(is_structure_instance(e)); struct_name = static_cast<structure_instance_macro_cell const*>(macro_def(e).raw())->get_struct(); list<name> const & fns = static_cast<structure_instance_macro_cell const*>(macro_def(e).raw())->get_field_names(); to_buffer(fns, field_names); unsigned num_fields = field_names.size(); lean_assert(macro_num_args(e) == num_fields || macro_num_args(e) == num_fields+1); if (num_fields < macro_num_args(e)) source = macro_arg(e, num_fields); for (unsigned i = 0; i < num_fields; i++) field_values.push_back(macro_arg(e, i)); }
parse_table parse_table::add_core(unsigned num, transition const * ts, expr const & a, unsigned priority, bool overload, buffer<action> & post_buffer) const { parse_table r(new cell(*m_ptr)); if (num == 0) { list<action> postponed = to_list(post_buffer); if (!overload) { r.m_ptr->m_accept = to_list(accepting(priority, postponed, a)); } else { auto new_accept = filter(r.m_ptr->m_accept, [&](accepting const & p) { return p.get_expr() != a || p.get_postponed() != postponed; }); r.m_ptr->m_accept = insert(new_accept, priority, postponed, a); } } else { list<pair<action, parse_table>> const * it = r.m_ptr->m_children.find(ts->get_token()); action const & ts_act = ts->get_action(); action_kind k = ts_act.kind(); if (k == action_kind::Exprs || k == action_kind::ScopedExpr) post_buffer.push_back(ts_act); list<pair<action, parse_table>> new_lst; if (it) { if (contains_equivalent_action(*it, ts_act)) { buffer<pair<action, parse_table>> tmp; to_buffer(*it, tmp); for (pair<action, parse_table> & p : tmp) { if (p.first.is_equivalent(ts_act)) { p.second = p.second.add_core(num-1, ts+1, a, priority, overload, post_buffer); break; } } new_lst = to_list(tmp); } else { // remove incompatible actions new_lst = filter(*it, [&](pair<action, parse_table> const & p) { return p.first.is_compatible(ts_act); }); parse_table new_child = parse_table().add_core(num-1, ts+1, a, priority, overload, post_buffer); new_lst = cons(mk_pair(ts_act, new_child), new_lst); } } else { parse_table new_child = parse_table().add_core(num-1, ts+1, a, priority, overload, post_buffer); new_lst = to_list(mk_pair(ts_act, new_child)); } r.m_ptr->m_children.insert(ts->get_token(), new_lst); } return r; }
void display(io_state_stream & out, unsigned num, transition const * ts, list<accepting> const & es, bool nud, optional<token_table> const & tt) { if (!nud) out << "_ "; for (unsigned i = 0; i < num; i++) { if (i > 0) out << " "; out << "`" << ts[i].get_token() << "`"; if (tt) { if (auto prec = get_expr_precedence(*tt, ts[i].get_token().to_string().c_str())) { out << ":" << *prec; } } switch (ts[i].get_action().kind()) { case action_kind::Skip: break; case action_kind::Expr: out << " _:"; ts[i].get_action().display(out); break; default: out << " "; ts[i].get_action().display(out); break; } } out << " :="; if (length(es) == 1) { out << " " << head(es).get_expr() << "\n"; } else { buffer<accepting> tmp; to_buffer(es, tmp); out << "\n"; unsigned i = tmp.size(); while (i > 0) { --i; out << " | "; if (tmp[i].get_prio() != LEAN_DEFAULT_NOTATION_PRIORITY) out << "[priority " << tmp[i].get_prio() << "] "; out << tmp[i].get_expr() << "\n"; } } }
void fun_info_manager::trace_if_unsupported(expr const & fn, buffer<expr> const & args, unsigned prefix_sz, fun_info const & result) { if (!is_fun_info_trace_enabled()) return; fun_info info = get(fn, args.size()); buffer<param_info> pinfos; to_buffer(info.get_params_info(), pinfos); /* Check if all remaining arguments are nondependent or dependent (but all forward dependencies are propositions or subsingletons) */ unsigned i = prefix_sz; for (; i < pinfos.size(); i++) { param_info const & pinfo = pinfos[i]; if (!pinfo.is_dep()) continue; /* nondependent argument */ if (has_nonprop_nonsubsingleton_fwd_dep(i, pinfos)) break; /* failed i-th argument has a forward dependent that is not a prop nor a subsingleton */ } if (i == pinfos.size()) return; // It is *cheap* case /* Expensive case */ /* We generate a trace message IF it would be possible to compute more precise information. That is, there is an argument that is a proposition and/or subsingleton, but the corresponding pinfo is not a marked a prop/subsingleton. */ i = 0; for (param_info const & pinfo : result.get_params_info()) { if (pinfo.is_prop() || pinfo.is_subsingleton()) continue; expr arg_type = m_ctx.infer(args[i]); if (m_ctx.is_prop(arg_type) || m_ctx.mk_subsingleton_instance(arg_type)) { lean_trace_fun_info( tout() << "approximating function information for '" << fn << "', this may affect the effectiveness of the simplifier and congruence closure modules, " << "more precise information can be efficiently computed if all parameters are moved to the beginning of the function\n";); return; }
expr mk_app(expr const & f, list<expr> const & args, tag g) { buffer<expr> _args; to_buffer(args, _args); return mk_app(f, _args, g); }
// global reducing function template <typename T> T global(T& value, const char* operation) { // initialize global value T global = value; #ifdef MPI_VERSION int id = MPI::COMM_WORLD.Get_rank(); int np = MPI::COMM_WORLD.Get_size(); if (id == 0) { // receive local values for (int i = 1; i < np; i++) { T temp; int size; MPI::COMM_WORLD.Recv(&size, 1, MPI_INT, i, 100); char* buffer = new char[size]; MPI::COMM_WORLD.Recv(buffer, size, MPI_CHAR, i, 200); from_buffer(temp, buffer); delete [] buffer; // perform operation if (std::string(operation)=="add" or std::string(operation)=="sum") global += temp; else if (std::string(operation)=="min" or std::string(operation)=="minimum") global = min(global, temp); else if (std::string(operation)=="max" or std::string(operation)=="maximum") global = max(global, temp); } // send global value for (int i = 1; i < np; i++) { int size = buffer_size(global); MPI::COMM_WORLD.Send(&size, 1, MPI_INT, i, 300); char* buffer = new char[size]; to_buffer(global, buffer); MPI::COMM_WORLD.Send(buffer, size, MPI_CHAR, i, 400); delete [] buffer; } } else { // send local value int size = buffer_size(value); MPI::COMM_WORLD.Send(&size, 1, MPI_INT, 0, 100); char* buffer = new char[size]; to_buffer(value, buffer); MPI::COMM_WORLD.Send(buffer, size, MPI_CHAR, 0, 200); delete [] buffer; // receive global value MPI::COMM_WORLD.Recv(&size, 1, MPI_INT, 0, 300); buffer = new char[size]; MPI::COMM_WORLD.Recv(buffer, size, MPI_CHAR, 0, 400); from_buffer(global, buffer); delete [] buffer; } MPI::COMM_WORLD.Barrier(); #endif return global; }