Beispiel #1
0
/*
 * @return:
 * 	1: you can never propagate l without a backtrack
 * 	2: you can not propagate l now, but maybe after more assignments
 * 	3: you can propagate l now
 */
int SymmetryPropagator::canPropagate(Lit l) {
	if (getPCSolver().isDecided(l.getAtom()) || symmetrical.count(l) == 0 || getPCSolver().value(symmetrical.at(l)) == l_True) {
		return 1;
	}
	if (getPCSolver().getLevel(l.getAtom()) == 0) {
		return 3;
	}

	rClause cl = getPCSolver().getExplanation(l);
	int nbUndefs = 0;
	for (int i = 0; i < getPCSolver().getClauseSize(cl); ++i) {
		lbool val = getPCSolver().value(getSymmetrical(getPCSolver().getClauseLit(cl, i)));
		if (val == l_True) {
			return 1;
		} else if (val == l_Undef) {
			++nbUndefs;
			if (nbUndefs >= 2) {
				return 2;
			}
		}
	}

	return 3;
}
std::string ExternalConstraintVisitor::toString(const Lit& l) const {
	auto overriddenit = atom2string.find(l.getAtom());
	if(overriddenit!=atom2string.cend()){
		return sign(l)?"~"+overriddenit->second:overriddenit->second;
	}
	std::stringstream ss;
	if (getRemapper()->wasInput(l)) {
		auto lit = getRemapper()->getLiteral(l);
		if (getTranslator()->hasTranslation(lit)) {
			ss << getTranslator()->toString(lit);
			return ss.str();
		}
	}
	ss << (sign(l) ? "~" : "") << "i_" << var(l) + 1; // NOTE: do not call <<l, this will cause an infinite loop (as that calls this method!)
	return ss.str();
}
Beispiel #3
0
rClause SymmetryPropagator::notifypropagate() {
	Lit l = getNextToPropagate();
	if (l == lit_Undef) {
		return nullPtrClause;
	}
	std::vector<Lit> symClause;
	if (getPCSolver().getLevel(l.getAtom()) == 0) {
		// TODO: @Broes: is this the right trick to use for a propagation / conflict at level 0?
		symClause.push_back(symmetrical.at(l));
		symClause.push_back(not l);
	} else {
		getSymmetricalClause(getPCSolver().getExplanation(l), symClause);
	}
	auto c = getPCSolver().createClause(Disjunction(getID(), symClause), true);
	bool isConflict = true;
	for (auto ll : symClause) {
		MAssert(getPCSolver().value(ll)==l_Undef || getPCSolver().value(ll)==l_False);
		if (getPCSolver().value(ll) == l_Undef) {
			isConflict = false;
			break;
		}
	}
	if (isConflict) {
		if (verbosity() > 1) {
			cout << "Symmetry propagation detected conflict!" << endl;
			for(auto ll: symClause){
				cout << ll.x << ",";// << "-" << getPCSolver().value(ll) << "|";
			}
			cout << endl;
		}
		getPCSolver().addConflictClause(c);
		return c;
	} else {
		if (verbosity() > 1) {
			cout << "Symmetry propagation detected propagation!" << endl;
			for(auto ll: symClause){
				cout << ll.x << ",";// << "-" << getPCSolver().value(ll) << "|";
			}
			cout << endl;
		}
		getPCSolver().addLearnedClause(c);
		return nullPtrClause;
	}
}
Beispiel #4
0
BinaryConstraint::BinaryConstraint(PCSolver* engine, IntView* _left, EqType comp, IntView* _right, const Lit& h)
		: Propagator(engine, "binary constraint") {
	// FIXME optimize if left and right are the same variable!
	switch (comp) {
	case EqType::EQ: {
		stringstream ss;
		ss <<_left->toString() << " = " << _right->toString();
		getPCSolver().setString(h.getAtom(),ss.str());
		auto lefthead = mkPosLit(getPCSolver().newAtom());
		auto righthead = mkPosLit(getPCSolver().newAtom());
		add(Implication(h, ImplicationType::EQUIVALENT, { lefthead, righthead }, true));
		add(CPBinaryRelVar(righthead, _left->getID(), EqType::GEQ, _right->getID()));
		head_ = lefthead;
		left_ = getPCSolver().getIntView(_left->getID(), 0);
		right_ = getPCSolver().getIntView(_right->getID(), 0);
		break;
	}
	case EqType::NEQ: {
		stringstream ss;
		ss <<_left->toString() << " != " << _right->toString();
		getPCSolver().setString(h.getAtom(),ss.str());
		auto lefthead = mkPosLit(getPCSolver().newAtom());
		auto righthead = mkPosLit(getPCSolver().newAtom());
		add(Implication(h, ImplicationType::EQUIVALENT, { lefthead, righthead }, false));
		add(CPBinaryRelVar(righthead, _left->getID(), EqType::G, _right->getID()));
		head_ = lefthead;
		left_ = getPCSolver().getIntView(_left->getID(), 0);
		if(_right->minValue()==getMinElem<int>()){
			add(Disjunction({head_}));
			notifyNotPresent();
			return;
		}
		right_ = getPCSolver().getIntView(_right->getID(), -1);
		break;
	}
	case EqType::LEQ:
		head_ = h;
		left_ = getPCSolver().getIntView(_left->getID(), 0);
		right_ = getPCSolver().getIntView(_right->getID(), 0);
		break;
	case EqType::L:
		head_ = h;
		left_ = getPCSolver().getIntView(_left->getID(), 0);
		if(_right->minValue()==getMinElem<int>()){
			add(Disjunction({not head_}));
			notifyNotPresent();
			return;
		}
		right_ = getPCSolver().getIntView(_right->getID(), -1);
		break;
	case EqType::GEQ:
		head_ = h;
		left_ = getPCSolver().getIntView(_right->getID(), 0);
		right_ = getPCSolver().getIntView(_left->getID(), 0);
		break;
	case EqType::G:
		head_ = h;
		left_ = getPCSolver().getIntView(_right->getID(), 0);
		if(_left->minValue()==getMinElem<int>()){
			add(Disjunction({not head_}));
			notifyNotPresent();
			return;
		}
		right_ = getPCSolver().getIntView(_left->getID(), -1);
		break;
	}

	getPCSolver().accept(this);
	getPCSolver().accept(this, head(), FAST);
	getPCSolver().accept(this, not head(), FAST);
	if(left_->isPartial()){
		add(Implication(not head(), ImplicationType::IMPLIEDBY, {left_->getNoImageLit()}, true));
		getPCSolver().accept(this, left_->getNoImageLit(), FAST);
		getPCSolver().accept(this, not left_->getNoImageLit(), FAST);
	}
	if(right_->isPartial()){
		add(Implication(not head(), ImplicationType::IMPLIEDBY, {right_->getNoImageLit()}, true));
		getPCSolver().accept(this, right_->getNoImageLit(), FAST);
		getPCSolver().accept(this, not right_->getNoImageLit(), FAST);
	}
	getPCSolver().acceptBounds(left(), this);
	getPCSolver().acceptBounds(right(), this);
	getPCSolver().acceptForPropagation(this);

	stringstream ss;
	ss<<left()->toString() << " =< " << right()->toString();
	getPCSolver().setString(head().getAtom(), ss.str());

	if (verbosity() > 5) {
		clog << "Binconstr: " << toString(head()) << " <=> " << left()->toString() << " =< " << right()->toString() << "\n";
	}
}