示例#1
0
template <typename T, typename X>    void static_matrix<T, X>::check_consistency() {
    std::unordered_map<std::pair<unsigned, unsigned>, T> by_rows;
    for (int i = 0; i < m_rows.size(); i++){
        for (auto & t : m_rows[i]) {
            pair<unsigned, unsigned> p(i, t.m_j);
            lean_assert(by_rows.find(p) == by_rows.end());
            by_rows[p] = t.get_val();
        }
    }
    std::unordered_map<pair<unsigned, unsigned>, T> by_cols;
    for (int i = 0; i < m_columns.size(); i++){
        for (auto & t : m_columns[i]) {
            pair<unsigned, unsigned> p(t.m_i, i);
            lean_assert(by_cols.find(p) == by_cols.end());
            by_cols[p] = get_value_of_column_cell(t);
        }
    }
    lean_assert(by_rows.size() == by_cols.size());

    for (auto & t : by_rows) {
        auto ic = by_cols.find(t.first);
        if (ic == by_cols.end()){
            std::cout << "rows have pair (" << t.first.first <<"," << t.first.second
                      << "), but columns don't " << std::endl;
        }
        lean_assert(ic != by_cols.end());
        lean_assert(t.second == ic->second);
    }
}
示例#2
0
// Read until the end_str is found, store all characters (not including end_str) in m_buffer.
// Throw a parser exception error_msg if end of file is found before end_str.
void scanner::read_until(char const * end_str, char const * error_msg) {
    lean_assert(end_str);
    lean_assert(end_str[0]);
    m_buffer.clear();
    while (true) {
        check_not_eof(error_msg);
        char c = curr_next();
        if (c == end_str[0]) {
            m_aux_buffer.clear();
            m_aux_buffer += c;
            unsigned i = 1;
            while (true) {
                if (!end_str[i])
                    return;
                check_not_eof(error_msg);
                c = curr_next();
                if (c != end_str[i]) {
                    m_buffer += m_aux_buffer;
                    break;
                }
                i++;
            }
        } else {
            m_buffer += c;
        }
    }
}
示例#3
0
 expr visit_projection(name const & fn, buffer<expr> const & args) {
     projection_info const & info = *get_projection_info(env(), fn);
     expr major = visit(args[info.m_nparams]);
     buffer<bool> rel_fields;
     name I_name = *inductive::is_intro_rule(env(), info.m_constructor);
     get_constructor_info(info.m_constructor, rel_fields);
     lean_assert(info.m_i < rel_fields.size());
     lean_assert(rel_fields[info.m_i]); /* We already erased irrelevant information */
     /* Adjust projection index by ignoring irrelevant fields */
     unsigned j = 0;
     for (unsigned i = 0; i < info.m_i; i++) {
         if (rel_fields[i])
             j++;
     }
     expr r;
     if (has_trivial_structure(I_name, rel_fields)) {
         lean_assert(j == 0);
         r = major;
     } else {
         r = mk_app(mk_proj(j), major);
     }
     /* Add additional arguments */
     for (unsigned i = info.m_nparams + 1; i < args.size(); i++)
         r = mk_app(r, visit(args[i]));
     return r;
 }
