@lucern/confidence 0.3.0-alpha.0 → 0.3.0-alpha.10
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/README.md +5 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +227 -98
- package/dist/index.js.map +1 -1
- package/dist/v1/codec.d.ts +42 -0
- package/dist/v1/codec.js +62 -0
- package/dist/v1/codec.js.map +1 -0
- package/dist/v1/index.d.ts +5 -3
- package/dist/v1/index.js +227 -98
- package/dist/v1/index.js.map +1 -1
- package/dist/v1/operations/approximation.js +30 -21
- package/dist/v1/operations/approximation.js.map +1 -1
- package/dist/v1/operations/bridge/index.d.ts +3 -3
- package/dist/v1/operations/bridge/index.js +27 -13
- package/dist/v1/operations/bridge/index.js.map +1 -1
- package/dist/v1/operations/canonical.d.ts +2 -2
- package/dist/v1/operations/canonical.js +16 -19
- package/dist/v1/operations/canonical.js.map +1 -1
- package/dist/v1/operations/contracts/epistemicContract.d.ts +1 -1
- package/dist/v1/operations/contracts/epistemicContract.js +13 -11
- package/dist/v1/operations/contracts/epistemicContract.js.map +1 -1
- package/dist/v1/operations/contradiction/detectTupleContradiction.js.map +1 -1
- package/dist/v1/operations/contradiction/index.js.map +1 -1
- package/dist/v1/operations/dynamics/cascade.js +19 -6
- package/dist/v1/operations/dynamics/cascade.js.map +1 -1
- package/dist/v1/operations/dynamics/decay.d.ts +1 -1
- package/dist/v1/operations/dynamics/decay.js +5 -4
- package/dist/v1/operations/dynamics/decay.js.map +1 -1
- package/dist/v1/operations/dynamics/defeat.d.ts +1 -1
- package/dist/v1/operations/dynamics/defeat.js +22 -17
- package/dist/v1/operations/dynamics/defeat.js.map +1 -1
- package/dist/v1/operations/dynamics/propagation.js +66 -33
- package/dist/v1/operations/dynamics/propagation.js.map +1 -1
- package/dist/v1/operations/dynamics/revision.d.ts +6 -6
- package/dist/v1/operations/dynamics/revision.js +31 -19
- package/dist/v1/operations/dynamics/revision.js.map +1 -1
- package/dist/v1/operations/index.js +9 -5
- package/dist/v1/operations/index.js.map +1 -1
- package/dist/v1/operations/lucern.d.ts +4 -2
- package/dist/v1/operations/lucern.js +192 -87
- package/dist/v1/operations/lucern.js.map +1 -1
- package/dist/v1/operations/operatorTaxonomy.d.ts +23 -1
- package/dist/v1/operations/operatorTaxonomy.js +28 -0
- package/dist/v1/operations/operatorTaxonomy.js.map +1 -1
- package/dist/v1/operations/scoring.d.ts +30 -12
- package/dist/v1/operations/scoring.js +82 -40
- package/dist/v1/operations/scoring.js.map +1 -1
- package/dist/v1/operations/subjectiveLogic/index.d.ts +20 -19
- package/dist/v1/operations/subjectiveLogic/index.js +11 -10
- package/dist/v1/operations/subjectiveLogic/index.js.map +1 -1
- package/dist/v1/operations/temporalDecay.js +9 -5
- package/dist/v1/operations/temporalDecay.js.map +1 -1
- package/dist/v1/types.d.ts +5 -1
- package/package.json +5 -1
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
1
3
|
// src/v1/operations/subjectiveLogic/index.ts
|
|
2
|
-
function
|
|
3
|
-
const b =
|
|
4
|
-
const d =
|
|
5
|
-
const u =
|
|
4
|
+
function mkOpinion(belief, disbelief, uncertainty, baseRate) {
|
|
5
|
+
const b = Number.isFinite(belief) ? Math.max(0, belief) : 0;
|
|
6
|
+
const d = Number.isFinite(disbelief) ? Math.max(0, disbelief) : 0;
|
|
7
|
+
const u = Number.isFinite(uncertainty) ? Math.max(0, uncertainty) : 0;
|
|
6
8
|
const a = Math.max(0, Math.min(1, baseRate));
|
|
7
9
|
const sum = b + d + u;
|
|
8
10
|
if (sum === 0) {
|
|
@@ -15,8 +17,9 @@ function opinion(belief, disbelief, uncertainty, baseRate = 0.5) {
|
|
|
15
17
|
a
|
|
16
18
|
};
|
|
17
19
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
var opinion = mkOpinion;
|
|
21
|
+
function vacuous(baseRate) {
|
|
22
|
+
return mkOpinion(0, 0, 1, baseRate);
|
|
20
23
|
}
|
|
21
24
|
function project(o) {
|
|
22
25
|
return o.b + o.a * o.u;
|
|
@@ -172,7 +175,7 @@ function conditionalDeduction(opinionA, ifTrue, ifFalse, fallbackBaseRate) {
|
|
|
172
175
|
);
|
|
173
176
|
}
|
|
174
177
|
function negate(o) {
|
|
175
|
-
return
|
|
178
|
+
return mkOpinion(o.d, o.b, o.u, 1 - o.a);
|
|
176
179
|
}
|
|
177
180
|
function constraintFusion(left, right, mode = "pressure") {
|
|
178
181
|
if (mode === "redistribute") {
|
|
@@ -239,6 +242,15 @@ function informationGain(o) {
|
|
|
239
242
|
function finiteNumber(value) {
|
|
240
243
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
241
244
|
}
|
|
245
|
+
function requiredOpinionNumber(label, ...values) {
|
|
246
|
+
for (const value of values) {
|
|
247
|
+
const numberValue = finiteNumber(value);
|
|
248
|
+
if (numberValue !== void 0) {
|
|
249
|
+
return numberValue;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
throw new Error(`Opinion record is missing required ${label}.`);
|
|
253
|
+
}
|
|
242
254
|
function clamp01(value) {
|
|
243
255
|
return Math.max(0, Math.min(1, value));
|
|
244
256
|
}
|
|
@@ -253,34 +265,56 @@ function toStoredOpinionFields(opinion2) {
|
|
|
253
265
|
baseRate: opinion2.a
|
|
254
266
|
};
|
|
255
267
|
}
|
|
256
|
-
function readOpinionFromRecord(source
|
|
268
|
+
function readOpinionFromRecord(source) {
|
|
257
269
|
const record = source && typeof source === "object" ? source : {};
|
|
258
|
-
return
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
270
|
+
return mkOpinion(
|
|
271
|
+
requiredOpinionNumber(
|
|
272
|
+
"belief",
|
|
273
|
+
record.b,
|
|
274
|
+
record.belief,
|
|
275
|
+
record.slBelief,
|
|
276
|
+
record.opinion_b
|
|
277
|
+
),
|
|
278
|
+
requiredOpinionNumber(
|
|
279
|
+
"disbelief",
|
|
280
|
+
record.d,
|
|
281
|
+
record.disbelief,
|
|
282
|
+
record.slDisbelief,
|
|
283
|
+
record.opinion_d
|
|
284
|
+
),
|
|
285
|
+
requiredOpinionNumber(
|
|
286
|
+
"uncertainty",
|
|
287
|
+
record.u,
|
|
288
|
+
record.uncertainty,
|
|
289
|
+
record.slUncertainty,
|
|
290
|
+
record.opinion_u
|
|
291
|
+
),
|
|
292
|
+
requiredOpinionNumber(
|
|
293
|
+
"baseRate",
|
|
294
|
+
record.a,
|
|
295
|
+
record.baseRate,
|
|
296
|
+
record.slBaseRate,
|
|
297
|
+
record.opinion_a
|
|
298
|
+
)
|
|
299
|
+
);
|
|
264
300
|
}
|
|
265
301
|
function opinionFromScalar(value, mode, options) {
|
|
266
302
|
const clampedValue = clamp01(value);
|
|
267
|
-
const baseRate =
|
|
303
|
+
const baseRate = options?.baseRate === void 0 ? void 0 : clamp01(options.baseRate);
|
|
268
304
|
switch (mode) {
|
|
269
305
|
case "base_rate":
|
|
270
|
-
return
|
|
271
|
-
b: 0,
|
|
272
|
-
d: 0,
|
|
273
|
-
u: 1,
|
|
274
|
-
a: clampedValue
|
|
275
|
-
};
|
|
306
|
+
return mkOpinion(0, 0, 1, clampedValue);
|
|
276
307
|
case "dogmatic":
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
a: baseRate
|
|
282
|
-
};
|
|
308
|
+
if (baseRate === void 0) {
|
|
309
|
+
throw new Error('opinionFromScalar(value, "dogmatic") requires options.baseRate.');
|
|
310
|
+
}
|
|
311
|
+
return mkOpinion(clampedValue, 1 - clampedValue, 0, baseRate);
|
|
283
312
|
case "projected_with_u": {
|
|
313
|
+
if (baseRate === void 0) {
|
|
314
|
+
throw new Error(
|
|
315
|
+
'opinionFromScalar(value, "projected_with_u") requires options.baseRate.'
|
|
316
|
+
);
|
|
317
|
+
}
|
|
284
318
|
const uncertainty = options?.uncertainty;
|
|
285
319
|
if (uncertainty === void 0) {
|
|
286
320
|
throw new Error(
|
|
@@ -289,22 +323,57 @@ function opinionFromScalar(value, mode, options) {
|
|
|
289
323
|
}
|
|
290
324
|
const clampedUncertainty = clamp01(uncertainty);
|
|
291
325
|
const evidenceWeight = 1 - clampedUncertainty;
|
|
292
|
-
return
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
326
|
+
return mkOpinion(
|
|
327
|
+
clampedValue * evidenceWeight,
|
|
328
|
+
(1 - clampedValue) * evidenceWeight,
|
|
329
|
+
clampedUncertainty,
|
|
330
|
+
baseRate
|
|
331
|
+
);
|
|
298
332
|
}
|
|
299
333
|
}
|
|
300
334
|
throw new Error(`Unsupported opinionFromScalar mode: ${mode}`);
|
|
301
335
|
}
|
|
302
|
-
function toDogmaticOpinion(confidence, baseRate
|
|
336
|
+
function toDogmaticOpinion(confidence, baseRate) {
|
|
303
337
|
return opinionFromScalar(confidence, "dogmatic", { baseRate });
|
|
304
338
|
}
|
|
305
339
|
function hasProjectedOpinionChanged(current, next, tolerance = 0.01) {
|
|
306
340
|
return Math.abs(confidenceFromOpinion(next) - confidenceFromOpinion(current)) >= tolerance;
|
|
307
341
|
}
|
|
342
|
+
var SL_EPSILON = 1e-9;
|
|
343
|
+
z.object({
|
|
344
|
+
b: z.number(),
|
|
345
|
+
d: z.number(),
|
|
346
|
+
u: z.number(),
|
|
347
|
+
a: z.number()
|
|
348
|
+
}).refine((o) => Math.abs(o.b + o.d + o.u - 1) < SL_EPSILON, {
|
|
349
|
+
message: "SL invariant b+d+u=1 violated"
|
|
350
|
+
});
|
|
351
|
+
function fromStorage(fields) {
|
|
352
|
+
const sum = fields.belief + fields.disbelief + fields.uncertainty;
|
|
353
|
+
const opinion2 = mkOpinion(
|
|
354
|
+
fields.belief,
|
|
355
|
+
fields.disbelief,
|
|
356
|
+
fields.uncertainty,
|
|
357
|
+
fields.baseRate
|
|
358
|
+
);
|
|
359
|
+
if (Math.abs(sum - 1) < SL_EPSILON) {
|
|
360
|
+
return { ok: true, opinion: opinion2 };
|
|
361
|
+
}
|
|
362
|
+
return {
|
|
363
|
+
ok: false,
|
|
364
|
+
opinion: opinion2,
|
|
365
|
+
repairNeeded: true,
|
|
366
|
+
reason: `Stored fields sum to ${sum.toFixed(6)}, not 1; normalized on read`
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
function toStorage(opinion2) {
|
|
370
|
+
return {
|
|
371
|
+
belief: opinion2.b,
|
|
372
|
+
disbelief: opinion2.d,
|
|
373
|
+
uncertainty: opinion2.u,
|
|
374
|
+
baseRate: opinion2.a
|
|
375
|
+
};
|
|
376
|
+
}
|
|
308
377
|
function toEpochMs(value) {
|
|
309
378
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
310
379
|
return value;
|
|
@@ -336,7 +405,10 @@ function temporalDecay(sourceOpinion, now, decayParams) {
|
|
|
336
405
|
return { ...sourceOpinion };
|
|
337
406
|
}
|
|
338
407
|
const retainedEvidenceWeight = Math.pow(0.5, ageMs / halfLifeMs);
|
|
339
|
-
return trustDiscount(
|
|
408
|
+
return trustDiscount(
|
|
409
|
+
mkOpinion(sourceOpinion.b, sourceOpinion.d, sourceOpinion.u, sourceOpinion.a),
|
|
410
|
+
retainedEvidenceWeight
|
|
411
|
+
);
|
|
340
412
|
}
|
|
341
413
|
|
|
342
414
|
// src/v1/operations/contradiction/detectTupleContradiction.ts
|
|
@@ -373,7 +445,14 @@ function evaluateTupleContradictionTransition(args) {
|
|
|
373
445
|
|
|
374
446
|
// src/v1/operations/dynamics/cascade.ts
|
|
375
447
|
function dampedDependencyOpinion(dependencyOpinion, beliefOpinion, mode = "continuous", threshold = 0.3) {
|
|
376
|
-
const dependencyProjection = project(
|
|
448
|
+
const dependencyProjection = project(
|
|
449
|
+
mkOpinion(
|
|
450
|
+
dependencyOpinion.b,
|
|
451
|
+
dependencyOpinion.d,
|
|
452
|
+
dependencyOpinion.u,
|
|
453
|
+
dependencyOpinion.a
|
|
454
|
+
)
|
|
455
|
+
);
|
|
377
456
|
if (mode === "threshold") {
|
|
378
457
|
if (dependencyProjection < threshold) {
|
|
379
458
|
return opinion(
|
|
@@ -398,40 +477,49 @@ function dampedDependencyCascade(dependencyOpinion, beliefOpinion, mode = "conti
|
|
|
398
477
|
opinion: dampedDependencyOpinion(dependencyOpinion, beliefOpinion, mode),
|
|
399
478
|
operator: "dependency_cascade",
|
|
400
479
|
rationale: `Damped dependency cascade (${mode}): prerequisite at ${project(
|
|
401
|
-
|
|
480
|
+
mkOpinion(
|
|
481
|
+
dependencyOpinion.b,
|
|
482
|
+
dependencyOpinion.d,
|
|
483
|
+
dependencyOpinion.u,
|
|
484
|
+
dependencyOpinion.a
|
|
485
|
+
)
|
|
402
486
|
).toFixed(2)}`
|
|
403
487
|
};
|
|
404
488
|
}
|
|
405
489
|
|
|
406
490
|
// src/v1/operations/dynamics/defeat.ts
|
|
407
491
|
function applyNegativeSupport(source, target, weight, metadata = {}) {
|
|
492
|
+
const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);
|
|
493
|
+
const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);
|
|
408
494
|
if (metadata.constraint === "xor") {
|
|
409
495
|
const result = constraintFusion(
|
|
410
|
-
|
|
411
|
-
|
|
496
|
+
sourceOpinion,
|
|
497
|
+
targetOpinion,
|
|
412
498
|
metadata.normalization ?? "pressure"
|
|
413
499
|
);
|
|
414
500
|
return {
|
|
415
501
|
opinion: result.o2,
|
|
416
502
|
operator: "constraint_fusion",
|
|
417
|
-
rationale: `XOR constraint: source belief at ${project(
|
|
418
|
-
|
|
419
|
-
)} pressures target`
|
|
503
|
+
rationale: `XOR constraint: source belief at ${project(
|
|
504
|
+
sourceOpinion
|
|
505
|
+
).toFixed(2)} pressures target`
|
|
420
506
|
};
|
|
421
507
|
}
|
|
422
|
-
const discounted = trustDiscount(negate(
|
|
508
|
+
const discounted = trustDiscount(negate(sourceOpinion), Math.abs(weight));
|
|
423
509
|
return {
|
|
424
|
-
opinion: cumulativeFusion(
|
|
510
|
+
opinion: cumulativeFusion(targetOpinion, discounted),
|
|
425
511
|
operator: "cumulative_fusion",
|
|
426
512
|
rationale: `Contradicting evidence (weight=${weight.toFixed(
|
|
427
513
|
2
|
|
428
|
-
)}) from source at ${project(
|
|
514
|
+
)}) from source at ${project(sourceOpinion).toFixed(2)}`
|
|
429
515
|
};
|
|
430
516
|
}
|
|
431
517
|
function applyNegativeEvidence(source, target, weight) {
|
|
432
|
-
const
|
|
518
|
+
const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);
|
|
519
|
+
const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);
|
|
520
|
+
const discounted = trustDiscount(negate(sourceOpinion), Math.abs(weight));
|
|
433
521
|
return {
|
|
434
|
-
opinion: cumulativeFusion(
|
|
522
|
+
opinion: cumulativeFusion(targetOpinion, discounted),
|
|
435
523
|
operator: "cumulative_fusion",
|
|
436
524
|
rationale: `Contradicting evidence (weight=${weight.toFixed(2)})`
|
|
437
525
|
};
|
|
@@ -442,28 +530,32 @@ var EDGE_PROPAGATION_RULES = {
|
|
|
442
530
|
supports: {
|
|
443
531
|
direction: "outgoing",
|
|
444
532
|
handler: (source, target, weight, metadata) => {
|
|
533
|
+
const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);
|
|
534
|
+
const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);
|
|
445
535
|
if (weight < 0) {
|
|
446
|
-
return applyNegativeSupport(
|
|
536
|
+
return applyNegativeSupport(sourceOpinion, targetOpinion, weight, metadata);
|
|
447
537
|
}
|
|
448
|
-
const discounted = trustDiscount(
|
|
538
|
+
const discounted = trustDiscount(sourceOpinion, weight);
|
|
449
539
|
return {
|
|
450
|
-
opinion: cumulativeFusion(
|
|
540
|
+
opinion: cumulativeFusion(targetOpinion, discounted),
|
|
451
541
|
operator: "cumulative_fusion",
|
|
452
542
|
rationale: `Supporting evidence (weight=${weight.toFixed(
|
|
453
543
|
2
|
|
454
|
-
)}) from source at ${project(
|
|
544
|
+
)}) from source at ${project(sourceOpinion).toFixed(2)}`
|
|
455
545
|
};
|
|
456
546
|
}
|
|
457
547
|
},
|
|
458
548
|
informs: {
|
|
459
549
|
direction: "outgoing",
|
|
460
550
|
handler: (source, target, weight) => {
|
|
551
|
+
const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);
|
|
552
|
+
const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);
|
|
461
553
|
if (weight < 0) {
|
|
462
|
-
return applyNegativeEvidence(
|
|
554
|
+
return applyNegativeEvidence(sourceOpinion, targetOpinion, weight);
|
|
463
555
|
}
|
|
464
|
-
const discounted = trustDiscount(
|
|
556
|
+
const discounted = trustDiscount(sourceOpinion, Math.abs(weight));
|
|
465
557
|
return {
|
|
466
|
-
opinion: cumulativeFusion(
|
|
558
|
+
opinion: cumulativeFusion(targetOpinion, discounted),
|
|
467
559
|
operator: "cumulative_fusion",
|
|
468
560
|
rationale: `Supporting evidence (weight=${weight.toFixed(2)})`
|
|
469
561
|
};
|
|
@@ -472,23 +564,35 @@ var EDGE_PROPAGATION_RULES = {
|
|
|
472
564
|
depends_on: {
|
|
473
565
|
direction: "incoming",
|
|
474
566
|
handler: (source, target, _weight, metadata) => {
|
|
567
|
+
const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);
|
|
568
|
+
const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);
|
|
475
569
|
if (metadata.conditionalA && metadata.conditionalNotA) {
|
|
476
570
|
return {
|
|
477
571
|
opinion: conditionalDeduction(
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
572
|
+
sourceOpinion,
|
|
573
|
+
mkOpinion(
|
|
574
|
+
metadata.conditionalA.b,
|
|
575
|
+
metadata.conditionalA.d,
|
|
576
|
+
metadata.conditionalA.u,
|
|
577
|
+
metadata.conditionalA.a
|
|
578
|
+
),
|
|
579
|
+
mkOpinion(
|
|
580
|
+
metadata.conditionalNotA.b,
|
|
581
|
+
metadata.conditionalNotA.d,
|
|
582
|
+
metadata.conditionalNotA.u,
|
|
583
|
+
metadata.conditionalNotA.a
|
|
584
|
+
),
|
|
585
|
+
targetOpinion.a
|
|
482
586
|
),
|
|
483
587
|
operator: "conditional_deduction",
|
|
484
588
|
rationale: `Conditional deduction: prerequisite at ${project(
|
|
485
|
-
|
|
589
|
+
sourceOpinion
|
|
486
590
|
).toFixed(2)}`
|
|
487
591
|
};
|
|
488
592
|
}
|
|
489
593
|
return dampedDependencyCascade(
|
|
490
|
-
|
|
491
|
-
|
|
594
|
+
sourceOpinion,
|
|
595
|
+
targetOpinion,
|
|
492
596
|
metadata.propagation ?? "continuous"
|
|
493
597
|
);
|
|
494
598
|
}
|
|
@@ -580,10 +684,6 @@ function normalizeBaseRateVector(baseRate, size) {
|
|
|
580
684
|
if (size === 0) {
|
|
581
685
|
return [];
|
|
582
686
|
}
|
|
583
|
-
const fallback = Array.from({ length: size }, () => 1 / size);
|
|
584
|
-
if (!baseRate) {
|
|
585
|
-
return fallback;
|
|
586
|
-
}
|
|
587
687
|
if (baseRate.length !== size) {
|
|
588
688
|
throw new Error(
|
|
589
689
|
`Base-rate vector length ${baseRate.length} must match evidence vector length ${size}.`
|
|
@@ -592,11 +692,11 @@ function normalizeBaseRateVector(baseRate, size) {
|
|
|
592
692
|
const normalized = baseRate.map((value) => clampNonNegative(value));
|
|
593
693
|
const total = normalized.reduce((sum, value) => sum + value, 0);
|
|
594
694
|
if (total === 0) {
|
|
595
|
-
|
|
695
|
+
throw new Error("Base-rate vector must contain at least one positive value.");
|
|
596
696
|
}
|
|
597
697
|
return normalized.map((value) => value / total);
|
|
598
698
|
}
|
|
599
|
-
function opinionFromDirichlet(alpha, nonInformativeWeight
|
|
699
|
+
function opinionFromDirichlet(alpha, nonInformativeWeight, baseRate) {
|
|
600
700
|
const evidence = alpha.map((value) => clampNonNegative(value));
|
|
601
701
|
const safeWeight = normalizeNonInformativeWeight(nonInformativeWeight);
|
|
602
702
|
const normalizedBaseRate = normalizeBaseRateVector(baseRate, evidence.length);
|
|
@@ -615,18 +715,18 @@ function opinionFromDirichlet(alpha, nonInformativeWeight = DEFAULT_NON_INFORMAT
|
|
|
615
715
|
a: normalizedBaseRate
|
|
616
716
|
};
|
|
617
717
|
}
|
|
618
|
-
function opinionFromBeta(alpha, beta, nonInformativeWeight
|
|
718
|
+
function opinionFromBeta(alpha, beta, nonInformativeWeight, baseRate) {
|
|
619
719
|
const dirichlet = opinionFromDirichlet(
|
|
620
720
|
[alpha, beta],
|
|
621
721
|
nonInformativeWeight,
|
|
622
722
|
[clamp012(baseRate), 1 - clamp012(baseRate)]
|
|
623
723
|
);
|
|
624
|
-
return
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
724
|
+
return mkOpinion(
|
|
725
|
+
dirichlet.b[0] ?? 0,
|
|
726
|
+
dirichlet.b[1] ?? 0,
|
|
727
|
+
dirichlet.u,
|
|
728
|
+
dirichlet.a[0] ?? clamp012(baseRate)
|
|
729
|
+
);
|
|
630
730
|
}
|
|
631
731
|
|
|
632
732
|
// src/v1/operations/dynamics/revision.ts
|
|
@@ -661,7 +761,7 @@ function reviseConfidenceOpinion(args) {
|
|
|
661
761
|
priorEvidence.alpha + newEvidence.alpha,
|
|
662
762
|
priorEvidence.beta + newEvidence.beta,
|
|
663
763
|
args.nonInformativeWeight ?? DEFAULT_NON_INFORMATIVE_WEIGHT,
|
|
664
|
-
args.baseRate
|
|
764
|
+
args.baseRate
|
|
665
765
|
);
|
|
666
766
|
}
|
|
667
767
|
|
|
@@ -928,6 +1028,9 @@ function generateContractId() {
|
|
|
928
1028
|
}
|
|
929
1029
|
return `contract-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
|
930
1030
|
}
|
|
1031
|
+
function isRecord(value) {
|
|
1032
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1033
|
+
}
|
|
931
1034
|
function deriveContractStatus(result, currentStatus) {
|
|
932
1035
|
if (currentStatus === "archived") {
|
|
933
1036
|
return currentStatus;
|
|
@@ -1069,18 +1172,17 @@ function pickFiniteNumber(config, keys) {
|
|
|
1069
1172
|
return void 0;
|
|
1070
1173
|
}
|
|
1071
1174
|
function getEvaluatorInputRecord(inputData, nestedKey) {
|
|
1072
|
-
if (!inputData
|
|
1175
|
+
if (!isRecord(inputData)) {
|
|
1073
1176
|
return {};
|
|
1074
1177
|
}
|
|
1075
|
-
const
|
|
1076
|
-
|
|
1077
|
-
if (nested && typeof nested === "object") {
|
|
1178
|
+
const nested = inputData[nestedKey];
|
|
1179
|
+
if (isRecord(nested)) {
|
|
1078
1180
|
return nested;
|
|
1079
1181
|
}
|
|
1080
|
-
return
|
|
1182
|
+
return inputData;
|
|
1081
1183
|
}
|
|
1082
1184
|
function parseEvidentialEvaluatorConfig(value) {
|
|
1083
|
-
if (!value
|
|
1185
|
+
if (!isRecord(value)) {
|
|
1084
1186
|
throw new Error(
|
|
1085
1187
|
"Evidential contracts require condition.evaluatorConfig with metric/operator/threshold."
|
|
1086
1188
|
);
|
|
@@ -1098,7 +1200,7 @@ function parseEvidentialEvaluatorConfig(value) {
|
|
|
1098
1200
|
if (typeof threshold !== "number" || !Number.isFinite(threshold)) {
|
|
1099
1201
|
throw new Error("Evidential contracts require a numeric threshold.");
|
|
1100
1202
|
}
|
|
1101
|
-
const actionParams = config.actionParams
|
|
1203
|
+
const actionParams = isRecord(config.actionParams) ? config.actionParams : void 0;
|
|
1102
1204
|
return {
|
|
1103
1205
|
metric,
|
|
1104
1206
|
operator,
|
|
@@ -1147,7 +1249,7 @@ function buildEvidentialRationale(args) {
|
|
|
1147
1249
|
return `${clause}; comparison ${args.comparisonSatisfied ? "passed" : "failed"}, resulting in ${args.result}.`;
|
|
1148
1250
|
}
|
|
1149
1251
|
function parseMetricCheckerConfig(value) {
|
|
1150
|
-
if (!value
|
|
1252
|
+
if (!isRecord(value)) {
|
|
1151
1253
|
throw new Error(
|
|
1152
1254
|
"metric_checker requires condition.evaluatorConfig with observedValue/operator/threshold."
|
|
1153
1255
|
);
|
|
@@ -1164,7 +1266,7 @@ function parseMetricCheckerConfig(value) {
|
|
|
1164
1266
|
};
|
|
1165
1267
|
}
|
|
1166
1268
|
function parseReferenceCheckCounterConfig(value) {
|
|
1167
|
-
if (!value
|
|
1269
|
+
if (!isRecord(value)) {
|
|
1168
1270
|
throw new Error(
|
|
1169
1271
|
"reference_check_counter requires condition.evaluatorConfig with tag/operator/threshold."
|
|
1170
1272
|
);
|
|
@@ -1187,7 +1289,7 @@ function parseReferenceCheckCounterConfig(value) {
|
|
|
1187
1289
|
};
|
|
1188
1290
|
}
|
|
1189
1291
|
function parseTemporalDeadlineConfig(value) {
|
|
1190
|
-
if (!value
|
|
1292
|
+
if (!isRecord(value)) {
|
|
1191
1293
|
return {};
|
|
1192
1294
|
}
|
|
1193
1295
|
const config = value;
|
|
@@ -1201,7 +1303,7 @@ function parseTemporalDeadlineConfig(value) {
|
|
|
1201
1303
|
};
|
|
1202
1304
|
}
|
|
1203
1305
|
function parseMarketIndexComparatorConfig(value) {
|
|
1204
|
-
if (!value
|
|
1306
|
+
if (!isRecord(value)) {
|
|
1205
1307
|
throw new Error(
|
|
1206
1308
|
"market_index_comparator requires condition.evaluatorConfig with subjectValue/benchmarkValue/operator/threshold."
|
|
1207
1309
|
);
|
|
@@ -1228,6 +1330,8 @@ function parseMarketIndexComparatorConfig(value) {
|
|
|
1228
1330
|
// src/v1/operations/lucern.ts
|
|
1229
1331
|
var LUCERN_SPECIFIC_OPERATOR_NAMES = [
|
|
1230
1332
|
"clamp01",
|
|
1333
|
+
"fromStorage",
|
|
1334
|
+
"toStorage",
|
|
1231
1335
|
"toStoredOpinionFields",
|
|
1232
1336
|
"readOpinionFromRecord",
|
|
1233
1337
|
"opinionFromScalar",
|
|
@@ -1248,6 +1352,7 @@ var LUCERN_SPECIFIC_OPERATOR_NAMES = [
|
|
|
1248
1352
|
"propagateAllEdges",
|
|
1249
1353
|
"bayesianUpdate",
|
|
1250
1354
|
"reviseConfidence",
|
|
1355
|
+
"reviseConfidenceOpinion",
|
|
1251
1356
|
"computeBaseDecay",
|
|
1252
1357
|
"computeDeadlineUrgency",
|
|
1253
1358
|
"computeEffectiveDecay",
|
|
@@ -1275,6 +1380,6 @@ var LUCERN_SPECIFIC_OPERATOR_NAMES = [
|
|
|
1275
1380
|
"parseMarketIndexComparatorConfig"
|
|
1276
1381
|
];
|
|
1277
1382
|
|
|
1278
|
-
export { LUCERN_SPECIFIC_OPERATOR_NAMES, applyNegativeEvidence, applyNegativeSupport, areTensioned, bayesianUpdate, buildComparisonRationale, buildEvidentialRationale, clamp01, compareMetricValue, computeBaseDecay, computeDeadlineUrgency, computeEffectiveDecay, confidenceLevel, constraintFusion, createInheritedContractRecord, decay, deriveContractModulationPlan, deriveContractStatus, deriveVerificationTrigger, detectTupleContradiction, evaluateTupleContradictionTransition, evidenceBalance, getEvaluatorInputRecord, getPropagationTraversalSpecs, getRescoringSchedule, hasProjectedOpinionChanged, informationGain, isPropagationEdgeType, normalizeEvidentialAction, normalizeTupleContradictionPolicy, opinionFromScalar, parseComparisonOperator, parseEvidentialEvaluatorConfig, parseMarketIndexComparatorConfig, parseMetricCheckerConfig, parseNumericThreshold, parseReferenceCheckCounterConfig, parseTemporalDeadlineConfig, pickFiniteNumber, propagateAllEdges, propagateThroughEdge, readOpinionFromRecord, resolveComparisonResult, reviseConfidence, temporalDecay, toDogmaticOpinion, toStoredOpinionFields };
|
|
1383
|
+
export { LUCERN_SPECIFIC_OPERATOR_NAMES, applyNegativeEvidence, applyNegativeSupport, areTensioned, bayesianUpdate, buildComparisonRationale, buildEvidentialRationale, clamp01, compareMetricValue, computeBaseDecay, computeDeadlineUrgency, computeEffectiveDecay, confidenceLevel, constraintFusion, createInheritedContractRecord, decay, deriveContractModulationPlan, deriveContractStatus, deriveVerificationTrigger, detectTupleContradiction, evaluateTupleContradictionTransition, evidenceBalance, fromStorage, getEvaluatorInputRecord, getPropagationTraversalSpecs, getRescoringSchedule, hasProjectedOpinionChanged, informationGain, isPropagationEdgeType, normalizeEvidentialAction, normalizeTupleContradictionPolicy, opinionFromScalar, parseComparisonOperator, parseEvidentialEvaluatorConfig, parseMarketIndexComparatorConfig, parseMetricCheckerConfig, parseNumericThreshold, parseReferenceCheckCounterConfig, parseTemporalDeadlineConfig, pickFiniteNumber, propagateAllEdges, propagateThroughEdge, readOpinionFromRecord, resolveComparisonResult, reviseConfidence, reviseConfidenceOpinion, temporalDecay, toDogmaticOpinion, toStorage, toStoredOpinionFields };
|
|
1279
1384
|
//# sourceMappingURL=lucern.js.map
|
|
1280
1385
|
//# sourceMappingURL=lucern.js.map
|