예제 #1
0
void tilingInterpolation::integer_pruning(box const & old_box, box const & new_box, int i) {
    Enode * it;
    //TODO what about shared ? should we rather take the projections
    if (is_a_var(i)) {
        it = make_false();
    } else {
        assert(is_b_var(i));
        it = make_true();
    }
    if (new_box.get_values()[i].is_empty()) {
        //if the new box is empty then we have a leaf
        push_partial_interpolant(it);
        proof_size += 1;
    } else {
        //we need to figure out what parts are pruned
        auto const fst_value = old_box.get_value(i);
        auto const snd_value = new_box.get_value(i);
        //pruning on the lower end
        if (fst_value.lb() < snd_value.lb()) {
            std::tuple<bool,int,double,bool> pivot(false, i, snd_value.lb(), false);
            split_stack.push(pivot);
            push_partial_interpolant(it);
            proof_size += 1;
        }
        //pruning on the upper end
        if (fst_value.ub() > snd_value.ub()) {
            std::tuple<bool,int,double,bool> pivot(true, i, snd_value.ub(), false);
            split_stack.push(pivot);
            push_partial_interpolant(it);
            proof_size += 1;
        }
    }
}
예제 #2
0
void tilingInterpolation::pruning(box const & old_box, box const & new_box, std::shared_ptr<constraint> cstr) {
    Enode * it;
    if (is_a_constraint(cstr)) {
        it = make_false();
    } else if (is_b_constraint(cstr)) {
        it = make_true();
    } else {
        assert(is_bound(cstr));
        DREAL_LOG_DEBUG << "pruning, ignoring bound: " << cstr.get();
        return;
    }
    if (new_box.is_empty()) {
        //if the new box is empty then we have a leaf
        push_partial_interpolant(it);
        proof_size += 1;
    } else {
        //we need to figure out what parts are pruned
        int max_var = domain.get_vars().size();
        for (int i = 0; i < max_var; i++) {
            auto const fst_value = old_box.get_value(i);
            auto const snd_value = new_box.get_value(i);
            //pruning on the lower end
            if (fst_value.lb() < snd_value.lb()) {
                std::tuple<bool,int,double,bool> pivot(false, i, snd_value.lb(), false);
                split_stack.push(pivot);
                push_partial_interpolant(it);
                proof_size += 1;
            }
            //pruning on the upper end
            if (fst_value.ub() > snd_value.ub()) {
                std::tuple<bool,int,double,bool> pivot(true, i, snd_value.ub(), false);
                split_stack.push(pivot);
                push_partial_interpolant(it);
                proof_size += 1;
            }
        }
    }
}
예제 #3
0
bool optimizer::improve_naive(box& p) { //note that p is a point not a nontrivial box
    Enode * target = NULL; //will pick one target error function
    double delta = config.nra_precision;
    double max_error = delta;
    for (auto f : error_funcs) {
	//evaluate f on p
	double c = std::fabs(eval_enode_term(f,p));
	cerr << "for f = " << f << ", the error evaluates to " << c << endl;
	if (c > max_error) {
	    max_error = c;
	    target = f;
	}
    }
    if (max_error<=delta) {
	cerr << "error already minimized" << endl;
	return false;
    }
    cerr << "max_error is: " << max_error << ", happening on function " << target << endl;
    //otherwise, move on each dimension based on the gradient of f
    Enode * ptarget = plainf[target]; //use the simplified form for computing gradients
    map<Enode*, double> new_values;
    unordered_set<Enode*> vars = ptarget->get_vars();
    for (auto v : vars) {
	Enode * gradient_v = egraph.mkDeriv(ptarget,v);
	double p_v = p.get_value(v).lb();	
	double grad = eval_enode_term(gradient_v,p);
	//take a newton step on the dimention
	cerr << "exploring the domain:\n" << domain << endl;
	double length = domain.get_value(v).ub() - domain.get_value(v).lb();
	double step = ((p_v-domain.get_value(v).lb())/(length+delta))*(domain.get_value(v).ub()-p_v);
	cerr << "taking a step of size: " << step << endl;
	cerr << "at gradient " << grad << endl;
	double newv = p_v - step*grad;
	cerr << "making a move on " << v << " by " << newv << endl;
	new_values.emplace(v,newv);
    }
    //TODO: collect the box that it has been through
	//if value interval has no zero, push to the learned boxes; the new point is the improved point
	//if value interval has zero, push that box to the top!
    for (auto v : vars) {
	//change the value in p using the new point
	p.set_value(v,new_values[v],new_values[v]); //lower and upper bounds are the same
    }
    cerr << "the new point is:\n" << p << endl;
    return true;
}
예제 #4
0
파일: eval.cpp 프로젝트: scungao/dreal3
double eval_enode_term(Enode * const e, box const & b) {
    if (e->isVar()) {
        return b.get_value(e).lb();
    } else if (e->isConstant()) {
        double const v = e->getValue();
        return v;
    } else if (e->isSymb()) {
        throw runtime_error("eval_enode: Symb");
    } else if (e->isNumb()) {
        throw runtime_error("eval_enode: Numb");
    } else if (e->isTerm()) {
        assert(e->getArity() >= 1);
        enodeid_t id = e->getCar()->getId();
        double ret = 0.0;
        Enode * tmp = e;
        switch (id) {
        case ENODE_ID_PLUS:
            ret = eval_enode_term(tmp->get1st(), b);
            tmp = tmp->getCdr()->getCdr();  // e is pointing to the 2nd arg
            while (!tmp->isEnil()) {
                ret = ret + eval_enode_term(tmp->getCar(), b);
                tmp = tmp->getCdr();
            }
            return ret;
        case ENODE_ID_MINUS:
            ret = eval_enode_term(tmp->get1st(), b);
            tmp = tmp->getCdr()->getCdr();  // e is pointing to the 2nd arg
            while (!tmp->isEnil()) {
                ret = ret - eval_enode_term(tmp->getCar(), b);
                tmp = tmp->getCdr();
            }
            return ret;
        case ENODE_ID_UMINUS:
            ret = eval_enode_term(tmp->get1st(), b);
            assert(tmp->getArity() == 1);
            return (- ret);
        case ENODE_ID_TIMES:
            ret = eval_enode_term(tmp->get1st(), b);
            tmp = tmp->getCdr()->getCdr();  // e is pointing to the 2nd arg
            while (!tmp->isEnil()) {
                ret = ret * eval_enode_term(tmp->getCar(), b);
                tmp = tmp->getCdr();
            }
            return ret;
        case ENODE_ID_DIV:
            ret = eval_enode_term(tmp->get1st(), b);
            tmp = tmp->getCdr()->getCdr();  // e is pointing to the 2nd arg
            while (!tmp->isEnil()) {
                ret = ret / eval_enode_term(tmp->getCar(), b);
                tmp = tmp->getCdr();
            }
            return ret;
        case ENODE_ID_ACOS:
            assert(e->getArity() == 1);
            return acos(eval_enode_term(e->get1st(), b));
        case ENODE_ID_ASIN:
            assert(e->getArity() == 1);
            return asin(eval_enode_term(e->get1st(), b));
        case ENODE_ID_ATAN:
            assert(e->getArity() == 1);
            return atan(eval_enode_term(e->get1st(), b));
        case ENODE_ID_ATAN2:
            assert(e->getArity() == 2);
            return atan2(eval_enode_term(e->get1st(), b),
                         eval_enode_term(e->get2nd(), b));
        case ENODE_ID_MIN:
            assert(e->getArity() == 2);
            return fmin(eval_enode_term(e->get1st(), b),
                        eval_enode_term(e->get2nd(), b));
        case ENODE_ID_MAX:
            assert(e->getArity() == 2);
            return fmax(eval_enode_term(e->get1st(), b),
                        eval_enode_term(e->get2nd(), b));
        case ENODE_ID_MATAN:
            assert(e->getArity() == 1);
            throw runtime_error("eval_enode: MATAN");
        case ENODE_ID_SAFESQRT:
            assert(e->getArity() == 1);
            throw runtime_error("eval_enode: SAFESQRT");
        case ENODE_ID_SQRT:
            assert(e->getArity() == 1);
            return sqrt(eval_enode_term(e->get1st(), b));
        case ENODE_ID_EXP:
            assert(e->getArity() == 1);
            return exp(eval_enode_term(e->get1st(), b));
        case ENODE_ID_LOG:
            assert(e->getArity() == 1);
            return log(eval_enode_term(e->get1st(), b));
        case ENODE_ID_POW:
            assert(e->getArity() == 2);
            return pow(eval_enode_term(e->get1st(), b),
                       eval_enode_term(e->get2nd(), b));
        case ENODE_ID_ABS:
            assert(e->getArity() == 1);
            return fabs(eval_enode_term(e->get1st(), b));
        case ENODE_ID_SIN:
            assert(e->getArity() == 1);
            return sin(eval_enode_term(e->get1st(), b));
        case ENODE_ID_COS:
            assert(e->getArity() == 1);
            return cos(eval_enode_term(e->get1st(), b));
        case ENODE_ID_TAN:
            assert(e->getArity() == 1);
            return tan(eval_enode_term(e->get1st(), b));
        case ENODE_ID_SINH:
            assert(e->getArity() == 1);
            return sinh(eval_enode_term(e->get1st(), b));
        case ENODE_ID_COSH:
            assert(e->getArity() == 1);
            return cosh(eval_enode_term(e->get1st(), b));
        case ENODE_ID_TANH:
            assert(e->getArity() == 1);
            return tanh(eval_enode_term(e->get1st(), b));
        default:
            throw runtime_error("eval_enode: Unknown Term");
        }
    } else if (e->isList()) {
        throw runtime_error("eval_enode: List");
    } else if (e->isDef()) {
        throw runtime_error("eval_enode: Def");
    } else if (e->isEnil()) {
        throw runtime_error("eval_enode: Nil");
    } else {
        throw runtime_error("eval_enode: unknown case");
    }
    throw runtime_error("Not implemented yet: eval_enode");
}