@lapxo/obligations 0.3.5 → 0.4.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 (45) hide show
  1. package/README.md +8 -143
  2. package/TARGET.bound +574 -507
  3. package/dist/measures/error-events.d.ts +27 -0
  4. package/dist/measures/error-events.js +43 -0
  5. package/dist/measures/experiments.d.ts +15 -0
  6. package/dist/measures/experiments.js +53 -0
  7. package/dist/measures/fitting.d.ts +243 -0
  8. package/dist/measures/fitting.js +115 -0
  9. package/dist/measures/identification.d.ts +156 -0
  10. package/dist/measures/identification.js +107 -0
  11. package/dist/measures/index.d.ts +18 -0
  12. package/dist/measures/index.js +9 -0
  13. package/dist/measures/m3-experiment.d.ts +69 -0
  14. package/dist/measures/m3-experiment.js +70 -0
  15. package/dist/measures/m3.d.ts +139 -0
  16. package/dist/measures/m3.js +181 -0
  17. package/dist/measures/model.d.ts +14 -0
  18. package/dist/measures/model.js +67 -0
  19. package/dist/measures/rational.d.ts +19 -0
  20. package/dist/measures/rational.js +53 -0
  21. package/dist/measures/spectrum.d.ts +22 -0
  22. package/dist/measures/spectrum.js +84 -0
  23. package/docs/measures.md +149 -0
  24. package/package.json +1 -93
  25. package/receipts.bound +75 -0
  26. package/samples/measures/descent.json +92 -0
  27. package/samples/measures/m3-reader.mjs +732 -0
  28. package/samples/measures/m3.json +3126 -0
  29. package/samples/measures/observations.json +212 -0
  30. package/samples/measures/reader.mjs +424 -0
  31. package/samples/measures/spectrum.json +6530 -0
  32. package/samples/measures/unanimity.json +76 -0
  33. package/samples/no/installed-artifact.json +302 -0
  34. package/samples/yes/algebra-is-closed.json +17 -0
  35. package/samples/yes/field-uses-price-and-debit.json +9 -0
  36. package/samples/yes/installed-artifact.json +397 -0
  37. package/samples/yes/three-theories-one-algebra.json +5 -0
  38. package/src/field/motion.ts +59 -0
  39. package/src/lattice/index.ts +79 -0
  40. package/vectors/measures/descent.cli.json +148 -0
  41. package/vectors/measures/installed-artifact.cli.json +43 -0
  42. package/vectors/measures/m3.cli.json +148 -0
  43. package/vectors/measures/observations.cli.json +148 -0
  44. package/vectors/measures/spectrum.cli.json +148 -0
  45. package/vectors/measures/unanimity.cli.json +148 -0
