binary-decision-diagram 4.0.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 (185) 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 +1 -0
  6. package/dist/cjs/src/branches.js +2 -1
  7. package/dist/cjs/src/branches.js.map +1 -1
  8. package/dist/cjs/src/create-bdd-from-truth-table.js.map +1 -1
  9. package/dist/cjs/src/index.d.ts +2 -1
  10. package/dist/cjs/src/index.es5.js +17 -7
  11. package/dist/cjs/src/index.es5.js.map +1 -1
  12. package/dist/cjs/src/index.js +2 -1
  13. package/dist/cjs/src/index.js.map +1 -1
  14. package/dist/cjs/src/internal-node.js +6 -3
  15. package/dist/cjs/src/internal-node.js.map +1 -1
  16. package/dist/cjs/src/optimize-brute-force.js +5 -7
  17. package/dist/cjs/src/optimize-brute-force.js.map +1 -1
  18. package/dist/cjs/src/ordering/build-bdd.d.ts +13 -0
  19. package/dist/cjs/src/ordering/build-bdd.js +64 -0
  20. package/dist/cjs/src/ordering/build-bdd.js.map +1 -0
  21. package/dist/cjs/src/ordering/dense-truth-table.d.ts +42 -0
  22. package/dist/cjs/src/ordering/dense-truth-table.js +125 -0
  23. package/dist/cjs/src/ordering/dense-truth-table.js.map +1 -0
  24. package/dist/cjs/src/ordering/exact-cost-ordering.d.ts +91 -0
  25. package/dist/cjs/src/ordering/exact-cost-ordering.js +351 -0
  26. package/dist/cjs/src/ordering/exact-cost-ordering.js.map +1 -0
  27. package/dist/cjs/src/ordering/exact-ordering.d.ts +89 -0
  28. package/dist/cjs/src/ordering/exact-ordering.js +260 -0
  29. package/dist/cjs/src/ordering/exact-ordering.js.map +1 -0
  30. package/dist/cjs/src/ordering/index.d.ts +22 -0
  31. package/dist/cjs/src/ordering/index.js +38 -0
  32. package/dist/cjs/src/ordering/index.js.map +1 -0
  33. package/dist/cjs/src/ordering/int-pair-map.d.ts +20 -0
  34. package/dist/cjs/src/ordering/int-pair-map.js +85 -0
  35. package/dist/cjs/src/ordering/int-pair-map.js.map +1 -0
  36. package/dist/cjs/src/ordering/local-search.d.ts +114 -0
  37. package/dist/cjs/src/ordering/local-search.js +317 -0
  38. package/dist/cjs/src/ordering/local-search.js.map +1 -0
  39. package/dist/cjs/src/ordering/optimize-ordering.d.ts +153 -0
  40. package/dist/cjs/src/ordering/optimize-ordering.js +406 -0
  41. package/dist/cjs/src/ordering/optimize-ordering.js.map +1 -0
  42. package/dist/cjs/src/ordering/ordering-evaluator.d.ts +198 -0
  43. package/dist/cjs/src/ordering/ordering-evaluator.js +384 -0
  44. package/dist/cjs/src/ordering/ordering-evaluator.js.map +1 -0
  45. package/dist/cjs/src/ordering/shared-diagram.d.ts +85 -0
  46. package/dist/cjs/src/ordering/shared-diagram.js +295 -0
  47. package/dist/cjs/src/ordering/shared-diagram.js.map +1 -0
  48. package/dist/cjs/src/packed/index.d.ts +2 -0
  49. package/dist/cjs/src/{minimal-string → packed}/index.js +2 -5
  50. package/dist/cjs/src/packed/index.js.map +1 -0
  51. package/dist/cjs/src/packed/packed-bdd-base64-string.d.ts +3 -0
  52. package/dist/cjs/src/packed/packed-bdd-base64-string.js +46 -0
  53. package/dist/cjs/src/packed/packed-bdd-base64-string.js.map +1 -0
  54. package/dist/cjs/src/packed/packed-bdd.d.ts +13 -0
  55. package/dist/cjs/src/packed/packed-bdd.js +70 -0
  56. package/dist/cjs/src/packed/packed-bdd.js.map +1 -0
  57. package/dist/cjs/src/root-node.d.ts +1 -2
  58. package/dist/cjs/src/root-node.js +1 -5
  59. package/dist/cjs/src/root-node.js.map +1 -1
  60. package/dist/cjs/src/types.d.ts +0 -12
  61. package/dist/cjs/src/util.js +14 -5
  62. package/dist/cjs/src/util.js.map +1 -1
  63. package/dist/esm/src/abstract-node.js +7 -4
  64. package/dist/esm/src/abstract-node.js.map +1 -1
  65. package/dist/esm/src/branches.d.ts +1 -0
  66. package/dist/esm/src/branches.js +1 -0
  67. package/dist/esm/src/branches.js.map +1 -1
  68. package/dist/esm/src/create-bdd-from-truth-table.js.map +1 -1
  69. package/dist/esm/src/index.d.ts +2 -1
  70. package/dist/esm/src/index.js +2 -1
  71. package/dist/esm/src/index.js.map +1 -1
  72. package/dist/esm/src/internal-node.js +7 -4
  73. package/dist/esm/src/internal-node.js.map +1 -1
  74. package/dist/esm/src/optimize-brute-force.js +5 -7
  75. package/dist/esm/src/optimize-brute-force.js.map +1 -1
  76. package/dist/esm/src/ordering/build-bdd.d.ts +13 -0
  77. package/dist/esm/src/ordering/build-bdd.js +61 -0
  78. package/dist/esm/src/ordering/build-bdd.js.map +1 -0
  79. package/dist/esm/src/ordering/dense-truth-table.d.ts +42 -0
  80. package/dist/esm/src/ordering/dense-truth-table.js +117 -0
  81. package/dist/esm/src/ordering/dense-truth-table.js.map +1 -0
  82. package/dist/esm/src/ordering/exact-cost-ordering.d.ts +91 -0
  83. package/dist/esm/src/ordering/exact-cost-ordering.js +347 -0
  84. package/dist/esm/src/ordering/exact-cost-ordering.js.map +1 -0
  85. package/dist/esm/src/ordering/exact-ordering.d.ts +89 -0
  86. package/dist/esm/src/ordering/exact-ordering.js +256 -0
  87. package/dist/esm/src/ordering/exact-ordering.js.map +1 -0
  88. package/dist/esm/src/ordering/index.d.ts +22 -0
  89. package/dist/esm/src/ordering/index.js +17 -0
  90. package/dist/esm/src/ordering/index.js.map +1 -0
  91. package/dist/esm/src/ordering/int-pair-map.d.ts +20 -0
  92. package/dist/esm/src/ordering/int-pair-map.js +81 -0
  93. package/dist/esm/src/ordering/int-pair-map.js.map +1 -0
  94. package/dist/esm/src/ordering/local-search.d.ts +114 -0
  95. package/dist/esm/src/ordering/local-search.js +308 -0
  96. package/dist/esm/src/ordering/local-search.js.map +1 -0
  97. package/dist/esm/src/ordering/optimize-ordering.d.ts +153 -0
  98. package/dist/esm/src/ordering/optimize-ordering.js +399 -0
  99. package/dist/esm/src/ordering/optimize-ordering.js.map +1 -0
  100. package/dist/esm/src/ordering/ordering-evaluator.d.ts +198 -0
  101. package/dist/esm/src/ordering/ordering-evaluator.js +377 -0
  102. package/dist/esm/src/ordering/ordering-evaluator.js.map +1 -0
  103. package/dist/esm/src/ordering/shared-diagram.d.ts +85 -0
  104. package/dist/esm/src/ordering/shared-diagram.js +289 -0
  105. package/dist/esm/src/ordering/shared-diagram.js.map +1 -0
  106. package/dist/esm/src/packed/index.d.ts +2 -0
  107. package/dist/esm/src/packed/index.js +3 -0
  108. package/dist/esm/src/packed/index.js.map +1 -0
  109. package/dist/esm/src/packed/packed-bdd-base64-string.d.ts +3 -0
  110. package/dist/esm/src/packed/packed-bdd-base64-string.js +42 -0
  111. package/dist/esm/src/packed/packed-bdd-base64-string.js.map +1 -0
  112. package/dist/esm/src/packed/packed-bdd.d.ts +13 -0
  113. package/dist/esm/src/packed/packed-bdd.js +66 -0
  114. package/dist/esm/src/packed/packed-bdd.js.map +1 -0
  115. package/dist/esm/src/root-node.d.ts +1 -2
  116. package/dist/esm/src/root-node.js +1 -5
  117. package/dist/esm/src/root-node.js.map +1 -1
  118. package/dist/esm/src/types.d.ts +0 -12
  119. package/dist/esm/src/util.js +14 -5
  120. package/dist/esm/src/util.js.map +1 -1
  121. package/docs/variable-ordering.md +306 -0
  122. package/package.json +11 -9
  123. package/src/abstract-node.ts +7 -5
  124. package/src/branches.ts +2 -0
  125. package/src/create-bdd-from-truth-table.ts +1 -1
  126. package/src/index.ts +2 -1
  127. package/src/internal-node.ts +7 -4
  128. package/src/optimize-brute-force.ts +5 -7
  129. package/src/ordering/build-bdd.ts +70 -0
  130. package/src/ordering/dense-truth-table.ts +161 -0
  131. package/src/ordering/exact-cost-ordering.ts +425 -0
  132. package/src/ordering/exact-ordering.ts +317 -0
  133. package/src/ordering/index.ts +57 -0
  134. package/src/ordering/int-pair-map.ts +85 -0
  135. package/src/ordering/local-search.ts +369 -0
  136. package/src/ordering/optimize-ordering.ts +570 -0
  137. package/src/ordering/ordering-evaluator.ts +479 -0
  138. package/src/ordering/shared-diagram.ts +310 -0
  139. package/src/packed/index.ts +2 -0
  140. package/src/packed/packed-bdd-base64-string.ts +47 -0
  141. package/src/packed/packed-bdd.ts +98 -0
  142. package/src/root-node.ts +2 -8
  143. package/src/types.ts +0 -18
  144. package/src/util.ts +15 -6
  145. package/dist/cjs/src/minimal-string/bdd-to-minimal-string.d.ts +0 -8
  146. package/dist/cjs/src/minimal-string/bdd-to-minimal-string.js +0 -59
  147. package/dist/cjs/src/minimal-string/bdd-to-minimal-string.js.map +0 -1
  148. package/dist/cjs/src/minimal-string/bdd-to-simple-bdd.d.ts +0 -11
  149. package/dist/cjs/src/minimal-string/bdd-to-simple-bdd.js +0 -23
  150. package/dist/cjs/src/minimal-string/bdd-to-simple-bdd.js.map +0 -1
  151. package/dist/cjs/src/minimal-string/index.d.ts +0 -5
  152. package/dist/cjs/src/minimal-string/index.js.map +0 -1
  153. package/dist/cjs/src/minimal-string/minimal-string-to-simple-bdd.d.ts +0 -2
  154. package/dist/cjs/src/minimal-string/minimal-string-to-simple-bdd.js +0 -57
  155. package/dist/cjs/src/minimal-string/minimal-string-to-simple-bdd.js.map +0 -1
  156. package/dist/cjs/src/minimal-string/resolve-with-simple-bdd.d.ts +0 -2
  157. package/dist/cjs/src/minimal-string/resolve-with-simple-bdd.js +0 -18
  158. package/dist/cjs/src/minimal-string/resolve-with-simple-bdd.js.map +0 -1
  159. package/dist/cjs/src/minimal-string/string-format.d.ts +0 -9
  160. package/dist/cjs/src/minimal-string/string-format.js +0 -61
  161. package/dist/cjs/src/minimal-string/string-format.js.map +0 -1
  162. package/dist/esm/src/minimal-string/bdd-to-minimal-string.d.ts +0 -8
  163. package/dist/esm/src/minimal-string/bdd-to-minimal-string.js +0 -55
  164. package/dist/esm/src/minimal-string/bdd-to-minimal-string.js.map +0 -1
  165. package/dist/esm/src/minimal-string/bdd-to-simple-bdd.d.ts +0 -11
  166. package/dist/esm/src/minimal-string/bdd-to-simple-bdd.js +0 -19
  167. package/dist/esm/src/minimal-string/bdd-to-simple-bdd.js.map +0 -1
  168. package/dist/esm/src/minimal-string/index.d.ts +0 -5
  169. package/dist/esm/src/minimal-string/index.js +0 -6
  170. package/dist/esm/src/minimal-string/index.js.map +0 -1
  171. package/dist/esm/src/minimal-string/minimal-string-to-simple-bdd.d.ts +0 -2
  172. package/dist/esm/src/minimal-string/minimal-string-to-simple-bdd.js +0 -54
  173. package/dist/esm/src/minimal-string/minimal-string-to-simple-bdd.js.map +0 -1
  174. package/dist/esm/src/minimal-string/resolve-with-simple-bdd.d.ts +0 -2
  175. package/dist/esm/src/minimal-string/resolve-with-simple-bdd.js +0 -15
  176. package/dist/esm/src/minimal-string/resolve-with-simple-bdd.js.map +0 -1
  177. package/dist/esm/src/minimal-string/string-format.d.ts +0 -9
  178. package/dist/esm/src/minimal-string/string-format.js +0 -54
  179. package/dist/esm/src/minimal-string/string-format.js.map +0 -1
  180. package/src/minimal-string/bdd-to-minimal-string.ts +0 -72
  181. package/src/minimal-string/bdd-to-simple-bdd.ts +0 -31
  182. package/src/minimal-string/index.ts +0 -5
  183. package/src/minimal-string/minimal-string-to-simple-bdd.ts +0 -67
  184. package/src/minimal-string/resolve-with-simple-bdd.ts +0 -23
  185. package/src/minimal-string/string-format.ts +0 -67
