mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
create Logic.Solution
This commit is contained in:
@@ -102,6 +102,10 @@ Logic.Solver = function () {
|
||||
// Map of Formulas whose info has `false` for either
|
||||
// `occursPositively` or `occursNegatively`
|
||||
this._ungeneratedFormulas = {}; // varNum -> Formula
|
||||
|
||||
this._numClausesAddedToMiniSat = 0;
|
||||
this._unsat = false; // once true, no solution henceforth
|
||||
this._minisat = null; // created lazily
|
||||
};
|
||||
|
||||
// Get a var number for vname, assigning it a number if it is new.
|
||||
@@ -1008,3 +1012,53 @@ Logic.sum = function (/*formulaOrBitsOrArray, ...*/) {
|
||||
|
||||
return new Logic.Bits(binaryWeightedSum(binaryWeighted));
|
||||
};
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
Logic.Solver.prototype.solve = function () {
|
||||
var self = this;
|
||||
|
||||
if (self._unsat) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! self._minisat) {
|
||||
self._minisat = new MiniSat();
|
||||
}
|
||||
|
||||
while (self._numClausesAddedToMiniSat < self.clauses.length) {
|
||||
var i = self._numClausesAddedToMiniSat;
|
||||
var stillSat = self._minisat.addClause(self.clauses[i].terms);
|
||||
self._numClausesAddedToMiniSat++;
|
||||
if (! stillSat) {
|
||||
self._unsat = true;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
var stillSat = self._minisat.solve();
|
||||
if (! stillSat) {
|
||||
self._unsat = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Logic.Solution(self, self._minisat.getSolution());
|
||||
};
|
||||
|
||||
Logic.Solution = function (_solver, _assignment) {
|
||||
this._solver = _solver;
|
||||
this._assignment = _assignment;
|
||||
};
|
||||
|
||||
Logic.Solution.prototype.getMap = function () {
|
||||
var solver = this._solver;
|
||||
var assignment = this._assignment;
|
||||
var result = {};
|
||||
for (var i = 1; i < assignment.length; i++) {
|
||||
var name = solver.getVarName(i);
|
||||
if (name && name.charAt(0) !== '$') {
|
||||
result[name] = assignment[i];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
@@ -1118,3 +1118,22 @@ Tinytest.add("logic-solver - MiniSat", function (test) {
|
||||
test.isFalse(M.solve());
|
||||
test.isFalse(M.addClause([4]));
|
||||
});
|
||||
|
||||
Tinytest.add("logic-solver - simple solve", function (test) {
|
||||
var s = new Logic.Solver;
|
||||
// Unique solution is (1,2,3,4) = (0,1,0,0)
|
||||
s.require("-D");
|
||||
s.require(Logic.or("-A", "-B"));
|
||||
s.require(Logic.or("D", "-A", "B"));
|
||||
s.require(Logic.or("A", "B", "C"));
|
||||
s.require(Logic.or("A", "B", "-C", "D"));
|
||||
s.require(Logic.or("A", "-B", "-C"));
|
||||
var sol = s.solve();
|
||||
test.isTrue(sol);
|
||||
test.equal(sol.getMap(), {
|
||||
A: false, B: true, C: false, D: false
|
||||
});
|
||||
s.require(Logic.or("A", "-B", "C", "D"));
|
||||
var sol2 = s.solve();
|
||||
test.isFalse(sol2);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user