Esempio n. 1
0
double nonlinear_constraint::eval_error(box const & b) const {
    // Construct iv from box b
    if (get_var_array().size() > 0) {
        ibex::IntervalVector iv(get_var_array().size());
        for (int i = 0; i < get_var_array().size(); i++) {
            iv[i] = b[get_var_array()[i].name];
            DREAL_LOG_DEBUG << get_var_array()[i].name << " = " << iv[i];
        }
        return eval_error(iv);
    } else {
        ibex::IntervalVector iv(1);
        return eval_error(iv);
    }
}
void contractor_generic_forall::handle_disjunction(contractor_status & cs, vector<Enode *> const &vec, bool const p) {
    DREAL_LOG_DEBUG << "contractor_generic_forall::handle_disjunction" << endl;
    unordered_set<Enode *> forall_vars;
    for (Enode * e : vec) {
        std::unordered_set<Enode *> const & vars = e->get_forall_vars();
        forall_vars.insert(vars.begin(), vars.end());
    }

    unordered_map<Enode*, ibex::Interval> subst;
    if (!forall_vars.empty()) {
        // Step 2. Find a counter-example
        //         Solve(¬ l_1 ∧ ¬ l_2 ∧ ... ∧ ¬ l_n)
        //
        //         Make each ¬ l_i as a contractor ctc_i
        //         Make a fixed_point contractor with ctc_is.
        //         Pass it to icp::solve

        box counterexample = find_CE(cs.m_box, forall_vars, vec, p, cs.m_config);
        if (counterexample.is_empty()) {
            // Step 2.1. (NO Counterexample)
            //           Return B.
            DREAL_LOG_DEBUG << "handle_disjunction: no counterexample found." << endl
                            << "current box = " << endl
                            << cs.m_box << endl;
            return;
        } else {
            // Step 2.2. (There IS a counterexample C)
            //
            //      Using C, prune B.
            //
            // We've found a counterexample (c1, c2) where ¬ f(c1, c2) holds
            // Prune X using a point 'y = c2'. (technically, a point in c2, which is an interval)
            subst = make_subst_from_value(counterexample, forall_vars);
        }
    }

    // Step 3. Compute B_i = prune(B, l_i)
    //         Update B with ∨ B_i
    //                       i
    thread_local static vector<box> boxes;
    boxes.clear();
    auto vars = cs.m_box.get_vars();
    unordered_set<Enode*> const var_set(vars.begin(), vars.end());
    for (Enode * e : vec) {
        if (!e->get_exist_vars().empty()) {
            lbool polarity = p ? l_True : l_False;
            if (e->isNot()) {
                polarity = !polarity;
                e = e->get1st();
            }
            auto ctr = make_shared<nonlinear_constraint>(e, var_set, polarity, subst);
            if (ctr->get_var_array().size() == 0) {
                auto result = ctr->eval(cs.m_box);
                if (result.first != false) {
                    boxes.emplace_back(cs.m_box);
                }
            } else {
                contractor ctc = mk_contractor_ibex_fwdbwd(ctr);
                contractor_status bt(cs.m_box, cs.m_config);
                ctc.prune(bt);
                cs.m_output.union_with(bt.m_output);
                unordered_set<shared_ptr<constraint>> const & used_ctrs = bt.m_used_constraints;
                cs.m_used_constraints.insert(used_ctrs.begin(), used_ctrs.end());
                boxes.emplace_back(bt.m_box);
            }
        }
    }
    if (boxes.size() > 0) {
        cs.m_box = hull(boxes);
    } else {
        cs.m_box.set_empty();
    }
    return;
}