@@ -0,0 +1,89 @@
1
+ import type { DenseTruthTable } from './dense-truth-table.js';
2
+ export interface ExactOrderingOptions {
3
+ /**
4
+ * The search stops without a proof when more states were expanded.
5
+ * Default: 200000
6
+ */
7
+ maxExpansions?: number;
8
+ /**
9
+ * The search stops without a proof when the stored cofactor sets
10
+ * contain more entries in total (memory protection).
11
+ * Default: 2^25
12
+ */
13
+ maxCofactorEntries?: number;
14
+ /**
15
+ * A known good ordering. Its size is used as upper bound to prune the search,
16
+ * which makes the search much faster when the ordering is already close to optimal.
17
+ */
18
+ upperBoundOrdering?: ArrayLike<number>;
19
+ /**
20
+ * Only orderings with fewer internal nodes than this are searched for.
21
+ */
22
+ upperBound?: number;
23
+ log?: (message: string) => void;
24
+ }
25
+ export interface ExactOrderingResult {
26
+ /**
27
+ * true when it is proven that no ordering has fewer internal nodes
28
+ * than the returned one (or than the upper bound, when ordering is null)
29
+ */
30
+ solved: boolean;
31
+ /**
32
+ * The best ordering that was found. Irrelevant boolean functions
33
+ * are always at the bottom. null when no ordering below the numeric
34
+ * upper bound exists and the upperBoundOrdering (if given) is not
35
+ * below it either.
36
+ */
37
+ ordering: number[] | null;
38
+ /** amount of internal (non-leaf) nodes of `ordering`, -1 when ordering is null */
39
+ internalNodeCount: number;
40
+ /** amount of expanded states */
41
+ expansions: number;
42
+ /** amount of generated states */
43
+ generated: number;
44
+ }
45
+ /**
46
+ * The number of nodes on a level of a reduced BDD only depends on the SET of
47
+ * variables above that level, not on their order (Friedman & Supowit, 1990):
48
+ * it is the amount of distinct cofactors with respect to that set that still
49
+ * depend on the level's variable.
50
+ *
51
+ * Therefore the optimal ordering is a shortest path through the lattice of
52
+ * variable subsets, from the empty set to the full set, where the edge
53
+ * S -> S + {x} costs the amount of nodes that test x when exactly the
54
+ * variables of S are above it.
55
+ *
56
+ * This class finds that shortest path with an A* search. Each subset S is
57
+ * represented by the set of its distinct non-constant cofactors, which are
58
+ * nodes of one shared hash-consed diagram in the natural variable order
59
+ * (so equal functions always have equal ids). The admissible estimate for the
60
+ * remaining cost of a subset is the amount of its distinct non-constant
61
+ * cofactors: each of them needs its own node below.
62
+ *
63
+ * With a good upper bound (from the local search) the search typically only
64
+ * has to look at a tiny fraction of the 2^n subsets.
65
+ */
66
+ export declare class ExactOrderingSearch {
67
+ private readonly table;
68
+ private readonly diagram;
69
+ private readonly n;
70
+ private readonly terminalCount;
71
+ constructor(table: DenseTruthTable, options?: {
72
+ maxDiagramNodes?: number;
73
+ });
74
+ /**
75
+ * Moves the boolean functions the truth table does not depend on
76
+ * to the bottom. This never changes the amount of internal nodes
77
+ * but ensures the root node tests a relevant boolean function.
78
+ */
79
+ normalizeOrdering(ordering: ArrayLike<number>): number[];
80
+ run(options?: ExactOrderingOptions): ExactOrderingResult;
81
+ /**
82
+ * lower bound for the amount of nodes below the given subset
83
+ */
84
+ private estimate;
85
+ /**
86
+ * the distinct non-constant cofactors after additionally fixing `variable`
87
+ */
88
+ private cofactorsAfter;
89
+ }
@@ -0,0 +1,260 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ExactOrderingSearch = void 0;
4
+ const dense_truth_table_js_1 = require("./dense-truth-table.js");
5
+ const ordering_evaluator_js_1 = require("./ordering-evaluator.js");
6
+ const shared_diagram_js_1 = require("./shared-diagram.js");
7
+ /**
8
+ * The number of nodes on a level of a reduced BDD only depends on the SET of
9
+ * variables above that level, not on their order (Friedman & Supowit, 1990):
10
+ * it is the amount of distinct cofactors with respect to that set that still
11
+ * depend on the level's variable.
12
+ *
13
+ * Therefore the optimal ordering is a shortest path through the lattice of
14
+ * variable subsets, from the empty set to the full set, where the edge
15
+ * S -> S + {x} costs the amount of nodes that test x when exactly the
16
+ * variables of S are above it.
17
+ *
18
+ * This class finds that shortest path with an A* search. Each subset S is
19
+ * represented by the set of its distinct non-constant cofactors, which are
20
+ * nodes of one shared hash-consed diagram in the natural variable order
21
+ * (so equal functions always have equal ids). The admissible estimate for the
22
+ * remaining cost of a subset is the amount of its distinct non-constant
23
+ * cofactors: each of them needs its own node below.
24
+ *
25
+ * With a good upper bound (from the local search) the search typically only
26
+ * has to look at a tiny fraction of the 2^n subsets.
27
+ */
28
+ class ExactOrderingSearch {
29
+ table;
30
+ diagram;
31
+ n;
32
+ terminalCount;
33
+ constructor(table, options = {}) {
34
+ this.table = table;
35
+ if (table.dontCareTerminal >= 0) {
36
+ throw new Error('the exact search needs a truth table without don\'t-care rows, resolve them with OrderingEvaluator.complete() first');
37
+ }
38
+ this.diagram = new shared_diagram_js_1.SharedDiagram(table, options.maxDiagramNodes === undefined ? shared_diagram_js_1.DEFAULT_MAX_DIAGRAM_NODES : options.maxDiagramNodes);
39
+ this.n = table.variableCount;
40
+ this.terminalCount = table.terminalValues.length;
41
+ }
42
+ /**
43
+ * Moves the boolean functions the truth table does not depend on
44
+ * to the bottom. This never changes the amount of internal nodes
45
+ * but ensures the root node tests a relevant boolean function.
46
+ */
47
+ normalizeOrdering(ordering) {
48
+ return this.diagram.normalizeOrdering(ordering);
49
+ }
50
+ run(options = {}) {
51
+ const log = options.log ? options.log : () => null;
52
+ const maxExpansions = options.maxExpansions === undefined ? 200000 : options.maxExpansions;
53
+ const maxCofactorEntries = options.maxCofactorEntries === undefined ? Math.pow(2, 25) : options.maxCofactorEntries;
54
+ const diagram = this.diagram;
55
+ const relevant = diagram.relevant;
56
+ const m = relevant.length;
57
+ const irrelevant = diagram.irrelevantVariables();
58
+ // upper bound
59
+ let upperBound = options.upperBound === undefined ? Infinity : options.upperBound;
60
+ let incumbent = null;
61
+ if (options.upperBoundOrdering) {
62
+ incumbent = this.normalizeOrdering(options.upperBoundOrdering);
63
+ const incumbentCount = new ordering_evaluator_js_1.OrderingEvaluator(this.table).evaluate(incumbent).internalNodeCount;
64
+ if (incumbentCount >= upperBound) {
65
+ // the numeric bound is at least as good, the incumbent cannot be the answer
66
+ incumbent = null;
67
+ }
68
+ else {
69
+ upperBound = incumbentCount;
70
+ }
71
+ }
72
+ const giveUp = (reason, expansionCount, generatedCount) => {
73
+ log('exact search: ' + reason);
74
+ return {
75
+ solved: false,
76
+ ordering: incumbent,
77
+ internalNodeCount: incumbent ? upperBound : -1,
78
+ expansions: expansionCount,
79
+ generated: generatedCount
80
+ };
81
+ };
82
+ if (diagram.overBudget) {
83
+ return giveUp('diagram budget exceeded', 0, 0);
84
+ }
85
+ if (m === 0) {
86
+ // constant function: every ordering has 0 internal nodes
87
+ const constantOrdering = upperBound > 0 ? (0, dense_truth_table_js_1.naturalOrdering)(this.n) : incumbent;
88
+ return {
89
+ solved: true,
90
+ ordering: constantOrdering,
91
+ internalNodeCount: constantOrdering ? 0 : -1,
92
+ expansions: 0,
93
+ generated: 0
94
+ };
95
+ }
96
+ const full = (1 << m) - 1;
97
+ const cofactors = new Map();
98
+ const bestCost = new Map();
99
+ const parentVariable = new Map();
100
+ const closed = new Set();
101
+ const heap = new shared_diagram_js_1.StateHeap();
102
+ const startSet = new Int32Array(1);
103
+ startSet[0] = diagram.rootId;
104
+ cofactors.set(0, startSet);
105
+ bestCost.set(0, 0);
106
+ heap.push(this.estimate(0, startSet), 0, 0);
107
+ let expansions = 0;
108
+ let generated = 1;
109
+ let storedEntries = 1;
110
+ let solvedSet = -1;
111
+ let solvedCost = -1;
112
+ try {
113
+ while (heap.size > 0) {
114
+ const state = heap.pop();
115
+ const currentCost = state.cost;
116
+ const subset = state.subset;
117
+ if (currentCost !== bestCost.get(subset) || closed.has(subset)) {
118
+ // stale heap entry
119
+ continue;
120
+ }
121
+ if (state.estimate >= upperBound) {
122
+ // nothing left that can beat the upper bound
123
+ break;
124
+ }
125
+ if (subset === full) {
126
+ solvedSet = subset;
127
+ solvedCost = currentCost;
128
+ break;
129
+ }
130
+ closed.add(subset);
131
+ expansions++;
132
+ if (expansions > maxExpansions) {
133
+ return giveUp('expansion budget exceeded', expansions, generated);
134
+ }
135
+ if (storedEntries > maxCofactorEntries) {
136
+ return giveUp('memory budget exceeded', expansions, generated);
137
+ }
138
+ if (expansions % 10000 === 0) {
139
+ log('exact search: ' + expansions + ' states expanded, ' + generated + ' generated, ' + heap.size + ' open');
140
+ }
141
+ const set = cofactors.get(subset);
142
+ for (let c = 0; c < m; c++) {
143
+ const bit = 1 << c;
144
+ if ((subset & bit) !== 0) {
145
+ continue;
146
+ }
147
+ const variable = relevant[c];
148
+ let edgeCost = 0;
149
+ for (let i = 0; i < set.length; i++) {
150
+ if ((diagram.supportOf(set[i]) & bit) !== 0) {
151
+ edgeCost++;
152
+ }
153
+ }
154
+ const nextCost = currentCost + edgeCost;
155
+ const nextSubset = subset | bit;
156
+ const knownCost = bestCost.get(nextSubset);
157
+ if (knownCost !== undefined && knownCost <= nextCost) {
158
+ continue;
159
+ }
160
+ let nextSet = cofactors.get(nextSubset);
161
+ if (nextSet === undefined) {
162
+ nextSet = this.cofactorsAfter(set, variable);
163
+ cofactors.set(nextSubset, nextSet);
164
+ generated++;
165
+ storedEntries += nextSet.length;
166
+ }
167
+ const estimate = nextCost + this.estimate(nextSubset, nextSet);
168
+ if (estimate >= upperBound) {
169
+ continue;
170
+ }
171
+ bestCost.set(nextSubset, nextCost);
172
+ parentVariable.set(nextSubset, variable);
173
+ closed.delete(nextSubset);
174
+ heap.push(estimate, nextCost, nextSubset);
175
+ }
176
+ }
177
+ }
178
+ catch (err) {
179
+ if (err instanceof shared_diagram_js_1.DiagramBudgetExceededError) {
180
+ return giveUp('diagram budget exceeded', expansions, generated);
181
+ }
182
+ throw err;
183
+ }
184
+ if (solvedSet === -1) {
185
+ // no ordering below the upper bound exists: the incumbent (if any) is optimal
186
+ return {
187
+ solved: true,
188
+ ordering: incumbent,
189
+ internalNodeCount: incumbent ? upperBound : -1,
190
+ expansions,
191
+ generated
192
+ };
193
+ }
194
+ // reconstruct the path
195
+ const reversed = [];
196
+ let remainingSubset = solvedSet;
197
+ while (remainingSubset !== 0) {
198
+ const variable = parentVariable.get(remainingSubset);
199
+ reversed.push(variable);
200
+ remainingSubset = remainingSubset & ~(1 << diagram.compactOf[variable]);
201
+ }
202
+ const ordering = reversed.reverse().concat(irrelevant);
203
+ return {
204
+ solved: true,
205
+ ordering,
206
+ internalNodeCount: solvedCost,
207
+ expansions,
208
+ generated
209
+ };
210
+ }
211
+ /**
212
+ * lower bound for the amount of nodes below the given subset
213
+ */
214
+ estimate(subset, set) {
215
+ let union = 0;
216
+ for (let i = 0; i < set.length; i++) {
217
+ union |= this.diagram.supportOf(set[i]);
218
+ }
219
+ const remaining = union & ~subset;
220
+ let remainingCount = 0;
221
+ for (let x = remaining; x !== 0; x &= x - 1) {
222
+ remainingCount++;
223
+ }
224
+ return Math.max(set.length, remainingCount);
225
+ }
226
+ /**
227
+ * the distinct non-constant cofactors after additionally fixing `variable`
228
+ */
229
+ cofactorsAfter(set, variable) {
230
+ const diagram = this.diagram;
231
+ const bit = 1 << diagram.compactOf[variable];
232
+ const candidates = new Int32Array(set.length * 2);
233
+ let count = 0;
234
+ for (let i = 0; i < set.length; i++) {
235
+ const g = set[i];
236
+ if ((diagram.supportOf(g) & bit) === 0) {
237
+ candidates[count++] = g;
238
+ continue;
239
+ }
240
+ const lo = diagram.restrict(g, variable, 0);
241
+ if (lo >= this.terminalCount) {
242
+ candidates[count++] = lo;
243
+ }
244
+ const hi = diagram.restrict(g, variable, 1);
245
+ if (hi >= this.terminalCount) {
246
+ candidates[count++] = hi;
247
+ }
248
+ }
249
+ const sorted = candidates.subarray(0, count).sort();
250
+ let unique = 0;
251
+ for (let i = 0; i < sorted.length; i++) {
252
+ if (i === 0 || sorted[i] !== sorted[i - 1]) {
253
+ sorted[unique++] = sorted[i];
254
+ }
255
+ }
256
+ return sorted.slice(0, unique);
257
+ }
258
+ }
259
+ exports.ExactOrderingSearch = ExactOrderingSearch;
260
+ //# sourceMappingURL=exact-ordering.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exact-ordering.js","sourceRoot":"","sources":["../../../../src/ordering/exact-ordering.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Public API of the variable ordering optimizer, see docs/variable-ordering.md.
3
+ *
4
+ * - optimize-ordering.ts: optimizeOrdering(), findOrdering(), createBddWithOrdering()
5
+ * - ordering-evaluator.ts: counts the nodes (and the expected cost) of any ordering in O(2^n)
6
+ * - local-search.ts: deterministic seeds, sifting and window permutation
7
+ * - exact-ordering.ts, exact-cost-ordering.ts: A* searches that prove optimality
8
+ * - shared-diagram.ts: the shared function diagram the exact searches work on
9
+ * - dense-truth-table.ts, build-bdd.ts, int-pair-map.ts: data structures and helpers
10
+ */
11
+ export { optimizeOrdering, findOrdering, createBddWithOrdering, buildCostModel, DEFAULT_MAX_EXACT_VARIABLES, DEFAULT_MAX_EXACT_NODE_COUNT } from './optimize-ordering.js';
12
+ export type { FindOrderingInput, FindOrderingResult, OptimizeOrderingInput, OptimizeOrderingResult, OptimizeOrderingStats } from './optimize-ordering.js';
13
+ export { OrderingEvaluator, OrderingCursor } from './ordering-evaluator.js';
14
+ export type { CostModel, OrderingEvaluation, ReducedDiagram } from './ordering-evaluator.js';
15
+ export { LocalOrderingSearch, DEFAULT_WINDOW_SIZE, DEFAULT_MAX_ROUNDS, MAX_WINDOW_SIZE } from './local-search.js';
16
+ export type { LocalSearchOptions, OrderingSearchResult, OrderingProgress, OrderingProgressCallback } from './local-search.js';
17
+ export { ExactOrderingSearch } from './exact-ordering.js';
18
+ export type { ExactOrderingOptions, ExactOrderingResult } from './exact-ordering.js';
19
+ export { ExactCostOrderingSearch } from './exact-cost-ordering.js';
20
+ export type { ExactCostOrderingOptions, ExactCostOrderingResult } from './exact-cost-ordering.js';
21
+ export { parseTruthTable, denseTruthTableToMap, naturalOrdering, MAX_VARIABLE_COUNT } from './dense-truth-table.js';
22
+ export type { DenseTruthTable } from './dense-truth-table.js';
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_VARIABLE_COUNT = exports.naturalOrdering = exports.denseTruthTableToMap = exports.parseTruthTable = exports.ExactCostOrderingSearch = exports.ExactOrderingSearch = exports.MAX_WINDOW_SIZE = exports.DEFAULT_MAX_ROUNDS = exports.DEFAULT_WINDOW_SIZE = exports.LocalOrderingSearch = exports.OrderingCursor = exports.OrderingEvaluator = exports.DEFAULT_MAX_EXACT_NODE_COUNT = exports.DEFAULT_MAX_EXACT_VARIABLES = exports.buildCostModel = exports.createBddWithOrdering = exports.findOrdering = exports.optimizeOrdering = void 0;
4
+ /**
5
+ * Public API of the variable ordering optimizer, see docs/variable-ordering.md.
6
+ *
7
+ * - optimize-ordering.ts: optimizeOrdering(), findOrdering(), createBddWithOrdering()
8
+ * - ordering-evaluator.ts: counts the nodes (and the expected cost) of any ordering in O(2^n)
9
+ * - local-search.ts: deterministic seeds, sifting and window permutation
10
+ * - exact-ordering.ts, exact-cost-ordering.ts: A* searches that prove optimality
11
+ * - shared-diagram.ts: the shared function diagram the exact searches work on
12
+ * - dense-truth-table.ts, build-bdd.ts, int-pair-map.ts: data structures and helpers
13
+ */
14
+ var optimize_ordering_js_1 = require("./optimize-ordering.js");
15
+ Object.defineProperty(exports, "optimizeOrdering", { enumerable: true, get: function () { return optimize_ordering_js_1.optimizeOrdering; } });
16
+ Object.defineProperty(exports, "findOrdering", { enumerable: true, get: function () { return optimize_ordering_js_1.findOrdering; } });
17
+ Object.defineProperty(exports, "createBddWithOrdering", { enumerable: true, get: function () { return optimize_ordering_js_1.createBddWithOrdering; } });
18
+ Object.defineProperty(exports, "buildCostModel", { enumerable: true, get: function () { return optimize_ordering_js_1.buildCostModel; } });
19
+ Object.defineProperty(exports, "DEFAULT_MAX_EXACT_VARIABLES", { enumerable: true, get: function () { return optimize_ordering_js_1.DEFAULT_MAX_EXACT_VARIABLES; } });
20
+ Object.defineProperty(exports, "DEFAULT_MAX_EXACT_NODE_COUNT", { enumerable: true, get: function () { return optimize_ordering_js_1.DEFAULT_MAX_EXACT_NODE_COUNT; } });
21
+ var ordering_evaluator_js_1 = require("./ordering-evaluator.js");
22
+ Object.defineProperty(exports, "OrderingEvaluator", { enumerable: true, get: function () { return ordering_evaluator_js_1.OrderingEvaluator; } });
23
+ Object.defineProperty(exports, "OrderingCursor", { enumerable: true, get: function () { return ordering_evaluator_js_1.OrderingCursor; } });
24
+ var local_search_js_1 = require("./local-search.js");
25
+ Object.defineProperty(exports, "LocalOrderingSearch", { enumerable: true, get: function () { return local_search_js_1.LocalOrderingSearch; } });
26
+ Object.defineProperty(exports, "DEFAULT_WINDOW_SIZE", { enumerable: true, get: function () { return local_search_js_1.DEFAULT_WINDOW_SIZE; } });
27
+ Object.defineProperty(exports, "DEFAULT_MAX_ROUNDS", { enumerable: true, get: function () { return local_search_js_1.DEFAULT_MAX_ROUNDS; } });
28
+ Object.defineProperty(exports, "MAX_WINDOW_SIZE", { enumerable: true, get: function () { return local_search_js_1.MAX_WINDOW_SIZE; } });
29
+ var exact_ordering_js_1 = require("./exact-ordering.js");
30
+ Object.defineProperty(exports, "ExactOrderingSearch", { enumerable: true, get: function () { return exact_ordering_js_1.ExactOrderingSearch; } });
31
+ var exact_cost_ordering_js_1 = require("./exact-cost-ordering.js");
32
+ Object.defineProperty(exports, "ExactCostOrderingSearch", { enumerable: true, get: function () { return exact_cost_ordering_js_1.ExactCostOrderingSearch; } });
33
+ var dense_truth_table_js_1 = require("./dense-truth-table.js");
34
+ Object.defineProperty(exports, "parseTruthTable", { enumerable: true, get: function () { return dense_truth_table_js_1.parseTruthTable; } });
35
+ Object.defineProperty(exports, "denseTruthTableToMap", { enumerable: true, get: function () { return dense_truth_table_js_1.denseTruthTableToMap; } });
36
+ Object.defineProperty(exports, "naturalOrdering", { enumerable: true, get: function () { return dense_truth_table_js_1.naturalOrdering; } });
37
+ Object.defineProperty(exports, "MAX_VARIABLE_COUNT", { enumerable: true, get: function () { return dense_truth_table_js_1.MAX_VARIABLE_COUNT; } });
38
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ordering/index.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;GASG;AACH,+DAOgC;AAN5B,wHAAA,gBAAgB,OAAA;AAChB,oHAAA,YAAY,OAAA;AACZ,6HAAA,qBAAqB,OAAA;AACrB,sHAAA,cAAc,OAAA;AACd,mIAAA,2BAA2B,OAAA;AAC3B,oIAAA,4BAA4B,OAAA;AAShC,iEAGiC;AAF7B,0HAAA,iBAAiB,OAAA;AACjB,uHAAA,cAAc,OAAA;AAOlB,qDAK2B;AAJvB,sHAAA,mBAAmB,OAAA;AACnB,sHAAA,mBAAmB,OAAA;AACnB,qHAAA,kBAAkB,OAAA;AAClB,kHAAA,eAAe,OAAA;AAQnB,yDAA0D;AAAjD,wHAAA,mBAAmB,OAAA;AAE5B,mEAAmE;AAA1D,iIAAA,uBAAuB,OAAA;AAEhC,+DAKgC;AAJ5B,uHAAA,eAAe,OAAA;AACf,4HAAA,oBAAoB,OAAA;AACpB,uHAAA,eAAe,OAAA;AACf,0HAAA,kBAAkB,OAAA"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Open addressing hash map from a pair of non-negative 32 bit integers
3
+ * to a non-negative 32 bit integer. Used in the hot paths of the exact search
4
+ * where a Map with string keys would be far too slow.
5
+ */
6
+ export declare class IntPairMap {
7
+ size: number;
8
+ private keysA;
9
+ private keysB;
10
+ private values;
11
+ private mask;
12
+ constructor(initialCapacity?: number);
13
+ /**
14
+ * @returns the stored value or -1
15
+ */
16
+ get(a: number, b: number): number;
17
+ set(a: number, b: number, value: number): void;
18
+ private hash;
19
+ private grow;
20
+ }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IntPairMap = void 0;
4
+ /**
5
+ * Open addressing hash map from a pair of non-negative 32 bit integers
6
+ * to a non-negative 32 bit integer. Used in the hot paths of the exact search
7
+ * where a Map with string keys would be far too slow.
8
+ */
9
+ class IntPairMap {
10
+ size = 0;
11
+ keysA;
12
+ keysB;
13
+ values;
14
+ mask;
15
+ constructor(initialCapacity = 1024) {
16
+ let capacity = 16;
17
+ while (capacity < initialCapacity) {
18
+ capacity *= 2;
19
+ }
20
+ this.keysA = new Int32Array(capacity).fill(-1);
21
+ this.keysB = new Int32Array(capacity);
22
+ this.values = new Int32Array(capacity);
23
+ this.mask = capacity - 1;
24
+ }
25
+ /**
26
+ * @returns the stored value or -1
27
+ */
28
+ get(a, b) {
29
+ let h = this.hash(a, b);
30
+ while (true) {
31
+ const storedA = this.keysA[h];
32
+ if (storedA === -1) {
33
+ return -1;
34
+ }
35
+ if (storedA === a && this.keysB[h] === b) {
36
+ return this.values[h];
37
+ }
38
+ h = (h + 1) & this.mask;
39
+ }
40
+ }
41
+ set(a, b, value) {
42
+ if ((this.size + 1) * 2 > this.keysA.length) {
43
+ this.grow();
44
+ }
45
+ let h = this.hash(a, b);
46
+ while (true) {
47
+ const storedA = this.keysA[h];
48
+ if (storedA === -1) {
49
+ this.keysA[h] = a;
50
+ this.keysB[h] = b;
51
+ this.values[h] = value;
52
+ this.size++;
53
+ return;
54
+ }
55
+ if (storedA === a && this.keysB[h] === b) {
56
+ this.values[h] = value;
57
+ return;
58
+ }
59
+ h = (h + 1) & this.mask;
60
+ }
61
+ }
62
+ hash(a, b) {
63
+ let h = (Math.imul(a, 0x9E3779B1) ^ Math.imul(b + 0x7F4A7C15, 0x85EBCA77)) >>> 0;
64
+ h ^= h >>> 15;
65
+ return h & this.mask;
66
+ }
67
+ grow() {
68
+ const oldA = this.keysA;
69
+ const oldB = this.keysB;
70
+ const oldValues = this.values;
71
+ const capacity = oldA.length * 2;
72
+ this.keysA = new Int32Array(capacity).fill(-1);
73
+ this.keysB = new Int32Array(capacity);
74
+ this.values = new Int32Array(capacity);
75
+ this.mask = capacity - 1;
76
+ this.size = 0;
77
+ for (let i = 0; i < oldA.length; i++) {
78
+ if (oldA[i] !== -1) {
79
+ this.set(oldA[i], oldB[i], oldValues[i]);
80
+ }
81
+ }
82
+ }
83
+ }
84
+ exports.IntPairMap = IntPairMap;
85
+ //# sourceMappingURL=int-pair-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"int-pair-map.js","sourceRoot":"","sources":["../../../../src/ordering/int-pair-map.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,MAAa,UAAU;IACZ,IAAI,GAAW,CAAC,CAAC;IAChB,KAAK,CAAa;IAClB,KAAK,CAAa;IAClB,MAAM,CAAa;IACnB,IAAI,CAAS;IAErB,YAAY,kBAA0B,IAAI;QACtC,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,OAAO,QAAQ,GAAG,eAAe,EAAE,CAAC;YAChC,QAAQ,IAAI,CAAC,CAAC;QAClB,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,QAAQ,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACI,GAAG,CAAC,CAAS,EAAE,CAAS;QAC3B,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACxB,OAAO,IAAI,EAAE,CAAC;YACV,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC9B,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;gBACjB,OAAO,CAAC,CAAC,CAAC;YACd,CAAC;YACD,IAAI,OAAO,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC1B,CAAC;YACD,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;QAC5B,CAAC;IACL,CAAC;IAEM,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,KAAa;QAC1C,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;QAChB,CAAC;QACD,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACxB,OAAO,IAAI,EAAE,CAAC;YACV,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC9B,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;gBACjB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBAClB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBAClB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;gBACvB,IAAI,CAAC,IAAI,EAAE,CAAC;gBACZ,OAAO;YACX,CAAC;YACD,IAAI,OAAO,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;gBACvB,OAAO;YACX,CAAC;YACD,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;QAC5B,CAAC;IACL,CAAC;IAEO,IAAI,CAAC,CAAS,EAAE,CAAS;QAC7B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,UAAU,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC;QACjF,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;IACzB,CAAC;IAEO,IAAI;QACR,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,QAAQ,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBACjB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7C,CAAC;QACL,CAAC;IACL,CAAC;CACJ;AA/ED,gCA+EC"}
@@ -0,0 +1,114 @@
1
+ import { OrderingEvaluator, OrderingEvaluation } from './ordering-evaluator.js';
2
+ export interface OrderingProgress {
3
+ ordering: number[];
4
+ nodeCount: number;
5
+ /** 0 without cost model */
6
+ expectedCost: number;
7
+ phase: string;
8
+ }
9
+ export type OrderingProgressCallback = (progress: OrderingProgress) => void;
10
+ export interface LocalSearchOptions {
11
+ /**
12
+ * Size of the windows whose variables are permuted exhaustively.
13
+ * 0 or 1 disables window permutation. The work grows with windowSize!,
14
+ * so at most MAX_WINDOW_SIZE (8) is allowed.
15
+ * Default: 3
16
+ */
17
+ windowSize?: number;
18
+ /**
19
+ * Maximum amount of sifting rounds.
20
+ * Default: 50
21
+ */
22
+ maxRounds?: number;
23
+ onImprovement?: OrderingProgressCallback;
24
+ log?: (message: string) => void;
25
+ }
26
+ export interface OrderingSearchResult {
27
+ ordering: number[];
28
+ nodeCount: number;
29
+ expectedCost: number;
30
+ nodesPerLevel: number[];
31
+ evaluation: OrderingEvaluation;
32
+ }
33
+ /**
34
+ * Deterministic greedy construction:
35
+ * fills the levels from the top, at each level the boolean function
36
+ * that leads to the best BDD (with the other functions in their index order)
37
+ * is picked.
38
+ */
39
+ export declare function greedyTopDownOrdering(evaluator: OrderingEvaluator): number[];
40
+ /**
41
+ * Deterministic greedy construction from the bottom:
42
+ * at each step the boolean function that is best as the lowest
43
+ * remaining level is picked.
44
+ */
45
+ export declare function greedyBottomUpOrdering(evaluator: OrderingEvaluator): number[];
46
+ export declare const DEFAULT_WINDOW_SIZE = 3;
47
+ export declare const DEFAULT_MAX_ROUNDS = 50;
48
+ /**
49
+ * Window permutation tries all w! orderings of every window of w levels,
50
+ * larger windows take too long.
51
+ */
52
+ export declare const MAX_WINDOW_SIZE = 8;
53
+ export declare function ensureNonNegativeInteger(value: number, name: string): void;
54
+ export declare function ensureWindowSize(windowSize: number): void;
55
+ /**
56
+ * Improves an ordering by sifting (moving each variable through all positions
57
+ * and keeping the best one) and exhaustive window permutation until no
58
+ * strict improvement is found anymore. "Better" is decided by
59
+ * OrderingEvaluator.isBetter(): fewer nodes, or with a cost model a lower
60
+ * expected cost. Everything is deterministic: the same input always gives
61
+ * the same output.
62
+ */
63
+ export declare class LocalOrderingSearch {
64
+ private readonly evaluator;
65
+ best: OrderingEvaluation;
66
+ private readonly cursor;
67
+ private readonly n;
68
+ private readonly windowPermutations;
69
+ private readonly windowSize;
70
+ private readonly maxRounds;
71
+ private readonly onImprovement;
72
+ private readonly log;
73
+ constructor(evaluator: OrderingEvaluator, initialOrdering: ArrayLike<number>, options?: LocalSearchOptions);
74
+ /**
75
+ * ordering[level] = boolean function tested on that level
76
+ */
77
+ get ordering(): number[];
78
+ result(): OrderingSearchResult;
79
+ /**
80
+ * Runs sifting rounds and window permutation rounds
81
+ * until a full cycle gives no improvement.
82
+ */
83
+ run(): OrderingSearchResult;
84
+ /**
85
+ * One sifting round: each variable, largest level first,
86
+ * is moved to the position where the BDD is best.
87
+ * @returns true if the ordering improved
88
+ */
89
+ siftRound(): boolean;
90
+ /**
91
+ * One window permutation round: for each window of adjacent levels
92
+ * all permutations of its variables are tried.
93
+ * @returns true if the ordering improved
94
+ */
95
+ windowRound(): boolean;
96
+ private progress;
97
+ private describe;
98
+ /**
99
+ * swaps the variables of level and level+1
100
+ */
101
+ private swapAdjacent;
102
+ private swapLevels;
103
+ /**
104
+ * Arranges the window so that level (windowStart + i) holds original[permutation[i]].
105
+ */
106
+ private setWindow;
107
+ }
108
+ /**
109
+ * Deterministic start orderings for the local search.
110
+ */
111
+ export declare function seedOrderings(evaluator: OrderingEvaluator): {
112
+ name: string;
113
+ ordering: number[];
114
+ }[];