SatSolverWrapper.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.cast_de_nrw_schule_svws_core_kursblockung_satsolver_SatSolverWrapper = exports.SatSolverWrapper = void 0;
  4. const JavaObject_1 = require("../../../java/lang/JavaObject");
  5. const SatSolverA_1 = require("../../../core/kursblockung/satsolver/SatSolverA");
  6. const LinkedCollection_1 = require("../../../core/adt/collection/LinkedCollection");
  7. class SatSolverWrapper extends SatSolverA_1.SatSolverA {
  8. _solver;
  9. varFALSE;
  10. varTRUE;
  11. /**
  12. * Erstellt eine Ebene über dem {@link SatSolverA}, um verschiedene Bedingungen/Constraints als Klauseln zu
  13. * codieren.
  14. *
  15. * @param solver Der Solver, der intern verwendet wird.
  16. */
  17. constructor(solver) {
  18. super();
  19. this._solver = solver;
  20. this.varTRUE = this._solver.createNewVar();
  21. this.varFALSE = -this.varTRUE;
  22. this.c_1(this.varTRUE);
  23. }
  24. createNewVar() {
  25. return this._solver.createNewVar();
  26. }
  27. addClause(pVars) {
  28. this._solver.addClause(pVars);
  29. }
  30. isVarTrue(pVar) {
  31. return this._solver.isVarTrue(pVar);
  32. }
  33. solve(maxTimeMillis) {
  34. return this._solver.solve(maxTimeMillis);
  35. }
  36. getVarCount() {
  37. return this._solver.getVarCount();
  38. }
  39. getClauseCount() {
  40. return this._solver.getClauseCount();
  41. }
  42. /**
  43. * Liefert ein Array der Länge n mit neu erzeugten Variablennummern.
  44. *
  45. * @param n Die Länge des Arrays.
  46. *
  47. * @return Ein Array der Länge n mit neu erzeugten Variablennummern.
  48. */
  49. createNewVars(n) {
  50. let temp = Array(n).fill(0);
  51. for (let i = 0; i < temp.length; i++) {
  52. temp[i] = this._solver.createNewVar();
  53. }
  54. return temp;
  55. }
  56. /**
  57. * Liefert eine Variable, die zuvor auf FALSE forciert wurde.
  58. *
  59. * @return Eine Variable, die zuvor auf FALSE forciert wurde.
  60. */
  61. getVarFALSE() {
  62. return this.varFALSE;
  63. }
  64. /**
  65. * Liefert eine Variable, die zuvor auf TRUE forciert wurde.
  66. *
  67. * @return Eine Variable, die zuvor auf TRUE forciert wurde.
  68. */
  69. getVarTRUE() {
  70. return this.varTRUE;
  71. }
  72. /**
  73. * Fügt eine Klausel der Größe 1 hinzu. Forciert damit die übergebene Variable auf TRUE.
  74. *
  75. * @param x Die Variable wird auf TRUE gesetzt.
  76. */
  77. c_1(x) {
  78. this._solver.addClause([x]);
  79. }
  80. /**
  81. * Fügt eine Klausel der Größe 2 hinzu. Forciert damit, dass mindestens eine der beiden Variablen TRUE ist,
  82. * letzlich @code{x + y >= 1}.
  83. *
  84. * @param x Die Variable x der Klausel (x OR y).
  85. * @param y Die Variable y der Klausel (x OR y).
  86. */
  87. c_2(x, y) {
  88. this._solver.addClause([x, y]);
  89. }
  90. /**
  91. * Fügt eine Klausel der Größe 3 hinzu. Forciert damit, dass mindestens eine der drei Variablen TRUE ist,
  92. * letzlich @code{x + y + z >= 1}.
  93. *
  94. * @param x Die Variable x der Klausel (x OR y OR z).
  95. * @param y Die Variable y der Klausel (x OR y OR z).
  96. * @param z Die Variable z der Klausel (x OR y OR z).
  97. */
  98. c_3(x, y, z) {
  99. this._solver.addClause([x, y, z]);
  100. }
  101. /**
  102. * Forciert, dass nicht beide Variablen TRUE sind, letzlich @code{x + y ≤ 1}.
  103. *
  104. * @param x Die Variable x der Klausel (-x OR -y).
  105. * @param y Die Variable y der Klausel (-x OR -y).
  106. */
  107. c_not_both(x, y) {
  108. this.c_2(-x, -y);
  109. }
  110. /**
  111. * Liefert die Variable z für die {@code z = x AND y} gilt.
  112. *
  113. * @param x Variable der obigen Gleichung.
  114. * @param y Variable der obigen Gleichung.
  115. *
  116. * @return Die Variable z für die {@code z = x AND y} gilt.
  117. */
  118. c_new_var_AND(x, y) {
  119. let c = this._solver.createNewVar();
  120. this.c_2(x, -c);
  121. this.c_2(y, -c);
  122. this.c_3(-x, -y, c);
  123. return c;
  124. }
  125. /**
  126. * Implementation for method overloads of 'c_exactly_GENERIC'
  127. */
  128. c_exactly_GENERIC(__param0, __param1) {
  129. if (((typeof __param0 !== "undefined") && Array.isArray(__param0)) && ((typeof __param1 !== "undefined") && typeof __param1 === "number")) {
  130. let pArray = __param0;
  131. let amount = __param1;
  132. this.c_exactly_GENERIC(SatSolverWrapper.toList(pArray), amount);
  133. }
  134. else if (((typeof __param0 !== "undefined") && ((__param0 instanceof JavaObject_1.JavaObject) && (__param0.isTranspiledInstanceOf('de.nrw.schule.svws.core.adt.collection.LinkedCollection'))) || (__param0 === null)) && ((typeof __param1 !== "undefined") && typeof __param1 === "number")) {
  135. let list = (0, LinkedCollection_1.cast_de_nrw_schule_svws_core_adt_collection_LinkedCollection)(__param0);
  136. let amount = __param1;
  137. list = new LinkedCollection_1.LinkedCollection(list);
  138. if (amount > list.size()) {
  139. console.log(JSON.stringify("FEHLER: c_exactly_GENERIC --> amount > list.size()"));
  140. }
  141. if (amount === 0) {
  142. for (let x of list) {
  143. this.c_1(-x);
  144. }
  145. return;
  146. }
  147. if (amount === list.size()) {
  148. for (let x of list) {
  149. this.c_1(+x);
  150. }
  151. return;
  152. }
  153. if (amount === 1) {
  154. if (list.size() === 1) {
  155. this.c_1(list.getFirst().valueOf());
  156. return;
  157. }
  158. if (list.size() === 2) {
  159. this.c_unequal(list.getFirst().valueOf(), list.getLast().valueOf());
  160. return;
  161. }
  162. this.c_exactly_one(list);
  163. return;
  164. }
  165. this.c_exactly_NETWORK(list, amount);
  166. }
  167. else
  168. throw new Error('invalid method overload');
  169. }
  170. /**
  171. * Forciert, dass höchstens {@code maximum} Variablen der Variablenliste den Wert TRUE haben.
  172. *
  173. * @param list Die Variablenliste.
  174. * @param maximum Die maximale Anzahl an TRUEs in der Variablenliste.
  175. */
  176. c_at_most_GENERIC(list, maximum) {
  177. list = new LinkedCollection_1.LinkedCollection(list);
  178. if (maximum >= list.size()) {
  179. return;
  180. }
  181. if (maximum === 0) {
  182. for (let x of list) {
  183. this.c_1(-x);
  184. }
  185. return;
  186. }
  187. if (maximum === 1) {
  188. this.c_at_most_one_tree(list);
  189. return;
  190. }
  191. this.c_at_most_NETWORK(list, maximum);
  192. }
  193. /**
  194. * Forciert, dass genau eine Variable der Liste TRUE ist. Falls die Liste leer ist, führt das zur direkten
  195. * Unlösbarkeit der Formel.
  196. *
  197. * @param list Genau eine der Variablen der Liste muss TRUE sein.
  198. */
  199. c_exactly_one(list) {
  200. this.c_1(this.c_at_most_one_tree(list));
  201. }
  202. /**
  203. * Forciert, dass {@code z = x OR y} gilt.
  204. *
  205. * @param x Variable der obigen Gleichung.
  206. * @param y Variable der obigen Gleichung.
  207. * @param z Variable der obigen Gleichung.
  208. */
  209. c_z_equals_x_or_y(x, y, z) {
  210. this.c_2(-x, z);
  211. this.c_2(-y, z);
  212. this.c_3(x, y, -z);
  213. }
  214. /**
  215. * Liefert die Variable z für die {@code z = x OR y} gilt.
  216. *
  217. * @param x Variable der obigen Gleichung.
  218. * @param y Variable der obigen Gleichung.
  219. *
  220. * @return Die Variable z für die {@code z = x OR y} gilt.
  221. */
  222. c_new_var_OR(x, y) {
  223. let z = this._solver.createNewVar();
  224. this.c_2(-x, z);
  225. this.c_2(-y, z);
  226. this.c_3(x, y, -z);
  227. return z;
  228. }
  229. /**
  230. * Forciert, dass in der Liste maximal eine Variable TRUE ist. Die Ergebnisvariable ist eine OR-Verknüpfung
  231. * aller Variablen der Liste.
  232. *
  233. * @param list Forciert, dass maximal eine Variable der Liste TRUE ist.
  234. *
  235. * @return Die Ergebnisvariable ist eine OR-Verknüpfung aller Variablen der Liste.
  236. */
  237. c_at_most_one_tree(list) {
  238. list = new LinkedCollection_1.LinkedCollection(list);
  239. if (list.isEmpty()) {
  240. list.add(this.varFALSE);
  241. }
  242. while (list.size() >= 2) {
  243. let a = list.removeFirst().valueOf();
  244. let b = list.removeFirst().valueOf();
  245. let c = this._solver.createNewVar();
  246. this.c_not_both(a, b);
  247. this.c_z_equals_x_or_y(a, b, c);
  248. list.add(c);
  249. }
  250. return list.removeFirst().valueOf();
  251. }
  252. c_exactly_NETWORK(list, amount) {
  253. this.c_bitonic_sort(list);
  254. let i = 0;
  255. let iter = list.iterator();
  256. while (iter.hasNext()) {
  257. let value = iter.next();
  258. if (i < amount) {
  259. this.c_1(+value.valueOf());
  260. }
  261. else {
  262. this.c_1(-value.valueOf());
  263. }
  264. i++;
  265. }
  266. }
  267. c_at_most_NETWORK(list, maximum) {
  268. this.c_bitonic_sort(list);
  269. let i = 0;
  270. let iter = list.iterator();
  271. while (iter.hasNext()) {
  272. let value = iter.next();
  273. if (i < maximum)
  274. i++;
  275. else
  276. this.c_1(-value.valueOf());
  277. }
  278. }
  279. c_bitonic_sort(list) {
  280. this.c_fill_False_until_power_two(list);
  281. this.c_bitonic_sort_power_two(list);
  282. }
  283. c_fill_False_until_power_two(list) {
  284. let size = 1;
  285. while (size < list.size()) {
  286. size *= 2;
  287. }
  288. while (list.size() < size) {
  289. list.addLast(this.varFALSE);
  290. }
  291. }
  292. c_bitonic_sort_power_two(list) {
  293. for (let window = 2; window <= list.size(); window *= 2) {
  294. this.c_bitonic_sort_spiral(list, window);
  295. for (let difference = Math.trunc(window / 2); difference >= 2; difference /= 2) {
  296. this.c_bitonic_sort_difference(list, difference);
  297. }
  298. }
  299. }
  300. c_bitonic_sort_spiral(list, size) {
  301. for (let i = 0; i < list.size(); i += size) {
  302. for (let i1 = i, i2 = i + size - 1; i1 < i2; i1++, i2--) {
  303. this.c_bitonic_comparator(list, i1, i2);
  304. }
  305. }
  306. }
  307. c_bitonic_sort_difference(list, size) {
  308. let half = Math.trunc(size / 2);
  309. for (let i = 0; i < list.size(); i += size) {
  310. for (let j = 0; j < half; j++) {
  311. this.c_bitonic_comparator(list, i + j, i + j + half);
  312. }
  313. }
  314. }
  315. c_bitonic_comparator(result, i1, i2) {
  316. if (i1 >= i2) {
  317. console.log(JSON.stringify("c_bitonic_comparator: " + i1 + "," + i2 + " <-- ERROR!!!"));
  318. }
  319. let a = result.get(i1).valueOf();
  320. let b = result.get(i2).valueOf();
  321. result.set(i1, this.c_new_var_OR(a, b));
  322. result.set(i2, this.c_new_var_AND(a, b));
  323. }
  324. static toList(pArray) {
  325. let list = new LinkedCollection_1.LinkedCollection();
  326. for (let x of pArray) {
  327. list.addLast(x);
  328. }
  329. return list;
  330. }
  331. c_unequal(x, y) {
  332. this.c_equal(x, -y);
  333. }
  334. c_equal(x, y) {
  335. this.c_2(-x, +y);
  336. this.c_2(+x, -y);
  337. }
  338. isTranspiledInstanceOf(name) {
  339. return ['de.nrw.schule.svws.core.kursblockung.satsolver.SatSolverA', 'de.nrw.schule.svws.core.kursblockung.satsolver.SatSolverWrapper'].includes(name);
  340. }
  341. }
  342. exports.SatSolverWrapper = SatSolverWrapper;
  343. function cast_de_nrw_schule_svws_core_kursblockung_satsolver_SatSolverWrapper(obj) {
  344. return obj;
  345. }
  346. exports.cast_de_nrw_schule_svws_core_kursblockung_satsolver_SatSolverWrapper = cast_de_nrw_schule_svws_core_kursblockung_satsolver_SatSolverWrapper;
  347. //# sourceMappingURL=SatSolverWrapper.js.map