@@ -0,0 +1,732 @@
1
+ // work/obligations-0.4.0/repository/dist/measures/error-events.js
2
+ function errorMatrix(rows, policy, requested) {
3
+ if (!Number.isSafeInteger(policy.minCells) || policy.minCells < 2)
4
+ throw new Error("REFUSE\xB7measure invalid minimum cells");
5
+ const cells = /* @__PURE__ */ new Map();
6
+ for (const row of rows) {
7
+ if (!row.event || !row.origin || row.error !== 0 && row.error !== 1)
8
+ throw new Error("REFUSE\xB7measure invalid error event");
9
+ const at = cells.get(row.event) ?? /* @__PURE__ */ new Map();
10
+ if (at.has(row.origin) && at.get(row.origin) !== row.error)
11
+ throw new Error("REFUSE\xB7measure conflicting error event");
12
+ at.set(row.origin, row.error);
13
+ cells.set(row.event, at);
14
+ }
15
+ const origins = [...new Set(requested ?? rows.map((row) => row.origin))].sort();
16
+ if (origins.some((origin) => !origin))
17
+ throw new Error("REFUSE\xB7measure invalid origin");
18
+ const events = [...cells.keys()].filter((event) => origins.some((origin) => cells.get(event).has(origin))).sort();
19
+ if (events.length < policy.minCells || !origins.length)
20
+ return { status: "unmeasured", cause: "insufficient observed events" };
21
+ if (events.some((event) => origins.some((origin) => !cells.get(event).has(origin))))
22
+ return { status: "unmeasured", cause: "incomplete shared event observations" };
23
+ return { status: "measured", origins, events, matrix: events.map((event) => origins.map((origin) => cells.get(event).get(origin))) };
24
+ }
25
+
26
+ // work/obligations-0.4.0/repository/dist/measures/rational.js
27
+ var zero = [0n, 1n];
28
+ var one = [1n, 1n];
29
+ var refuse = (cause) => {
30
+ throw new Error("REFUSE\xB7model/M3 " + cause);
31
+ };
32
+ var gcd = (a, b) => {
33
+ a = a < 0n ? -a : a;
34
+ while (b) {
35
+ const r = a % b;
36
+ a = b;
37
+ b = r;
38
+ }
39
+ return a;
40
+ };
41
+ function q(a, b = 1n) {
42
+ if (b === 0n)
43
+ refuse("zero rational denominator");
44
+ if (b < 0n) {
45
+ a = -a;
46
+ b = -b;
47
+ }
48
+ const d = gcd(a, b);
49
+ return [a / d, b / d];
50
+ }
51
+ function rational(input) {
52
+ if (typeof input === "string") {
53
+ if (/^-?\d+\/\d+$/.test(input)) {
54
+ const [a, b] = input.split("/");
55
+ return q(BigInt(a), BigInt(b));
56
+ }
57
+ if (!/^-?\d+(\.\d+)?$/.test(input))
58
+ refuse("invalid exact probability");
59
+ const sign = input.startsWith("-") ? -1n : 1n, text = input.replace(/^-/, "");
60
+ const [whole, part = ""] = text.split(".");
61
+ return q(sign * BigInt(whole + part), 10n ** BigInt(part.length));
62
+ }
63
+ if (!input || typeof input.numerator !== "string" || typeof input.denominator !== "string" || !/^[-]?\d+$/.test(input.numerator) || !/^\d+$/.test(input.denominator))
64
+ refuse("invalid rational");
65
+ return q(BigInt(input.numerator), BigInt(input.denominator));
66
+ }
67
+ var add = (a, b) => q(a[0] * b[1] + b[0] * a[1], a[1] * b[1]);
68
+ var sub = (a, b) => q(a[0] * b[1] - b[0] * a[1], a[1] * b[1]);
69
+ var mul = (a, b) => q(a[0] * b[0], a[1] * b[1]);
70
+ var div = (a, b) => q(a[0] * b[1], a[1] * b[0]);
71
+ var equal = (a, b) => a[0] === b[0] && a[1] === b[1];
72
+ var pack = (a) => ({ numerator: String(a[0]), denominator: String(a[1]) });
73
+ function probability(input) {
74
+ const a = rational(input);
75
+ if (a[0] < 0n || a[0] > a[1])
76
+ refuse("probability outside 0..1");
77
+ return a;
78
+ }
79
+
80
+ // work/obligations-0.4.0/repository/dist/measures/m3.js
81
+ var conditions = Object.freeze(["ordered-governance", "independent-factor-indicators", "independent-private-indicators", "independent-uniform-wrong-labels", "handed-parameters"]);
82
+ var named = (s) => typeof s === "string" && s.length > 0;
83
+ function validateM3(model) {
84
+ if (!model || !Array.isArray(model.witnesses) || !Array.isArray(model.factors) || !Array.isArray(model.selection) || model.witnesses.some((w) => !w) || model.factors.some((f) => !f || !Array.isArray(f.members)))
85
+ refuse("invalid model records");
86
+ if (!named(model.cell) || !Number.isSafeInteger(model.cardinality) || model.cardinality < 2)
87
+ refuse("invalid cell or cardinality");
88
+ const ids = model.witnesses.map((w) => w.id);
89
+ if (ids.some((id) => !named(id)) || new Set(ids).size !== ids.length)
90
+ refuse("duplicate or absent witness");
91
+ if (!model.selection.length || new Set(model.selection).size !== model.selection.length || model.selection.some((id) => !ids.includes(id)))
92
+ refuse("invalid selection");
93
+ const factors = [...model.factors].sort((a, b) => a.index - b.index);
94
+ if (new Set(factors.map((f) => f.id)).size !== factors.length || new Set(factors.map((f) => f.index)).size !== factors.length)
95
+ refuse("duplicate factor identity or index");
96
+ for (const f of factors)
97
+ if (!named(f.id) || !Number.isSafeInteger(f.index) || new Set(f.members).size !== f.members.length || f.members.some((id) => !ids.includes(id)))
98
+ refuse("invalid sharing set or order");
99
+ const required = /* @__PURE__ */ new Set([...model.selection, ...factors.filter((f) => f.members.some((id) => model.selection.includes(id))).flatMap((f) => f.members)]);
100
+ const allPrivate = model.witnesses.map((w) => {
101
+ if (w.privateError === void 0) {
102
+ if (required.has(w.id))
103
+ refuse("private probability absent for " + w.id);
104
+ return zero;
105
+ }
106
+ return probability(w.privateError);
107
+ });
108
+ const allRates = factors.map((f) => probability(f.probability));
109
+ const selected = model.selection.map((id) => model.witnesses[ids.indexOf(id)]);
110
+ const touching = factors.filter((f) => f.members.some((id) => model.selection.includes(id)));
111
+ return { witnesses: selected, factors: touching, private: selected.map((w) => allPrivate[ids.indexOf(w.id)]), rates: touching.map((f) => allRates[factors.indexOf(f)]) };
112
+ }
113
+ function limit(policy) {
114
+ if (!policy || !/^\d+$/.test(policy.budget))
115
+ refuse("invalid evaluator/budget");
116
+ return BigInt(policy.budget);
117
+ }
118
+ function bells(n, cap) {
119
+ let row = [1n];
120
+ const result = [1n];
121
+ for (let i = 1; i <= n; i++) {
122
+ const next = [row[row.length - 1]];
123
+ for (let j = 1; j <= i; j++)
124
+ next.push(next[j - 1] + row[j - 1]);
125
+ row = next;
126
+ result.push(row[0]);
127
+ if (row[0] > cap)
128
+ break;
129
+ }
130
+ return result;
131
+ }
132
+ function* configurations(input, masses = true) {
133
+ const ids = input.witnesses.map((w) => w.id), governors = ids.map(() => -1);
134
+ function* walk(i, mass, fired) {
135
+ if (i === input.factors.length) {
136
+ yield { governors: [...governors], mass, fired };
137
+ return;
138
+ }
139
+ yield* walk(i + 1, masses ? mul(mass, sub(one, input.rates[i])) : one, fired);
140
+ const changed = [];
141
+ for (let j = 0; j < ids.length; j++)
142
+ if (governors[j] === -1 && input.factors[i].members.includes(ids[j])) {
143
+ governors[j] = i;
144
+ changed.push(j);
145
+ }
146
+ yield* walk(i + 1, masses ? mul(mass, input.rates[i]) : one, true);
147
+ for (const j of changed)
148
+ governors[j] = -1;
149
+ }
150
+ yield* walk(0, one, false);
151
+ }
152
+ function countWork(input, cap) {
153
+ const k = input.witnesses.length, bell = bells(k + 1, cap);
154
+ if (bell.length <= k + 1 || bell[k + 1] > cap)
155
+ return cap + 1n;
156
+ let factorConfigurations = 1n;
157
+ for (let i = 0; i < input.factors.length; i++) {
158
+ factorConfigurations *= 2n;
159
+ if (factorConfigurations > cap)
160
+ return cap + 1n;
161
+ }
162
+ let total = 0n;
163
+ for (const c of configurations(input, false)) {
164
+ const free = c.governors.filter((g) => g === -1).length, groups = new Set(c.governors.filter((g) => g !== -1)).size;
165
+ let choose = 1n;
166
+ for (let r = 0; r <= free; r++) {
167
+ total += choose * bell[groups + r];
168
+ if (total > cap)
169
+ return cap + 1n;
170
+ choose = choose * BigInt(free - r) / BigInt(r + 1);
171
+ }
172
+ }
173
+ return total;
174
+ }
175
+ function conditional(a, b, cause) {
176
+ return b[0] === 0n ? { status: "unmeasured", cause, numerator: pack(a), denominator: pack(b) } : { status: "measured", value: pack(div(a, b)), numerator: pack(a), denominator: pack(b) };
177
+ }
178
+ function evaluateM3(model, policy) {
179
+ const input = validateM3(model), cap = limit(policy), work = countWork(input, cap);
180
+ const metadata = { model: "M/3", parameters: model, conditions, policy };
181
+ if (work > cap)
182
+ return { ...metadata, status: "unmeasured", cause: "evaluator/budget", requiredAtLeast: String(work) };
183
+ const k = input.witnesses.length, wrong = BigInt(model.cardinality - 1);
184
+ let truth = zero, falsehood = zero, fired = zero, majorityTrue = zero, majorityFalse = zero, majorityNone = zero;
185
+ for (const configuration of configurations(input)) {
186
+ let privatePatterns2 = function(i, mass, correct) {
187
+ if (mass[0] === 0n)
188
+ return;
189
+ if (i < free.length) {
190
+ const p = input.private[free[i]];
191
+ privatePatterns2(i + 1, mul(mass, sub(one, p)), correct + 1);
192
+ weights.push(1);
193
+ privatePatterns2(i + 1, mul(mass, p), correct);
194
+ weights.pop();
195
+ return;
196
+ }
197
+ const L = weights.length, blocks = [];
198
+ function partitions(label) {
199
+ if (label < L) {
200
+ for (let j = 0; j < blocks.length; j++) {
201
+ blocks[j] += weights[label];
202
+ partitions(label + 1);
203
+ blocks[j] -= weights[label];
204
+ }
205
+ blocks.push(weights[label]);
206
+ partitions(label + 1);
207
+ blocks.pop();
208
+ return;
209
+ }
210
+ const b = blocks.length;
211
+ if (BigInt(b) > wrong)
212
+ return;
213
+ let assignments = 1n;
214
+ for (let j = 0; j < b; j++)
215
+ assignments *= wrong - BigInt(j);
216
+ const probabilityMass = mul(mass, q(assignments, wrong ** BigInt(L)));
217
+ if (correct === k) {
218
+ truth = add(truth, probabilityMass);
219
+ return;
220
+ }
221
+ if (correct === 0 && b === 1) {
222
+ falsehood = add(falsehood, probabilityMass);
223
+ if (configuration.fired)
224
+ fired = add(fired, probabilityMass);
225
+ return;
226
+ }
227
+ if (2 * correct > k)
228
+ majorityTrue = add(majorityTrue, probabilityMass);
229
+ else if (blocks.some((weight) => 2 * weight > k))
230
+ majorityFalse = add(majorityFalse, probabilityMass);
231
+ else
232
+ majorityNone = add(majorityNone, probabilityMass);
233
+ }
234
+ partitions(0);
235
+ };
236
+ var privatePatterns = privatePatterns2;
237
+ if (configuration.mass[0] === 0n)
238
+ continue;
239
+ const grouped = /* @__PURE__ */ new Map();
240
+ configuration.governors.forEach((g) => {
241
+ if (g !== -1)
242
+ grouped.set(g, (grouped.get(g) ?? 0) + 1);
243
+ });
244
+ const weights = [...grouped.values()], free = configuration.governors.flatMap((g, i) => g === -1 ? [i] : []);
245
+ privatePatterns2(0, configuration.mass, 0);
246
+ }
247
+ const dissent = sub(sub(one, truth), falsehood), majorityMass = add(majorityTrue, majorityFalse), unanimity = add(truth, falsehood);
248
+ let closedTruth = one;
249
+ for (const p of input.private)
250
+ closedTruth = mul(closedTruth, sub(one, p));
251
+ for (const c of input.rates)
252
+ closedTruth = mul(closedTruth, sub(one, c));
253
+ if (!equal(closedTruth, truth) || !equal(dissent, add(majorityMass, majorityNone)))
254
+ refuse("partition mass identity");
255
+ return { ...metadata, status: "measured", work: String(work), probabilities: { true: pack(truth), false: pack(falsehood), fired: pack(fired), dissent: pack(dissent), majorityTrue: pack(majorityTrue), majorityFalse: pack(majorityFalse), majorityNone: pack(majorityNone) }, quantities: { phi: conditional(falsehood, unanimity, "no unanimity mass"), D: conditional(fired, unanimity, "no unanimity mass"), reliability: conditional(truth, unanimity, "no unanimity mass"), falseMajorityGivenDissent: conditional(majorityFalse, dissent, "no dissent mass"), falseMajorityGivenMajorityAndDissent: conditional(majorityFalse, majorityMass, "no majority mass") }, reliabilityLabel: "P(correct | unanimous) under M/3 with handed parameters" };
256
+ }
257
+ function probeUpdate(phi, error, cardinality) {
258
+ if (!Number.isSafeInteger(cardinality) || cardinality < 2)
259
+ refuse("invalid probe cardinality");
260
+ const f = probability(phi), p = probability(error), a = div(mul(f, p), q(BigInt(cardinality - 1))), b = mul(sub(one, f), sub(one, p));
261
+ return { model: "M/3", conditions: ["independent-private-only-probe", "independent-uniform-wrong-value"], parameters: { phi, error, cardinality }, result: conditional(a, add(a, b), "no extended unanimity mass") };
262
+ }
263
+ function dissentCertificate(model, fired) {
264
+ validateM3(model);
265
+ if (!Array.isArray(fired) || new Set(fired).size !== fired.length || fired.some((id) => !model.factors.some((f) => f.id === id)))
266
+ refuse("invalid fired configuration");
267
+ const selected = new Set(model.selection), active = model.factors.filter((f) => fired.includes(f.id) && f.members.some((id) => selected.has(id)));
268
+ const covering = active.filter((f) => model.selection.every((id) => f.members.includes(id)));
269
+ const witnesses = covering.filter((f) => !active.some((earlier) => earlier.index < f.index && !model.selection.every((id) => earlier.members.includes(id)))).map((f) => f.id);
270
+ return { model: "M/3", parameters: { model, fired }, conditions, unanimityForced: witnesses.length > 0, coveringFactors: witnesses, meaning: "observed dissent excludes this configuration only" };
271
+ }
272
+
273
+ // work/obligations-0.4.0/repository/dist/measures/identification.js
274
+ var key = (a, b) => JSON.stringify([a, b].sort());
275
+ var gcd2 = (a, b) => b ? gcd2(b, a % b) : a;
276
+ var integerPower = (a, n) => n < 0n ? q(a[1] ** -n, a[0] ** -n) : q(a[0] ** n, a[1] ** n);
277
+ function exactRoot(a, n) {
278
+ if (a === 0n || a === 1n || n === 1n)
279
+ return a;
280
+ if (n > BigInt(a.toString(2).length))
281
+ return void 0;
282
+ let low = 1n, high = a;
283
+ while (low <= high) {
284
+ const middle = (low + high) / 2n, p = middle ** n;
285
+ if (p === a)
286
+ return middle;
287
+ if (p < a)
288
+ low = middle + 1n;
289
+ else
290
+ high = middle - 1n;
291
+ }
292
+ return void 0;
293
+ }
294
+ function monomial(bases, powers) {
295
+ let degree = 1n;
296
+ for (const p of powers)
297
+ degree = degree / gcd2(degree, p[1]) * p[1];
298
+ let radicand = one;
299
+ for (let i = 0; i < bases.length; i++)
300
+ radicand = mul(radicand, integerPower(bases[i], powers[i][0] * (degree / powers[i][1])));
301
+ const a = exactRoot(radicand[0], degree), b = exactRoot(radicand[1], degree);
302
+ return { radicand: pack(radicand), degree: String(degree), rational: a === void 0 || b === void 0 ? void 0 : pack(q(a, b)) };
303
+ }
304
+ function identifyM3(input, policy) {
305
+ if (!input || !Array.isArray(input.witnesses) || !Array.isArray(input.factors) || !Array.isArray(input.pairs) || !policy || !/^\d+$/.test(policy.budget))
306
+ refuse("invalid identification inputs");
307
+ const ids = input.witnesses.map((w) => w?.id);
308
+ if (!ids.length || ids.some((id) => typeof id !== "string" || !id) || new Set(ids).size !== ids.length)
309
+ refuse("invalid identification witnesses");
310
+ if (input.factors.some((f) => !f || typeof f.id !== "string" || !f.id || !Array.isArray(f.members) || new Set(f.members).size !== f.members.length || f.members.some((id) => !ids.includes(id))) || new Set(input.factors.map((f) => f.id)).size !== input.factors.length)
311
+ refuse("invalid declared sharing structure");
312
+ const s = input.witnesses.map((w) => probability(w.correct));
313
+ const shared = input.factors.filter((f) => f.members.length > 1), rows = input.pairs.length, columns = shared.length;
314
+ const metadata = { model: "M/3", parameters: input, conditions: ["population-moments", "declared-sharing-sets", "positive-correctness", "full-column-rank", "singleton-private-unresolved"], policy };
315
+ if (s.some((p) => p[0] === 0n))
316
+ return { ...metadata, status: "unmeasured", cause: "zero correctness; unidentified" };
317
+ const seen = /* @__PURE__ */ new Set(), bases = [], matrix = [];
318
+ for (const pair of input.pairs) {
319
+ if (!pair || pair.a === pair.b || !ids.includes(pair.a) || !ids.includes(pair.b) || seen.has(key(pair.a, pair.b)))
320
+ refuse("invalid identification pair");
321
+ seen.add(key(pair.a, pair.b));
322
+ const a = s[ids.indexOf(pair.a)], b = s[ids.indexOf(pair.b)], joint = probability(pair.correctTogether);
323
+ if (joint[0] === 0n || sub(joint, a)[0] > 0n || sub(joint, b)[0] > 0n || sub(joint, sub(add(a, b), one))[0] < 0n)
324
+ return { ...metadata, status: "unmeasured", cause: "model/M misfit" };
325
+ bases.push(div(joint, mul(a, b)));
326
+ matrix.push(shared.map((f) => f.members.includes(pair.a) && f.members.includes(pair.b) ? one : zero));
327
+ }
328
+ const work = BigInt(rows) * BigInt(columns) * BigInt(rows + columns + 1);
329
+ if (work > BigInt(policy.budget))
330
+ return { ...metadata, status: "unmeasured", cause: "identification/budget", required: String(work) };
331
+ const transform = matrix.map((_, i) => matrix.map((__, j) => i === j ? one : zero));
332
+ let rank = 0;
333
+ const pivots = [];
334
+ for (let column = 0; column < columns; column++) {
335
+ const pivot = matrix.findIndex((row, i) => i >= rank && row[column][0] !== 0n);
336
+ if (pivot < 0)
337
+ continue;
338
+ [matrix[rank], matrix[pivot]] = [matrix[pivot], matrix[rank]];
339
+ [transform[rank], transform[pivot]] = [transform[pivot], transform[rank]];
340
+ const divisor = matrix[rank][column];
341
+ matrix[rank] = matrix[rank].map((v) => div(v, divisor));
342
+ transform[rank] = transform[rank].map((v) => div(v, divisor));
343
+ for (let i = 0; i < rows; i++)
344
+ if (i !== rank) {
345
+ const amount = matrix[i][column];
346
+ matrix[i] = matrix[i].map((v, j) => sub(v, mul(amount, matrix[rank][j])));
347
+ transform[i] = transform[i].map((v, j) => sub(v, mul(amount, transform[rank][j])));
348
+ }
349
+ pivots.push(column);
350
+ rank++;
351
+ }
352
+ if (rank !== columns)
353
+ return { ...metadata, status: "unmeasured", cause: "rank-deficient declared sharing system", rank, columns };
354
+ for (let i = rank; i < rows; i++) {
355
+ const residual = monomial(bases, transform[i]);
356
+ if (!equal(q(BigInt(residual.radicand.numerator), BigInt(residual.radicand.denominator)), one))
357
+ return { ...metadata, status: "unmeasured", cause: "model/M misfit", rank, columns };
358
+ }
359
+ const factors = shared.map((factor, j) => {
360
+ const powers = transform[pivots.indexOf(j)], inverseSurvival = monomial(bases, powers);
361
+ const radicand = q(BigInt(inverseSurvival.radicand.numerator), BigInt(inverseSurvival.radicand.denominator));
362
+ if (sub(radicand, one)[0] < 0n)
363
+ return { id: factor.id, misfit: true };
364
+ const survival = monomial(bases, powers.map((p) => q(-p[0], p[1])));
365
+ return { id: factor.id, survival, probability: survival.rational ? pack(sub(one, q(BigInt(survival.rational.numerator), BigInt(survival.rational.denominator)))) : void 0 };
366
+ });
367
+ if (factors.some((f) => "misfit" in f))
368
+ return { ...metadata, status: "unmeasured", cause: "model/M misfit", rank, columns };
369
+ const residualSurvival = input.witnesses.map((w, i) => {
370
+ const powers = bases.map(() => zero);
371
+ shared.forEach((f, j) => {
372
+ if (f.members.includes(w.id))
373
+ transform[pivots.indexOf(j)].forEach((p, k) => {
374
+ powers[k] = add(powers[k], p);
375
+ });
376
+ });
377
+ const r = monomial([s[i], ...bases], [one, ...powers]);
378
+ return { witness: w.id, r, privateSingletonDecomposition: "unresolved" };
379
+ });
380
+ if (residualSurvival.some((w) => sub(q(BigInt(w.r.radicand.numerator), BigInt(w.r.radicand.denominator)), one)[0] > 0n))
381
+ return { ...metadata, status: "unmeasured", cause: "model/M misfit", rank, columns };
382
+ return { ...metadata, status: "identified", rank, columns, factors, residualSurvival, representation: "positive exact rational roots" };
383
+ }
384
+
385
+ // work/obligations-0.4.0/repository/dist/measures/m3-experiment.js
386
+ function experimentM3(model, policy) {
387
+ validateM3(model);
388
+ if (!policy || policy.prng !== "xorshift32" || !Number.isInteger(policy.seed) || policy.seed <= 0 || policy.seed > 4294967295 || !Number.isSafeInteger(policy.trials) || policy.trials < 1 || !Number.isSafeInteger(policy.randomWords) || policy.randomWords < 0)
389
+ refuse("invalid experiment policy");
390
+ const metadata = { model: "M/3", parameters: model, policy, conditions: ["controlled-simulation", "declared-xorshift32-stream", "exact-rational-event-sampling", "not-a-law"] };
391
+ let x = policy.seed >>> 0, words = 0;
392
+ const exhausted = /* @__PURE__ */ Symbol("experiment/random-words");
393
+ const word = () => {
394
+ if (words === policy.randomWords)
395
+ throw exhausted;
396
+ words++;
397
+ x ^= x << 13;
398
+ x ^= x >>> 17;
399
+ x ^= x << 5;
400
+ return BigInt(x >>> 0);
401
+ };
402
+ const below = (n) => {
403
+ if (n === 1n)
404
+ return 0n;
405
+ const bits = BigInt((n - 1n).toString(2).length), mask = (1n << bits) - 1n;
406
+ for (; ; ) {
407
+ let r = 0n;
408
+ for (let b = 0n; b < bits; b += 32n)
409
+ r = r << 32n | word();
410
+ r &= mask;
411
+ if (r < n)
412
+ return r;
413
+ }
414
+ };
415
+ const bernoulli = (p2) => p2[0] === 0n ? false : p2[0] === p2[1] ? true : below(p2[1]) < p2[0];
416
+ const factors = [...model.factors].filter((f) => f.members.some((id) => model.selection.includes(id))).sort((a, b) => a.index - b.index);
417
+ const c = factors.map((f) => probability(f.probability)), p = model.selection.map((id) => probability(model.witnesses.find((w) => w.id === id).privateError)), k = model.selection.length;
418
+ const counts = { true: 0, false: 0, fired: 0, dissent: 0, majorityTrue: 0, majorityFalse: 0, majorityNone: 0 };
419
+ try {
420
+ for (let trial = 0; trial < policy.trials; trial++) {
421
+ const governors = model.selection.map(() => -1);
422
+ let fired = false;
423
+ factors.forEach((f, i) => {
424
+ if (bernoulli(c[i])) {
425
+ fired = true;
426
+ model.selection.forEach((id, j) => {
427
+ if (governors[j] === -1 && f.members.includes(id))
428
+ governors[j] = i;
429
+ });
430
+ }
431
+ });
432
+ const labels = /* @__PURE__ */ new Map(), values = /* @__PURE__ */ new Map();
433
+ const wrong = () => Number(below(BigInt(model.cardinality - 1))) + 1;
434
+ governors.forEach((g, i) => {
435
+ let value = 0;
436
+ if (g !== -1) {
437
+ if (!labels.has(g))
438
+ labels.set(g, wrong());
439
+ value = labels.get(g);
440
+ } else if (bernoulli(p[i]))
441
+ value = wrong();
442
+ values.set(value, (values.get(value) ?? 0) + 1);
443
+ });
444
+ if (values.size === 1) {
445
+ if (values.has(0))
446
+ counts.true++;
447
+ else {
448
+ counts.false++;
449
+ if (fired)
450
+ counts.fired++;
451
+ }
452
+ } else {
453
+ counts.dissent++;
454
+ if (2 * (values.get(0) ?? 0) > k)
455
+ counts.majorityTrue++;
456
+ else if ([...values].some(([value, count]) => value !== 0 && 2 * count > k))
457
+ counts.majorityFalse++;
458
+ else
459
+ counts.majorityNone++;
460
+ }
461
+ }
462
+ } catch (error) {
463
+ if (error !== exhausted)
464
+ throw error;
465
+ return { ...metadata, status: "unmeasured", cause: "experiment/random-words", words };
466
+ }
467
+ const conditional2 = (numerator, denominator) => ({ numerator, denominator, rate: denominator ? numerator / denominator : "unmeasured" });
468
+ return { ...metadata, status: "measured", words, counts, unanimity: conditional2(counts.false, counts.true + counts.false), falseMajorityGivenDissent: conditional2(counts.majorityFalse, counts.dissent), falseMajorityGivenMajorityAndDissent: conditional2(counts.majorityFalse, counts.majorityTrue + counts.majorityFalse) };
469
+ }
470
+
471
+ // work/obligations-0.4.0/repository/dist/measures/fitting.js
472
+ function solve(matrix, values, tolerance) {
473
+ const a = matrix.map((row, i) => [...row, values[i]]), n = a.length;
474
+ for (let j = 0; j < n; j++) {
475
+ let pivot = j;
476
+ for (let i = j + 1; i < n; i++)
477
+ if (Math.abs(a[i][j]) > Math.abs(a[pivot][j]))
478
+ pivot = i;
479
+ if (Math.abs(a[pivot][j]) <= tolerance)
480
+ return void 0;
481
+ [a[j], a[pivot]] = [a[pivot], a[j]];
482
+ const d = a[j][j];
483
+ a[j] = a[j].map((v) => v / d);
484
+ for (let i = 0; i < n; i++)
485
+ if (i !== j) {
486
+ const p = a[i][j];
487
+ a[i] = a[i].map((v, k) => v - p * a[j][k]);
488
+ }
489
+ }
490
+ return a.map((row) => row[n]);
491
+ }
492
+ function* subsets(total, max, start = 0, prefix = []) {
493
+ yield prefix;
494
+ if (prefix.length === max)
495
+ return;
496
+ for (let i = start; i < total; i++)
497
+ yield* subsets(total, max, i + 1, [...prefix, i]);
498
+ }
499
+ function fitM3(rows, structure, policy) {
500
+ if (!policy || !/^\d+$/.test(policy.activeSets) || !Number.isFinite(policy.solveTolerance) || policy.solveTolerance <= 0 || !Number.isFinite(policy.residualTolerance) || policy.residualTolerance < 0 || !policy.bootstrap || policy.bootstrap.prng !== "xorshift32" || !Number.isInteger(policy.bootstrap.seed) || policy.bootstrap.seed < 1 || policy.bootstrap.seed > 4294967295 || !Number.isSafeInteger(policy.bootstrap.B) || policy.bootstrap.B < 0 || !Number.isSafeInteger(policy.bootstrap.randomWords) || policy.bootstrap.randomWords < 0)
501
+ refuse("invalid fitting policy");
502
+ const reading = errorMatrix(rows, policy.observation), metadata = { model: "M/3", parameters: { rows, structure }, policy, conditions: ["one-declared-parameter-population", "declared-sharing-sets", "finite-data", "no-pseudocounts", "fitted-not-handed"], procedure: "constrained-log-least-squares/active-set@1" };
503
+ if (reading.status === "unmeasured")
504
+ return { ...metadata, ...reading };
505
+ if (!structure || !Array.isArray(structure.factors) || structure.factors.some((f) => !f) || new Set(structure.factors.map((f) => f.id)).size !== structure.factors.length || structure.factors.some((f) => !f.id || !Array.isArray(f.members) || new Set(f.members).size !== f.members.length || f.members.some((id) => !reading.origins.includes(id))))
506
+ refuse("invalid fitting sharing structure");
507
+ const shared = structure.factors.filter((f) => f.members.length > 1), n = shared.length, w = reading.origins.length;
508
+ const pairs = [...reading.origins.flatMap((_, i) => reading.origins.flatMap((__, j) => j > i ? [[i, j]] : []))];
509
+ const A = pairs.map(([i, j]) => shared.map((f) => f.members.includes(reading.origins[i]) && f.members.includes(reading.origins[j]) ? 1 : 0));
510
+ const H = shared.map((_, i) => shared.map((__, j) => A.reduce((sum, row) => sum + row[i] * row[j], 0)));
511
+ if (n && !solve(H, Array(n).fill(0), policy.solveTolerance))
512
+ return { ...metadata, status: "unmeasured", cause: "rank-deficient declared sharing system" };
513
+ let combinations = 1n, term = 1n;
514
+ for (let k = 1; k <= n; k++) {
515
+ term = term * BigInt(n + w - k + 1) / BigInt(k);
516
+ combinations += term;
517
+ }
518
+ const required = combinations * BigInt(policy.bootstrap.B + 1);
519
+ if (required > BigInt(policy.activeSets))
520
+ return { ...metadata, status: "unmeasured", cause: "fitting/active-sets", required: String(required) };
521
+ const once = (data) => {
522
+ const s = reading.origins.map((_, i) => data.reduce((sum, row) => sum + (1 - row[i]), 0) / data.length);
523
+ if (s.some((v) => v === 0))
524
+ return { status: "unmeasured", cause: "model/M misfit: zero correct count" };
525
+ const joints = pairs.map(([i, j]) => data.reduce((sum, row) => sum + (1 - row[i]) * (1 - row[j]), 0) / data.length);
526
+ if (joints.some((v) => v === 0))
527
+ return { status: "unmeasured", cause: "model/M misfit: zero joint-correct count" };
528
+ const y = joints.map((v, k) => Math.log(v / (s[pairs[k][0]] * s[pairs[k][1]]))), g = shared.map((_, j) => A.reduce((sum, row, i) => sum + row[j] * y[i], 0));
529
+ const C = [...shared.map((_, i) => shared.map((__, j) => i === j ? -1 : 0)), ...reading.origins.map((id) => shared.map((f) => f.members.includes(id) ? 1 : 0))], d = [...shared.map(() => 0), ...s.map((v) => -Math.log(v))];
530
+ let best, bestCost = Infinity;
531
+ for (const active of subsets(n + w, n)) {
532
+ const size = n + active.length, K = Array.from({ length: size }, () => Array(size).fill(0));
533
+ for (let i = 0; i < n; i++)
534
+ for (let j = 0; j < n; j++)
535
+ K[i][j] = H[i][j];
536
+ active.forEach((constraint, k) => C[constraint].forEach((v, j) => {
537
+ K[n + k][j] = v;
538
+ K[j][n + k] = v;
539
+ }));
540
+ const candidate = solve(K, [...g, ...active.map((i) => d[i])], policy.solveTolerance);
541
+ if (!candidate)
542
+ continue;
543
+ const alpha = candidate.slice(0, n), lambda = candidate.slice(n);
544
+ if (alpha.some((v) => v < 0) || lambda.some((v) => v < -policy.solveTolerance) || C.some((row, i) => row.reduce((sum, v, j) => sum + v * alpha[j], 0) > d[i] + policy.solveTolerance))
545
+ continue;
546
+ const cost = A.reduce((sum, row, i) => sum + (row.reduce((s2, v, j) => s2 + v * alpha[j], 0) - y[i]) ** 2, 0);
547
+ if (cost < bestCost) {
548
+ best = alpha;
549
+ bestCost = cost;
550
+ }
551
+ }
552
+ if (!best)
553
+ return { status: "unmeasured", cause: "model/M misfit: no feasible numerical solution" };
554
+ const residuals = A.map((row, i) => row.reduce((sum, v, j) => sum + v * best[j], 0) - y[i]);
555
+ if (residuals.some((v) => Math.abs(v) > policy.residualTolerance))
556
+ return { status: "unmeasured", cause: "model/M misfit: residual tolerance", residuals };
557
+ return { status: "fitted", factors: shared.map((f, i) => ({ id: f.id, probability: 1 - Math.exp(-best[i]) })), residuals, residualSumSquares: bestCost, residualSurvival: reading.origins.map((id, i) => ({ id, r: s[i] * Math.exp(shared.reduce((sum, f, j) => sum + (f.members.includes(id) ? best[j] : 0), 0)), privateSingletonDecomposition: "unresolved" })) };
558
+ };
559
+ const fit = once(reading.matrix);
560
+ if (fit.status !== "fitted")
561
+ return { ...metadata, ...fit };
562
+ let x = policy.bootstrap.seed >>> 0, words = 0;
563
+ const exhausted = /* @__PURE__ */ Symbol("bootstrap/random-words");
564
+ const index = () => {
565
+ const N = reading.matrix.length, limit2 = Math.floor(4294967296 / N) * N;
566
+ for (; ; ) {
567
+ if (words === policy.bootstrap.randomWords)
568
+ throw exhausted;
569
+ words++;
570
+ x ^= x << 13;
571
+ x ^= x >>> 17;
572
+ x ^= x << 5;
573
+ const r = x >>> 0;
574
+ if (r < limit2)
575
+ return r % N;
576
+ }
577
+ };
578
+ const replicates = [];
579
+ try {
580
+ for (let b = 0; b < policy.bootstrap.B; b++)
581
+ replicates.push(once(reading.matrix.map(() => reading.matrix[index()])));
582
+ } catch (error) {
583
+ if (error !== exhausted)
584
+ throw error;
585
+ return { ...metadata, ...fit, bootstrap: { status: "unmeasured", cause: "bootstrap/random-words", words } };
586
+ }
587
+ const complete = policy.bootstrap.B > 0 && replicates.every((r) => r.status === "fitted");
588
+ return { ...metadata, ...fit, bootstrap: { status: complete ? "measured" : "unmeasured", cause: complete ? void 0 : policy.bootstrap.B ? "model/M misfit in bootstrap replicates" : "no bootstrap replicates requested", words, replicates }, quantities: "\u03A6 and D require handed parameters; never reported from this fit" };
589
+ }
590
+
591
+ // work/obligations-0.4.0/repository/dist/lattice/errors.js
592
+ var UnitError = class _UnitError extends Error {
593
+ code;
594
+ detail;
595
+ constructor(code, message, detail = {}) {
596
+ super(message);
597
+ this.name = "UnitError";
598
+ this.code = code;
599
+ this.detail = Object.freeze({ ...detail });
600
+ Object.setPrototypeOf(this, _UnitError.prototype);
601
+ }
602
+ };
603
+
604
+ // work/obligations-0.4.0/repository/dist/lattice/order.js
605
+ function build(levels, join, meet) {
606
+ const n = levels.length;
607
+ for (let i = 0; i < n; i++) {
608
+ if (levels.indexOf(levels[i]) !== i) {
609
+ throw new UnitError("DUPLICATE_LEVEL", `the level \`${levels[i]}\` is declared twice`, {
610
+ level: levels[i]
611
+ });
612
+ }
613
+ }
614
+ const index = new Map(levels.map((l, i) => [l, i]));
615
+ const leq = (a, b) => join[a][b] === b;
616
+ const total = levels.every((_, i) => levels.every((__, j) => join[i][j] === i || join[i][j] === j));
617
+ let simple = true;
618
+ for (let x = 0; x < n && simple; x++) {
619
+ for (let y = 0; y < n && simple; y++) {
620
+ for (let z = 0; z < n; z++) {
621
+ if (meet[x][join[y][z]] !== join[meet[x][y]][meet[x][z]]) {
622
+ simple = false;
623
+ break;
624
+ }
625
+ }
626
+ }
627
+ }
628
+ const all = [...levels.keys()];
629
+ const bottomIx = all.find((i) => all.every((j) => leq(i, j))) ?? 0;
630
+ const topIx = all.find((i) => all.every((j) => leq(j, i))) ?? n - 1;
631
+ const joinIrr = all.filter((j) => j !== bottomIx && all.filter((x) => x !== j && leq(x, j)).reduce((acc, x) => join[acc][x], bottomIx) !== j);
632
+ const meetIrr = all.filter((m) => m !== topIx && all.filter((x) => x !== m && leq(m, x)).reduce((acc, x) => meet[acc][x], topIx) !== m);
633
+ const seen = /* @__PURE__ */ new Set();
634
+ const allDebits = [];
635
+ for (const x of [...joinIrr, ...meetIrr]) {
636
+ if (!seen.has(x)) {
637
+ seen.add(x);
638
+ allDebits.push(x);
639
+ }
640
+ }
641
+ return {
642
+ levels,
643
+ isLadder: total,
644
+ isSimple: simple,
645
+ bottomIx,
646
+ topIx,
647
+ bottom: levels[bottomIx],
648
+ top: levels[topIx],
649
+ leq,
650
+ higher: (a, b) => join[a][b],
651
+ lower: (a, b) => meet[a][b],
652
+ rank(level) {
653
+ const r = index.get(level);
654
+ if (r === void 0) {
655
+ throw new UnitError("UNKNOWN_LEVEL", `no level \`${level}\` in this scale`, {
656
+ level,
657
+ levels
658
+ });
659
+ }
660
+ return r;
661
+ },
662
+ stateOf(floor, ceiling) {
663
+ if (!leq(floor, ceiling))
664
+ return "CONFLICT";
665
+ if (floor !== bottomIx)
666
+ return "REQUIRED";
667
+ if (ceiling !== topIx)
668
+ return "FORBIDDEN";
669
+ return "FREE";
670
+ },
671
+ joins: () => joinIrr.slice(),
672
+ limits: () => meetIrr.slice(),
673
+ debits: () => allDebits.slice(),
674
+ intervalHeight(lo, hi) {
675
+ if (!leq(lo, hi))
676
+ return null;
677
+ const inside = all.filter((x) => leq(lo, x) && leq(x, hi));
678
+ const covers = (x) => inside.filter((y) => y !== x && leq(x, y) && !inside.some((z) => z !== x && z !== y && leq(x, z) && leq(z, y)));
679
+ const long = /* @__PURE__ */ new Map([[lo, 0]]);
680
+ const short = /* @__PURE__ */ new Map([[lo, 0]]);
681
+ const walk = [...inside].sort((a, b) => inside.filter((z) => leq(z, a)).length - inside.filter((z) => leq(z, b)).length);
682
+ for (const x of walk) {
683
+ const lx = long.get(x);
684
+ const sx = short.get(x);
685
+ if (lx === void 0 || sx === void 0)
686
+ continue;
687
+ for (const y of covers(x)) {
688
+ long.set(y, Math.max(long.get(y) ?? lx + 1, lx + 1));
689
+ short.set(y, Math.min(short.get(y) ?? sx + 1, sx + 1));
690
+ }
691
+ }
692
+ const l = long.get(hi);
693
+ return l !== void 0 && l === short.get(hi) ? l : null;
694
+ }
695
+ };
696
+ }
697
+ function chain(levels) {
698
+ if (!Array.isArray(levels) || levels.length === 0) {
699
+ throw new UnitError("EMPTY_CHAIN", "a chain needs at least one level");
700
+ }
701
+ const n = levels.length;
702
+ const grid = (f) => [...Array(n)].map((_, i) => [...Array(n)].map((__, j) => f(i, j)));
703
+ return build(levels, grid(Math.max), grid(Math.min));
704
+ }
705
+
706
+ // work/obligations-0.4.0/repository/dist/debit/unit.js
707
+ function unit(subject, bounds) {
708
+ return { subject, floor: bounds.floor, ceiling: bounds.ceiling };
709
+ }
710
+ function state(c, u) {
711
+ return c.stateOf(c.rank(u.floor), c.rank(u.ceiling));
712
+ }
713
+
714
+ // work/obligations-0.4.0/m3-reader.mjs
715
+ function observe(bytes) {
716
+ const sample = JSON.parse(new TextDecoder().decode(bytes));
717
+ const scale = chain(["off", "on"]), cells = [unit("free", { floor: "off", ceiling: "on" }), unit("required", { floor: "on", ceiling: "on" }), unit("forbidden", { floor: "off", ceiling: "off" }), unit("conflict", { floor: "on", ceiling: "off" })];
718
+ const before = JSON.stringify(cells), states = cells.map((c) => state(scale, c));
719
+ cells.forEach(Object.freeze);
720
+ const results = sample.models.map((entry) => ({ name: entry.name, result: evaluateM3(entry.model, sample.policy) }));
721
+ const phi = { numerator: "797", denominator: "10373" };
722
+ const probes = ["0.2", "0.98", "0.99", "1"].map((error) => probeUpdate(phi, error, 64));
723
+ const identification = sample.identifications.map((input) => identifyM3(input, sample.identificationPolicy));
724
+ const experiment = experimentM3(sample.models[0].model, sample.experiment);
725
+ const fitting = sample.fits.map((input) => fitM3(input.rows, input.structure, input.policy));
726
+ const certificate = dissentCertificate(sample.models[0].model, []);
727
+ if (JSON.stringify(cells) !== before || JSON.stringify(cells.map((c) => state(scale, c))) !== JSON.stringify(states)) throw Error("REFUSE\xB7model/M3 algebra changed");
728
+ return [{ scope: "measurement/m3/" + sample.place, role: "writes", measure: "result", bound: { kind: "enumerated", values: [JSON.stringify({ results, probes, identification, experiment, fitting, certificate, states })] } }];
729
+ }
730
+ export {
731
+ observe
732
+ };