Implement analysis of conflicting rules
parent
6d157b325d
commit
37e676cedd
|
@ -29,6 +29,7 @@ class Solver
|
|||
const RULE_PACKAGE_CONFLICT = 7;
|
||||
const RULE_PACKAGE_NOT_EXIST = 8;
|
||||
const RULE_PACKAGE_REQUIRES = 9;
|
||||
const RULE_LEARNED = 10;
|
||||
|
||||
protected $policy;
|
||||
protected $pool;
|
||||
|
@ -1129,9 +1130,7 @@ class Solver
|
|||
}
|
||||
|
||||
// conflict
|
||||
$learnedRule = null;
|
||||
$why = null;
|
||||
$newLevel = $this->analyze($level, $rule, $learnedRule, $why);
|
||||
list($newLevel, $newRule, $why) = $this->analyze($level, $rule);
|
||||
|
||||
assert($newLevel > 0);
|
||||
assert($newLevel < $level);
|
||||
|
@ -1174,6 +1173,99 @@ class Solver
|
|||
return $this->setPropagateLearn($level, $literals[0], $disableRules, $rule);
|
||||
}
|
||||
|
||||
protected function analyze($level, $rule)
|
||||
{
|
||||
$ruleLevel = 1;
|
||||
$num = 0;
|
||||
$l1num = 0;
|
||||
$seen = array();
|
||||
$learnedLiterals = array(null);
|
||||
|
||||
$decisionId = count($this->decisionQueue);
|
||||
|
||||
$this->learnedPool[] = array();
|
||||
|
||||
while(true) {
|
||||
$this->learnedPool[count($this->learnedPool) - 1][] = $rule;
|
||||
|
||||
foreach ($rule->getLiterals() as $literal) {
|
||||
// skip the one true literal
|
||||
if ($this->decisionsSatisfy($literal)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($seen[$literal->getPackageId()])) {
|
||||
continue;
|
||||
}
|
||||
$seen[$literal->getPackageId()] = true;
|
||||
|
||||
$l = abs($this->decisionMap[$literal->getPackageId()]);
|
||||
|
||||
if (1 === $l) {
|
||||
$l1num++;
|
||||
} else if ($level === $l) {
|
||||
$num++;
|
||||
} else {
|
||||
// not level1 or conflict level, add to new rule
|
||||
$learnedLiterals[] = $literal;
|
||||
|
||||
if ($l > $ruleLevel) {
|
||||
$ruleLevel = $l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$l1retry = true;
|
||||
while ($l1retry) {
|
||||
|
||||
$l1retry = false;
|
||||
|
||||
if (!$num && !$l1num) {
|
||||
// all level 1 literals done
|
||||
break 2;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
assert($decisionId > 0);
|
||||
$decisionId--;
|
||||
|
||||
$literal = $this->decisionQueue[$decisionId];
|
||||
|
||||
if (isset($seen[$literal->getPackageId()])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unset($seen[$literal->getPackageId()]);
|
||||
|
||||
if ($num && 0 === --$num) {
|
||||
$learnedLiterals[0] = $this->literalFromId(-$literal->getPackageId());
|
||||
|
||||
if (!$l1num) {
|
||||
break 2;
|
||||
}
|
||||
|
||||
foreach ($this->learnedLiterals as $i => $learnedLiteral) {
|
||||
if ($i !== 0) {
|
||||
unset($seen[$literal->getPackageId()]);
|
||||
}
|
||||
}
|
||||
// only level 1 marks left
|
||||
$l1num++;
|
||||
$l1retry = true;
|
||||
}
|
||||
|
||||
$rule = $this->decisionQueueWhy[$decisionId];
|
||||
}
|
||||
}
|
||||
|
||||
$why = $this->learnedPool[count($this->learnedPool) - 1];
|
||||
|
||||
$newRule = new Rule($learnedLiterals, self::RULE_LEARNED, $why);
|
||||
|
||||
return array($ruleLevel, $newRule, $why);
|
||||
}
|
||||
|
||||
private function analyzeUnsolvableRule($conflictRule, &$lastWeakWhy)
|
||||
{
|
||||
$why = $conflictRule->getId();
|
||||
|
|
Loading…
Reference in New Issue