binary-decision-diagram 3.2.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +211 -31
  3. package/dist/cjs/src/abstract-node.js +7 -4
  4. package/dist/cjs/src/abstract-node.js.map +1 -1
  5. package/dist/cjs/src/branches.d.ts +4 -1
  6. package/dist/cjs/src/branches.js +10 -9
  7. package/dist/cjs/src/branches.js.map +1 -1
  8. package/dist/cjs/src/create-bdd-from-truth-table.js +1 -2
  9. package/dist/cjs/src/create-bdd-from-truth-table.js.map +1 -1
  10. package/dist/cjs/src/ensure-correct-bdd.js +2 -3
  11. package/dist/cjs/src/ensure-correct-bdd.js.map +1 -1
  12. package/dist/cjs/src/fill-truth-table.js +1 -2
  13. package/dist/cjs/src/fill-truth-table.js.map +1 -1
  14. package/dist/cjs/src/find-similar-node.js +1 -2
  15. package/dist/cjs/src/find-similar-node.js.map +1 -1
  16. package/dist/cjs/src/index.d.ts +2 -1
  17. package/dist/cjs/src/index.es5.js +17 -7
  18. package/dist/cjs/src/index.es5.js.map +1 -1
  19. package/dist/cjs/src/index.js +2 -1
  20. package/dist/cjs/src/index.js.map +1 -1
  21. package/dist/cjs/src/internal-node.js +6 -3
  22. package/dist/cjs/src/internal-node.js.map +1 -1
  23. package/dist/cjs/src/optimize-brute-force.js +10 -12
  24. package/dist/cjs/src/optimize-brute-force.js.map +1 -1
  25. package/dist/cjs/src/ordering/build-bdd.d.ts +13 -0
  26. package/dist/cjs/src/ordering/build-bdd.js +64 -0
  27. package/dist/cjs/src/ordering/build-bdd.js.map +1 -0
  28. package/dist/cjs/src/ordering/dense-truth-table.d.ts +42 -0
  29. package/dist/cjs/src/ordering/dense-truth-table.js +125 -0
  30. package/dist/cjs/src/ordering/dense-truth-table.js.map +1 -0
  31. package/dist/cjs/src/ordering/exact-cost-ordering.d.ts +91 -0
  32. package/dist/cjs/src/ordering/exact-cost-ordering.js +351 -0
  33. package/dist/cjs/src/ordering/exact-cost-ordering.js.map +1 -0
  34. package/dist/cjs/src/ordering/exact-ordering.d.ts +89 -0
  35. package/dist/cjs/src/ordering/exact-ordering.js +260 -0
  36. package/dist/cjs/src/ordering/exact-ordering.js.map +1 -0
  37. package/dist/cjs/src/ordering/index.d.ts +22 -0
  38. package/dist/cjs/src/ordering/index.js +38 -0
  39. package/dist/cjs/src/ordering/index.js.map +1 -0
  40. package/dist/cjs/src/ordering/int-pair-map.d.ts +20 -0
  41. package/dist/cjs/src/ordering/int-pair-map.js +85 -0
  42. package/dist/cjs/src/ordering/int-pair-map.js.map +1 -0
  43. package/dist/cjs/src/ordering/local-search.d.ts +114 -0
  44. package/dist/cjs/src/ordering/local-search.js +317 -0
  45. package/dist/cjs/src/ordering/local-search.js.map +1 -0
  46. package/dist/cjs/src/ordering/optimize-ordering.d.ts +153 -0
  47. package/dist/cjs/src/ordering/optimize-ordering.js +406 -0
  48. package/dist/cjs/src/ordering/optimize-ordering.js.map +1 -0
  49. package/dist/cjs/src/ordering/ordering-evaluator.d.ts +198 -0
  50. package/dist/cjs/src/ordering/ordering-evaluator.js +384 -0
  51. package/dist/cjs/src/ordering/ordering-evaluator.js.map +1 -0
  52. package/dist/cjs/src/ordering/shared-diagram.d.ts +85 -0
  53. package/dist/cjs/src/ordering/shared-diagram.js +295 -0
  54. package/dist/cjs/src/ordering/shared-diagram.js.map +1 -0
  55. package/dist/cjs/src/packed/index.d.ts +2 -0
  56. package/dist/cjs/src/{minimal-string → packed}/index.js +2 -5
  57. package/dist/cjs/src/packed/index.js.map +1 -0
  58. package/dist/cjs/src/packed/packed-bdd-base64-string.d.ts +3 -0
  59. package/dist/cjs/src/packed/packed-bdd-base64-string.js +46 -0
  60. package/dist/cjs/src/packed/packed-bdd-base64-string.js.map +1 -0
  61. package/dist/cjs/src/packed/packed-bdd.d.ts +13 -0
  62. package/dist/cjs/src/packed/packed-bdd.js +70 -0
  63. package/dist/cjs/src/packed/packed-bdd.js.map +1 -0
  64. package/dist/cjs/src/root-node.d.ts +1 -2
  65. package/dist/cjs/src/root-node.js +4 -9
  66. package/dist/cjs/src/root-node.js.map +1 -1
  67. package/dist/cjs/src/types.d.ts +0 -12
  68. package/dist/cjs/src/util.js +29 -21
  69. package/dist/cjs/src/util.js.map +1 -1
  70. package/dist/esm/src/abstract-node.js +7 -4
  71. package/dist/esm/src/abstract-node.js.map +1 -1
  72. package/dist/esm/src/branches.d.ts +4 -1
  73. package/dist/esm/src/branches.js +8 -7
  74. package/dist/esm/src/branches.js.map +1 -1
  75. package/dist/esm/src/create-bdd-from-truth-table.js.map +1 -1
  76. package/dist/esm/src/index.d.ts +2 -1
  77. package/dist/esm/src/index.js +2 -1
  78. package/dist/esm/src/index.js.map +1 -1
  79. package/dist/esm/src/internal-node.js +7 -4
  80. package/dist/esm/src/internal-node.js.map +1 -1
  81. package/dist/esm/src/optimize-brute-force.js +5 -7
  82. package/dist/esm/src/optimize-brute-force.js.map +1 -1
  83. package/dist/esm/src/ordering/build-bdd.d.ts +13 -0
  84. package/dist/esm/src/ordering/build-bdd.js +61 -0
  85. package/dist/esm/src/ordering/build-bdd.js.map +1 -0
  86. package/dist/esm/src/ordering/dense-truth-table.d.ts +42 -0
  87. package/dist/esm/src/ordering/dense-truth-table.js +117 -0
  88. package/dist/esm/src/ordering/dense-truth-table.js.map +1 -0
  89. package/dist/esm/src/ordering/exact-cost-ordering.d.ts +91 -0
  90. package/dist/esm/src/ordering/exact-cost-ordering.js +347 -0
  91. package/dist/esm/src/ordering/exact-cost-ordering.js.map +1 -0
  92. package/dist/esm/src/ordering/exact-ordering.d.ts +89 -0
  93. package/dist/esm/src/ordering/exact-ordering.js +256 -0
  94. package/dist/esm/src/ordering/exact-ordering.js.map +1 -0
  95. package/dist/esm/src/ordering/index.d.ts +22 -0
  96. package/dist/esm/src/ordering/index.js +17 -0
  97. package/dist/esm/src/ordering/index.js.map +1 -0
  98. package/dist/esm/src/ordering/int-pair-map.d.ts +20 -0
  99. package/dist/esm/src/ordering/int-pair-map.js +81 -0
  100. package/dist/esm/src/ordering/int-pair-map.js.map +1 -0
  101. package/dist/esm/src/ordering/local-search.d.ts +114 -0
  102. package/dist/esm/src/ordering/local-search.js +308 -0
  103. package/dist/esm/src/ordering/local-search.js.map +1 -0
  104. package/dist/esm/src/ordering/optimize-ordering.d.ts +153 -0
  105. package/dist/esm/src/ordering/optimize-ordering.js +399 -0
  106. package/dist/esm/src/ordering/optimize-ordering.js.map +1 -0
  107. package/dist/esm/src/ordering/ordering-evaluator.d.ts +198 -0
  108. package/dist/esm/src/ordering/ordering-evaluator.js +377 -0
  109. package/dist/esm/src/ordering/ordering-evaluator.js.map +1 -0
  110. package/dist/esm/src/ordering/shared-diagram.d.ts +85 -0
  111. package/dist/esm/src/ordering/shared-diagram.js +289 -0
  112. package/dist/esm/src/ordering/shared-diagram.js.map +1 -0
  113. package/dist/esm/src/packed/index.d.ts +2 -0
  114. package/dist/esm/src/packed/index.js +3 -0
  115. package/dist/esm/src/packed/index.js.map +1 -0
  116. package/dist/esm/src/packed/packed-bdd-base64-string.d.ts +3 -0
  117. package/dist/esm/src/packed/packed-bdd-base64-string.js +42 -0
  118. package/dist/esm/src/packed/packed-bdd-base64-string.js.map +1 -0
  119. package/dist/esm/src/packed/packed-bdd.d.ts +13 -0
  120. package/dist/esm/src/packed/packed-bdd.js +66 -0
  121. package/dist/esm/src/packed/packed-bdd.js.map +1 -0
  122. package/dist/esm/src/root-node.d.ts +1 -2
  123. package/dist/esm/src/root-node.js +5 -10
  124. package/dist/esm/src/root-node.js.map +1 -1
  125. package/dist/esm/src/types.d.ts +0 -12
  126. package/dist/esm/src/util.js +14 -5
  127. package/dist/esm/src/util.js.map +1 -1
  128. package/docs/variable-ordering.md +306 -0
  129. package/package.json +15 -12
  130. package/src/abstract-node.ts +7 -5
  131. package/src/branches.ts +9 -7
  132. package/src/create-bdd-from-truth-table.ts +1 -1
  133. package/src/index.ts +2 -1
  134. package/src/internal-node.ts +7 -4
  135. package/src/optimize-brute-force.ts +5 -7
  136. package/src/ordering/build-bdd.ts +70 -0
  137. package/src/ordering/dense-truth-table.ts +161 -0
  138. package/src/ordering/exact-cost-ordering.ts +425 -0
  139. package/src/ordering/exact-ordering.ts +317 -0
  140. package/src/ordering/index.ts +57 -0
  141. package/src/ordering/int-pair-map.ts +85 -0
  142. package/src/ordering/local-search.ts +369 -0
  143. package/src/ordering/optimize-ordering.ts +570 -0
  144. package/src/ordering/ordering-evaluator.ts +479 -0
  145. package/src/ordering/shared-diagram.ts +310 -0
  146. package/src/packed/index.ts +2 -0
  147. package/src/packed/packed-bdd-base64-string.ts +47 -0
  148. package/src/packed/packed-bdd.ts +98 -0
  149. package/src/root-node.ts +8 -17
  150. package/src/types.ts +0 -18
  151. package/src/util.ts +15 -6
  152. package/dist/cjs/src/minimal-string/bdd-to-minimal-string.d.ts +0 -8
  153. package/dist/cjs/src/minimal-string/bdd-to-minimal-string.js +0 -60
  154. package/dist/cjs/src/minimal-string/bdd-to-minimal-string.js.map +0 -1
  155. package/dist/cjs/src/minimal-string/bdd-to-simple-bdd.d.ts +0 -11
  156. package/dist/cjs/src/minimal-string/bdd-to-simple-bdd.js +0 -24
  157. package/dist/cjs/src/minimal-string/bdd-to-simple-bdd.js.map +0 -1
  158. package/dist/cjs/src/minimal-string/index.d.ts +0 -5
  159. package/dist/cjs/src/minimal-string/index.js.map +0 -1
  160. package/dist/cjs/src/minimal-string/minimal-string-to-simple-bdd.d.ts +0 -2
  161. package/dist/cjs/src/minimal-string/minimal-string-to-simple-bdd.js +0 -58
  162. package/dist/cjs/src/minimal-string/minimal-string-to-simple-bdd.js.map +0 -1
  163. package/dist/cjs/src/minimal-string/resolve-with-simple-bdd.d.ts +0 -2
  164. package/dist/cjs/src/minimal-string/resolve-with-simple-bdd.js +0 -21
  165. package/dist/cjs/src/minimal-string/resolve-with-simple-bdd.js.map +0 -1
  166. package/dist/cjs/src/minimal-string/string-format.d.ts +0 -9
  167. package/dist/cjs/src/minimal-string/string-format.js +0 -61
  168. package/dist/cjs/src/minimal-string/string-format.js.map +0 -1
  169. package/dist/esm/src/minimal-string/bdd-to-minimal-string.d.ts +0 -8
  170. package/dist/esm/src/minimal-string/bdd-to-minimal-string.js +0 -55
  171. package/dist/esm/src/minimal-string/bdd-to-minimal-string.js.map +0 -1
  172. package/dist/esm/src/minimal-string/bdd-to-simple-bdd.d.ts +0 -11
  173. package/dist/esm/src/minimal-string/bdd-to-simple-bdd.js +0 -19
  174. package/dist/esm/src/minimal-string/bdd-to-simple-bdd.js.map +0 -1
  175. package/dist/esm/src/minimal-string/index.d.ts +0 -5
  176. package/dist/esm/src/minimal-string/index.js +0 -6
  177. package/dist/esm/src/minimal-string/index.js.map +0 -1
  178. package/dist/esm/src/minimal-string/minimal-string-to-simple-bdd.d.ts +0 -2
  179. package/dist/esm/src/minimal-string/minimal-string-to-simple-bdd.js +0 -54
  180. package/dist/esm/src/minimal-string/minimal-string-to-simple-bdd.js.map +0 -1
  181. package/dist/esm/src/minimal-string/resolve-with-simple-bdd.d.ts +0 -2
  182. package/dist/esm/src/minimal-string/resolve-with-simple-bdd.js +0 -17
  183. package/dist/esm/src/minimal-string/resolve-with-simple-bdd.js.map +0 -1
  184. package/dist/esm/src/minimal-string/string-format.d.ts +0 -9
  185. package/dist/esm/src/minimal-string/string-format.js +0 -54
  186. package/dist/esm/src/minimal-string/string-format.js.map +0 -1
  187. package/src/minimal-string/bdd-to-minimal-string.ts +0 -72
  188. package/src/minimal-string/bdd-to-simple-bdd.ts +0 -31
  189. package/src/minimal-string/index.ts +0 -5
  190. package/src/minimal-string/minimal-string-to-simple-bdd.ts +0 -67
  191. package/src/minimal-string/resolve-with-simple-bdd.ts +0 -25
  192. package/src/minimal-string/string-format.ts +0 -67
