123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.cast_de_nrw_schule_svws_core_kursblockung_satsolver_SatSolver3 = exports.SatSolver3 = void 0;
- const AVLSet_1 = require("../../../core/adt/set/AVLSet");
- const Variable_1 = require("../../../core/kursblockung/satsolver/Variable");
- const SatSolverA_1 = require("../../../core/kursblockung/satsolver/SatSolverA");
- const NullPointerException_1 = require("../../../java/lang/NullPointerException");
- const LinkedCollection_1 = require("../../../core/adt/collection/LinkedCollection");
- const Clause_1 = require("../../../core/kursblockung/satsolver/Clause");
- const Arrays_1 = require("../../../java/util/Arrays");
- const Heap_1 = require("../../../core/kursblockung/satsolver/Heap");
- const System_1 = require("../../../java/lang/System");
- class SatSolver3 extends SatSolverA_1.SatSolverA {
- static MAX_LEARNED_CLAUSE_SIZE = 3;
- heap;
- vSize = 0;
- vArrayPos;
- vArrayNeg;
- cSize = 0;
- learnClauseMin = 0;
- /**
- * Konstruktor.
- */
- constructor() {
- super();
- this.heap = new Heap_1.Heap();
- this.vSize = 0;
- this.cSize = 0;
- this.vArrayPos = Array(1).fill(null);
- this.vArrayNeg = Array(1).fill(null);
- }
- isVarTrue(pVar) {
- let v = this.getVarOf(pVar);
- return v.index === -1;
- }
- createNewVar() {
- this.vSize++;
- if (this.vSize >= this.vArrayPos.length) {
- let newSize = this.vSize * 2;
- this.vArrayPos = Arrays_1.Arrays.copyOf(this.vArrayPos, newSize);
- this.vArrayNeg = Arrays_1.Arrays.copyOf(this.vArrayNeg, newSize);
- }
- let vPos = new Variable_1.Variable(+this.vSize);
- let vNeg = new Variable_1.Variable(-this.vSize);
- vPos.negation = vNeg;
- vNeg.negation = vPos;
- this.vArrayPos[this.vSize] = vPos;
- this.vArrayNeg[this.vSize] = vNeg;
- this.heap.insert(vPos);
- this.heap.insert(vNeg);
- return this.vSize;
- }
- addClause(pVars) {
- if (pVars.length === 0) {
- console.log(JSON.stringify("WARNUNG: Leere Klausel bei SatSolver.addClause(int[] pVars)!"));
- return;
- }
- let set = new AVLSet_1.AVLSet();
- for (let v of pVars) {
- if (set.contains(-v)) {
- return;
- }
- set.add(v);
- }
- let list = new LinkedCollection_1.LinkedCollection();
- while (!set.isEmpty()) {
- list.addLast(set.pollFirst());
- }
- while (list.size() > 3) {
- let x = list.removeFirst().valueOf();
- let y = list.removeFirst().valueOf();
- let z = this.createNewVar();
- list.addLast(z);
- this.addClause2(-x, z);
- this.addClause2(-y, z);
- this.addClause3(x, y, -z);
- }
- if (list.size() === 3) {
- this.addClause3(list.removeFirst().valueOf(), list.removeFirst().valueOf(), list.removeFirst().valueOf());
- }
- if (list.size() === 2) {
- this.addClause2(list.removeFirst().valueOf(), list.removeFirst().valueOf());
- }
- if (list.size() === 1) {
- this.addClause1(list.removeFirst().valueOf());
- }
- }
- /**
- * Fügt der Datenstruktur eine 1-CNF-Klausel hinzu.
- *
- * @param x Das 1. Literal (Variablennummer) der Klausel.
- */
- addClause1(x) {
- let varX = this.getVarOf(x);
- if (varX.negation === null)
- throw new NullPointerException_1.NullPointerException();
- this.heap.remove(varX);
- this.heap.remove(varX.negation);
- let c = new Clause_1.Clause(varX);
- this.cSize++;
- varX.clauses.addLast(c);
- varX.statSatFree[c.sat][c.free]++;
- this.heap.insert(varX);
- this.heap.insert(varX.negation);
- }
- /**
- * Fügt der Datenstruktur eine 2-CNF-Klausel hinzu.
- *
- * @param x Das 1. Literal (Variablennummer) der Klausel.
- * @param y Das 2. Literal (Variablennummer) der Klausel.
- */
- addClause2(x, y) {
- let varX = this.getVarOf(x);
- let varY = this.getVarOf(y);
- if ((varX.negation === null) || (varY.negation === null))
- throw new NullPointerException_1.NullPointerException();
- this.heap.remove(varX);
- this.heap.remove(varY);
- this.heap.remove(varX.negation);
- this.heap.remove(varY.negation);
- let c = new Clause_1.Clause(varX, varY);
- this.cSize++;
- varX.clauses.addLast(c);
- varX.statSatFree[c.sat][c.free]++;
- varX.neighbours.addLast(varY);
- varY.clauses.addLast(c);
- varY.statSatFree[c.sat][c.free]++;
- varY.neighbours.addLast(varX);
- this.heap.insert(varX);
- this.heap.insert(varY);
- this.heap.insert(varX.negation);
- this.heap.insert(varY.negation);
- }
- /**
- * Fügt der Datenstruktur eine 3-CNF-Klausel hinzu.
- *
- * @param x Das 1. Literal (Variablennummer) der Klausel.
- * @param y Das 2. Literal (Variablennummer) der Klausel.
- * @param z Das 3. Literal (Variablennummer) der Klausel.
- */
- addClause3(x, y, z) {
- let varX = this.getVarOf(x);
- let varY = this.getVarOf(y);
- let varZ = this.getVarOf(z);
- if ((varX.negation === null) || (varY.negation === null) || (varZ.negation === null))
- throw new NullPointerException_1.NullPointerException();
- this.heap.remove(varX);
- this.heap.remove(varY);
- this.heap.remove(varZ);
- this.heap.remove(varX.negation);
- this.heap.remove(varY.negation);
- this.heap.remove(varZ.negation);
- let c = new Clause_1.Clause(varX, varY, varZ);
- this.cSize++;
- varX.clauses.addLast(c);
- varX.statSatFree[c.sat][c.free]++;
- varX.neighbours.addLast(varY);
- varX.neighbours.addLast(varZ);
- varY.clauses.addLast(c);
- varY.statSatFree[c.sat][c.free]++;
- varY.neighbours.addLast(varX);
- varY.neighbours.addLast(varZ);
- varZ.clauses.addLast(c);
- varZ.statSatFree[c.sat][c.free]++;
- varZ.neighbours.addLast(varX);
- varZ.neighbours.addLast(varY);
- this.heap.insert(varX);
- this.heap.insert(varY);
- this.heap.insert(varZ);
- this.heap.insert(varX.negation);
- this.heap.insert(varY.negation);
- this.heap.insert(varZ.negation);
- }
- getVarCount() {
- return this.vSize;
- }
- getClauseCount() {
- return this.cSize;
- }
- solve(pMaxTimeMillis) {
- let timeStart = System_1.System.currentTimeMillis();
- let backtrackV = Array(this.vSize).fill(null);
- let backtrackLearn = Array(SatSolver3.MAX_LEARNED_CLAUSE_SIZE).fill(null);
- let backtrackB = Array(this.vSize).fill(false);
- let index = 0;
- let max = 1;
- let countDown = 0;
- this.learnClauseMin = SatSolver3.MAX_LEARNED_CLAUSE_SIZE + 1;
- let maxIndex = 0;
- while ((index >= 0) && !this.heap.isEmpty()) {
- if (index > maxIndex) {
- maxIndex = index;
- }
- if (countDown === 0) {
- for (let i = index; i >= 0; i--) {
- if (backtrackV[i] !== null) {
- this.unitpropagation_undo((0, Variable_1.cast_de_nrw_schule_svws_core_kursblockung_satsolver_Variable)(backtrackV[i]));
- }
- backtrackV[i] = null;
- backtrackB[i] = false;
- }
- index = 0;
- if ((this.learnClauseMin >= 1) && (this.learnClauseMin <= SatSolver3.MAX_LEARNED_CLAUSE_SIZE)) {
- let clause = Array(this.learnClauseMin).fill(0);
- for (let i = 0; i < clause.length; i++) {
- clause[i] = -backtrackLearn[i].nr;
- }
- this.addClause(clause);
- }
- let result = this.simplify();
- if (result !== SatSolverA_1.SatSolverA.RESULT_UNKNOWN) {
- return result;
- }
- max = max + 1 + Math.trunc(max / 2);
- countDown = max;
- this.learnClauseMin = SatSolver3.MAX_LEARNED_CLAUSE_SIZE + 1;
- if (System_1.System.currentTimeMillis() - timeStart > pMaxTimeMillis) {
- return SatSolverA_1.SatSolverA.RESULT_UNKNOWN;
- }
- continue;
- }
- countDown--;
- let varP = backtrackV[index];
- if ((varP !== null) && (backtrackB[index])) {
- this.unitpropagation_undo(varP);
- backtrackV[index] = null;
- backtrackB[index] = false;
- this.learnClause(backtrackV, backtrackLearn, index);
- index--;
- continue;
- }
- if (varP === null) {
- varP = this.heap.top();
- if (!varP.isUnsat()) {
- backtrackV[index] = varP;
- this.unitpropagation(varP);
- index++;
- continue;
- }
- }
- else {
- this.unitpropagation_undo(varP);
- }
- if (varP.negation === null)
- throw new NullPointerException_1.NullPointerException();
- varP = varP.negation;
- if (varP.isUnsat()) {
- backtrackV[index] = null;
- this.learnClause(backtrackV, backtrackLearn, index);
- index--;
- continue;
- }
- backtrackV[index] = varP;
- backtrackB[index] = true;
- this.unitpropagation(varP);
- index++;
- continue;
- }
- return this.heap.isEmpty() ? SatSolverA_1.SatSolverA.RESULT_SATISFIABLE : SatSolverA_1.SatSolverA.RESULT_UNSATISFIABLE;
- }
- learnClause(backtrackV, backtrackLearn, size) {
- if (size < 1) {
- return;
- }
- if (size >= this.learnClauseMin) {
- return;
- }
- this.learnClauseMin = size;
- for (let i = 0; i < size; i++) {
- backtrackLearn[i] = backtrackV[i];
- }
- }
- simplify() {
- let count1 = 0;
- let changed = true;
- while (changed) {
- changed = false;
- for (let nr = 1; nr <= this.vSize; nr++) {
- let varP = this.vArrayPos[nr];
- if (varP.index < 0) {
- continue;
- }
- if (varP.statSatFree[0][0] > 0) {
- return SatSolverA_1.SatSolverA.RESULT_UNSATISFIABLE;
- }
- if (varP.negation === null)
- throw new NullPointerException_1.NullPointerException();
- if (varP.negation.statSatFree[0][0] > 0) {
- return SatSolverA_1.SatSolverA.RESULT_UNSATISFIABLE;
- }
- if ((varP.statSatFree[0][1] > 0) && (varP.negation.statSatFree[0][1] > 0)) {
- return SatSolverA_1.SatSolverA.RESULT_UNSATISFIABLE;
- }
- if (varP.statSatFree[0][1] > 0) {
- this.unitpropagation(varP);
- count1++;
- changed = true;
- continue;
- }
- if (varP.negation.statSatFree[0][1] > 0) {
- this.unitpropagation(varP.negation);
- count1++;
- changed = true;
- continue;
- }
- if (varP.getClauseOccurences() === 0) {
- this.unitpropagation(varP.negation);
- count1++;
- changed = true;
- continue;
- }
- if (varP.negation.getClauseOccurences() === 0) {
- this.unitpropagation(varP);
- count1++;
- changed = true;
- continue;
- }
- }
- }
- return SatSolverA_1.SatSolverA.RESULT_UNKNOWN;
- }
- static fill(index) {
- let s = "";
- for (let i = 0; i < index; i++) {
- s = s.valueOf() + " ";
- }
- return s;
- }
- /**
- * Setzt die Variable {@code varP} auf TRUE und aktualisiert die gesamte Datenstruktur entsprechend.
- *
- * @param varP Die Variable, die auf TRUE gesetzt wird.
- */
- unitpropagation(varP) {
- let varN = varP.negation;
- if (varN === null)
- throw new NullPointerException_1.NullPointerException();
- this.heap.remove(varP);
- this.heap.remove(varN);
- varP.index = -1;
- varN.index = -2;
- this.unitpropagationHelper(varP.clauses, +1, -1);
- this.unitpropagationHelper(varN.clauses, +0, -1);
- }
- /**
- * Setzt die Variable {@code varP} von TRUE auf FREI und aktualisiert die gesamte Datenstruktur entsprechend.
- *
- * @param varP Die Variable, die von TRUE auf FREI gesetzt wird.
- */
- unitpropagation_undo(varP) {
- let varN = varP.negation;
- if (varN === null)
- throw new NullPointerException_1.NullPointerException();
- this.unitpropagationHelper(varP.clauses, -1, +1);
- this.unitpropagationHelper(varN.clauses, +0, +1);
- this.heap.insert(varP);
- this.heap.insert(varN);
- }
- /**
- * Eine Hilsmethode, die alle Klauseln der Liste aktualisiert.
- *
- * @param clauses Alle zu informmierenden Klausel.
- * @param pDeltaSat Die Veränderung der erfüllten Klauseln, relativ zum 1. Index im 2D-Array
- * {@link Variable#statSatFree}.
- * @param pDeltaFree Die Veränderung der freien Variablen, relativ zum 2. Index im 2D-Array
- * {@link Variable#statSatFree}.
- */
- unitpropagationHelper(clauses, pDeltaSat, pDeltaFree) {
- for (let c of clauses) {
- let sat1 = c.sat;
- let free1 = c.free;
- let sat2 = sat1 + pDeltaSat;
- let free2 = free1 + pDeltaFree;
- for (let v of c.variables) {
- v.statSatFree[sat1][free1]--;
- v.statSatFree[sat2][free2]++;
- this.heap.update(v);
- }
- c.sat = sat2;
- c.free = free2;
- }
- }
- /**
- * Liefert das zugehörige Variablenobjekt.
- *
- * @param pNr Der Variablennummer.
- *
- * @return Das zugehörige Variablenobjekt.
- */
- getVarOf(pNr) {
- return (pNr > 0) ? this.vArrayPos[pNr] : this.vArrayNeg[-pNr];
- }
- isTranspiledInstanceOf(name) {
- return ['de.nrw.schule.svws.core.kursblockung.satsolver.SatSolverA', 'de.nrw.schule.svws.core.kursblockung.satsolver.SatSolver3'].includes(name);
- }
- }
- exports.SatSolver3 = SatSolver3;
- function cast_de_nrw_schule_svws_core_kursblockung_satsolver_SatSolver3(obj) {
- return obj;
- }
- exports.cast_de_nrw_schule_svws_core_kursblockung_satsolver_SatSolver3 = cast_de_nrw_schule_svws_core_kursblockung_satsolver_SatSolver3;
- //# sourceMappingURL=SatSolver3.js.map
|