Example #1
0
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));
}
Example #2
0
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;
}
Example #3
0
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;
        }
Example #5
0
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);
}
Example #6
0
// 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;
}