coercion_elaborator::coercion_elaborator(coercion_info_manager & info, expr const & arg,
                                         list<constraints> const & choices, list<expr> const & coes,
                                         bool use_id):
    m_info(info), m_arg(arg), m_id(use_id), m_choices(choices), m_coercions(coes) {
    lean_assert(!use_id || length(m_coercions) + 1 == length(m_choices));
    lean_assert(use_id  || length(m_coercions)     == length(m_choices));
}
示例#5
0
文件: util.cpp 项目: cpehle/lean
void get_rec_args(environment const & env, name const & n, buffer<buffer<bool>> & r) {
    lean_assert(inductive::is_inductive_decl(env, n));
    type_checker tc(env);
    name_generator ngen;
    declaration ind_decl   = env.get(n);
    declaration rec_decl   = env.get(inductive::get_elim_name(n));
    unsigned nparams       = *inductive::get_num_params(env, n);
    unsigned nminors       = *inductive::get_num_minor_premises(env, n);
    unsigned ntypeformers  = *inductive::get_num_type_formers(env, n);
    buffer<expr> rec_args;
    to_telescope(ngen, rec_decl.get_type(), rec_args);
    buffer<name> typeformer_names;
    for (unsigned i = nparams; i < nparams + ntypeformers; i++) {
        typeformer_names.push_back(mlocal_name(rec_args[i]));
    }
    lean_assert(typeformer_names.size() == ntypeformers);
    r.clear();
    // add minor premises
    for (unsigned i = nparams + ntypeformers; i < nparams + ntypeformers + nminors; i++) {
        r.push_back(buffer<bool>());
        buffer<bool> & bv = r.back();
        expr minor_type = mlocal_type(rec_args[i]);
        buffer<expr> minor_args;
        to_telescope(ngen, minor_type, minor_args);
        for (expr & minor_arg : minor_args) {
            buffer<expr> minor_arg_args;
            expr minor_arg_type = to_telescope(tc, mlocal_type(minor_arg), minor_arg_args);
            bv.push_back(is_typeformer_app(typeformer_names, minor_arg_type));
        }
    }
}
示例#6
0
expr mk_app(unsigned n, expr const * as) {
    lean_assert(n > 1);
    unsigned new_n;
    unsigned n0 = 0;
    expr const & arg0 = as[0];
    bool has_mv = std::any_of(as, as + n, [](expr const & c) { return c.has_metavar(); });
    // Remark: we represent ((app a b) c) as (app a b c)
    if (is_app(arg0)) {
        n0    = num_args(arg0);
        new_n = n + n0 - 1;
    } else {
        new_n = n;
    }
    char * mem   = new char[sizeof(expr_app) + new_n*sizeof(expr)];
    expr r(new (mem) expr_app(new_n, has_mv));
    expr * m_args = to_app(r)->m_args;
    unsigned i = 0;
    unsigned j = 0;
    if (new_n != n) {
        for (; i < n0; i++)
            new (m_args+i) expr(arg(arg0, i));
        j++;
    }
    for (; i < new_n; ++i, ++j) {
        lean_assert(j < n);
        new (m_args+i) expr(as[j]);
    }
    to_app(r)->m_hash = hash_args(new_n, m_args);
    return r;
}
示例#7
0
void tmp_type_context::update_assignment(level const & u, level const & v) {
    unsigned idx = to_meta_idx(u);
    lean_assert(idx < m_uassignment.size()); // see comments above
    lean_assert(!m_uassignment[idx]);
    m_uassignment[idx] = v;
    if (!m_scopes.empty())
        m_trail.emplace_back(trail_kind::Level, idx);
}
示例#8
0
void lar_solver::solve_with_core_solver() {
    m_mpq_lar_core_solver.solve();
    m_status = m_mpq_lar_core_solver.m_status;
    lean_assert(m_status != OPTIMAL  || all_constraints_hold());
#ifdef LEAN_DEBUG
    lean_assert(!settings().row_feasibility || m_status != INFEASIBLE || the_evidence_is_correct());
#endif
}
示例#9
0
mpq lar_solver::find_ratio_of_original_constraint_to_normalized(canonic_left_side * ls, const lar_constraint & constraint) {
    lean_assert(ls->m_coeffs.size() > 0);
    auto first_pair = ls->m_coeffs[0];
    lean_assert(first_pair.first == numeric_traits<mpq>::one());
    var_index i = first_pair.second;
    auto it = constraint.m_left_side.find(i);
    lean_assert(it != constraint.m_left_side.end());
    return it->second;
}
示例#10
0
void lar_solver::fill_row_of_A(static_matrix<U, V> & A, unsigned i, canonic_left_side * ls) {
    for (auto & t : ls->m_coeffs) {
        var_index vi = t.second;
        unsigned column = get_column_index_from_var_index(vi);
        lean_assert(is_valid(column));
        A.set(i, column, convert_struct<U, mpq>::convert(t.first));
    }
    unsigned additional_column = get_column_index_from_var_index(ls->m_additional_var_index);
    lean_assert(is_valid(additional_column));
    A.set(i, additional_column, - one_of_type<U>());
}
示例#11
0
void lar_solver::prepare_core_solver_fields(static_matrix<U, V> & A, std::vector<V> & x,
                                            std::vector<V> & low_bound,
                                            std::vector<V> & upper_bound) {
    create_matrix_A(A);
    fill_bounds_for_core_solver(low_bound, upper_bound);
    if (m_status == INFEASIBLE) {
        lean_assert(false); // not implemented
    }
    resize_and_init_x_with_zeros(x, A.column_count());
    lean_assert(m_lar_core_solver_params.m_basis.size() == A.row_count());
}
示例#12
0
 edge(expr const & e, bool fn) {
     m_fn = fn;
     lean_assert(is_constant(e) || is_local(e));
     if (is_constant(e)) {
         m_kind = edge_kind::Constant;
         m_name = const_name(e);
     } else {
         lean_assert(is_local(e));
         m_kind = edge_kind::Local;
         m_name = mlocal_name(e);
     }
 }