@@ -0,0 +1,317 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LocalOrderingSearch = exports.MAX_WINDOW_SIZE = exports.DEFAULT_MAX_ROUNDS = exports.DEFAULT_WINDOW_SIZE = void 0;
4
+ exports.greedyTopDownOrdering = greedyTopDownOrdering;
5
+ exports.greedyBottomUpOrdering = greedyBottomUpOrdering;
6
+ exports.ensureNonNegativeInteger = ensureNonNegativeInteger;
7
+ exports.ensureWindowSize = ensureWindowSize;
8
+ exports.seedOrderings = seedOrderings;
9
+ const dense_truth_table_js_1 = require("./dense-truth-table.js");
10
+ /**
11
+ * Deterministic greedy construction:
12
+ * fills the levels from the top, at each level the boolean function
13
+ * that leads to the best BDD (with the other functions in their index order)
14
+ * is picked.
15
+ */
16
+ function greedyTopDownOrdering(evaluator) {
17
+ const n = evaluator.variableCount;
18
+ const prefix = [];
19
+ let remaining = (0, dense_truth_table_js_1.naturalOrdering)(n);
20
+ while (remaining.length > 1) {
21
+ let bestVar = -1;
22
+ let best = null;
23
+ for (const candidate of remaining) {
24
+ const ordering = prefix.concat([candidate], remaining.filter(v => v !== candidate));
25
+ const evaluation = evaluator.evaluate(ordering);
26
+ if (!best || evaluator.isBetter(evaluation, best)) {
27
+ best = evaluation;
28
+ bestVar = candidate;
29
+ }
30
+ }
31
+ prefix.push(bestVar);
32
+ remaining = remaining.filter(v => v !== bestVar);
33
+ }
34
+ return prefix.concat(remaining);
35
+ }
36
+ /**
37
+ * Deterministic greedy construction from the bottom:
38
+ * at each step the boolean function that is best as the lowest
39
+ * remaining level is picked.
40
+ */
41
+ function greedyBottomUpOrdering(evaluator) {
42
+ const n = evaluator.variableCount;
43
+ let suffix = [];
44
+ let remaining = (0, dense_truth_table_js_1.naturalOrdering)(n);
45
+ while (remaining.length > 1) {
46
+ let bestVar = -1;
47
+ let best = null;
48
+ for (const candidate of remaining) {
49
+ const ordering = remaining.filter(v => v !== candidate).concat([candidate], suffix);
50
+ const evaluation = evaluator.evaluate(ordering);
51
+ if (!best || evaluator.isBetter(evaluation, best)) {
52
+ best = evaluation;
53
+ bestVar = candidate;
54
+ }
55
+ }
56
+ suffix = [bestVar].concat(suffix);
57
+ remaining = remaining.filter(v => v !== bestVar);
58
+ }
59
+ return remaining.concat(suffix);
60
+ }
61
+ /**
62
+ * Lexicographically ordered permutations of 0..size-1
63
+ */
64
+ function allPermutations(size) {
65
+ const ret = [];
66
+ const recurse = (prefix, rest) => {
67
+ if (rest.length === 0) {
68
+ ret.push(prefix);
69
+ return;
70
+ }
71
+ for (let i = 0; i < rest.length; i++) {
72
+ recurse(prefix.concat([rest[i]]), rest.slice(0, i).concat(rest.slice(i + 1)));
73
+ }
74
+ };
75
+ recurse([], (0, dense_truth_table_js_1.naturalOrdering)(size));
76
+ return ret;
77
+ }
78
+ exports.DEFAULT_WINDOW_SIZE = 3;
79
+ exports.DEFAULT_MAX_ROUNDS = 50;
80
+ /**
81
+ * Window permutation tries all w! orderings of every window of w levels,
82
+ * larger windows take too long.
83
+ */
84
+ exports.MAX_WINDOW_SIZE = 8;
85
+ function ensureNonNegativeInteger(value, name) {
86
+ if (!Number.isInteger(value) || value < 0) {
87
+ throw new Error(name + ' must be a non-negative integer');
88
+ }
89
+ }
90
+ function ensureWindowSize(windowSize) {
91
+ ensureNonNegativeInteger(windowSize, 'windowSize');
92
+ if (windowSize > exports.MAX_WINDOW_SIZE) {
93
+ throw new Error('windowSize must be at most ' + exports.MAX_WINDOW_SIZE + ', window permutation tries windowSize! orderings per window');
94
+ }
95
+ }
96
+ /**
97
+ * Improves an ordering by sifting (moving each variable through all positions
98
+ * and keeping the best one) and exhaustive window permutation until no
99
+ * strict improvement is found anymore. "Better" is decided by
100
+ * OrderingEvaluator.isBetter(): fewer nodes, or with a cost model a lower
101
+ * expected cost. Everything is deterministic: the same input always gives
102
+ * the same output.
103
+ */
104
+ class LocalOrderingSearch {
105
+ evaluator;
106
+ best;
107
+ cursor;
108
+ n;
109
+ windowPermutations;
110
+ windowSize;
111
+ maxRounds;
112
+ onImprovement;
113
+ log;
114
+ constructor(evaluator, initialOrdering, options = {}) {
115
+ this.evaluator = evaluator;
116
+ this.n = evaluator.variableCount;
117
+ (0, dense_truth_table_js_1.ensureValidOrdering)(initialOrdering, this.n);
118
+ const windowSize = options.windowSize === undefined ? exports.DEFAULT_WINDOW_SIZE : options.windowSize;
119
+ ensureWindowSize(windowSize);
120
+ const maxRounds = options.maxRounds === undefined ? exports.DEFAULT_MAX_ROUNDS : options.maxRounds;
121
+ ensureNonNegativeInteger(maxRounds, 'maxRounds');
122
+ this.cursor = evaluator.cursor(initialOrdering);
123
+ this.best = this.cursor.evaluation;
124
+ this.windowSize = Math.min(windowSize, this.n);
125
+ // the identity permutation is the current state, no need to evaluate it again
126
+ this.windowPermutations = this.windowSize >= 2 ?
127
+ allPermutations(this.windowSize).filter(permutation => permutation.some((v, i) => v !== i)) :
128
+ [];
129
+ this.maxRounds = maxRounds;
130
+ this.onImprovement = options.onImprovement ? options.onImprovement : () => null;
131
+ this.log = options.log ? options.log : () => null;
132
+ }
133
+ /**
134
+ * ordering[level] = boolean function tested on that level
135
+ */
136
+ get ordering() {
137
+ return this.cursor.ordering;
138
+ }
139
+ result() {
140
+ return {
141
+ ordering: this.ordering.slice(),
142
+ nodeCount: this.best.nodeCount,
143
+ expectedCost: this.best.expectedCost,
144
+ nodesPerLevel: this.best.nodesPerLevel.slice(),
145
+ evaluation: this.best
146
+ };
147
+ }
148
+ /**
149
+ * Runs sifting rounds and window permutation rounds
150
+ * until a full cycle gives no improvement.
151
+ */
152
+ run() {
153
+ let round = 0;
154
+ while (round < this.maxRounds) {
155
+ round++;
156
+ const before = this.best;
157
+ this.siftRound();
158
+ if (this.windowSize >= 2) {
159
+ this.windowRound();
160
+ }
161
+ this.log('local search round ' + round + ': ' + this.describe(before) + ' -> ' + this.describe(this.best));
162
+ if (!this.evaluator.isBetter(this.best, before)) {
163
+ break;
164
+ }
165
+ }
166
+ return this.result();
167
+ }
168
+ /**
169
+ * One sifting round: each variable, largest level first,
170
+ * is moved to the position where the BDD is best.
171
+ * @returns true if the ordering improved
172
+ */
173
+ siftRound() {
174
+ const startEvaluation = this.best;
175
+ const n = this.n;
176
+ const positionOf = (v) => this.ordering.indexOf(v);
177
+ const variables = this.ordering.slice().sort((a, b) => {
178
+ const diff = this.best.nodesPerLevel[positionOf(b)] - this.best.nodesPerLevel[positionOf(a)];
179
+ return diff !== 0 ? diff : a - b;
180
+ });
181
+ for (const variable of variables) {
182
+ const start = positionOf(variable);
183
+ let bestEvaluation = this.best;
184
+ let bestPosition = start;
185
+ let position = start;
186
+ const moveTo = (target) => {
187
+ while (position < target) {
188
+ this.swapAdjacent(position);
189
+ position++;
190
+ }
191
+ while (position > target) {
192
+ this.swapAdjacent(position - 1);
193
+ position--;
194
+ }
195
+ };
196
+ const sweep = (target) => {
197
+ while (position !== target) {
198
+ const step = position < target ? 1 : -1;
199
+ this.swapAdjacent(step === 1 ? position : position - 1);
200
+ position += step;
201
+ const evaluation = this.cursor.evaluation;
202
+ if (this.evaluator.isBetter(evaluation, bestEvaluation)) {
203
+ bestEvaluation = evaluation;
204
+ bestPosition = position;
205
+ }
206
+ }
207
+ };
208
+ // go to the closer end first, then to the other end
209
+ if (start < n - 1 - start) {
210
+ sweep(0);
211
+ sweep(n - 1);
212
+ }
213
+ else {
214
+ sweep(n - 1);
215
+ sweep(0);
216
+ }
217
+ moveTo(bestPosition);
218
+ if (this.evaluator.isBetter(bestEvaluation, this.best)) {
219
+ this.best = bestEvaluation;
220
+ this.log('sifting: ' + this.describe(bestEvaluation));
221
+ this.onImprovement(this.progress('sifting'));
222
+ }
223
+ }
224
+ return this.evaluator.isBetter(this.best, startEvaluation);
225
+ }
226
+ /**
227
+ * One window permutation round: for each window of adjacent levels
228
+ * all permutations of its variables are tried.
229
+ * @returns true if the ordering improved
230
+ */
231
+ windowRound() {
232
+ const startEvaluation = this.best;
233
+ const w = this.windowSize;
234
+ if (w < 2) {
235
+ return false;
236
+ }
237
+ for (let windowStart = 0; windowStart + w <= this.n; windowStart++) {
238
+ const original = this.ordering.slice(windowStart, windowStart + w);
239
+ let bestEvaluation = this.best;
240
+ let bestPermutation = null;
241
+ for (const permutation of this.windowPermutations) {
242
+ this.setWindow(windowStart, original, permutation);
243
+ const evaluation = this.cursor.evaluation;
244
+ if (this.evaluator.isBetter(evaluation, bestEvaluation)) {
245
+ bestEvaluation = evaluation;
246
+ bestPermutation = permutation;
247
+ }
248
+ }
249
+ if (bestPermutation) {
250
+ this.setWindow(windowStart, original, bestPermutation);
251
+ this.best = bestEvaluation;
252
+ this.log('window permutation: ' + this.describe(bestEvaluation));
253
+ this.onImprovement(this.progress('window'));
254
+ }
255
+ else {
256
+ this.setWindow(windowStart, original, (0, dense_truth_table_js_1.naturalOrdering)(w));
257
+ }
258
+ }
259
+ return this.evaluator.isBetter(this.best, startEvaluation);
260
+ }
261
+ progress(phase) {
262
+ return {
263
+ ordering: this.ordering.slice(),
264
+ nodeCount: this.best.nodeCount,
265
+ expectedCost: this.best.expectedCost,
266
+ phase
267
+ };
268
+ }
269
+ describe(evaluation) {
270
+ return evaluation.nodeCount + ' nodes' +
271
+ (this.evaluator.costModel ? ', expected cost ' + evaluation.expectedCost : '');
272
+ }
273
+ /**
274
+ * swaps the variables of level and level+1
275
+ */
276
+ swapAdjacent(level) {
277
+ this.swapLevels(level, level + 1);
278
+ }
279
+ swapLevels(levelA, levelB) {
280
+ this.cursor.swap(levelA, levelB);
281
+ }
282
+ /**
283
+ * Arranges the window so that level (windowStart + i) holds original[permutation[i]].
284
+ */
285
+ setWindow(windowStart, original, permutation) {
286
+ for (let i = 0; i < permutation.length; i++) {
287
+ const wanted = original[permutation[i]];
288
+ const currentLevel = this.ordering.indexOf(wanted);
289
+ this.swapLevels(windowStart + i, currentLevel);
290
+ }
291
+ }
292
+ }
293
+ exports.LocalOrderingSearch = LocalOrderingSearch;
294
+ /**
295
+ * Deterministic start orderings for the local search.
296
+ */
297
+ function seedOrderings(evaluator) {
298
+ const n = evaluator.variableCount;
299
+ const natural = (0, dense_truth_table_js_1.naturalOrdering)(n);
300
+ const seeds = [
301
+ { name: 'natural', ordering: natural },
302
+ { name: 'reversed', ordering: natural.slice().reverse() },
303
+ { name: 'greedy-top-down', ordering: greedyTopDownOrdering(evaluator) },
304
+ { name: 'greedy-bottom-up', ordering: greedyBottomUpOrdering(evaluator) }
305
+ ];
306
+ // remove duplicates, keep the first occurrence
307
+ const seen = new Set();
308
+ return seeds.filter(seed => {
309
+ const key = seed.ordering.join(',');
310
+ if (seen.has(key)) {
311
+ return false;
312
+ }
313
+ seen.add(key);
314
+ return true;
315
+ });
316
+ }
317
+ //# sourceMappingURL=local-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-search.js","sourceRoot":"","sources":["../../../../src/ordering/local-search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,153 @@
1
+ import type { TruthTable } from '../types.js';
2
+ import { RootNode } from '../root-node.js';
3
+ import { DenseTruthTable } from './dense-truth-table.js';
4
+ import { CostModel } from './ordering-evaluator.js';
5
+ import { OrderingProgressCallback } from './local-search.js';
6
+ export declare const DEFAULT_MAX_EXACT_VARIABLES = 20;
7
+ export declare const DEFAULT_MAX_EXACT_NODE_COUNT = 5000;
8
+ export interface FindOrderingInput {
9
+ truthTable: TruthTable;
10
+ /**
11
+ * Value of the rows that can never occur at runtime.
12
+ * These rows are resolved exactly like removeIrrelevantLeafNodes() does it:
13
+ * a branch that only leads to don't-care rows is replaced by its sibling.
14
+ * Which ordering profits most from that is part of the search, but the
15
+ * rule itself is a heuristic, not the smallest possible completion.
16
+ */
17
+ dontCareValue?: number;
18
+ /**
19
+ * Cost of calling each boolean function: functionCosts[i] belongs to the
20
+ * boolean function with index i (the i-th character of the truth table keys).
21
+ * When given, the optimizer minimizes the expected cost of one resolve() call,
22
+ * that is the sum of the costs of the boolean functions that are called on the
23
+ * way from the root to the leaf, averaged over the rows, instead of the amount
24
+ * of nodes. Among orderings with the same expected cost, fewer nodes are
25
+ * preferred (best effort, not part of the optimality proof).
26
+ */
27
+ functionCosts?: number[];
28
+ /**
29
+ * How often each row occurs at runtime relative to the other rows,
30
+ * used together with functionCosts. Default: every row that is not a
31
+ * don't-care row occurs equally often. Don't-care rows never occur.
32
+ */
33
+ rowWeight?: (key: string, value: number) => number;
34
+ /**
35
+ * Additional start orderings for the local search, for example the
36
+ * best ordering of a previous run. ordering[level] is the index
37
+ * of the boolean function tested at that level.
38
+ */
39
+ initialOrderings?: number[][];
40
+ /**
41
+ * - 'auto' (default): run the exact search when the truth table has at
42
+ * most maxExactVariables boolean functions and the BDD found by the local
43
+ * search has at most maxExactNodeCount internal nodes (unstructured
44
+ * functions have big BDDs, and on them the exact search is slow and
45
+ * cannot gain much)
46
+ * - true: always run the exact search (within the budgets below)
47
+ * - false: never
48
+ */
49
+ exact?: boolean | 'auto';
50
+ /** Default: 20 */
51
+ maxExactVariables?: number;
52
+ /** Default: 5000 */
53
+ maxExactNodeCount?: number;
54
+ /**
55
+ * Budget of the exact search per candidate completion of the truth table.
56
+ * A candidate whose search exceeds it cannot be proven optimal.
57
+ * Default: 200000
58
+ */
59
+ maxExactExpansions?: number;
60
+ /**
61
+ * Memory budget of the exact search: the maximum amount of nodes of its
62
+ * internal diagram (roughly 100 bytes each).
63
+ * Default: 4000000
64
+ */
65
+ maxExactDiagramNodes?: number;
66
+ /**
67
+ * Size of the windows the local search permutes exhaustively,
68
+ * at most 8 (the work grows with windowSize!).
69
+ * Default: 3
70
+ */
71
+ windowSize?: number;
72
+ /**
73
+ * Maximum amount of sifting + window permutation rounds per start ordering.
74
+ * Default: 50
75
+ */
76
+ maxRounds?: number;
77
+ log?: boolean;
78
+ /** called whenever a better ordering was found */
79
+ onImprovement?: OrderingProgressCallback;
80
+ }
81
+ export interface FindOrderingResult {
82
+ /** ordering[level] = index of the boolean function tested at that level */
83
+ ordering: number[];
84
+ /** amount of nodes of the BDD, as RootNode.countNodes() returns it */
85
+ nodeCount: number;
86
+ /**
87
+ * Expected cost of one resolve() call with the returned ordering,
88
+ * only set when functionCosts were given.
89
+ */
90
+ expectedCost?: number;
91
+ /**
92
+ * true when the exact search has proven that no other ordering gives a
93
+ * BDD with fewer nodes (or, with functionCosts, a lower expected cost)
94
+ * for the truth table in `truthTable`. With don't-care rows that is one
95
+ * completion of the input: another ordering can occasionally reach a smaller
96
+ * BDD by resolving the don't-care rows differently.
97
+ */
98
+ optimal: boolean;
99
+ /**
100
+ * The truth table the BDD represents: the input table with the don't-care
101
+ * rows resolved, with the same keys as the input (iterated in row order).
102
+ * createBddWithOrdering(result.truthTable, result.ordering) rebuilds the BDD.
103
+ * When don't-care rows exist, this completion can differ from the one that
104
+ * createBddWithOrdering(input, result.ordering, dontCareValue) would pick.
105
+ */
106
+ truthTable: TruthTable;
107
+ stats: OptimizeOrderingStats;
108
+ }
109
+ export interface OptimizeOrderingStats {
110
+ /** amount of orderings that were evaluated */
111
+ evaluations: number;
112
+ /** amount of states the exact search expanded */
113
+ exactExpansions: number;
114
+ /** the amount of nodes found by the local search alone */
115
+ localSearchNodeCount: number;
116
+ durationMs: number;
117
+ }
118
+ export interface OptimizeOrderingInput extends FindOrderingInput {
119
+ /**
120
+ * Hook that runs on the created BDD before it is minimized,
121
+ * for compatibility with optimizeBruteForce().
122
+ * The optimizer cannot account for what the hook does, so prefer dontCareValue
123
+ * over removeIrrelevantLeafNodes() in the hook. When the hook changes the BDD,
124
+ * `optimal` is false, and `truthTable` and `expectedCost` describe the BDD
125
+ * before the hook.
126
+ */
127
+ afterBddCreation?: (bdd: RootNode) => void;
128
+ }
129
+ export interface OptimizeOrderingResult extends FindOrderingResult {
130
+ bdd: RootNode;
131
+ }
132
+ /**
133
+ * Validates functionCosts and rowWeight and turns them into a cost model.
134
+ */
135
+ export declare function buildCostModel(table: DenseTruthTable, functionCosts?: number[], rowWeight?: (key: string, value: number) => number): CostModel | null;
136
+ /**
137
+ * Deterministically finds a variable ordering with a small BDD
138
+ * (or, with functionCosts, with a cheap resolve() call).
139
+ * See docs/variable-ordering.md for how it works.
140
+ * Does not create BDD nodes, use optimizeOrdering() for that.
141
+ */
142
+ export declare function findOrdering(input: FindOrderingInput): FindOrderingResult;
143
+ /**
144
+ * Deterministic replacement for optimizeBruteForce():
145
+ * finds a good variable ordering and returns the minimized BDD for it.
146
+ * All work is synchronous, the promise exists for compatibility with optimizeBruteForce().
147
+ */
148
+ export declare function optimizeOrdering(input: OptimizeOrderingInput): Promise<OptimizeOrderingResult>;
149
+ /**
150
+ * Creates the minimized BDD of a truth table for a given ordering
151
+ * without going through the unreduced decision tree.
152
+ */
153
+ export declare function createBddWithOrdering(truthTable: TruthTable, ordering: ArrayLike<number>, dontCareValue?: number): RootNode;