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.
- 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 +1 -0
- package/dist/cjs/src/branches.js +2 -1
- package/dist/cjs/src/branches.js.map +1 -1
- package/dist/cjs/src/create-bdd-from-truth-table.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 +5 -7
- 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 +1 -5
- 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 +14 -5
- 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 +1 -0
- package/dist/esm/src/branches.js +1 -0
- 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 +1 -5
- 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 +11 -9
- package/src/abstract-node.ts +7 -5
- package/src/branches.ts +2 -0
- 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 +2 -8
- 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 -59
- 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 -23
- 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 -57
- 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 -18
- 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 -15
- 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 -23
- package/src/minimal-string/string-format.ts +0 -67
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
import { parseTruthTable, denseTruthTableToMap, ensureValidOrdering } from './dense-truth-table.js';
|
|
2
|
+
import { OrderingEvaluator } from './ordering-evaluator.js';
|
|
3
|
+
import { LocalOrderingSearch, seedOrderings, DEFAULT_WINDOW_SIZE, ensureWindowSize, ensureNonNegativeInteger } from './local-search.js';
|
|
4
|
+
import { ExactOrderingSearch } from './exact-ordering.js';
|
|
5
|
+
import { ExactCostOrderingSearch } from './exact-cost-ordering.js';
|
|
6
|
+
import { buildBddFromDiagram } from './build-bdd.js';
|
|
7
|
+
export const DEFAULT_MAX_EXACT_VARIABLES = 20;
|
|
8
|
+
export const DEFAULT_MAX_EXACT_NODE_COUNT = 5000;
|
|
9
|
+
/**
|
|
10
|
+
* Validates functionCosts and rowWeight and turns them into a cost model.
|
|
11
|
+
*/
|
|
12
|
+
export function buildCostModel(table, functionCosts, rowWeight) {
|
|
13
|
+
if (!functionCosts) {
|
|
14
|
+
if (rowWeight) {
|
|
15
|
+
throw new Error('rowWeight can only be used together with functionCosts');
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const n = table.variableCount;
|
|
20
|
+
if (functionCosts.length !== n) {
|
|
21
|
+
throw new Error('functionCosts must have one entry per boolean function (' + n + ')');
|
|
22
|
+
}
|
|
23
|
+
const costs = new Float64Array(n);
|
|
24
|
+
for (let v = 0; v < n; v++) {
|
|
25
|
+
const cost = functionCosts[v];
|
|
26
|
+
if (typeof cost !== 'number' || !isFinite(cost) || cost < 0) {
|
|
27
|
+
throw new Error('functionCosts[' + v + '] must be a non-negative number');
|
|
28
|
+
}
|
|
29
|
+
costs[v] = cost;
|
|
30
|
+
}
|
|
31
|
+
const weights = new Float64Array(table.rowCount);
|
|
32
|
+
let totalWeight = 0;
|
|
33
|
+
for (let row = 0; row < table.rowCount; row++) {
|
|
34
|
+
const id = table.terminalIds[row];
|
|
35
|
+
if (id === table.dontCareTerminal) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
let weight = 1;
|
|
39
|
+
if (rowWeight) {
|
|
40
|
+
const key = row.toString(2).padStart(n, '0');
|
|
41
|
+
weight = rowWeight(key, table.terminalValues[id]);
|
|
42
|
+
if (typeof weight !== 'number' || !isFinite(weight) || weight < 0) {
|
|
43
|
+
throw new Error('rowWeight must return a non-negative number, got ' + weight + ' for ' + key);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
weights[row] = weight;
|
|
47
|
+
totalWeight += weight;
|
|
48
|
+
}
|
|
49
|
+
if (totalWeight <= 0) {
|
|
50
|
+
throw new Error('all row weights are zero');
|
|
51
|
+
}
|
|
52
|
+
let maxCost = 0;
|
|
53
|
+
costs.forEach(cost => maxCost = Math.max(maxCost, cost));
|
|
54
|
+
if (!isFinite(totalWeight) || !isFinite(maxCost * totalWeight)) {
|
|
55
|
+
throw new Error('the function costs or row weights are too large, scale them down');
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
functionCosts: costs,
|
|
59
|
+
rowWeights: weights,
|
|
60
|
+
totalWeight
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Deterministically finds a variable ordering with a small BDD
|
|
65
|
+
* (or, with functionCosts, with a cheap resolve() call).
|
|
66
|
+
* See docs/variable-ordering.md for how it works.
|
|
67
|
+
* Does not create BDD nodes, use optimizeOrdering() for that.
|
|
68
|
+
*/
|
|
69
|
+
export function findOrdering(input) {
|
|
70
|
+
return findOrderingWithTable(input).result;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Checks the options before any expensive work starts.
|
|
74
|
+
*/
|
|
75
|
+
function ensureValidOptions(input) {
|
|
76
|
+
if (input.windowSize !== undefined) {
|
|
77
|
+
ensureWindowSize(input.windowSize);
|
|
78
|
+
}
|
|
79
|
+
if (input.maxRounds !== undefined) {
|
|
80
|
+
ensureNonNegativeInteger(input.maxRounds, 'maxRounds');
|
|
81
|
+
}
|
|
82
|
+
const budgets = ['maxExactVariables', 'maxExactNodeCount', 'maxExactExpansions', 'maxExactDiagramNodes'];
|
|
83
|
+
budgets.forEach(name => {
|
|
84
|
+
const value = input[name];
|
|
85
|
+
if (value !== undefined) {
|
|
86
|
+
ensureNonNegativeInteger(value, name);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
if (input.exact !== undefined && input.exact !== true && input.exact !== false && input.exact !== 'auto') {
|
|
90
|
+
throw new Error('exact must be true, false or \'auto\'');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function findOrderingWithTable(input) {
|
|
94
|
+
const startTime = Date.now();
|
|
95
|
+
ensureValidOptions(input);
|
|
96
|
+
const log = input.log ? (message) => console.log('findOrdering(): ' + message) : () => null;
|
|
97
|
+
const onImprovement = input.onImprovement ? input.onImprovement : () => null;
|
|
98
|
+
const base = parseTruthTable(input.truthTable, input.dontCareValue);
|
|
99
|
+
const n = base.variableCount;
|
|
100
|
+
const costModel = buildCostModel(base, input.functionCosts, input.rowWeight);
|
|
101
|
+
const baseEvaluator = new OrderingEvaluator(base, costModel);
|
|
102
|
+
const windowSize = input.windowSize === undefined ? DEFAULT_WINDOW_SIZE : input.windowSize;
|
|
103
|
+
let evaluations = 0;
|
|
104
|
+
const describe = (evaluation) => evaluation.nodeCount + ' nodes' +
|
|
105
|
+
(costModel ? ', expected cost ' + evaluation.expectedCost : '');
|
|
106
|
+
/**
|
|
107
|
+
* phase 1: deterministic seeds, each improved by sifting and window permutation
|
|
108
|
+
*/
|
|
109
|
+
const userSeeds = (input.initialOrderings ? input.initialOrderings : []).map((ordering, index) => {
|
|
110
|
+
ensureValidOrdering(ordering, n);
|
|
111
|
+
return { name: 'initial-' + index, ordering: Array.from(ordering) };
|
|
112
|
+
});
|
|
113
|
+
const seenSeeds = new Set();
|
|
114
|
+
const seeds = userSeeds.concat(seedOrderings(baseEvaluator)).filter(seed => {
|
|
115
|
+
const key = seed.ordering.join(',');
|
|
116
|
+
if (seenSeeds.has(key)) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
seenSeeds.add(key);
|
|
120
|
+
return true;
|
|
121
|
+
});
|
|
122
|
+
let localBest = null;
|
|
123
|
+
const seedResults = [];
|
|
124
|
+
// the last evaluation passed to onImprovement
|
|
125
|
+
const reported = { evaluation: null };
|
|
126
|
+
for (const seed of seeds) {
|
|
127
|
+
const search = new LocalOrderingSearch(baseEvaluator, seed.ordering, {
|
|
128
|
+
windowSize,
|
|
129
|
+
maxRounds: input.maxRounds,
|
|
130
|
+
log: message => log('[' + seed.name + '] ' + message),
|
|
131
|
+
onImprovement: progress => {
|
|
132
|
+
if (!localBest || baseEvaluator.isBetter(search.best, localBest.evaluation)) {
|
|
133
|
+
reported.evaluation = search.best;
|
|
134
|
+
onImprovement(progress);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
const result = search.run();
|
|
139
|
+
log('seed ' + seed.name + ': ' + describe(result.evaluation));
|
|
140
|
+
seedResults.push({ ordering: result.ordering, evaluation: result.evaluation });
|
|
141
|
+
if (!localBest || baseEvaluator.isBetter(result.evaluation, localBest.evaluation)) {
|
|
142
|
+
localBest = { ordering: result.ordering, evaluation: result.evaluation };
|
|
143
|
+
if (!reported.evaluation || baseEvaluator.isBetter(result.evaluation, reported.evaluation)) {
|
|
144
|
+
// the seed itself was better than everything before, the search did not report it
|
|
145
|
+
reported.evaluation = result.evaluation;
|
|
146
|
+
onImprovement({
|
|
147
|
+
ordering: result.ordering.slice(),
|
|
148
|
+
nodeCount: result.evaluation.nodeCount,
|
|
149
|
+
expectedCost: result.evaluation.expectedCost,
|
|
150
|
+
phase: 'seed'
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (!localBest) {
|
|
156
|
+
throw new Error('no ordering found, this should not happen');
|
|
157
|
+
}
|
|
158
|
+
let best = localBest;
|
|
159
|
+
const localSearchNodeCount = best.evaluation.nodeCount;
|
|
160
|
+
/**
|
|
161
|
+
* phase 2: exact search
|
|
162
|
+
*
|
|
163
|
+
* The exact search needs a fully specified function, so it runs on the
|
|
164
|
+
* truth table with the don't-care rows resolved. Different orderings resolve
|
|
165
|
+
* them differently, so every completion the local search came across is a
|
|
166
|
+
* candidate. Whenever a new best ordering is found, its own completion
|
|
167
|
+
* becomes a candidate too.
|
|
168
|
+
*/
|
|
169
|
+
let completed = baseEvaluator.complete(best.ordering);
|
|
170
|
+
let optimal = false;
|
|
171
|
+
let exactExpansions = 0;
|
|
172
|
+
const exactMode = input.exact === undefined ? 'auto' : input.exact;
|
|
173
|
+
const maxExactVariables = input.maxExactVariables === undefined ? DEFAULT_MAX_EXACT_VARIABLES : input.maxExactVariables;
|
|
174
|
+
const maxExactNodeCount = input.maxExactNodeCount === undefined ? DEFAULT_MAX_EXACT_NODE_COUNT : input.maxExactNodeCount;
|
|
175
|
+
const runExact = exactMode === true || (exactMode === 'auto' &&
|
|
176
|
+
n <= maxExactVariables &&
|
|
177
|
+
best.evaluation.internalNodeCount <= maxExactNodeCount);
|
|
178
|
+
if (exactMode === 'auto' && !runExact) {
|
|
179
|
+
log('exact search skipped: ' + n + ' boolean functions, ' + best.evaluation.internalNodeCount + ' internal nodes');
|
|
180
|
+
}
|
|
181
|
+
if (runExact) {
|
|
182
|
+
const candidates = [];
|
|
183
|
+
const seenCompletions = new Set();
|
|
184
|
+
const addCandidate = (ordering, front) => {
|
|
185
|
+
const table = baseEvaluator.complete(ordering);
|
|
186
|
+
const key = completionKey(table);
|
|
187
|
+
if (seenCompletions.has(key)) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
seenCompletions.add(key);
|
|
191
|
+
const candidate = { ordering, table };
|
|
192
|
+
if (front) {
|
|
193
|
+
candidates.unshift(candidate);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
candidates.push(candidate);
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
addCandidate(best.ordering, false);
|
|
200
|
+
if (base.dontCareTerminal >= 0) {
|
|
201
|
+
seedResults.forEach(result => addCandidate(result.ordering, false));
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* completions for which the exact search finished: on them, no ordering
|
|
205
|
+
* beats the best evaluation known at that time (which is never worse than
|
|
206
|
+
* the final one)
|
|
207
|
+
*/
|
|
208
|
+
const solvedCompletions = new Set();
|
|
209
|
+
while (candidates.length > 0) {
|
|
210
|
+
const candidate = candidates.shift();
|
|
211
|
+
const candidateKey = completionKey(candidate.table);
|
|
212
|
+
let exactOrdering;
|
|
213
|
+
let solved;
|
|
214
|
+
let expansions;
|
|
215
|
+
const searchOptions = { maxDiagramNodes: input.maxExactDiagramNodes };
|
|
216
|
+
if (costModel) {
|
|
217
|
+
const exactResult = new ExactCostOrderingSearch(candidate.table, costModel, searchOptions).run({
|
|
218
|
+
maxExpansions: input.maxExactExpansions,
|
|
219
|
+
upperBoundOrdering: candidate.ordering,
|
|
220
|
+
// only orderings that beat the best known one are interesting
|
|
221
|
+
upperBound: best.evaluation.expectedCost,
|
|
222
|
+
log
|
|
223
|
+
});
|
|
224
|
+
exactOrdering = exactResult.ordering;
|
|
225
|
+
solved = exactResult.solved;
|
|
226
|
+
expansions = exactResult.expansions;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
const exactResult = new ExactOrderingSearch(candidate.table, searchOptions).run({
|
|
230
|
+
maxExpansions: input.maxExactExpansions,
|
|
231
|
+
upperBoundOrdering: candidate.ordering,
|
|
232
|
+
upperBound: best.evaluation.nodeCount - candidate.table.leafCount,
|
|
233
|
+
log
|
|
234
|
+
});
|
|
235
|
+
exactOrdering = exactResult.ordering;
|
|
236
|
+
solved = exactResult.solved;
|
|
237
|
+
expansions = exactResult.expansions;
|
|
238
|
+
}
|
|
239
|
+
exactExpansions += expansions;
|
|
240
|
+
if (!solved) {
|
|
241
|
+
log('exact search gave up on one completion of the truth table');
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
solvedCompletions.add(candidateKey);
|
|
245
|
+
if (!exactOrdering) {
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
const candidateEvaluator = new OrderingEvaluator(candidate.table, costModel);
|
|
249
|
+
let exactEvaluation = candidateEvaluator.evaluate(exactOrdering);
|
|
250
|
+
if (costModel) {
|
|
251
|
+
/**
|
|
252
|
+
* The exact cost search only minimizes the expected cost. Among the
|
|
253
|
+
* orderings with the same cost, fewer nodes are better, which the
|
|
254
|
+
* local search on the same completion takes care of.
|
|
255
|
+
*/
|
|
256
|
+
const polished = new LocalOrderingSearch(candidateEvaluator, exactOrdering, {
|
|
257
|
+
windowSize,
|
|
258
|
+
maxRounds: input.maxRounds
|
|
259
|
+
}).run();
|
|
260
|
+
exactOrdering = polished.ordering;
|
|
261
|
+
exactEvaluation = polished.evaluation;
|
|
262
|
+
}
|
|
263
|
+
evaluations += candidateEvaluator.evaluations;
|
|
264
|
+
log('exact search: ' + describe(exactEvaluation) + ' after ' + expansions + ' expansions');
|
|
265
|
+
if (baseEvaluator.isBetter(exactEvaluation, best.evaluation)) {
|
|
266
|
+
best = { ordering: exactOrdering, evaluation: exactEvaluation };
|
|
267
|
+
completed = candidate.table;
|
|
268
|
+
onImprovement({
|
|
269
|
+
ordering: best.ordering.slice(),
|
|
270
|
+
nodeCount: exactEvaluation.nodeCount,
|
|
271
|
+
expectedCost: exactEvaluation.expectedCost,
|
|
272
|
+
phase: 'exact'
|
|
273
|
+
});
|
|
274
|
+
if (base.dontCareTerminal >= 0) {
|
|
275
|
+
// the don't-care rows might resolve even better with the new ordering
|
|
276
|
+
addCandidate(best.ordering, true);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* When the completion the ordering picks itself is just as good,
|
|
282
|
+
* prefer it: then createBddWithOrdering(input, ordering, dontCareValue)
|
|
283
|
+
* rebuilds the same BDD.
|
|
284
|
+
*/
|
|
285
|
+
if (base.dontCareTerminal >= 0) {
|
|
286
|
+
const own = baseEvaluator.complete(best.ordering);
|
|
287
|
+
if (completionKey(own) !== completionKey(completed)) {
|
|
288
|
+
const ownEvaluation = baseEvaluator.evaluate(best.ordering);
|
|
289
|
+
if (baseEvaluator.compare(ownEvaluation, best.evaluation) === 0) {
|
|
290
|
+
best = { ordering: best.ordering, evaluation: ownEvaluation };
|
|
291
|
+
completed = own;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
optimal = solvedCompletions.has(completionKey(completed));
|
|
296
|
+
}
|
|
297
|
+
evaluations += baseEvaluator.evaluations;
|
|
298
|
+
return {
|
|
299
|
+
result: {
|
|
300
|
+
ordering: best.ordering,
|
|
301
|
+
nodeCount: best.evaluation.nodeCount,
|
|
302
|
+
expectedCost: costModel ? best.evaluation.expectedCost : undefined,
|
|
303
|
+
optimal,
|
|
304
|
+
truthTable: denseTruthTableToMap(completed),
|
|
305
|
+
stats: {
|
|
306
|
+
evaluations,
|
|
307
|
+
exactExpansions,
|
|
308
|
+
localSearchNodeCount,
|
|
309
|
+
durationMs: Date.now() - startTime
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
table: completed
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* identifies the content of a (completed) table
|
|
317
|
+
*/
|
|
318
|
+
function completionKey(table) {
|
|
319
|
+
let h1 = 0x811C9DC5;
|
|
320
|
+
let h2 = 0x01000193;
|
|
321
|
+
const ids = table.terminalIds;
|
|
322
|
+
for (let i = 0; i < ids.length; i++) {
|
|
323
|
+
h1 = Math.imul(h1 ^ ids[i], 0x01000193);
|
|
324
|
+
h2 = Math.imul(h2 + ids[i], 0x9E3779B1) ^ (h2 >>> 13);
|
|
325
|
+
}
|
|
326
|
+
return (h1 >>> 0).toString(16) + ':' + (h2 >>> 0).toString(16) + ':' + ids.length;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Deterministic replacement for optimizeBruteForce():
|
|
330
|
+
* finds a good variable ordering and returns the minimized BDD for it.
|
|
331
|
+
* All work is synchronous, the promise exists for compatibility with optimizeBruteForce().
|
|
332
|
+
*/
|
|
333
|
+
export async function optimizeOrdering(input) {
|
|
334
|
+
const { result: found, table } = findOrderingWithTable(input);
|
|
335
|
+
const bdd = buildBddForOrdering(table, found.ordering);
|
|
336
|
+
let optimal = found.optimal;
|
|
337
|
+
if (input.afterBddCreation) {
|
|
338
|
+
const before = fingerprint(bdd);
|
|
339
|
+
input.afterBddCreation(bdd);
|
|
340
|
+
bdd.minimize();
|
|
341
|
+
if (fingerprint(bdd) !== before) {
|
|
342
|
+
// the hook changed the BDD, the proof does not hold for it anymore
|
|
343
|
+
optimal = false;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return {
|
|
347
|
+
bdd,
|
|
348
|
+
ordering: found.ordering,
|
|
349
|
+
nodeCount: bdd.countNodes(),
|
|
350
|
+
expectedCost: found.expectedCost,
|
|
351
|
+
optimal,
|
|
352
|
+
truthTable: found.truthTable,
|
|
353
|
+
stats: found.stats
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Describes the structure and the leaf values of a BDD,
|
|
358
|
+
* equal BDDs give equal strings.
|
|
359
|
+
*/
|
|
360
|
+
function fingerprint(bdd) {
|
|
361
|
+
const ids = new Map();
|
|
362
|
+
const parts = [];
|
|
363
|
+
const visit = (node) => {
|
|
364
|
+
const known = ids.get(node);
|
|
365
|
+
if (known !== undefined) {
|
|
366
|
+
return known;
|
|
367
|
+
}
|
|
368
|
+
let part;
|
|
369
|
+
if (node.isLeafNode()) {
|
|
370
|
+
part = 'v' + String(node.asLeafNode().value);
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
const branches = node.branches;
|
|
374
|
+
part = node.level + ':' + visit(branches.getBranch('0')) + ',' + visit(branches.getBranch('1'));
|
|
375
|
+
}
|
|
376
|
+
const id = parts.length;
|
|
377
|
+
parts.push(part);
|
|
378
|
+
ids.set(node, id);
|
|
379
|
+
return id;
|
|
380
|
+
};
|
|
381
|
+
visit(bdd);
|
|
382
|
+
return parts.join(';');
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Creates the minimized BDD of a truth table for a given ordering
|
|
386
|
+
* without going through the unreduced decision tree.
|
|
387
|
+
*/
|
|
388
|
+
export function createBddWithOrdering(truthTable, ordering, dontCareValue) {
|
|
389
|
+
const base = parseTruthTable(truthTable, dontCareValue);
|
|
390
|
+
const evaluator = new OrderingEvaluator(base);
|
|
391
|
+
const completed = evaluator.complete(ordering);
|
|
392
|
+
return buildBddForOrdering(completed, ordering);
|
|
393
|
+
}
|
|
394
|
+
function buildBddForOrdering(table, ordering) {
|
|
395
|
+
const evaluator = new OrderingEvaluator(table);
|
|
396
|
+
const diagram = evaluator.buildDiagram(ordering);
|
|
397
|
+
return buildBddFromDiagram(diagram, table);
|
|
398
|
+
}
|
|
399
|
+
//# sourceMappingURL=optimize-ordering.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optimize-ordering.js","sourceRoot":"","sources":["../../../../src/ordering/optimize-ordering.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import type { DenseTruthTable } from './dense-truth-table.js';
|
|
2
|
+
/**
|
|
3
|
+
* Describes what a resolve() call costs.
|
|
4
|
+
*/
|
|
5
|
+
export interface CostModel {
|
|
6
|
+
/** functionCosts[v] = cost of calling boolean function v */
|
|
7
|
+
functionCosts: Float64Array;
|
|
8
|
+
/**
|
|
9
|
+
* rowWeights[row] = how often the row occurs at runtime, relative to the other rows.
|
|
10
|
+
* Must be 0 for don't-care rows, they never occur.
|
|
11
|
+
*/
|
|
12
|
+
rowWeights: Float64Array;
|
|
13
|
+
/** sum of rowWeights */
|
|
14
|
+
totalWeight: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Result of evaluating a variable ordering.
|
|
18
|
+
*/
|
|
19
|
+
export interface OrderingEvaluation {
|
|
20
|
+
/**
|
|
21
|
+
* nodesPerLevel[k] is the amount of nodes of the reduced BDD
|
|
22
|
+
* that test the boolean function ordering[k].
|
|
23
|
+
*/
|
|
24
|
+
nodesPerLevel: number[];
|
|
25
|
+
/** sum of nodesPerLevel */
|
|
26
|
+
internalNodeCount: number;
|
|
27
|
+
/**
|
|
28
|
+
* Amount of nodes as RootNode.countNodes() would return it:
|
|
29
|
+
* the root node, plus all nodes below the top level, plus the leaf nodes.
|
|
30
|
+
*/
|
|
31
|
+
nodeCount: number;
|
|
32
|
+
/**
|
|
33
|
+
* Expected cost of one resolve() call: the costs of the boolean functions
|
|
34
|
+
* that are called on the way from the root to the leaf, averaged over the
|
|
35
|
+
* rows with their weights. 0 when the evaluator has no cost model.
|
|
36
|
+
*/
|
|
37
|
+
expectedCost: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A reduced ordered (multi terminal) decision diagram
|
|
41
|
+
* in a flat array representation. Ids below terminalCount are terminals
|
|
42
|
+
* (and equal the terminal id of the dense truth table), ids from terminalCount
|
|
43
|
+
* on are internal nodes: node i is stored at index (i - terminalCount).
|
|
44
|
+
*/
|
|
45
|
+
export interface ReducedDiagram {
|
|
46
|
+
variableCount: number;
|
|
47
|
+
terminalCount: number;
|
|
48
|
+
/** id of the root, can be a terminal when the function is constant */
|
|
49
|
+
root: number;
|
|
50
|
+
/** level (index into the ordering) of each internal node */
|
|
51
|
+
nodeLevel: Int32Array;
|
|
52
|
+
/** id of the 0-branch of each internal node */
|
|
53
|
+
nodeLo: Int32Array;
|
|
54
|
+
/** id of the 1-branch of each internal node */
|
|
55
|
+
nodeHi: Int32Array;
|
|
56
|
+
/** ordering[level] = boolean function tested on that level */
|
|
57
|
+
ordering: number[];
|
|
58
|
+
nodesPerLevel: number[];
|
|
59
|
+
}
|
|
60
|
+
interface DiagramRecord {
|
|
61
|
+
nodeLevel: Int32Array;
|
|
62
|
+
nodeLo: Int32Array;
|
|
63
|
+
nodeHi: Int32Array;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* relative tolerance for comparing expected costs
|
|
67
|
+
*/
|
|
68
|
+
export declare const COST_EPSILON = 1e-9;
|
|
69
|
+
/**
|
|
70
|
+
* Two costs closer than this are treated as equal. The tolerance is relative
|
|
71
|
+
* to the larger of the value and the cost of one call of the most expensive
|
|
72
|
+
* boolean function (`unit`), so it does not depend on the unit the
|
|
73
|
+
* functionCosts are given in (milliseconds, seconds, ...).
|
|
74
|
+
*/
|
|
75
|
+
export declare function costTolerance(value: number, unit: number): number;
|
|
76
|
+
/**
|
|
77
|
+
* The cost of one call of the most expensive boolean function,
|
|
78
|
+
* the unit of costTolerance() for expected costs.
|
|
79
|
+
*/
|
|
80
|
+
export declare function costUnit(costModel: CostModel): number;
|
|
81
|
+
/**
|
|
82
|
+
* An ordering together with the intermediate results of its evaluation.
|
|
83
|
+
*
|
|
84
|
+
* levelIds[L] holds the ids of the 2^L blocks of level L (levelIds[n] are the
|
|
85
|
+
* rows of the truth table). Because blocks are indexed by the natural
|
|
86
|
+
* assignment to the functions above their level, swapping the functions of two
|
|
87
|
+
* levels keeps all levels below the lower one valid, only the levels from the
|
|
88
|
+
* lower one up to the root are recomputed.
|
|
89
|
+
*/
|
|
90
|
+
export declare class OrderingCursor {
|
|
91
|
+
private readonly evaluator;
|
|
92
|
+
private readonly record;
|
|
93
|
+
readonly ordering: number[];
|
|
94
|
+
evaluation: OrderingEvaluation;
|
|
95
|
+
/** id of the root block, a terminal when the function is constant */
|
|
96
|
+
root: number;
|
|
97
|
+
private readonly n;
|
|
98
|
+
private readonly levelIds;
|
|
99
|
+
private readonly levelWeights;
|
|
100
|
+
private readonly created;
|
|
101
|
+
private readonly payingWeights;
|
|
102
|
+
constructor(evaluator: OrderingEvaluator, ordering: ArrayLike<number>, record?: DiagramRecord | null);
|
|
103
|
+
/**
|
|
104
|
+
* Starts over with another ordering.
|
|
105
|
+
*/
|
|
106
|
+
reset(ordering: ArrayLike<number>): void;
|
|
107
|
+
/**
|
|
108
|
+
* Swaps the boolean functions of two levels and updates the evaluation.
|
|
109
|
+
*/
|
|
110
|
+
swap(levelA: number, levelB: number): void;
|
|
111
|
+
/**
|
|
112
|
+
* recomputes the levels top .. 0 (the levels below stay as they are)
|
|
113
|
+
*/
|
|
114
|
+
private recomputeFrom;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Evaluates variable orderings of a truth table without ever creating
|
|
118
|
+
* BDD node objects.
|
|
119
|
+
*
|
|
120
|
+
* The reduced BDD is built bottom-up: the rows of the truth table are the
|
|
121
|
+
* leaves, every level above merges the two children of each block into a node
|
|
122
|
+
* through a hash table (hash-consing). Equal children collapse to a single edge
|
|
123
|
+
* (reduction rule) and equal (child0, child1) pairs share one node (elimination
|
|
124
|
+
* rule), so the amount of nodes created per level is exactly the amount of
|
|
125
|
+
* nodes the reduced BDD has on that level. Everything runs in O(2^n) integer
|
|
126
|
+
* operations.
|
|
127
|
+
*
|
|
128
|
+
* A block on level L is the set of rows that agree on the boolean functions
|
|
129
|
+
* above level L. Blocks are indexed by the assignment to those functions in
|
|
130
|
+
* their natural (index) order, not in the order of the levels. That way the
|
|
131
|
+
* blocks of a level only depend on the SET of functions above it: when two
|
|
132
|
+
* levels swap their functions, nothing below them changes and OrderingCursor
|
|
133
|
+
* only recomputes the levels above.
|
|
134
|
+
*
|
|
135
|
+
* Don't-care rows are handled like RootNode.removeIrrelevantLeafNodes() does it:
|
|
136
|
+
* a node whose one branch is entirely don't-care is replaced by its other branch.
|
|
137
|
+
*
|
|
138
|
+
* With a cost model, the same pass also sums up the weight of the rows that
|
|
139
|
+
* pass through a node on each level, which gives the expected cost of a
|
|
140
|
+
* resolve() call: a row pays for the boolean function of a level exactly when
|
|
141
|
+
* its block on that level has a node. The root node always calls its boolean
|
|
142
|
+
* function, even when the function is irrelevant.
|
|
143
|
+
*/
|
|
144
|
+
export declare class OrderingEvaluator {
|
|
145
|
+
readonly table: DenseTruthTable;
|
|
146
|
+
readonly costModel: CostModel | null;
|
|
147
|
+
readonly variableCount: number;
|
|
148
|
+
readonly rowCount: number;
|
|
149
|
+
readonly terminalCount: number;
|
|
150
|
+
readonly dontCare: number;
|
|
151
|
+
/** amount of evaluations run so far */
|
|
152
|
+
evaluations: number;
|
|
153
|
+
private readonly hashLo;
|
|
154
|
+
private readonly hashHi;
|
|
155
|
+
private readonly hashId;
|
|
156
|
+
private scratch;
|
|
157
|
+
private costUnit;
|
|
158
|
+
constructor(table: DenseTruthTable, costModel?: CostModel | null);
|
|
159
|
+
/**
|
|
160
|
+
* Evaluates an ordering.
|
|
161
|
+
*/
|
|
162
|
+
evaluate(ordering: ArrayLike<number>): OrderingEvaluation;
|
|
163
|
+
/**
|
|
164
|
+
* A cursor keeps the intermediate results of an ordering so that
|
|
165
|
+
* swapping two levels only recomputes the levels above them.
|
|
166
|
+
*/
|
|
167
|
+
cursor(ordering: ArrayLike<number>): OrderingCursor;
|
|
168
|
+
/**
|
|
169
|
+
* @returns true when evaluation a is strictly better than b:
|
|
170
|
+
* fewer nodes, or with a cost model a lower expected cost
|
|
171
|
+
* (ties in the expected cost are broken by the amount of nodes)
|
|
172
|
+
*/
|
|
173
|
+
isBetter(a: OrderingEvaluation, b: OrderingEvaluation): boolean;
|
|
174
|
+
/**
|
|
175
|
+
* negative when a is better than b, positive when b is better, 0 when equal
|
|
176
|
+
*/
|
|
177
|
+
compare(a: OrderingEvaluation, b: OrderingEvaluation): number;
|
|
178
|
+
/**
|
|
179
|
+
* Builds the reduced diagram of an ordering.
|
|
180
|
+
*/
|
|
181
|
+
buildDiagram(ordering: ArrayLike<number>): ReducedDiagram;
|
|
182
|
+
/**
|
|
183
|
+
* Resolves the don't-care rows the same way the BDD of the given ordering
|
|
184
|
+
* resolves them (a don't-care branch takes the value of its sibling branch)
|
|
185
|
+
* and returns a table without don't-care rows.
|
|
186
|
+
* When the table has no don't-care rows, the same table is returned.
|
|
187
|
+
*/
|
|
188
|
+
complete(ordering: ArrayLike<number>): DenseTruthTable;
|
|
189
|
+
/**
|
|
190
|
+
* Computes the blocks of one level out of the blocks of the level below.
|
|
191
|
+
* @internal
|
|
192
|
+
*/
|
|
193
|
+
computeLevel(ordering: number[], level: number, deeperIds: Int32Array, deeperWeights: Float64Array | null, ids: Int32Array, weights: Float64Array | null, firstId: number, record: DiagramRecord | null): {
|
|
194
|
+
created: number;
|
|
195
|
+
payingWeight: number;
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
export {};
|