示例#13
0
template <typename T, typename X>    unsigned static_matrix<T, X>::lowest_row_in_column(unsigned col) {
    lean_assert(col < column_count());
    column_strip & colstrip = m_columns[col];
    lean_assert(colstrip.size() > 0);
    unsigned ret = 0;
    for (auto & t : colstrip) {
        if (t.m_i > ret) {
            ret = t.m_i;
        }
    }
    return ret;
}
示例#14
0
constraint_index lar_solver::add_constraint(const buffer<std::pair<mpq, var_index>>& left_side, lconstraint_kind kind_par, mpq right_side_par) {
    lean_assert(left_side.size() > 0);
    constraint_index i = m_available_constr_index++;
    lean_assert(m_normalized_constraints.find(i) == m_normalized_constraints.end());
    lar_constraint original_constr(left_side, kind_par, right_side_par, i);
    canonic_left_side * ls = create_or_fetch_existing_left_side(left_side);
    mpq ratio = find_ratio_of_original_constraint_to_normalized(ls, original_constr);
    auto kind = ratio.is_neg()? flip_kind(kind_par): kind_par;
    mpq right_side = right_side_par / ratio;
    lar_normalized_constraint normalized_constraint(ls, ratio, kind, right_side, original_constr);
    m_normalized_constraints[i] = normalized_constraint;
    return i;
}
示例#15
0
template <typename T, typename X>    void static_matrix<T, X>::set(unsigned row, unsigned col, T const & val) {
    if (numeric_traits<T>::is_zero(val)) return;
    lean_assert(row < row_count() && col < column_count());
#ifdef LEAN_DEBUG
    pair<unsigned, unsigned> p(row, col);
    lean_assert(m_domain.find(p) == m_domain.end());
    m_domain.insert(p);
#endif
    auto & r = m_rows[row];
    unsigned offs_in_cols = m_columns[col].size();
    m_columns[col].push_back(make_column_cell(row, r.size(), val));
    r.push_back(make_row_cell(col, offs_in_cols, val));
}
示例#16
0
void lar_solver::map_left_side_to_A_of_core_solver(canonic_left_side*  left_side, unsigned  j) {
    var_index additional_var = left_side->m_additional_var_index;
    lean_assert(valid_index(additional_var));
    auto it = m_map_from_var_index_to_column_info_with_cls.find(additional_var);
    lean_assert(it != m_map_from_var_index_to_column_info_with_cls.end());
    column_info<mpq> & ci = it->second.m_column_info;
    lean_assert(!is_valid(ci.get_column_index()));
    lean_assert(left_side->size() > 0); // if size is zero we have an empty row
    left_side->m_row_index = m_lar_core_solver_params.m_basis.size();
    m_lar_core_solver_params.m_basis.push_back(j); // j will be a basis column, so we put it into the basis as well
    lean_assert(m_map_from_column_indices_to_var_index.find(j) == m_map_from_column_indices_to_var_index.end());
    ci.set_column_index(j);
    m_map_from_column_indices_to_var_index[j] = additional_var;
}
示例#17
0
void lar_solver::restrict_delta_on_upper_bound(mpq& delta, unsigned j) {
    numeric_pair<mpq> & x = m_lar_core_solver_params.m_x[j];
    numeric_pair<mpq> & u = m_lar_core_solver_params.m_upper_bounds[j];
    mpq & xx = x.x;
    mpq & xy = x.y;
    mpq & ux = u.x;
    if (xx == ux) {
        lean_assert(xy <= numeric_traits<mpq>::zero());
    } else {
        lean_assert(xx < ux);
        if (xy <= zero_of_type<mpq>()) return;
        delta = std::min(delta, (ux - xx)/ (2 * xy)); // we need to have delta * xy < ux - xx, for the strict case
    }
}
示例#18
0
void refine_lower(mpq const & q, mpbq & l, mpbq & u) {
    lean_assert(l < q && q < u);
    lean_assert(!q.get_denominator().is_power_of_two());
    mpbq mid;
    while (true) {
        mid = l + u;
        div2(mid);
        if (mid < q) {
            swap(l, mid);
            lean_assert(l < q && q < u);
            return;
        }
        swap(u, mid);
    }
}
示例#19
0
void lar_solver::fill_bounds_for_core_solver(std::vector<V> & lb, std::vector<V> & ub) {
    unsigned n = static_cast<unsigned>(m_map_from_var_index_to_column_info_with_cls.size()); // this is the number of columns
    lb.resize(n);
    ub.resize(n);
    for (auto t : m_set_of_canonic_left_sides) {
        auto & ci = get_column_info_from_var_index(t->m_additional_var_index);
        unsigned j = ci.get_column_index();
        lean_assert(is_valid(j));
        lean_assert(j < n);
        if (ci.low_bound_is_set())
            lb[j] = conversion_helper<V>::get_low_bound(ci);
        if (ci.upper_bound_is_set())
            ub[j] = conversion_helper<V>::get_upper_bound(ci);
    }
}
示例#20
0
template <typename T, typename X>    void static_matrix<T, X>::forget_last_columns(unsigned how_many_to_forget) {
    lean_assert(m_columns.size() >= how_many_to_forget);
    unsigned j = column_count() - 1;
    for (; how_many_to_forget > 0; how_many_to_forget--) {
        remove_last_column(j --);
    }
}
示例#21
0
文件: dsimplify.cpp 项目: avigad/lean
expr dsimplify_core_fn::visit_app(expr const & e) {
    buffer<expr> args;
    bool modified = false;
    expr f        = get_app_args(e, args);
    unsigned i    = 0;
    if (!m_cfg.m_canonize_instances) {
        fun_info info = get_fun_info(m_ctx, f, args.size());
        for (param_info const & pinfo : info.get_params_info()) {
            lean_assert(i < args.size());
            expr new_a;
            if (pinfo.is_inst_implicit()) {
                new_a = m_defeq_canonizer.canonize(args[i], m_need_restart);
            } else {
                new_a = visit(args[i]);
            }
            if (new_a != args[i])
                modified = true;
            args[i] = new_a;
            i++;
        }
    }
    for (; i < args.size(); i++) {
        expr new_a = visit(args[i]);
        if (new_a != args[i])
            modified = true;
        args[i] = new_a;
    }
    if (modified)
        return mk_app(f, args);
    else
        return e;
}
示例#22
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));
}
示例#23
0
bool scanner::is_next_digit() {
    lean_assert(curr() != EOF);
    if (m_spos + 1 < static_cast<int>(m_curr_line.size()))
        return std::isdigit(m_curr_line[m_spos+1]);
    else
        return false;
}
示例#24
0
expr replace_visitor::visit_let(expr const & e) {
    lean_assert(is_let(e));
    expr new_t = visit(let_type(e));
    expr new_v = visit(let_value(e));
    expr new_b = visit(let_body(e));
    return update_let(e, new_t, new_v, new_b);
}
示例#25
0
void lar_solver::restrict_delta_on_low_bound_column(mpq& delta, unsigned j) {
    numeric_pair<mpq> & x = m_lar_core_solver_params.m_x[j];
    numeric_pair<mpq> & l = m_lar_core_solver_params.m_low_bounds[j];
    mpq & xx = x.x;
    mpq & xy = x.y;
    mpq & lx = l.x;
    if (xx == lx) {
        lean_assert(xy >= numeric_traits<mpq>::zero());
    } else {
        lean_assert(xx >= lx); // we need lx <= xx + delta*xy, or delta*xy >= lx - xx, or - delta*xy <= xx - ls.
        // The right part is not negative. The delta is positive. If xy >= 0 we have the ineqality
        // otherwise we need to have delta not greater than - (xx - lx)/xy. We use the 2 coefficient to handle the strict case
        if (xy >= zero_of_type<mpq>()) return;
        delta = std::min(delta, (lx - xx)/ (2 * xy)); // we need to have delta * xy < xx - lx for the strict case
    }
}
示例#26
0
expr replace_visitor::visit_macro(expr const & e) {
    lean_assert(is_macro(e));
    buffer<expr> new_args;
    for (unsigned i = 0; i < macro_num_args(e); i++)
        new_args.push_back(visit(macro_arg(e, i)));
    return update_macro(e, new_args.size(), new_args.data());
}
示例#27
0
void display_decimal(std::ostream & out, mpq const & a, unsigned prec) {
    mpz n1, d1, v1;
    numerator(n1, a);
    denominator(d1, a);
    if (a.is_neg()) {
        out << "-";
        n1.neg();
    }
    v1 = n1 / d1;
    out << v1;
    n1 = rem(n1, d1);
    if (n1.is_zero())
        return;
    out << ".";
    for (unsigned i = 0; i < prec; i++) {
        n1 *= 10;
        v1 = n1 / d1;
        lean_assert(v1 < 10);
        out << v1;
        n1 = rem(n1, d1);
        if (n1.is_zero())
            return;
    }
    out << "?";
}
示例#28
0
template <typename T, typename X>    void static_matrix<T, X>::copy_column_to_vector (unsigned j, indexed_vector<T> & v) const {
    lean_assert(j < m_columns.size());
    for (auto & it : m_columns[j]) {
        if (!is_zero(it.m_value))
            v.set_value(it.m_value, it.m_i);
    }
}
示例#29
0
文件: expr.cpp 项目: sakas--/lean
void expr_cell::dealloc() {
    try {
        del_buffer todo;
        todo.push_back(this);
        while (!todo.empty()) {
            expr_cell * it = todo.back();
            todo.pop_back();
            lean_assert(it->get_rc() == 0);
            switch (it->kind()) {
            case expr_kind::Var:        static_cast<expr_var*>(it)->dealloc(); break;
            case expr_kind::Macro:      static_cast<expr_macro*>(it)->dealloc(todo); break;
            case expr_kind::Meta:       static_cast<expr_mlocal*>(it)->dealloc(todo); break;
            case expr_kind::Local:      static_cast<expr_local*>(it)->dealloc(todo); break;
            case expr_kind::Constant:   static_cast<expr_const*>(it)->dealloc(); break;
            case expr_kind::Sort:       static_cast<expr_sort*>(it)->dealloc(); break;
            case expr_kind::App:        static_cast<expr_app*>(it)->dealloc(todo); break;
            case expr_kind::Lambda:
            case expr_kind::Pi:         static_cast<expr_binding*>(it)->dealloc(todo); break;
            case expr_kind::Let:        static_cast<expr_let*>(it)->dealloc(todo); break;
           }
        }
    } catch (std::bad_alloc&) {
        // We need this catch, because push_back may fail when expanding the buffer.
        // In this case, we avoid the crash, and "accept" the memory leak.
    }
}
示例#30
0
void row_eta_matrix<T, X>::apply_from_right(indexed_vector<T> & w) {
    T w_row = w[m_row];
    if (numeric_traits<T>::is_zero(w_row)) return;
#ifdef LEAN_DEBUG
    //        dense_matrix<T> deb(*this);
    // auto clone_w = clone_vector<T>(w.m_data, m_dimension);
    // deb.apply_from_right(clone_w);
#endif
    for (auto & it : m_row_vector.m_data) {
        T old_val = w[it.first];
        T v = w[it.index()] += w_row * it.second;
        if (numeric_traits<T>::is_zero(old_val)) {
            w.m_index.push_back(it.index());
        } else if (numeric_traits<T>::is_zero(v)) { // it is a very rare case
            auto w_it = std::find(w.m_index.begin(), w.m_index.end(), it.index());
            lean_assert(w_it != w.m_index.end());
            w.m_index.erase(w_it);
        }
    }
#ifdef LEAN_DEBUG
    // lean_assert(vectors_are_equal<T>(clone_w, w.m_data, m_dimension));
    // for (unsigned i = 0; i < m_dimension; i++) {
    //     if (!numeric_traits<T>::is_zero(w.m_data[i])) {
    //         lean_assert(std::find(w.m_index.begin(), w.m_index.end(), i) != w.m_index.end());
    //     }
    // }
    // delete clone_w;
#endif
}