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.
- package/CHANGELOG.md +6 -0
- package/README.md +211 -31
- package/dist/cjs/src/abstract-node.js +7 -4
- package/dist/cjs/src/abstract-node.js.map +1 -1
- package/dist/cjs/src/branches.d.ts +4 -1
- package/dist/cjs/src/branches.js +10 -9
- package/dist/cjs/src/branches.js.map +1 -1
- package/dist/cjs/src/create-bdd-from-truth-table.js +1 -2
- package/dist/cjs/src/create-bdd-from-truth-table.js.map +1 -1
- package/dist/cjs/src/ensure-correct-bdd.js +2 -3
- package/dist/cjs/src/ensure-correct-bdd.js.map +1 -1
- package/dist/cjs/src/fill-truth-table.js +1 -2
- package/dist/cjs/src/fill-truth-table.js.map +1 -1
- package/dist/cjs/src/find-similar-node.js +1 -2
- package/dist/cjs/src/find-similar-node.js.map +1 -1
- package/dist/cjs/src/index.d.ts +2 -1
- package/dist/cjs/src/index.es5.js +17 -7
- package/dist/cjs/src/index.es5.js.map +1 -1
- package/dist/cjs/src/index.js +2 -1
- package/dist/cjs/src/index.js.map +1 -1
- package/dist/cjs/src/internal-node.js +6 -3
- package/dist/cjs/src/internal-node.js.map +1 -1
- package/dist/cjs/src/optimize-brute-force.js +10 -12
- package/dist/cjs/src/optimize-brute-force.js.map +1 -1
- package/dist/cjs/src/ordering/build-bdd.d.ts +13 -0
- package/dist/cjs/src/ordering/build-bdd.js +64 -0
- package/dist/cjs/src/ordering/build-bdd.js.map +1 -0
- package/dist/cjs/src/ordering/dense-truth-table.d.ts +42 -0
- package/dist/cjs/src/ordering/dense-truth-table.js +125 -0
- package/dist/cjs/src/ordering/dense-truth-table.js.map +1 -0
- package/dist/cjs/src/ordering/exact-cost-ordering.d.ts +91 -0
- package/dist/cjs/src/ordering/exact-cost-ordering.js +351 -0
- package/dist/cjs/src/ordering/exact-cost-ordering.js.map +1 -0
- package/dist/cjs/src/ordering/exact-ordering.d.ts +89 -0
- package/dist/cjs/src/ordering/exact-ordering.js +260 -0
- package/dist/cjs/src/ordering/exact-ordering.js.map +1 -0
- package/dist/cjs/src/ordering/index.d.ts +22 -0
- package/dist/cjs/src/ordering/index.js +38 -0
- package/dist/cjs/src/ordering/index.js.map +1 -0
- package/dist/cjs/src/ordering/int-pair-map.d.ts +20 -0
- package/dist/cjs/src/ordering/int-pair-map.js +85 -0
- package/dist/cjs/src/ordering/int-pair-map.js.map +1 -0
- package/dist/cjs/src/ordering/local-search.d.ts +114 -0
- package/dist/cjs/src/ordering/local-search.js +317 -0
- package/dist/cjs/src/ordering/local-search.js.map +1 -0
- package/dist/cjs/src/ordering/optimize-ordering.d.ts +153 -0
- package/dist/cjs/src/ordering/optimize-ordering.js +406 -0
- package/dist/cjs/src/ordering/optimize-ordering.js.map +1 -0
- package/dist/cjs/src/ordering/ordering-evaluator.d.ts +198 -0
- package/dist/cjs/src/ordering/ordering-evaluator.js +384 -0
- package/dist/cjs/src/ordering/ordering-evaluator.js.map +1 -0
- package/dist/cjs/src/ordering/shared-diagram.d.ts +85 -0
- package/dist/cjs/src/ordering/shared-diagram.js +295 -0
- package/dist/cjs/src/ordering/shared-diagram.js.map +1 -0
- package/dist/cjs/src/packed/index.d.ts +2 -0
- package/dist/cjs/src/{minimal-string → packed}/index.js +2 -5
- package/dist/cjs/src/packed/index.js.map +1 -0
- package/dist/cjs/src/packed/packed-bdd-base64-string.d.ts +3 -0
- package/dist/cjs/src/packed/packed-bdd-base64-string.js +46 -0
- package/dist/cjs/src/packed/packed-bdd-base64-string.js.map +1 -0
- package/dist/cjs/src/packed/packed-bdd.d.ts +13 -0
- package/dist/cjs/src/packed/packed-bdd.js +70 -0
- package/dist/cjs/src/packed/packed-bdd.js.map +1 -0
- package/dist/cjs/src/root-node.d.ts +1 -2
- package/dist/cjs/src/root-node.js +4 -9
- package/dist/cjs/src/root-node.js.map +1 -1
- package/dist/cjs/src/types.d.ts +0 -12
- package/dist/cjs/src/util.js +29 -21
- package/dist/cjs/src/util.js.map +1 -1
- package/dist/esm/src/abstract-node.js +7 -4
- package/dist/esm/src/abstract-node.js.map +1 -1
- package/dist/esm/src/branches.d.ts +4 -1
- package/dist/esm/src/branches.js +8 -7
- package/dist/esm/src/branches.js.map +1 -1
- package/dist/esm/src/create-bdd-from-truth-table.js.map +1 -1
- package/dist/esm/src/index.d.ts +2 -1
- package/dist/esm/src/index.js +2 -1
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/internal-node.js +7 -4
- package/dist/esm/src/internal-node.js.map +1 -1
- package/dist/esm/src/optimize-brute-force.js +5 -7
- package/dist/esm/src/optimize-brute-force.js.map +1 -1
- package/dist/esm/src/ordering/build-bdd.d.ts +13 -0
- package/dist/esm/src/ordering/build-bdd.js +61 -0
- package/dist/esm/src/ordering/build-bdd.js.map +1 -0
- package/dist/esm/src/ordering/dense-truth-table.d.ts +42 -0
- package/dist/esm/src/ordering/dense-truth-table.js +117 -0
- package/dist/esm/src/ordering/dense-truth-table.js.map +1 -0
- package/dist/esm/src/ordering/exact-cost-ordering.d.ts +91 -0
- package/dist/esm/src/ordering/exact-cost-ordering.js +347 -0
- package/dist/esm/src/ordering/exact-cost-ordering.js.map +1 -0
- package/dist/esm/src/ordering/exact-ordering.d.ts +89 -0
- package/dist/esm/src/ordering/exact-ordering.js +256 -0
- package/dist/esm/src/ordering/exact-ordering.js.map +1 -0
- package/dist/esm/src/ordering/index.d.ts +22 -0
- package/dist/esm/src/ordering/index.js +17 -0
- package/dist/esm/src/ordering/index.js.map +1 -0
- package/dist/esm/src/ordering/int-pair-map.d.ts +20 -0
- package/dist/esm/src/ordering/int-pair-map.js +81 -0
- package/dist/esm/src/ordering/int-pair-map.js.map +1 -0
- package/dist/esm/src/ordering/local-search.d.ts +114 -0
- package/dist/esm/src/ordering/local-search.js +308 -0
- package/dist/esm/src/ordering/local-search.js.map +1 -0
- package/dist/esm/src/ordering/optimize-ordering.d.ts +153 -0
- package/dist/esm/src/ordering/optimize-ordering.js +399 -0
- package/dist/esm/src/ordering/optimize-ordering.js.map +1 -0
- package/dist/esm/src/ordering/ordering-evaluator.d.ts +198 -0
- package/dist/esm/src/ordering/ordering-evaluator.js +377 -0
- package/dist/esm/src/ordering/ordering-evaluator.js.map +1 -0
- package/dist/esm/src/ordering/shared-diagram.d.ts +85 -0
- package/dist/esm/src/ordering/shared-diagram.js +289 -0
- package/dist/esm/src/ordering/shared-diagram.js.map +1 -0
- package/dist/esm/src/packed/index.d.ts +2 -0
- package/dist/esm/src/packed/index.js +3 -0
- package/dist/esm/src/packed/index.js.map +1 -0
- package/dist/esm/src/packed/packed-bdd-base64-string.d.ts +3 -0
- package/dist/esm/src/packed/packed-bdd-base64-string.js +42 -0
- package/dist/esm/src/packed/packed-bdd-base64-string.js.map +1 -0
- package/dist/esm/src/packed/packed-bdd.d.ts +13 -0
- package/dist/esm/src/packed/packed-bdd.js +66 -0
- package/dist/esm/src/packed/packed-bdd.js.map +1 -0
- package/dist/esm/src/root-node.d.ts +1 -2
- package/dist/esm/src/root-node.js +5 -10
- package/dist/esm/src/root-node.js.map +1 -1
- package/dist/esm/src/types.d.ts +0 -12
- package/dist/esm/src/util.js +14 -5
- package/dist/esm/src/util.js.map +1 -1
- package/docs/variable-ordering.md +306 -0
- package/package.json +15 -12
- package/src/abstract-node.ts +7 -5
- package/src/branches.ts +9 -7
- package/src/create-bdd-from-truth-table.ts +1 -1
- package/src/index.ts +2 -1
- package/src/internal-node.ts +7 -4
- package/src/optimize-brute-force.ts +5 -7
- package/src/ordering/build-bdd.ts +70 -0
- package/src/ordering/dense-truth-table.ts +161 -0
- package/src/ordering/exact-cost-ordering.ts +425 -0
- package/src/ordering/exact-ordering.ts +317 -0
- package/src/ordering/index.ts +57 -0
- package/src/ordering/int-pair-map.ts +85 -0
- package/src/ordering/local-search.ts +369 -0
- package/src/ordering/optimize-ordering.ts +570 -0
- package/src/ordering/ordering-evaluator.ts +479 -0
- package/src/ordering/shared-diagram.ts +310 -0
- package/src/packed/index.ts +2 -0
- package/src/packed/packed-bdd-base64-string.ts +47 -0
- package/src/packed/packed-bdd.ts +98 -0
- package/src/root-node.ts +8 -17
- package/src/types.ts +0 -18
- package/src/util.ts +15 -6
- package/dist/cjs/src/minimal-string/bdd-to-minimal-string.d.ts +0 -8
- package/dist/cjs/src/minimal-string/bdd-to-minimal-string.js +0 -60
- package/dist/cjs/src/minimal-string/bdd-to-minimal-string.js.map +0 -1
- package/dist/cjs/src/minimal-string/bdd-to-simple-bdd.d.ts +0 -11
- package/dist/cjs/src/minimal-string/bdd-to-simple-bdd.js +0 -24
- package/dist/cjs/src/minimal-string/bdd-to-simple-bdd.js.map +0 -1
- package/dist/cjs/src/minimal-string/index.d.ts +0 -5
- package/dist/cjs/src/minimal-string/index.js.map +0 -1
- package/dist/cjs/src/minimal-string/minimal-string-to-simple-bdd.d.ts +0 -2
- package/dist/cjs/src/minimal-string/minimal-string-to-simple-bdd.js +0 -58
- package/dist/cjs/src/minimal-string/minimal-string-to-simple-bdd.js.map +0 -1
- package/dist/cjs/src/minimal-string/resolve-with-simple-bdd.d.ts +0 -2
- package/dist/cjs/src/minimal-string/resolve-with-simple-bdd.js +0 -21
- package/dist/cjs/src/minimal-string/resolve-with-simple-bdd.js.map +0 -1
- package/dist/cjs/src/minimal-string/string-format.d.ts +0 -9
- package/dist/cjs/src/minimal-string/string-format.js +0 -61
- package/dist/cjs/src/minimal-string/string-format.js.map +0 -1
- package/dist/esm/src/minimal-string/bdd-to-minimal-string.d.ts +0 -8
- package/dist/esm/src/minimal-string/bdd-to-minimal-string.js +0 -55
- package/dist/esm/src/minimal-string/bdd-to-minimal-string.js.map +0 -1
- package/dist/esm/src/minimal-string/bdd-to-simple-bdd.d.ts +0 -11
- package/dist/esm/src/minimal-string/bdd-to-simple-bdd.js +0 -19
- package/dist/esm/src/minimal-string/bdd-to-simple-bdd.js.map +0 -1
- package/dist/esm/src/minimal-string/index.d.ts +0 -5
- package/dist/esm/src/minimal-string/index.js +0 -6
- package/dist/esm/src/minimal-string/index.js.map +0 -1
- package/dist/esm/src/minimal-string/minimal-string-to-simple-bdd.d.ts +0 -2
- package/dist/esm/src/minimal-string/minimal-string-to-simple-bdd.js +0 -54
- package/dist/esm/src/minimal-string/minimal-string-to-simple-bdd.js.map +0 -1
- package/dist/esm/src/minimal-string/resolve-with-simple-bdd.d.ts +0 -2
- package/dist/esm/src/minimal-string/resolve-with-simple-bdd.js +0 -17
- package/dist/esm/src/minimal-string/resolve-with-simple-bdd.js.map +0 -1
- package/dist/esm/src/minimal-string/string-format.d.ts +0 -9
- package/dist/esm/src/minimal-string/string-format.js +0 -54
- package/dist/esm/src/minimal-string/string-format.js.map +0 -1
- package/src/minimal-string/bdd-to-minimal-string.ts +0 -72
- package/src/minimal-string/bdd-to-simple-bdd.ts +0 -31
- package/src/minimal-string/index.ts +0 -5
- package/src/minimal-string/minimal-string-to-simple-bdd.ts +0 -67
- package/src/minimal-string/resolve-with-simple-bdd.ts +0 -25
- package/src/minimal-string/string-format.ts +0 -67
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { ensureValidOrdering, withTerminalIds } from './dense-truth-table.js';
|
|
2
|
+
/**
|
|
3
|
+
* relative tolerance for comparing expected costs
|
|
4
|
+
*/
|
|
5
|
+
export const COST_EPSILON = 1e-9;
|
|
6
|
+
/**
|
|
7
|
+
* Two costs closer than this are treated as equal. The tolerance is relative
|
|
8
|
+
* to the larger of the value and the cost of one call of the most expensive
|
|
9
|
+
* boolean function (`unit`), so it does not depend on the unit the
|
|
10
|
+
* functionCosts are given in (milliseconds, seconds, ...).
|
|
11
|
+
*/
|
|
12
|
+
export function costTolerance(value, unit) {
|
|
13
|
+
return COST_EPSILON * Math.max(unit, Math.abs(value));
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The cost of one call of the most expensive boolean function,
|
|
17
|
+
* the unit of costTolerance() for expected costs.
|
|
18
|
+
*/
|
|
19
|
+
export function costUnit(costModel) {
|
|
20
|
+
let unit = 0;
|
|
21
|
+
for (let v = 0; v < costModel.functionCosts.length; v++) {
|
|
22
|
+
unit = Math.max(unit, costModel.functionCosts[v]);
|
|
23
|
+
}
|
|
24
|
+
return unit;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* An ordering together with the intermediate results of its evaluation.
|
|
28
|
+
*
|
|
29
|
+
* levelIds[L] holds the ids of the 2^L blocks of level L (levelIds[n] are the
|
|
30
|
+
* rows of the truth table). Because blocks are indexed by the natural
|
|
31
|
+
* assignment to the functions above their level, swapping the functions of two
|
|
32
|
+
* levels keeps all levels below the lower one valid, only the levels from the
|
|
33
|
+
* lower one up to the root are recomputed.
|
|
34
|
+
*/
|
|
35
|
+
export class OrderingCursor {
|
|
36
|
+
evaluator;
|
|
37
|
+
record;
|
|
38
|
+
ordering;
|
|
39
|
+
evaluation;
|
|
40
|
+
/** id of the root block, a terminal when the function is constant */
|
|
41
|
+
root = 0;
|
|
42
|
+
n;
|
|
43
|
+
levelIds = [];
|
|
44
|
+
levelWeights;
|
|
45
|
+
created;
|
|
46
|
+
payingWeights;
|
|
47
|
+
constructor(evaluator, ordering, record = null) {
|
|
48
|
+
this.evaluator = evaluator;
|
|
49
|
+
this.record = record;
|
|
50
|
+
this.n = evaluator.variableCount;
|
|
51
|
+
ensureValidOrdering(ordering, this.n);
|
|
52
|
+
this.ordering = Array.from(ordering);
|
|
53
|
+
for (let level = 0; level < this.n; level++) {
|
|
54
|
+
this.levelIds.push(new Int32Array(1 << level));
|
|
55
|
+
}
|
|
56
|
+
this.levelIds.push(evaluator.table.terminalIds);
|
|
57
|
+
if (evaluator.costModel) {
|
|
58
|
+
this.levelWeights = [];
|
|
59
|
+
for (let level = 0; level < this.n; level++) {
|
|
60
|
+
this.levelWeights.push(new Float64Array(1 << level));
|
|
61
|
+
}
|
|
62
|
+
this.levelWeights.push(evaluator.costModel.rowWeights);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
this.levelWeights = null;
|
|
66
|
+
}
|
|
67
|
+
this.created = new Array(this.n).fill(0);
|
|
68
|
+
this.payingWeights = new Array(this.n).fill(0);
|
|
69
|
+
this.evaluation = this.recomputeFrom(this.n - 1);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Starts over with another ordering.
|
|
73
|
+
*/
|
|
74
|
+
reset(ordering) {
|
|
75
|
+
ensureValidOrdering(ordering, this.n);
|
|
76
|
+
for (let i = 0; i < this.n; i++) {
|
|
77
|
+
this.ordering[i] = ordering[i];
|
|
78
|
+
}
|
|
79
|
+
this.evaluation = this.recomputeFrom(this.n - 1);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Swaps the boolean functions of two levels and updates the evaluation.
|
|
83
|
+
*/
|
|
84
|
+
swap(levelA, levelB) {
|
|
85
|
+
if (levelA === levelB) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const tmp = this.ordering[levelA];
|
|
89
|
+
this.ordering[levelA] = this.ordering[levelB];
|
|
90
|
+
this.ordering[levelB] = tmp;
|
|
91
|
+
this.evaluation = this.recomputeFrom(Math.max(levelA, levelB));
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* recomputes the levels top .. 0 (the levels below stay as they are)
|
|
95
|
+
*/
|
|
96
|
+
recomputeFrom(top) {
|
|
97
|
+
this.evaluator.evaluations++;
|
|
98
|
+
const n = this.n;
|
|
99
|
+
const terminalCount = this.evaluator.terminalCount;
|
|
100
|
+
// ids used by the levels below `top`
|
|
101
|
+
let nextId = terminalCount;
|
|
102
|
+
for (let level = n - 1; level > top; level--) {
|
|
103
|
+
nextId += this.created[level];
|
|
104
|
+
}
|
|
105
|
+
for (let level = top; level >= 0; level--) {
|
|
106
|
+
const result = this.evaluator.computeLevel(this.ordering, level, this.levelIds[level + 1], this.levelWeights ? this.levelWeights[level + 1] : null, this.levelIds[level], this.levelWeights ? this.levelWeights[level] : null, nextId, this.record);
|
|
107
|
+
this.created[level] = result.created;
|
|
108
|
+
this.payingWeights[level] = result.payingWeight;
|
|
109
|
+
nextId += result.created;
|
|
110
|
+
}
|
|
111
|
+
this.root = this.levelIds[0][0];
|
|
112
|
+
const nodesPerLevel = this.created.slice();
|
|
113
|
+
const internalNodeCount = nextId - terminalCount;
|
|
114
|
+
const nodeCount = 1 + (internalNodeCount - nodesPerLevel[0]) + this.evaluator.table.leafCount;
|
|
115
|
+
let expectedCost = 0;
|
|
116
|
+
const costModel = this.evaluator.costModel;
|
|
117
|
+
if (costModel) {
|
|
118
|
+
const costs = costModel.functionCosts;
|
|
119
|
+
// the root node always calls its boolean function
|
|
120
|
+
expectedCost = costs[this.ordering[0]];
|
|
121
|
+
for (let level = 1; level < n; level++) {
|
|
122
|
+
expectedCost += costs[this.ordering[level]] * this.payingWeights[level] / costModel.totalWeight;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
nodesPerLevel,
|
|
127
|
+
internalNodeCount,
|
|
128
|
+
nodeCount,
|
|
129
|
+
expectedCost
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Evaluates variable orderings of a truth table without ever creating
|
|
135
|
+
* BDD node objects.
|
|
136
|
+
*
|
|
137
|
+
* The reduced BDD is built bottom-up: the rows of the truth table are the
|
|
138
|
+
* leaves, every level above merges the two children of each block into a node
|
|
139
|
+
* through a hash table (hash-consing). Equal children collapse to a single edge
|
|
140
|
+
* (reduction rule) and equal (child0, child1) pairs share one node (elimination
|
|
141
|
+
* rule), so the amount of nodes created per level is exactly the amount of
|
|
142
|
+
* nodes the reduced BDD has on that level. Everything runs in O(2^n) integer
|
|
143
|
+
* operations.
|
|
144
|
+
*
|
|
145
|
+
* A block on level L is the set of rows that agree on the boolean functions
|
|
146
|
+
* above level L. Blocks are indexed by the assignment to those functions in
|
|
147
|
+
* their natural (index) order, not in the order of the levels. That way the
|
|
148
|
+
* blocks of a level only depend on the SET of functions above it: when two
|
|
149
|
+
* levels swap their functions, nothing below them changes and OrderingCursor
|
|
150
|
+
* only recomputes the levels above.
|
|
151
|
+
*
|
|
152
|
+
* Don't-care rows are handled like RootNode.removeIrrelevantLeafNodes() does it:
|
|
153
|
+
* a node whose one branch is entirely don't-care is replaced by its other branch.
|
|
154
|
+
*
|
|
155
|
+
* With a cost model, the same pass also sums up the weight of the rows that
|
|
156
|
+
* pass through a node on each level, which gives the expected cost of a
|
|
157
|
+
* resolve() call: a row pays for the boolean function of a level exactly when
|
|
158
|
+
* its block on that level has a node. The root node always calls its boolean
|
|
159
|
+
* function, even when the function is irrelevant.
|
|
160
|
+
*/
|
|
161
|
+
export class OrderingEvaluator {
|
|
162
|
+
table;
|
|
163
|
+
costModel;
|
|
164
|
+
variableCount;
|
|
165
|
+
rowCount;
|
|
166
|
+
terminalCount;
|
|
167
|
+
dontCare;
|
|
168
|
+
/** amount of evaluations run so far */
|
|
169
|
+
evaluations = 0;
|
|
170
|
+
hashLo;
|
|
171
|
+
hashHi;
|
|
172
|
+
hashId;
|
|
173
|
+
scratch = null;
|
|
174
|
+
costUnit = 0;
|
|
175
|
+
constructor(table, costModel = null) {
|
|
176
|
+
this.table = table;
|
|
177
|
+
this.costModel = costModel;
|
|
178
|
+
this.variableCount = table.variableCount;
|
|
179
|
+
this.rowCount = table.rowCount;
|
|
180
|
+
this.terminalCount = table.terminalValues.length;
|
|
181
|
+
this.dontCare = table.dontCareTerminal;
|
|
182
|
+
if (costModel) {
|
|
183
|
+
if (costModel.functionCosts.length !== this.variableCount || costModel.rowWeights.length !== this.rowCount) {
|
|
184
|
+
throw new Error('cost model does not fit the truth table');
|
|
185
|
+
}
|
|
186
|
+
for (let row = 0; row < this.rowCount; row++) {
|
|
187
|
+
if (costModel.rowWeights[row] !== 0 && table.terminalIds[row] === table.dontCareTerminal) {
|
|
188
|
+
// a don't-care row is merged into the subtree of its sibling, its weight would be lost
|
|
189
|
+
throw new Error('don\'t-care rows must have a row weight of 0');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
this.costUnit = costUnit(costModel);
|
|
193
|
+
}
|
|
194
|
+
// at most rowCount/2 distinct nodes per level -> load factor <= 0.5
|
|
195
|
+
let hashSize = 16;
|
|
196
|
+
while (hashSize < this.rowCount) {
|
|
197
|
+
hashSize *= 2;
|
|
198
|
+
}
|
|
199
|
+
this.hashLo = new Int32Array(hashSize);
|
|
200
|
+
this.hashHi = new Int32Array(hashSize);
|
|
201
|
+
this.hashId = new Int32Array(hashSize);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Evaluates an ordering.
|
|
205
|
+
*/
|
|
206
|
+
evaluate(ordering) {
|
|
207
|
+
if (!this.scratch) {
|
|
208
|
+
this.scratch = new OrderingCursor(this, ordering);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
this.scratch.reset(ordering);
|
|
212
|
+
}
|
|
213
|
+
return this.scratch.evaluation;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* A cursor keeps the intermediate results of an ordering so that
|
|
217
|
+
* swapping two levels only recomputes the levels above them.
|
|
218
|
+
*/
|
|
219
|
+
cursor(ordering) {
|
|
220
|
+
return new OrderingCursor(this, ordering);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* @returns true when evaluation a is strictly better than b:
|
|
224
|
+
* fewer nodes, or with a cost model a lower expected cost
|
|
225
|
+
* (ties in the expected cost are broken by the amount of nodes)
|
|
226
|
+
*/
|
|
227
|
+
isBetter(a, b) {
|
|
228
|
+
return this.compare(a, b) < 0;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* negative when a is better than b, positive when b is better, 0 when equal
|
|
232
|
+
*/
|
|
233
|
+
compare(a, b) {
|
|
234
|
+
if (this.costModel) {
|
|
235
|
+
const epsilon = costTolerance(Math.max(Math.abs(a.expectedCost), Math.abs(b.expectedCost)), this.costUnit);
|
|
236
|
+
if (a.expectedCost < b.expectedCost - epsilon) {
|
|
237
|
+
return -1;
|
|
238
|
+
}
|
|
239
|
+
if (a.expectedCost > b.expectedCost + epsilon) {
|
|
240
|
+
return 1;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return a.nodeCount - b.nodeCount;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Builds the reduced diagram of an ordering.
|
|
247
|
+
*/
|
|
248
|
+
buildDiagram(ordering) {
|
|
249
|
+
const capacity = Math.max(1, this.rowCount);
|
|
250
|
+
const record = {
|
|
251
|
+
nodeLevel: new Int32Array(capacity),
|
|
252
|
+
nodeLo: new Int32Array(capacity),
|
|
253
|
+
nodeHi: new Int32Array(capacity)
|
|
254
|
+
};
|
|
255
|
+
const cursor = new OrderingCursor(this, ordering, record);
|
|
256
|
+
const count = cursor.evaluation.internalNodeCount;
|
|
257
|
+
return {
|
|
258
|
+
variableCount: this.variableCount,
|
|
259
|
+
terminalCount: this.terminalCount,
|
|
260
|
+
root: cursor.root,
|
|
261
|
+
nodeLevel: record.nodeLevel.subarray(0, count),
|
|
262
|
+
nodeLo: record.nodeLo.subarray(0, count),
|
|
263
|
+
nodeHi: record.nodeHi.subarray(0, count),
|
|
264
|
+
ordering: Array.from(ordering),
|
|
265
|
+
nodesPerLevel: cursor.evaluation.nodesPerLevel
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Resolves the don't-care rows the same way the BDD of the given ordering
|
|
270
|
+
* resolves them (a don't-care branch takes the value of its sibling branch)
|
|
271
|
+
* and returns a table without don't-care rows.
|
|
272
|
+
* When the table has no don't-care rows, the same table is returned.
|
|
273
|
+
*/
|
|
274
|
+
complete(ordering) {
|
|
275
|
+
if (this.dontCare < 0) {
|
|
276
|
+
return this.table;
|
|
277
|
+
}
|
|
278
|
+
const diagram = this.buildDiagram(ordering);
|
|
279
|
+
const n = this.variableCount;
|
|
280
|
+
const terminalCount = this.terminalCount;
|
|
281
|
+
const terminalIds = new Int32Array(this.rowCount);
|
|
282
|
+
let stillDontCare = false;
|
|
283
|
+
for (let row = 0; row < this.rowCount; row++) {
|
|
284
|
+
let id = diagram.root;
|
|
285
|
+
while (id >= terminalCount) {
|
|
286
|
+
const index = id - terminalCount;
|
|
287
|
+
const variable = diagram.ordering[diagram.nodeLevel[index]];
|
|
288
|
+
id = ((row >>> (n - 1 - variable)) & 1) === 0 ? diagram.nodeLo[index] : diagram.nodeHi[index];
|
|
289
|
+
}
|
|
290
|
+
terminalIds[row] = id;
|
|
291
|
+
if (id === this.dontCare) {
|
|
292
|
+
stillDontCare = true;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return withTerminalIds(this.table, terminalIds, stillDontCare ? this.dontCare : -1);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Computes the blocks of one level out of the blocks of the level below.
|
|
299
|
+
* @internal
|
|
300
|
+
*/
|
|
301
|
+
computeLevel(ordering, level, deeperIds, deeperWeights, ids, weights, firstId, record) {
|
|
302
|
+
const dc = this.dontCare;
|
|
303
|
+
const terminalCount = this.terminalCount;
|
|
304
|
+
const hashLo = this.hashLo;
|
|
305
|
+
const hashHi = this.hashHi;
|
|
306
|
+
const hashId = this.hashId;
|
|
307
|
+
const count = 1 << level;
|
|
308
|
+
let tableSize = 16;
|
|
309
|
+
while (tableSize < count * 2) {
|
|
310
|
+
tableSize *= 2;
|
|
311
|
+
}
|
|
312
|
+
const mask = tableSize - 1;
|
|
313
|
+
hashLo.fill(-1, 0, tableSize);
|
|
314
|
+
// the position of this level's function inside the index of the level below:
|
|
315
|
+
// the functions above the level below are sorted ascending, the largest one is bit 0
|
|
316
|
+
const variable = ordering[level];
|
|
317
|
+
let position = 0;
|
|
318
|
+
for (let k = 0; k <= level; k++) {
|
|
319
|
+
if (ordering[k] > variable) {
|
|
320
|
+
position++;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
const lowMask = (1 << position) - 1;
|
|
324
|
+
const hiBit = 1 << position;
|
|
325
|
+
let nextId = firstId;
|
|
326
|
+
let created = 0;
|
|
327
|
+
let payingWeight = 0;
|
|
328
|
+
for (let block = 0; block < count; block++) {
|
|
329
|
+
const loIndex = ((block >>> position) << (position + 1)) | (block & lowMask);
|
|
330
|
+
const hiIndex = loIndex | hiBit;
|
|
331
|
+
const lo = deeperIds[loIndex];
|
|
332
|
+
const hi = deeperIds[hiIndex];
|
|
333
|
+
let blockWeight = 0;
|
|
334
|
+
if (deeperWeights && weights) {
|
|
335
|
+
blockWeight = deeperWeights[loIndex] + deeperWeights[hiIndex];
|
|
336
|
+
weights[block] = blockWeight;
|
|
337
|
+
}
|
|
338
|
+
let id;
|
|
339
|
+
if (lo === dc) {
|
|
340
|
+
id = hi;
|
|
341
|
+
}
|
|
342
|
+
else if (hi === dc || lo === hi) {
|
|
343
|
+
id = lo;
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
payingWeight += blockWeight;
|
|
347
|
+
let h = (Math.imul(lo, 0x9E3779B1) ^ Math.imul(hi, 0x85EBCA77)) >>> 0;
|
|
348
|
+
h = (h ^ (h >>> 15)) & mask;
|
|
349
|
+
while (true) {
|
|
350
|
+
const storedLo = hashLo[h];
|
|
351
|
+
if (storedLo === -1) {
|
|
352
|
+
hashLo[h] = lo;
|
|
353
|
+
hashHi[h] = hi;
|
|
354
|
+
hashId[h] = nextId;
|
|
355
|
+
id = nextId;
|
|
356
|
+
if (record) {
|
|
357
|
+
record.nodeLevel[nextId - terminalCount] = level;
|
|
358
|
+
record.nodeLo[nextId - terminalCount] = lo;
|
|
359
|
+
record.nodeHi[nextId - terminalCount] = hi;
|
|
360
|
+
}
|
|
361
|
+
nextId++;
|
|
362
|
+
created++;
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
if (storedLo === lo && hashHi[h] === hi) {
|
|
366
|
+
id = hashId[h];
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
h = (h + 1) & mask;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
ids[block] = id;
|
|
373
|
+
}
|
|
374
|
+
return { created, payingWeight };
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
//# sourceMappingURL=ordering-evaluator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ordering-evaluator.js","sourceRoot":"","sources":["../../../../src/ordering/ordering-evaluator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAqE9E;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,IAAY;IACrD,OAAO,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,SAAoB;IACzC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtD,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,OAAO,cAAc;IAaF;IAEA;IAdL,QAAQ,CAAW;IAC5B,UAAU,CAAqB;IACtC,qEAAqE;IAC9D,IAAI,GAAW,CAAC,CAAC;IAEP,CAAC,CAAS;IACV,QAAQ,GAAiB,EAAE,CAAC;IAC5B,YAAY,CAAwB;IACpC,OAAO,CAAW;IAClB,aAAa,CAAW;IAEzC,YACqB,SAA4B,EAC7C,QAA2B,EACV,SAA+B,IAAI;QAFnC,cAAS,GAAT,SAAS,CAAmB;QAE5B,WAAM,GAAN,MAAM,CAA6B;QAEpD,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,aAAa,CAAC;QACjC,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;YAC1C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAChD,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;YACvB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC1C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;YACzD,CAAC;YACD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC3D,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,CAAC,aAAa,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,QAA2B;QACpC,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9B,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,CAAC;IAED;;OAEG;IACI,IAAI,CAAC,MAAc,EAAE,MAAc;QACtC,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACpB,OAAO;QACX,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAClC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC;QAC5B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnE,CAAC;IAED;;OAEG;IACK,aAAa,CAAC,GAAW;QAC7B,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QACjB,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;QACnD,qCAAqC;QACrC,IAAI,MAAM,GAAG,aAAa,CAAC;QAC3B,KAAK,IAAI,KAAK,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3C,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;QACD,KAAK,IAAI,KAAK,GAAG,GAAG,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CACtC,IAAI,CAAC,QAAQ,EACb,KAAK,EACL,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,EACxB,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EACvD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EACpB,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EACnD,MAAM,EACN,IAAI,CAAC,MAAM,CACd,CAAC;YACF,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC;YACrC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC;YAChD,MAAM,IAAI,MAAM,CAAC,OAAO,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEhC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC3C,MAAM,iBAAiB,GAAG,MAAM,GAAG,aAAa,CAAC;QACjD,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,iBAAiB,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC;QAC9F,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;QAC3C,IAAI,SAAS,EAAE,CAAC;YACZ,MAAM,KAAK,GAAG,SAAS,CAAC,aAAa,CAAC;YACtC,kDAAkD;YAClD,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YACvC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBACrC,YAAY,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,WAAW,CAAC;YACpG,CAAC;QACL,CAAC;QACD,OAAO;YACH,aAAa;YACb,iBAAiB;YACjB,SAAS;YACT,YAAY;SACf,CAAC;IACN,CAAC;CACJ;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,OAAO,iBAAiB;IAeN;IACA;IAfJ,aAAa,CAAS;IACtB,QAAQ,CAAS;IACjB,aAAa,CAAS;IACtB,QAAQ,CAAS;IACjC,uCAAuC;IAChC,WAAW,GAAW,CAAC,CAAC;IAEd,MAAM,CAAa;IACnB,MAAM,CAAa;IACnB,MAAM,CAAa;IAC5B,OAAO,GAA0B,IAAI,CAAC;IACtC,QAAQ,GAAW,CAAC,CAAC;IAE7B,YACoB,KAAsB,EACtB,YAA8B,IAAI;QADlC,UAAK,GAAL,KAAK,CAAiB;QACtB,cAAS,GAAT,SAAS,CAAyB;QAElD,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;QACzC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QAC/B,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC;QACjD,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,gBAAgB,CAAC;QACvC,IAAI,SAAS,EAAE,CAAC;YACZ,IAAI,SAAS,CAAC,aAAa,CAAC,MAAM,KAAK,IAAI,CAAC,aAAa,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACzG,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;YAC/D,CAAC;YACD,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,CAAC;gBAC3C,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,gBAAgB,EAAE,CAAC;oBACvF,uFAAuF;oBACvF,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;gBACpE,CAAC;YACL,CAAC;YACD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;QACxC,CAAC;QACD,oEAAoE;QACpE,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,OAAO,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,QAAQ,IAAI,CAAC,CAAC;QAClB,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACI,QAAQ,CAAC,QAA2B;QACvC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACtD,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;IACnC,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,QAA2B;QACrC,OAAO,IAAI,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED;;;;OAIG;IACI,QAAQ,CAAC,CAAqB,EAAE,CAAqB;QACxD,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACI,OAAO,CAAC,CAAqB,EAAE,CAAqB;QACvD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC3G,IAAI,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,GAAG,OAAO,EAAE,CAAC;gBAC5C,OAAO,CAAC,CAAC,CAAC;YACd,CAAC;YACD,IAAI,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,GAAG,OAAO,EAAE,CAAC;gBAC5C,OAAO,CAAC,CAAC;YACb,CAAC;QACL,CAAC;QACD,OAAO,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;IACrC,CAAC;IAED;;OAEG;IACI,YAAY,CAAC,QAA2B;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAkB;YAC1B,SAAS,EAAE,IAAI,UAAU,CAAC,QAAQ,CAAC;YACnC,MAAM,EAAE,IAAI,UAAU,CAAC,QAAQ,CAAC;YAChC,MAAM,EAAE,IAAI,UAAU,CAAC,QAAQ,CAAC;SACnC,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC;QAClD,OAAO;YACH,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;YAC9C,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;YACxC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;YACxC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;YAC9B,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC,aAAa;SACjD,CAAC;IACN,CAAC;IAED;;;;;OAKG;IACI,QAAQ,CAAC,QAA2B;QACvC,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,KAAK,CAAC;QACtB,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC;QAC7B,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QACzC,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClD,IAAI,aAAa,GAAG,KAAK,CAAC;QAC1B,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,CAAC;YAC3C,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YACtB,OAAO,EAAE,IAAI,aAAa,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,EAAE,GAAG,aAAa,CAAC;gBACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC5D,EAAE,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAClG,CAAC;YACD,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YACtB,IAAI,EAAE,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACvB,aAAa,GAAG,IAAI,CAAC;YACzB,CAAC;QACL,CAAC;QACD,OAAO,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxF,CAAC;IAED;;;OAGG;IACI,YAAY,CACf,QAAkB,EAClB,KAAa,EACb,SAAqB,EACrB,aAAkC,EAClC,GAAe,EACf,OAA4B,EAC5B,OAAe,EACf,MAA4B;QAE5B,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QACzB,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,MAAM,KAAK,GAAG,CAAC,IAAI,KAAK,CAAC;QACzB,IAAI,SAAS,GAAG,EAAE,CAAC;QACnB,OAAO,SAAS,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC;YAC3B,SAAS,IAAI,CAAC,CAAC;QACnB,CAAC;QACD,MAAM,IAAI,GAAG,SAAS,GAAG,CAAC,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;QAE9B,6EAA6E;QAC7E,qFAAqF;QACrF,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9B,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,EAAE,CAAC;gBACzB,QAAQ,EAAE,CAAC;YACf,CAAC;QACL,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,CAAC,IAAI,QAAQ,CAAC;QAE5B,IAAI,MAAM,GAAG,OAAO,CAAC;QACrB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC;YAC7E,MAAM,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;YAChC,MAAM,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;YAC9B,MAAM,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;YAC9B,IAAI,WAAW,GAAG,CAAC,CAAC;YACpB,IAAI,aAAa,IAAI,OAAO,EAAE,CAAC;gBAC3B,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;gBAC9D,OAAO,CAAC,KAAK,CAAC,GAAG,WAAW,CAAC;YACjC,CAAC;YACD,IAAI,EAAU,CAAC;YACf,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBACZ,EAAE,GAAG,EAAE,CAAC;YACZ,CAAC;iBAAM,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBAChC,EAAE,GAAG,EAAE,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACJ,YAAY,IAAI,WAAW,CAAC;gBAC5B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC;gBACtE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;gBAC5B,OAAO,IAAI,EAAE,CAAC;oBACV,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;oBAC3B,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;wBAClB,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;wBACf,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;wBACf,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;wBACnB,EAAE,GAAG,MAAM,CAAC;wBACZ,IAAI,MAAM,EAAE,CAAC;4BACT,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,aAAa,CAAC,GAAG,KAAK,CAAC;4BACjD,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE,CAAC;4BAC3C,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE,CAAC;wBAC/C,CAAC;wBACD,MAAM,EAAE,CAAC;wBACT,OAAO,EAAE,CAAC;wBACV,MAAM;oBACV,CAAC;oBACD,IAAI,QAAQ,KAAK,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;wBACtC,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;wBACf,MAAM;oBACV,CAAC;oBACD,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;gBACvB,CAAC;YACL,CAAC;YACD,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QACpB,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;IACrC,CAAC;CACJ"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { DenseTruthTable } from './dense-truth-table.js';
|
|
2
|
+
/**
|
|
3
|
+
* thrown by SharedDiagram when more nodes than allowed would be created
|
|
4
|
+
*/
|
|
5
|
+
export declare class DiagramBudgetExceededError extends Error {
|
|
6
|
+
constructor();
|
|
7
|
+
}
|
|
8
|
+
export declare const DEFAULT_MAX_DIAGRAM_NODES = 4000000;
|
|
9
|
+
/**
|
|
10
|
+
* A hash-consed decision diagram of a fully specified truth table in the
|
|
11
|
+
* natural variable order, with a restrict() operation.
|
|
12
|
+
*
|
|
13
|
+
* Because the variable order is fixed, two functions are equal if and only if
|
|
14
|
+
* they have the same node id. The exact searches rely on this to recognize
|
|
15
|
+
* equal cofactors.
|
|
16
|
+
*/
|
|
17
|
+
export declare class SharedDiagram {
|
|
18
|
+
readonly table: DenseTruthTable;
|
|
19
|
+
readonly variableCount: number;
|
|
20
|
+
readonly terminalCount: number;
|
|
21
|
+
readonly rootId: number;
|
|
22
|
+
/** the boolean functions the truth table depends on, ascending */
|
|
23
|
+
readonly relevant: number[];
|
|
24
|
+
/** bit index of each relevant boolean function inside support masks, -1 for irrelevant ones */
|
|
25
|
+
readonly compactOf: Int32Array;
|
|
26
|
+
private nodeVar;
|
|
27
|
+
private nodeLo;
|
|
28
|
+
private nodeHi;
|
|
29
|
+
private nodeSupport;
|
|
30
|
+
private nodeCount;
|
|
31
|
+
private readonly uniqueTables;
|
|
32
|
+
private readonly restrictMemo;
|
|
33
|
+
private readonly maxNodes;
|
|
34
|
+
constructor(table: DenseTruthTable,
|
|
35
|
+
/**
|
|
36
|
+
* restrict() creates nodes for the restricted functions, which can be a lot
|
|
37
|
+
* on unstructured functions. More nodes than this throw a DiagramBudgetExceededError.
|
|
38
|
+
* Default: 4000000 (roughly 400 MB)
|
|
39
|
+
*/
|
|
40
|
+
maxNodes?: number);
|
|
41
|
+
isTerminal(id: number): boolean;
|
|
42
|
+
/** amount of internal nodes created so far */
|
|
43
|
+
get size(): number;
|
|
44
|
+
/** true when the diagram of the natural ordering alone already exceeds the node budget */
|
|
45
|
+
get overBudget(): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* support mask (compact bit indexes) of a node, 0 for terminals
|
|
48
|
+
*/
|
|
49
|
+
supportOf(id: number): number;
|
|
50
|
+
dependsOn(id: number, variable: number): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* the function with `variable` fixed to `value`
|
|
53
|
+
*/
|
|
54
|
+
restrict(g: number, variable: number, value: number): number;
|
|
55
|
+
/**
|
|
56
|
+
* Moves the boolean functions the truth table does not depend on
|
|
57
|
+
* to the bottom, keeping the order of the others.
|
|
58
|
+
*/
|
|
59
|
+
normalizeOrdering(ordering: ArrayLike<number>): number[];
|
|
60
|
+
irrelevantVariables(): number[];
|
|
61
|
+
private makeNode;
|
|
62
|
+
/**
|
|
63
|
+
* support in natural variable bits, only used before the compact mapping exists
|
|
64
|
+
*/
|
|
65
|
+
private rawSupport;
|
|
66
|
+
private growNodes;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* binary min-heap of search states, deterministic tie breaking:
|
|
70
|
+
* smaller estimate first, then larger cost (deeper states), then smaller subset
|
|
71
|
+
*/
|
|
72
|
+
export declare class StateHeap {
|
|
73
|
+
private readonly estimates;
|
|
74
|
+
private readonly costs;
|
|
75
|
+
private readonly subsets;
|
|
76
|
+
get size(): number;
|
|
77
|
+
push(estimate: number, cost: number, subset: number): void;
|
|
78
|
+
pop(): {
|
|
79
|
+
estimate: number;
|
|
80
|
+
cost: number;
|
|
81
|
+
subset: number;
|
|
82
|
+
};
|
|
83
|
+
private less;
|
|
84
|
+
private swap;
|
|
85
|
+
}
|