@lucern/confidence 1.0.28 → 1.0.30
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/dist/index.d.ts +7 -7
- package/dist/index.js +905 -770
- package/dist/index.js.map +1 -1
- package/dist/proof-attestation.json +1 -1
- package/dist/v1/codec.js.map +1 -1
- package/dist/v1/index.d.ts +7 -7
- package/dist/v1/index.js +905 -770
- package/dist/v1/index.js.map +1 -1
- package/dist/v1/interfaces.d.ts +5 -5
- package/dist/v1/operations/approximation.d.ts +1 -1
- package/dist/v1/operations/approximation.js +8 -7
- package/dist/v1/operations/approximation.js.map +1 -1
- package/dist/v1/operations/bridge/index.js +7 -6
- package/dist/v1/operations/bridge/index.js.map +1 -1
- package/dist/v1/operations/canonical.d.ts +1 -1
- package/dist/v1/operations/canonical.js +106 -57
- 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 +9 -3
- 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 +1 -1
- package/dist/v1/operations/dynamics/cascade.js.map +1 -1
- package/dist/v1/operations/dynamics/decay.js +105 -41
- package/dist/v1/operations/dynamics/decay.js.map +1 -1
- package/dist/v1/operations/dynamics/defeat.js.map +1 -1
- package/dist/v1/operations/dynamics/propagation.d.ts +3 -3
- package/dist/v1/operations/dynamics/propagation.js +101 -57
- package/dist/v1/operations/dynamics/propagation.js.map +1 -1
- package/dist/v1/operations/dynamics/revision.js +7 -6
- package/dist/v1/operations/dynamics/revision.js.map +1 -1
- package/dist/v1/operations/index.js +8 -3
- package/dist/v1/operations/index.js.map +1 -1
- package/dist/v1/operations/lucern.d.ts +7 -7
- package/dist/v1/operations/lucern.js +934 -807
- package/dist/v1/operations/lucern.js.map +1 -1
- package/dist/v1/operations/operatorTaxonomy.d.ts +10 -10
- package/dist/v1/operations/operatorTaxonomy.js.map +1 -1
- package/dist/v1/operations/scoring.d.ts +2 -1
- package/dist/v1/operations/scoring.js +20 -5
- package/dist/v1/operations/scoring.js.map +1 -1
- package/dist/v1/operations/subjectiveLogic/index.js +91 -54
- package/dist/v1/operations/subjectiveLogic/index.js.map +1 -1
- package/dist/v1/operations/temporalDecay.d.ts +3 -3
- package/dist/v1/operations/temporalDecay.js +8 -3
- package/dist/v1/operations/temporalDecay.js.map +1 -1
- package/dist/v1/types.d.ts +101 -101
- package/package.json +1 -1
|
@@ -92,14 +92,91 @@ function computeConditionalDeductionBaseRate(opinionA, ifTrue, ifFalse, fallback
|
|
|
92
92
|
}
|
|
93
93
|
function safeCorrectionTerm(numerator, denominator) {
|
|
94
94
|
if (Math.abs(denominator) <= EPSILON) {
|
|
95
|
-
return
|
|
95
|
+
return;
|
|
96
96
|
}
|
|
97
97
|
const value = numerator / denominator;
|
|
98
98
|
if (!Number.isFinite(value)) {
|
|
99
|
-
return
|
|
99
|
+
return;
|
|
100
100
|
}
|
|
101
101
|
return Math.max(0, value);
|
|
102
102
|
}
|
|
103
|
+
function correctionOrZero(numerator, denominator) {
|
|
104
|
+
return safeCorrectionTerm(numerator, denominator) ?? 0;
|
|
105
|
+
}
|
|
106
|
+
function hasNoConditionalDeductionCorrection(ifTrue, ifFalse) {
|
|
107
|
+
return ifTrue.b > ifFalse.b && ifTrue.d > ifFalse.d || ifTrue.b <= ifFalse.b && ifTrue.d <= ifFalse.d;
|
|
108
|
+
}
|
|
109
|
+
function usesLowerVacuousBranch(context) {
|
|
110
|
+
return context.projectedVacuousDeduction <= context.projectedConditionalA;
|
|
111
|
+
}
|
|
112
|
+
function usesLowerAntecedentBranch(context) {
|
|
113
|
+
return context.projectedAntecedent <= context.opinionA.a;
|
|
114
|
+
}
|
|
115
|
+
function computeTrueDominantDeductionCorrection(context) {
|
|
116
|
+
const beliefGap = context.ifTrue.b - context.ifFalse.b;
|
|
117
|
+
const disbeliefGap = context.ifFalse.d - context.ifTrue.d;
|
|
118
|
+
const lowerVacuous = usesLowerVacuousBranch(context);
|
|
119
|
+
const lowerAntecedent = usesLowerAntecedentBranch(context);
|
|
120
|
+
if (lowerVacuous && lowerAntecedent) {
|
|
121
|
+
return correctionOrZero(
|
|
122
|
+
context.opinionA.a * context.opinionA.u * (context.intermediateBelief - context.ifTrue.b),
|
|
123
|
+
context.projectedAntecedent * context.childBaseRate
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
if (lowerVacuous) {
|
|
127
|
+
return correctionOrZero(
|
|
128
|
+
context.opinionA.a * context.opinionA.u * (context.intermediateDisbelief - context.ifTrue.d) * beliefGap,
|
|
129
|
+
context.projectedAntecedentComplement * context.childBaseRate * disbeliefGap
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
if (lowerAntecedent) {
|
|
133
|
+
return correctionOrZero(
|
|
134
|
+
(1 - context.opinionA.a) * context.opinionA.u * (context.intermediateBelief - context.ifTrue.b) * disbeliefGap,
|
|
135
|
+
context.projectedAntecedent * (1 - context.childBaseRate) * beliefGap
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
return correctionOrZero(
|
|
139
|
+
(1 - context.opinionA.a) * context.opinionA.u * (context.intermediateDisbelief - context.ifTrue.d),
|
|
140
|
+
context.projectedAntecedentComplement * (1 - context.childBaseRate)
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
function computeFalseDominantDeductionCorrection(context) {
|
|
144
|
+
const beliefGap = context.ifFalse.b - context.ifTrue.b;
|
|
145
|
+
const disbeliefGap = context.ifTrue.d - context.ifFalse.d;
|
|
146
|
+
const lowerVacuous = usesLowerVacuousBranch(context);
|
|
147
|
+
const lowerAntecedent = usesLowerAntecedentBranch(context);
|
|
148
|
+
if (lowerVacuous && lowerAntecedent) {
|
|
149
|
+
return correctionOrZero(
|
|
150
|
+
(1 - context.opinionA.a) * context.opinionA.u * (context.intermediateDisbelief - context.ifTrue.d) * beliefGap,
|
|
151
|
+
context.projectedAntecedent * context.childBaseRate * disbeliefGap
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
if (lowerVacuous) {
|
|
155
|
+
return correctionOrZero(
|
|
156
|
+
(1 - context.opinionA.a) * context.opinionA.u * (context.intermediateBelief - context.ifTrue.b),
|
|
157
|
+
context.projectedAntecedentComplement * context.childBaseRate
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
if (lowerAntecedent) {
|
|
161
|
+
return correctionOrZero(
|
|
162
|
+
context.opinionA.a * context.opinionA.u * (context.intermediateDisbelief - context.ifTrue.d),
|
|
163
|
+
context.projectedAntecedent * (1 - context.childBaseRate)
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
return correctionOrZero(
|
|
167
|
+
context.opinionA.a * context.opinionA.u * (context.intermediateBelief - context.ifTrue.b) * disbeliefGap,
|
|
168
|
+
context.projectedAntecedentComplement * (1 - context.childBaseRate) * beliefGap
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
function computeConditionalDeductionCorrection(context) {
|
|
172
|
+
if (hasNoConditionalDeductionCorrection(context.ifTrue, context.ifFalse)) {
|
|
173
|
+
return 0;
|
|
174
|
+
}
|
|
175
|
+
if (context.ifTrue.b > context.ifFalse.b && context.ifTrue.d <= context.ifFalse.d) {
|
|
176
|
+
return computeTrueDominantDeductionCorrection(context);
|
|
177
|
+
}
|
|
178
|
+
return computeFalseDominantDeductionCorrection(context);
|
|
179
|
+
}
|
|
103
180
|
function conditionalDeduction(opinionA, ifTrue, ifFalse, fallbackBaseRate) {
|
|
104
181
|
const fallbackChildBaseRate = childBaseRateFallback(
|
|
105
182
|
ifTrue,
|
|
@@ -119,58 +196,18 @@ function conditionalDeduction(opinionA, ifTrue, ifFalse, fallbackBaseRate) {
|
|
|
119
196
|
const intermediateUncertainty = opinionA.b * ifTrue.u + opinionA.d * ifFalse.u + opinionA.u * (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));
|
|
120
197
|
const projectedVacuousDeduction = ifTrue.b * opinionA.a + ifFalse.b * (1 - opinionA.a) + childBaseRate * (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));
|
|
121
198
|
const projectedConditionalA = ifTrue.b + childBaseRate * (1 - ifTrue.b - ifTrue.d);
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
correction = safeCorrectionTerm(
|
|
135
|
-
opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d) * beliefGap,
|
|
136
|
-
projectedAntecedentComplement * childBaseRate * disbeliefGap
|
|
137
|
-
) ?? 0;
|
|
138
|
-
} else if (projectedVacuousDeduction > projectedConditionalA && projectedAntecedent <= opinionA.a) {
|
|
139
|
-
correction = safeCorrectionTerm(
|
|
140
|
-
(1 - opinionA.a) * opinionA.u * (intermediateBelief - ifTrue.b) * disbeliefGap,
|
|
141
|
-
projectedAntecedent * (1 - childBaseRate) * beliefGap
|
|
142
|
-
) ?? 0;
|
|
143
|
-
} else {
|
|
144
|
-
correction = safeCorrectionTerm(
|
|
145
|
-
(1 - opinionA.a) * opinionA.u * (intermediateDisbelief - ifTrue.d),
|
|
146
|
-
projectedAntecedentComplement * (1 - childBaseRate)
|
|
147
|
-
) ?? 0;
|
|
148
|
-
}
|
|
149
|
-
} else {
|
|
150
|
-
const beliefGap = ifFalse.b - ifTrue.b;
|
|
151
|
-
const disbeliefGap = ifTrue.d - ifFalse.d;
|
|
152
|
-
if (projectedVacuousDeduction <= projectedConditionalA && projectedAntecedent <= opinionA.a) {
|
|
153
|
-
correction = safeCorrectionTerm(
|
|
154
|
-
(1 - opinionA.a) * opinionA.u * (intermediateDisbelief - ifTrue.d) * beliefGap,
|
|
155
|
-
projectedAntecedent * childBaseRate * disbeliefGap
|
|
156
|
-
) ?? 0;
|
|
157
|
-
} else if (projectedVacuousDeduction <= projectedConditionalA && projectedAntecedent > opinionA.a) {
|
|
158
|
-
correction = safeCorrectionTerm(
|
|
159
|
-
(1 - opinionA.a) * opinionA.u * (intermediateBelief - ifTrue.b),
|
|
160
|
-
projectedAntecedentComplement * childBaseRate
|
|
161
|
-
) ?? 0;
|
|
162
|
-
} else if (projectedVacuousDeduction > projectedConditionalA && projectedAntecedent <= opinionA.a) {
|
|
163
|
-
correction = safeCorrectionTerm(
|
|
164
|
-
opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d),
|
|
165
|
-
projectedAntecedent * (1 - childBaseRate)
|
|
166
|
-
) ?? 0;
|
|
167
|
-
} else {
|
|
168
|
-
correction = safeCorrectionTerm(
|
|
169
|
-
opinionA.a * opinionA.u * (intermediateBelief - ifTrue.b) * disbeliefGap,
|
|
170
|
-
projectedAntecedentComplement * (1 - childBaseRate) * beliefGap
|
|
171
|
-
) ?? 0;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
199
|
+
const correction = computeConditionalDeductionCorrection({
|
|
200
|
+
childBaseRate,
|
|
201
|
+
ifFalse,
|
|
202
|
+
ifTrue,
|
|
203
|
+
intermediateBelief,
|
|
204
|
+
intermediateDisbelief,
|
|
205
|
+
opinionA,
|
|
206
|
+
projectedAntecedent,
|
|
207
|
+
projectedAntecedentComplement,
|
|
208
|
+
projectedConditionalA,
|
|
209
|
+
projectedVacuousDeduction
|
|
210
|
+
});
|
|
174
211
|
return opinion(
|
|
175
212
|
intermediateBelief - childBaseRate * correction,
|
|
176
213
|
intermediateDisbelief - (1 - childBaseRate) * correction,
|
|
@@ -244,7 +281,7 @@ function dampedDependencyOpinion(dependencyOpinion, beliefOpinion, mode = "conti
|
|
|
244
281
|
}
|
|
245
282
|
return beliefOpinion;
|
|
246
283
|
}
|
|
247
|
-
const dampingFactor =
|
|
284
|
+
const dampingFactor = dependencyProjection ** 0.5;
|
|
248
285
|
return opinion(
|
|
249
286
|
beliefOpinion.b * dampingFactor,
|
|
250
287
|
beliefOpinion.d + beliefOpinion.b * (1 - dampingFactor) * 0.3,
|
|
@@ -313,7 +350,12 @@ var EDGE_PROPAGATION_RULES = {
|
|
|
313
350
|
const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);
|
|
314
351
|
const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);
|
|
315
352
|
if (weight < 0) {
|
|
316
|
-
return applyNegativeSupport(
|
|
353
|
+
return applyNegativeSupport(
|
|
354
|
+
sourceOpinion,
|
|
355
|
+
targetOpinion,
|
|
356
|
+
weight,
|
|
357
|
+
metadata
|
|
358
|
+
);
|
|
317
359
|
}
|
|
318
360
|
const discounted = trustDiscount(sourceOpinion, weight);
|
|
319
361
|
return {
|
|
@@ -427,7 +469,9 @@ function propagateAllEdges(currentOpinion, incomingEdges) {
|
|
|
427
469
|
let result = currentOpinion;
|
|
428
470
|
const rationales = [];
|
|
429
471
|
for (const edgeType of ["depends_on", "informs", "supports"]) {
|
|
430
|
-
for (const incoming of incomingEdges.filter(
|
|
472
|
+
for (const incoming of incomingEdges.filter(
|
|
473
|
+
(edge) => edge.edgeType === edgeType
|
|
474
|
+
)) {
|
|
431
475
|
const propagated = propagateThroughEdge(
|
|
432
476
|
incoming.sourceOpinion,
|
|
433
477
|
result,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/v1/operations/subjectiveLogic/index.ts","../../../../src/v1/operations/dynamics/cascade.ts","../../../../src/v1/operations/dynamics/defeat.ts","../../../../src/v1/operations/dynamics/propagation.ts"],"names":[],"mappings":"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","file":"propagation.js","sourcesContent":["import type { SLOpinion } from \"../../types\";\n\nexport function opinion(\n belief: number,\n disbelief: number,\n uncertainty: number,\n baseRate: number\n): SLOpinion {\n const b = Number.isFinite(belief) ? Math.max(0, belief) : 0;\n const d = Number.isFinite(disbelief) ? Math.max(0, disbelief) : 0;\n const u = Number.isFinite(uncertainty) ? Math.max(0, uncertainty) : 0;\n const a = Math.max(0, Math.min(1, baseRate));\n const sum = b + d + u;\n\n if (sum === 0) {\n return { b: 0, d: 0, u: 1, a } as SLOpinion;\n }\n\n return {\n b: b / sum,\n d: d / sum,\n u: u / sum,\n a,\n } as SLOpinion;\n}\n\nexport function mkOpinion(\n belief: number,\n disbelief: number,\n uncertainty: number,\n baseRate: number\n): SLOpinion {\n return opinion(belief, disbelief, uncertainty, baseRate);\n}\n\nexport function vacuous(baseRate: number): SLOpinion {\n return mkOpinion(0, 0, 1, baseRate);\n}\n\nexport function dogmatic(probability: number, baseRate: number): SLOpinion {\n const p = Math.max(0, Math.min(1, probability));\n return mkOpinion(p, 1 - p, 0, baseRate);\n}\n\nexport function project(o: SLOpinion): number {\n return o.b + o.a * o.u;\n}\n\nexport function confidenceLevel(o: SLOpinion): \"high\" | \"medium\" | \"low\" {\n const projected = project(o);\n if (o.u > 0.5) {\n return \"low\";\n }\n if (projected >= 0.8 && o.u < 0.2) {\n return \"high\";\n }\n if (projected >= 0.6) {\n return \"medium\";\n }\n return \"low\";\n}\n\nconst VACUOUS_IDENTITY_EPSILON = 1e-12;\n\n/**\n * Associative, vacuous-identity-preserving base rate for a fused opinion.\n *\n * The legacy `(left.a + right.a) / 2` arithmetic mean was the shared root of\n * RR.7 F1 (projected-confidence non-associativity) and F2 (a vacuous opinion of\n * a different base rate was not a fusion identity): averaging always pulled the\n * fused base rate toward the other operand even when that operand carried no\n * evidence. Subjective Logic requires every opinion over the same frame to share\n * one canonical base rate, so a correct fusion never *invents* a new base rate\n * from the operands' priors. We therefore:\n *\n * - return the informative operand's base rate when exactly one operand is\n * vacuous (the vacuous operand contributes no prior), making `vacuous(a)` a\n * true identity for any `a`; and\n * - require equal base rates otherwise (the canonical-frame contract). When\n * they coincide the result is that shared value — trivially associative.\n *\n * If two informative opinions carry genuinely different base rates they are not\n * opinions over the same frame and must be reconciled before fusion; we fall\n * back to the arithmetic mean ONLY in that ill-posed case to stay total, and the\n * property suite documents that this path is outside the order-independence\n * guarantee.\n */\nfunction fusedBaseRate(left: SLOpinion, right: SLOpinion): number {\n const leftVacuous = 1 - left.u <= VACUOUS_IDENTITY_EPSILON;\n const rightVacuous = 1 - right.u <= VACUOUS_IDENTITY_EPSILON;\n if (leftVacuous && !rightVacuous) {\n return right.a;\n }\n if (rightVacuous && !leftVacuous) {\n return left.a;\n }\n if (Math.abs(left.a - right.a) <= VACUOUS_IDENTITY_EPSILON) {\n return left.a;\n }\n return (left.a + right.a) / 2;\n}\n\nexport function cumulativeFusion(left: SLOpinion, right: SLOpinion): SLOpinion {\n const a = fusedBaseRate(left, right);\n\n // F2: a vacuous operand is the identity element of cumulative fusion. Return\n // the other operand verbatim (including its base rate) so fusion with the\n // vacuous opinion is a true no-op regardless of differing priors.\n if (1 - left.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(right.b, right.d, right.u, a);\n }\n if (1 - right.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(left.b, left.d, left.u, a);\n }\n\n // F4: dogmatic pair handled via the ε-limit of the cumulative rule rather than\n // the standalone `(b+d)/2` shortcut. As both uncertainties shrink at the same\n // rate, the cumulative formula's `(b_L·u_R + b_R·u_L)/k` term converges to the\n // arithmetic mean of the masses; deriving it from the same limit the interior\n // formula uses keeps mass-associativity intact (no special-case discontinuity).\n if (left.u <= VACUOUS_IDENTITY_EPSILON && right.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion((left.b + right.b) / 2, (left.d + right.d) / 2, 0, a);\n }\n\n const k = left.u + right.u - left.u * right.u;\n if (k === 0) {\n return vacuous(a);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (left.u * right.u) / k,\n a\n );\n}\n\nexport function averagingFusion(left: SLOpinion, right: SLOpinion): SLOpinion {\n const a = fusedBaseRate(left, right);\n\n // F2: vacuous identity, mirroring cumulativeFusion.\n if (1 - left.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(right.b, right.d, right.u, a);\n }\n if (1 - right.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(left.b, left.d, left.u, a);\n }\n\n // F4: dogmatic pair via the ε-limit of the averaging rule.\n if (left.u <= VACUOUS_IDENTITY_EPSILON && right.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion((left.b + right.b) / 2, (left.d + right.d) / 2, 0, a);\n }\n\n const k = left.u + right.u;\n if (k === 0) {\n return vacuous(a);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (2 * left.u * right.u) / k,\n a\n );\n}\n\nexport function trustDiscount(sourceOpinion: SLOpinion, trust: number): SLOpinion {\n const weight = Math.max(0, Math.min(1, Math.abs(trust)));\n return opinion(\n weight * sourceOpinion.b,\n weight * sourceOpinion.d,\n 1 - weight * (sourceOpinion.b + sourceOpinion.d),\n sourceOpinion.a\n );\n}\n\nconst EPSILON = 1e-9;\n\nfunction childBaseRateFallback(\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate: number | undefined\n): number {\n if (fallbackBaseRate !== undefined) {\n return Math.max(0, Math.min(1, fallbackBaseRate));\n }\n\n if (Math.abs(ifTrue.a - ifFalse.a) <= EPSILON) {\n return ifTrue.a;\n }\n\n return (ifTrue.a + ifFalse.a) / 2;\n}\n\nfunction computeConditionalDeductionBaseRate(\n opinionA: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate: number\n): number {\n const denominator =\n 1 - opinionA.a * ifTrue.u - (1 - opinionA.a) * ifFalse.u;\n\n if (ifTrue.u + ifFalse.u < 2 - EPSILON && Math.abs(denominator) > EPSILON) {\n const baseRate =\n (opinionA.a * ifTrue.b + (1 - opinionA.a) * ifFalse.b) / denominator;\n if (baseRate >= -EPSILON && baseRate <= 1 + EPSILON) {\n return Math.max(0, Math.min(1, baseRate));\n }\n }\n\n return fallbackBaseRate;\n}\n\nfunction safeCorrectionTerm(\n numerator: number,\n denominator: number\n): number | undefined {\n if (Math.abs(denominator) <= EPSILON) {\n return undefined;\n }\n\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n return undefined;\n }\n\n return Math.max(0, value);\n}\n\nexport function conditionalDeduction(\n opinionA: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate?: number\n): SLOpinion {\n const fallbackChildBaseRate = childBaseRateFallback(\n ifTrue,\n ifFalse,\n fallbackBaseRate\n );\n const childBaseRate = computeConditionalDeductionBaseRate(\n opinionA,\n ifTrue,\n ifFalse,\n fallbackChildBaseRate\n );\n const projectedAntecedent = project(opinionA);\n const projectedAntecedentComplement = 1 - projectedAntecedent;\n const intermediateBelief =\n opinionA.b * ifTrue.b +\n opinionA.d * ifFalse.b +\n opinionA.u * (ifTrue.b * opinionA.a + ifFalse.b * (1 - opinionA.a));\n const intermediateDisbelief =\n opinionA.b * ifTrue.d +\n opinionA.d * ifFalse.d +\n opinionA.u * (ifTrue.d * opinionA.a + ifFalse.d * (1 - opinionA.a));\n const intermediateUncertainty =\n opinionA.b * ifTrue.u +\n opinionA.d * ifFalse.u +\n opinionA.u * (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedVacuousDeduction =\n ifTrue.b * opinionA.a +\n ifFalse.b * (1 - opinionA.a) +\n childBaseRate *\n (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedConditionalA =\n ifTrue.b + childBaseRate * (1 - ifTrue.b - ifTrue.d);\n let correction = 0;\n\n if (\n (ifTrue.b > ifFalse.b && ifTrue.d > ifFalse.d) ||\n (ifTrue.b <= ifFalse.b && ifTrue.d <= ifFalse.d)\n ) {\n correction = 0;\n } else if (ifTrue.b > ifFalse.b && ifTrue.d <= ifFalse.d) {\n const beliefGap = ifTrue.b - ifFalse.b;\n const disbeliefGap = ifFalse.d - ifTrue.d;\n\n if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateBelief - ifTrue.b),\n projectedAntecedent * childBaseRate\n ) ?? 0;\n } else if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent > opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d) * beliefGap,\n projectedAntecedentComplement * childBaseRate * disbeliefGap\n ) ?? 0;\n } else if (\n projectedVacuousDeduction > projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) *\n opinionA.u *\n (intermediateBelief - ifTrue.b) *\n disbeliefGap,\n projectedAntecedent * (1 - childBaseRate) * beliefGap\n ) ?? 0;\n } else {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) * opinionA.u * (intermediateDisbelief - ifTrue.d),\n projectedAntecedentComplement * (1 - childBaseRate)\n ) ?? 0;\n }\n } else {\n const beliefGap = ifFalse.b - ifTrue.b;\n const disbeliefGap = ifTrue.d - ifFalse.d;\n\n if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) *\n opinionA.u *\n (intermediateDisbelief - ifTrue.d) *\n beliefGap,\n projectedAntecedent * childBaseRate * disbeliefGap\n ) ?? 0;\n } else if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent > opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) * opinionA.u * (intermediateBelief - ifTrue.b),\n projectedAntecedentComplement * childBaseRate\n ) ?? 0;\n } else if (\n projectedVacuousDeduction > projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d),\n projectedAntecedent * (1 - childBaseRate)\n ) ?? 0;\n } else {\n correction =\n safeCorrectionTerm(\n opinionA.a *\n opinionA.u *\n (intermediateBelief - ifTrue.b) *\n disbeliefGap,\n projectedAntecedentComplement * (1 - childBaseRate) * beliefGap\n ) ?? 0;\n }\n }\n\n return opinion(\n intermediateBelief - childBaseRate * correction,\n intermediateDisbelief - (1 - childBaseRate) * correction,\n intermediateUncertainty + correction,\n childBaseRate\n );\n}\n\n/**\n * Abductive inference over a conditional.\n * Given an opinion on Y and conditionals P(Y|X), P(Y|~X), infer an opinion on X.\n */\nexport function conditionalAbduction(\n opinionY: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n baseRateX: number\n): SLOpinion {\n const priorX = Math.max(0, Math.min(1, baseRateX));\n const probabilityY = project(opinionY);\n const probabilityGivenTrue = project(ifTrue);\n const probabilityGivenFalse = project(ifFalse);\n\n const posteriorIfYDenominator =\n probabilityGivenTrue * priorX +\n probabilityGivenFalse * (1 - priorX);\n const posteriorIfY =\n posteriorIfYDenominator === 0\n ? priorX\n : (probabilityGivenTrue * priorX) / posteriorIfYDenominator;\n\n const posteriorIfNotYDenominator =\n (1 - probabilityGivenTrue) * priorX +\n (1 - probabilityGivenFalse) * (1 - priorX);\n const posteriorIfNotY =\n posteriorIfNotYDenominator === 0\n ? priorX\n : ((1 - probabilityGivenTrue) * priorX) / posteriorIfNotYDenominator;\n\n const projectedX =\n probabilityY * posteriorIfY + (1 - probabilityY) * posteriorIfNotY;\n const uncertainty = Math.max(\n opinionY.u * 0.5,\n probabilityY * ifTrue.u + (1 - probabilityY) * ifFalse.u\n );\n\n return opinion(\n projectedX * (1 - uncertainty),\n (1 - projectedX) * (1 - uncertainty),\n uncertainty,\n priorX\n );\n}\n\nexport function negate(o: SLOpinion): SLOpinion {\n return mkOpinion(o.d, o.b, o.u, 1 - o.a);\n}\n\nexport function constraintFusion(\n left: SLOpinion,\n right: SLOpinion,\n mode: \"pressure\" | \"redistribute\" = \"pressure\"\n): { o1: SLOpinion; o2: SLOpinion } {\n if (mode === \"redistribute\") {\n const leftProjected = project(left);\n const rightProjected = project(right);\n const total = leftProjected + rightProjected;\n\n if (total <= 1) {\n return { o1: left, o2: right };\n }\n\n const scale = 1 / total;\n return {\n o1: opinion(\n left.b * scale,\n left.d + left.b * (1 - scale),\n left.u,\n left.a\n ),\n o2: opinion(\n right.b * scale,\n right.d + right.b * (1 - scale),\n right.u,\n right.a\n ),\n };\n }\n\n const pressureLeft = right.b * 0.5;\n const pressureRight = left.b * 0.5;\n\n return {\n o1: opinion(\n left.b - pressureLeft * 0.3,\n left.d + pressureLeft * 0.3,\n left.u,\n left.a\n ),\n o2: opinion(\n right.b - pressureRight * 0.3,\n right.d + pressureRight * 0.3,\n right.u,\n right.a\n ),\n };\n}\n\nexport function evidenceBalance(o: SLOpinion): number {\n const total = o.b + o.d;\n if (total === 0) {\n return 0;\n }\n return (o.b - o.d) / total;\n}\n\nexport function areTensioned(left: SLOpinion, right: SLOpinion): boolean {\n return (\n project(left) > 0.5 &&\n project(right) > 0.5 &&\n (left.d > 0.2 || right.d > 0.2)\n );\n}\n\nexport function informationGain(o: SLOpinion): number {\n if (o.u === 0) {\n return 0;\n }\n if (o.u === 1) {\n return 1;\n }\n return o.u * (1 - Math.abs(o.b - o.d));\n}\n","import type { Opinion, PropagationMode, PropagationResult } from \"../../types\";\nimport { mkOpinion, opinion, project } from \"../subjectiveLogic\";\n\nexport function dampedDependencyOpinion(\n dependencyOpinion: Opinion,\n beliefOpinion: Opinion,\n mode: PropagationMode = \"continuous\",\n threshold: number = 0.3\n): Opinion {\n const dependencyProjection = project(\n mkOpinion(\n dependencyOpinion.b,\n dependencyOpinion.d,\n dependencyOpinion.u,\n dependencyOpinion.a\n )\n );\n\n if (mode === \"threshold\") {\n if (dependencyProjection < threshold) {\n return opinion(\n 0,\n beliefOpinion.d + beliefOpinion.b * 0.5,\n 0.5,\n beliefOpinion.a\n );\n }\n return beliefOpinion;\n }\n\n const dampingFactor = Math.pow(dependencyProjection, 0.5);\n return opinion(\n beliefOpinion.b * dampingFactor,\n beliefOpinion.d + beliefOpinion.b * (1 - dampingFactor) * 0.3,\n beliefOpinion.u + beliefOpinion.b * (1 - dampingFactor) * 0.7,\n beliefOpinion.a\n );\n}\n\nexport function dampedDependencyCascade(\n dependencyOpinion: Opinion,\n beliefOpinion: Opinion,\n mode: PropagationMode = \"continuous\"\n): PropagationResult {\n return {\n opinion: dampedDependencyOpinion(dependencyOpinion, beliefOpinion, mode),\n operator: \"dependency_cascade\",\n rationale: `Damped dependency cascade (${mode}): prerequisite at ${project(\n mkOpinion(\n dependencyOpinion.b,\n dependencyOpinion.d,\n dependencyOpinion.u,\n dependencyOpinion.a\n )\n ).toFixed(2)}`,\n };\n}\n","import type { EdgeMetadata, Opinion, PropagationResult } from \"../../types\";\nimport {\n constraintFusion,\n cumulativeFusion,\n mkOpinion,\n negate,\n project,\n trustDiscount,\n} from \"../subjectiveLogic\";\n\nexport function applyNegativeSupport(\n source: Opinion,\n target: Opinion,\n weight: number,\n metadata: EdgeMetadata = {}\n): PropagationResult {\n const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);\n const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);\n if (metadata.constraint === \"xor\") {\n const result = constraintFusion(\n sourceOpinion,\n targetOpinion,\n metadata.normalization ?? \"pressure\"\n );\n return {\n opinion: result.o2,\n operator: \"constraint_fusion\",\n rationale: `XOR constraint: source belief at ${project(\n sourceOpinion\n ).toFixed(2)} pressures target`,\n };\n }\n\n const discounted = trustDiscount(negate(sourceOpinion), Math.abs(weight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Contradicting evidence (weight=${weight.toFixed(\n 2\n )}) from source at ${project(sourceOpinion).toFixed(2)}`,\n };\n}\n\nexport function applyNegativeEvidence(\n source: Opinion,\n target: Opinion,\n weight: number\n): PropagationResult {\n const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);\n const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);\n const discounted = trustDiscount(negate(sourceOpinion), Math.abs(weight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Contradicting evidence (weight=${weight.toFixed(2)})`,\n };\n}\n","import type {\n EdgeMetadata,\n Opinion,\n PropagationResult,\n SLOperator,\n} from \"../../types\";\nimport { dampedDependencyCascade } from \"./cascade\";\nimport { applyNegativeEvidence, applyNegativeSupport } from \"./defeat\";\nimport {\n conditionalDeduction,\n cumulativeFusion,\n mkOpinion,\n project,\n trustDiscount,\n} from \"../subjectiveLogic\";\n\ntype EdgeHandler = (\n source: Opinion,\n target: Opinion,\n weight: number,\n metadata: EdgeMetadata\n) => PropagationResult;\n\nexport type PropagationTraversalDirection = \"outgoing\" | \"incoming\";\n\ntype EdgePropagationRule = {\n direction: PropagationTraversalDirection;\n handler: EdgeHandler;\n};\n\nconst EDGE_PROPAGATION_RULES = {\n supports: {\n direction: \"outgoing\",\n handler: (source, target, weight, metadata) => {\n const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);\n const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);\n if (weight < 0) {\n return applyNegativeSupport(sourceOpinion, targetOpinion, weight, metadata);\n }\n\n const discounted = trustDiscount(sourceOpinion, weight);\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${weight.toFixed(\n 2\n )}) from source at ${project(sourceOpinion).toFixed(2)}`,\n };\n },\n },\n informs: {\n direction: \"outgoing\",\n handler: (source, target, weight) => {\n const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);\n const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);\n if (weight < 0) {\n return applyNegativeEvidence(sourceOpinion, targetOpinion, weight);\n }\n\n const discounted = trustDiscount(sourceOpinion, Math.abs(weight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${weight.toFixed(2)})`,\n };\n },\n },\n depends_on: {\n direction: \"incoming\",\n handler: (source, target, _weight, metadata) => {\n const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);\n const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);\n if (metadata.conditionalA && metadata.conditionalNotA) {\n return {\n opinion: conditionalDeduction(\n sourceOpinion,\n mkOpinion(\n metadata.conditionalA.b,\n metadata.conditionalA.d,\n metadata.conditionalA.u,\n metadata.conditionalA.a\n ),\n mkOpinion(\n metadata.conditionalNotA.b,\n metadata.conditionalNotA.d,\n metadata.conditionalNotA.u,\n metadata.conditionalNotA.a\n ),\n targetOpinion.a\n ),\n operator: \"conditional_deduction\",\n rationale: `Conditional deduction: prerequisite at ${project(\n sourceOpinion\n ).toFixed(2)}`,\n };\n }\n\n return dampedDependencyCascade(\n sourceOpinion,\n targetOpinion,\n metadata.propagation ?? \"continuous\"\n );\n },\n },\n derived_from: {\n direction: \"incoming\",\n handler: (_source, target) => ({\n opinion: target,\n operator: \"trust_discount\",\n rationale: \"Provenance edge — no confidence propagation\",\n }),\n },\n contains: {\n direction: \"outgoing\",\n handler: (_source, target) => ({\n opinion: target,\n operator: \"trust_discount\",\n rationale: \"Containment edge — no confidence propagation\",\n }),\n },\n tests: {\n direction: \"outgoing\",\n handler: (_source, target) => ({\n opinion: target,\n operator: \"trust_discount\",\n rationale: \"Testing edge — no confidence propagation\",\n }),\n },\n} satisfies Record<string, EdgePropagationRule>;\n\nexport type PropagationEdgeType = keyof typeof EDGE_PROPAGATION_RULES;\n\nexport type PropagationTraversalSpec = {\n edgeType: PropagationEdgeType;\n direction: PropagationTraversalDirection;\n};\n\nexport const PROPAGATION_TRAVERSAL_SPECS: readonly PropagationTraversalSpec[] =\n Object.entries(EDGE_PROPAGATION_RULES).map(([edgeType, rule]) => ({\n edgeType: edgeType as PropagationEdgeType,\n direction: rule.direction,\n }));\n\nexport function isPropagationEdgeType(\n edgeType: string\n): edgeType is PropagationEdgeType {\n return edgeType in EDGE_PROPAGATION_RULES;\n}\n\nexport function getPropagationTraversalSpecs(): readonly PropagationTraversalSpec[] {\n return PROPAGATION_TRAVERSAL_SPECS;\n}\n\nexport function propagateThroughEdge(\n sourceOpinion: Opinion,\n targetOpinion: Opinion,\n edgeType: string,\n weight: number = 1,\n metadata: EdgeMetadata = {}\n): PropagationResult {\n const handler = isPropagationEdgeType(edgeType)\n ? EDGE_PROPAGATION_RULES[edgeType].handler\n : undefined;\n if (!handler) {\n return {\n opinion: targetOpinion,\n operator: \"no_op\",\n rationale: `Unknown edge type: ${edgeType} — no propagation`,\n };\n }\n return handler(sourceOpinion, targetOpinion, weight, metadata);\n}\n\nexport function propagateAllEdges(\n currentOpinion: Opinion,\n incomingEdges: Array<{\n sourceOpinion: Opinion;\n edgeType: string;\n weight: number;\n metadata: EdgeMetadata;\n }>\n): PropagationResult {\n let result = currentOpinion;\n const rationales: string[] = [];\n\n for (const edgeType of [\"depends_on\", \"informs\", \"supports\"]) {\n for (const incoming of incomingEdges.filter((edge) => edge.edgeType === edgeType)) {\n const propagated = propagateThroughEdge(\n incoming.sourceOpinion,\n result,\n incoming.edgeType,\n incoming.weight,\n incoming.metadata\n );\n result = propagated.opinion;\n rationales.push(propagated.rationale);\n }\n }\n\n return {\n opinion: result,\n operator: \"cumulative_fusion\" as SLOperator,\n rationale: rationales.join(\"; \"),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/v1/operations/subjectiveLogic/index.ts","../../../../src/v1/operations/dynamics/cascade.ts","../../../../src/v1/operations/dynamics/defeat.ts","../../../../src/v1/operations/dynamics/propagation.ts"],"names":[],"mappings":"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","file":"propagation.js","sourcesContent":["import type { SLOpinion } from \"../../types\";\n\nexport function opinion(\n belief: number,\n disbelief: number,\n uncertainty: number,\n baseRate: number\n): SLOpinion {\n const b = Number.isFinite(belief) ? Math.max(0, belief) : 0;\n const d = Number.isFinite(disbelief) ? Math.max(0, disbelief) : 0;\n const u = Number.isFinite(uncertainty) ? Math.max(0, uncertainty) : 0;\n const a = Math.max(0, Math.min(1, baseRate));\n const sum = b + d + u;\n\n if (sum === 0) {\n return { b: 0, d: 0, u: 1, a } as SLOpinion;\n }\n\n return {\n b: b / sum,\n d: d / sum,\n u: u / sum,\n a,\n } as SLOpinion;\n}\n\nexport function mkOpinion(\n belief: number,\n disbelief: number,\n uncertainty: number,\n baseRate: number\n): SLOpinion {\n return opinion(belief, disbelief, uncertainty, baseRate);\n}\n\nexport function vacuous(baseRate: number): SLOpinion {\n return mkOpinion(0, 0, 1, baseRate);\n}\n\nexport function dogmatic(probability: number, baseRate: number): SLOpinion {\n const p = Math.max(0, Math.min(1, probability));\n return mkOpinion(p, 1 - p, 0, baseRate);\n}\n\nexport function project(o: SLOpinion): number {\n return o.b + o.a * o.u;\n}\n\nexport function confidenceLevel(o: SLOpinion): \"high\" | \"medium\" | \"low\" {\n const projected = project(o);\n if (o.u > 0.5) {\n return \"low\";\n }\n if (projected >= 0.8 && o.u < 0.2) {\n return \"high\";\n }\n if (projected >= 0.6) {\n return \"medium\";\n }\n return \"low\";\n}\n\nconst VACUOUS_IDENTITY_EPSILON = 1e-12;\n\n/**\n * Associative, vacuous-identity-preserving base rate for a fused opinion.\n *\n * The legacy `(left.a + right.a) / 2` arithmetic mean was the shared root of\n * RR.7 F1 (projected-confidence non-associativity) and F2 (a vacuous opinion of\n * a different base rate was not a fusion identity): averaging always pulled the\n * fused base rate toward the other operand even when that operand carried no\n * evidence. Subjective Logic requires every opinion over the same frame to share\n * one canonical base rate, so a correct fusion never *invents* a new base rate\n * from the operands' priors. We therefore:\n *\n * - return the informative operand's base rate when exactly one operand is\n * vacuous (the vacuous operand contributes no prior), making `vacuous(a)` a\n * true identity for any `a`; and\n * - require equal base rates otherwise (the canonical-frame contract). When\n * they coincide the result is that shared value — trivially associative.\n *\n * If two informative opinions carry genuinely different base rates they are not\n * opinions over the same frame and must be reconciled before fusion; we fall\n * back to the arithmetic mean ONLY in that ill-posed case to stay total, and the\n * property suite documents that this path is outside the order-independence\n * guarantee.\n */\nfunction fusedBaseRate(left: SLOpinion, right: SLOpinion): number {\n const leftVacuous = 1 - left.u <= VACUOUS_IDENTITY_EPSILON;\n const rightVacuous = 1 - right.u <= VACUOUS_IDENTITY_EPSILON;\n if (leftVacuous && !rightVacuous) {\n return right.a;\n }\n if (rightVacuous && !leftVacuous) {\n return left.a;\n }\n if (Math.abs(left.a - right.a) <= VACUOUS_IDENTITY_EPSILON) {\n return left.a;\n }\n return (left.a + right.a) / 2;\n}\n\nexport function cumulativeFusion(left: SLOpinion, right: SLOpinion): SLOpinion {\n const a = fusedBaseRate(left, right);\n\n // F2: a vacuous operand is the identity element of cumulative fusion. Return\n // the other operand verbatim (including its base rate) so fusion with the\n // vacuous opinion is a true no-op regardless of differing priors.\n if (1 - left.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(right.b, right.d, right.u, a);\n }\n if (1 - right.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(left.b, left.d, left.u, a);\n }\n\n // F4: dogmatic pair handled via the ε-limit of the cumulative rule rather than\n // the standalone `(b+d)/2` shortcut. As both uncertainties shrink at the same\n // rate, the cumulative formula's `(b_L·u_R + b_R·u_L)/k` term converges to the\n // arithmetic mean of the masses; deriving it from the same limit the interior\n // formula uses keeps mass-associativity intact (no special-case discontinuity).\n if (\n left.u <= VACUOUS_IDENTITY_EPSILON &&\n right.u <= VACUOUS_IDENTITY_EPSILON\n ) {\n return opinion((left.b + right.b) / 2, (left.d + right.d) / 2, 0, a);\n }\n\n const k = left.u + right.u - left.u * right.u;\n if (k === 0) {\n return vacuous(a);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (left.u * right.u) / k,\n a\n );\n}\n\nexport function averagingFusion(left: SLOpinion, right: SLOpinion): SLOpinion {\n const a = fusedBaseRate(left, right);\n\n // F2: vacuous identity, mirroring cumulativeFusion.\n if (1 - left.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(right.b, right.d, right.u, a);\n }\n if (1 - right.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(left.b, left.d, left.u, a);\n }\n\n // F4: dogmatic pair via the ε-limit of the averaging rule.\n if (\n left.u <= VACUOUS_IDENTITY_EPSILON &&\n right.u <= VACUOUS_IDENTITY_EPSILON\n ) {\n return opinion((left.b + right.b) / 2, (left.d + right.d) / 2, 0, a);\n }\n\n const k = left.u + right.u;\n if (k === 0) {\n return vacuous(a);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (2 * left.u * right.u) / k,\n a\n );\n}\n\nexport function trustDiscount(\n sourceOpinion: SLOpinion,\n trust: number\n): SLOpinion {\n const weight = Math.max(0, Math.min(1, Math.abs(trust)));\n return opinion(\n weight * sourceOpinion.b,\n weight * sourceOpinion.d,\n 1 - weight * (sourceOpinion.b + sourceOpinion.d),\n sourceOpinion.a\n );\n}\n\nconst EPSILON = 1e-9;\n\nfunction childBaseRateFallback(\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate: number | undefined\n): number {\n if (fallbackBaseRate !== undefined) {\n return Math.max(0, Math.min(1, fallbackBaseRate));\n }\n\n if (Math.abs(ifTrue.a - ifFalse.a) <= EPSILON) {\n return ifTrue.a;\n }\n\n return (ifTrue.a + ifFalse.a) / 2;\n}\n\nfunction computeConditionalDeductionBaseRate(\n opinionA: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate: number\n): number {\n const denominator = 1 - opinionA.a * ifTrue.u - (1 - opinionA.a) * ifFalse.u;\n\n if (ifTrue.u + ifFalse.u < 2 - EPSILON && Math.abs(denominator) > EPSILON) {\n const baseRate =\n (opinionA.a * ifTrue.b + (1 - opinionA.a) * ifFalse.b) / denominator;\n if (baseRate >= -EPSILON && baseRate <= 1 + EPSILON) {\n return Math.max(0, Math.min(1, baseRate));\n }\n }\n\n return fallbackBaseRate;\n}\n\nfunction safeCorrectionTerm(\n numerator: number,\n denominator: number\n): number | undefined {\n if (Math.abs(denominator) <= EPSILON) {\n return;\n }\n\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n return;\n }\n\n return Math.max(0, value);\n}\n\ninterface ConditionalDeductionCorrectionContext {\n childBaseRate: number;\n ifFalse: SLOpinion;\n ifTrue: SLOpinion;\n intermediateBelief: number;\n intermediateDisbelief: number;\n opinionA: SLOpinion;\n projectedAntecedent: number;\n projectedAntecedentComplement: number;\n projectedConditionalA: number;\n projectedVacuousDeduction: number;\n}\n\nfunction correctionOrZero(numerator: number, denominator: number): number {\n return safeCorrectionTerm(numerator, denominator) ?? 0;\n}\n\nfunction hasNoConditionalDeductionCorrection(\n ifTrue: SLOpinion,\n ifFalse: SLOpinion\n): boolean {\n return (\n (ifTrue.b > ifFalse.b && ifTrue.d > ifFalse.d) ||\n (ifTrue.b <= ifFalse.b && ifTrue.d <= ifFalse.d)\n );\n}\n\nfunction usesLowerVacuousBranch(\n context: ConditionalDeductionCorrectionContext\n): boolean {\n return context.projectedVacuousDeduction <= context.projectedConditionalA;\n}\n\nfunction usesLowerAntecedentBranch(\n context: ConditionalDeductionCorrectionContext\n): boolean {\n return context.projectedAntecedent <= context.opinionA.a;\n}\n\nfunction computeTrueDominantDeductionCorrection(\n context: ConditionalDeductionCorrectionContext\n): number {\n const beliefGap = context.ifTrue.b - context.ifFalse.b;\n const disbeliefGap = context.ifFalse.d - context.ifTrue.d;\n const lowerVacuous = usesLowerVacuousBranch(context);\n const lowerAntecedent = usesLowerAntecedentBranch(context);\n\n if (lowerVacuous && lowerAntecedent) {\n return correctionOrZero(\n context.opinionA.a *\n context.opinionA.u *\n (context.intermediateBelief - context.ifTrue.b),\n context.projectedAntecedent * context.childBaseRate\n );\n }\n\n if (lowerVacuous) {\n return correctionOrZero(\n context.opinionA.a *\n context.opinionA.u *\n (context.intermediateDisbelief - context.ifTrue.d) *\n beliefGap,\n context.projectedAntecedentComplement *\n context.childBaseRate *\n disbeliefGap\n );\n }\n\n if (lowerAntecedent) {\n return correctionOrZero(\n (1 - context.opinionA.a) *\n context.opinionA.u *\n (context.intermediateBelief - context.ifTrue.b) *\n disbeliefGap,\n context.projectedAntecedent * (1 - context.childBaseRate) * beliefGap\n );\n }\n\n return correctionOrZero(\n (1 - context.opinionA.a) *\n context.opinionA.u *\n (context.intermediateDisbelief - context.ifTrue.d),\n context.projectedAntecedentComplement * (1 - context.childBaseRate)\n );\n}\n\nfunction computeFalseDominantDeductionCorrection(\n context: ConditionalDeductionCorrectionContext\n): number {\n const beliefGap = context.ifFalse.b - context.ifTrue.b;\n const disbeliefGap = context.ifTrue.d - context.ifFalse.d;\n const lowerVacuous = usesLowerVacuousBranch(context);\n const lowerAntecedent = usesLowerAntecedentBranch(context);\n\n if (lowerVacuous && lowerAntecedent) {\n return correctionOrZero(\n (1 - context.opinionA.a) *\n context.opinionA.u *\n (context.intermediateDisbelief - context.ifTrue.d) *\n beliefGap,\n context.projectedAntecedent * context.childBaseRate * disbeliefGap\n );\n }\n\n if (lowerVacuous) {\n return correctionOrZero(\n (1 - context.opinionA.a) *\n context.opinionA.u *\n (context.intermediateBelief - context.ifTrue.b),\n context.projectedAntecedentComplement * context.childBaseRate\n );\n }\n\n if (lowerAntecedent) {\n return correctionOrZero(\n context.opinionA.a *\n context.opinionA.u *\n (context.intermediateDisbelief - context.ifTrue.d),\n context.projectedAntecedent * (1 - context.childBaseRate)\n );\n }\n\n return correctionOrZero(\n context.opinionA.a *\n context.opinionA.u *\n (context.intermediateBelief - context.ifTrue.b) *\n disbeliefGap,\n context.projectedAntecedentComplement *\n (1 - context.childBaseRate) *\n beliefGap\n );\n}\n\nfunction computeConditionalDeductionCorrection(\n context: ConditionalDeductionCorrectionContext\n): number {\n if (hasNoConditionalDeductionCorrection(context.ifTrue, context.ifFalse)) {\n return 0;\n }\n\n if (\n context.ifTrue.b > context.ifFalse.b &&\n context.ifTrue.d <= context.ifFalse.d\n ) {\n return computeTrueDominantDeductionCorrection(context);\n }\n\n return computeFalseDominantDeductionCorrection(context);\n}\n\nexport function conditionalDeduction(\n opinionA: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate?: number\n): SLOpinion {\n const fallbackChildBaseRate = childBaseRateFallback(\n ifTrue,\n ifFalse,\n fallbackBaseRate\n );\n const childBaseRate = computeConditionalDeductionBaseRate(\n opinionA,\n ifTrue,\n ifFalse,\n fallbackChildBaseRate\n );\n const projectedAntecedent = project(opinionA);\n const projectedAntecedentComplement = 1 - projectedAntecedent;\n const intermediateBelief =\n opinionA.b * ifTrue.b +\n opinionA.d * ifFalse.b +\n opinionA.u * (ifTrue.b * opinionA.a + ifFalse.b * (1 - opinionA.a));\n const intermediateDisbelief =\n opinionA.b * ifTrue.d +\n opinionA.d * ifFalse.d +\n opinionA.u * (ifTrue.d * opinionA.a + ifFalse.d * (1 - opinionA.a));\n const intermediateUncertainty =\n opinionA.b * ifTrue.u +\n opinionA.d * ifFalse.u +\n opinionA.u * (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedVacuousDeduction =\n ifTrue.b * opinionA.a +\n ifFalse.b * (1 - opinionA.a) +\n childBaseRate * (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedConditionalA =\n ifTrue.b + childBaseRate * (1 - ifTrue.b - ifTrue.d);\n const correction = computeConditionalDeductionCorrection({\n childBaseRate,\n ifFalse,\n ifTrue,\n intermediateBelief,\n intermediateDisbelief,\n opinionA,\n projectedAntecedent,\n projectedAntecedentComplement,\n projectedConditionalA,\n projectedVacuousDeduction,\n });\n\n return opinion(\n intermediateBelief - childBaseRate * correction,\n intermediateDisbelief - (1 - childBaseRate) * correction,\n intermediateUncertainty + correction,\n childBaseRate\n );\n}\n\n/**\n * Abductive inference over a conditional.\n * Given an opinion on Y and conditionals P(Y|X), P(Y|~X), infer an opinion on X.\n */\nexport function conditionalAbduction(\n opinionY: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n baseRateX: number\n): SLOpinion {\n const priorX = Math.max(0, Math.min(1, baseRateX));\n const probabilityY = project(opinionY);\n const probabilityGivenTrue = project(ifTrue);\n const probabilityGivenFalse = project(ifFalse);\n\n const posteriorIfYDenominator =\n probabilityGivenTrue * priorX + probabilityGivenFalse * (1 - priorX);\n const posteriorIfY =\n posteriorIfYDenominator === 0\n ? priorX\n : (probabilityGivenTrue * priorX) / posteriorIfYDenominator;\n\n const posteriorIfNotYDenominator =\n (1 - probabilityGivenTrue) * priorX +\n (1 - probabilityGivenFalse) * (1 - priorX);\n const posteriorIfNotY =\n posteriorIfNotYDenominator === 0\n ? priorX\n : ((1 - probabilityGivenTrue) * priorX) / posteriorIfNotYDenominator;\n\n const projectedX =\n probabilityY * posteriorIfY + (1 - probabilityY) * posteriorIfNotY;\n const uncertainty = Math.max(\n opinionY.u * 0.5,\n probabilityY * ifTrue.u + (1 - probabilityY) * ifFalse.u\n );\n\n return opinion(\n projectedX * (1 - uncertainty),\n (1 - projectedX) * (1 - uncertainty),\n uncertainty,\n priorX\n );\n}\n\nexport function negate(o: SLOpinion): SLOpinion {\n return mkOpinion(o.d, o.b, o.u, 1 - o.a);\n}\n\nexport function constraintFusion(\n left: SLOpinion,\n right: SLOpinion,\n mode: \"pressure\" | \"redistribute\" = \"pressure\"\n): { o1: SLOpinion; o2: SLOpinion } {\n if (mode === \"redistribute\") {\n const leftProjected = project(left);\n const rightProjected = project(right);\n const total = leftProjected + rightProjected;\n\n if (total <= 1) {\n return { o1: left, o2: right };\n }\n\n const scale = 1 / total;\n return {\n o1: opinion(\n left.b * scale,\n left.d + left.b * (1 - scale),\n left.u,\n left.a\n ),\n o2: opinion(\n right.b * scale,\n right.d + right.b * (1 - scale),\n right.u,\n right.a\n ),\n };\n }\n\n const pressureLeft = right.b * 0.5;\n const pressureRight = left.b * 0.5;\n\n return {\n o1: opinion(\n left.b - pressureLeft * 0.3,\n left.d + pressureLeft * 0.3,\n left.u,\n left.a\n ),\n o2: opinion(\n right.b - pressureRight * 0.3,\n right.d + pressureRight * 0.3,\n right.u,\n right.a\n ),\n };\n}\n\nexport function evidenceBalance(o: SLOpinion): number {\n const total = o.b + o.d;\n if (total === 0) {\n return 0;\n }\n return (o.b - o.d) / total;\n}\n\nexport function areTensioned(left: SLOpinion, right: SLOpinion): boolean {\n return (\n project(left) > 0.5 &&\n project(right) > 0.5 &&\n (left.d > 0.2 || right.d > 0.2)\n );\n}\n\nexport function informationGain(o: SLOpinion): number {\n if (o.u === 0) {\n return 0;\n }\n if (o.u === 1) {\n return 1;\n }\n return o.u * (1 - Math.abs(o.b - o.d));\n}\n","import type { Opinion, PropagationMode, PropagationResult } from \"../../types\";\nimport { mkOpinion, opinion, project } from \"../subjectiveLogic\";\n\nexport function dampedDependencyOpinion(\n dependencyOpinion: Opinion,\n beliefOpinion: Opinion,\n mode: PropagationMode = \"continuous\",\n threshold = 0.3\n): Opinion {\n const dependencyProjection = project(\n mkOpinion(\n dependencyOpinion.b,\n dependencyOpinion.d,\n dependencyOpinion.u,\n dependencyOpinion.a\n )\n );\n\n if (mode === \"threshold\") {\n if (dependencyProjection < threshold) {\n return opinion(\n 0,\n beliefOpinion.d + beliefOpinion.b * 0.5,\n 0.5,\n beliefOpinion.a\n );\n }\n return beliefOpinion;\n }\n\n const dampingFactor = dependencyProjection ** 0.5;\n return opinion(\n beliefOpinion.b * dampingFactor,\n beliefOpinion.d + beliefOpinion.b * (1 - dampingFactor) * 0.3,\n beliefOpinion.u + beliefOpinion.b * (1 - dampingFactor) * 0.7,\n beliefOpinion.a\n );\n}\n\nexport function dampedDependencyCascade(\n dependencyOpinion: Opinion,\n beliefOpinion: Opinion,\n mode: PropagationMode = \"continuous\"\n): PropagationResult {\n return {\n opinion: dampedDependencyOpinion(dependencyOpinion, beliefOpinion, mode),\n operator: \"dependency_cascade\",\n rationale: `Damped dependency cascade (${mode}): prerequisite at ${project(\n mkOpinion(\n dependencyOpinion.b,\n dependencyOpinion.d,\n dependencyOpinion.u,\n dependencyOpinion.a\n )\n ).toFixed(2)}`,\n };\n}\n","import type { EdgeMetadata, Opinion, PropagationResult } from \"../../types\";\nimport {\n constraintFusion,\n cumulativeFusion,\n mkOpinion,\n negate,\n project,\n trustDiscount,\n} from \"../subjectiveLogic\";\n\nexport function applyNegativeSupport(\n source: Opinion,\n target: Opinion,\n weight: number,\n metadata: EdgeMetadata = {}\n): PropagationResult {\n const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);\n const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);\n if (metadata.constraint === \"xor\") {\n const result = constraintFusion(\n sourceOpinion,\n targetOpinion,\n metadata.normalization ?? \"pressure\"\n );\n return {\n opinion: result.o2,\n operator: \"constraint_fusion\",\n rationale: `XOR constraint: source belief at ${project(\n sourceOpinion\n ).toFixed(2)} pressures target`,\n };\n }\n\n const discounted = trustDiscount(negate(sourceOpinion), Math.abs(weight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Contradicting evidence (weight=${weight.toFixed(\n 2\n )}) from source at ${project(sourceOpinion).toFixed(2)}`,\n };\n}\n\nexport function applyNegativeEvidence(\n source: Opinion,\n target: Opinion,\n weight: number\n): PropagationResult {\n const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);\n const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);\n const discounted = trustDiscount(negate(sourceOpinion), Math.abs(weight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Contradicting evidence (weight=${weight.toFixed(2)})`,\n };\n}\n","import type {\n EdgeMetadata,\n Opinion,\n PropagationResult,\n SLOperator,\n} from \"../../types\";\nimport {\n conditionalDeduction,\n cumulativeFusion,\n mkOpinion,\n project,\n trustDiscount,\n} from \"../subjectiveLogic\";\nimport { dampedDependencyCascade } from \"./cascade\";\nimport { applyNegativeEvidence, applyNegativeSupport } from \"./defeat\";\n\ntype EdgeHandler = (\n source: Opinion,\n target: Opinion,\n weight: number,\n metadata: EdgeMetadata\n) => PropagationResult;\n\nexport type PropagationTraversalDirection = \"outgoing\" | \"incoming\";\n\ninterface EdgePropagationRule {\n direction: PropagationTraversalDirection;\n handler: EdgeHandler;\n}\n\nconst EDGE_PROPAGATION_RULES = {\n supports: {\n direction: \"outgoing\",\n handler: (source, target, weight, metadata) => {\n const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);\n const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);\n if (weight < 0) {\n return applyNegativeSupport(\n sourceOpinion,\n targetOpinion,\n weight,\n metadata\n );\n }\n\n const discounted = trustDiscount(sourceOpinion, weight);\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${weight.toFixed(\n 2\n )}) from source at ${project(sourceOpinion).toFixed(2)}`,\n };\n },\n },\n informs: {\n direction: \"outgoing\",\n handler: (source, target, weight) => {\n const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);\n const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);\n if (weight < 0) {\n return applyNegativeEvidence(sourceOpinion, targetOpinion, weight);\n }\n\n const discounted = trustDiscount(sourceOpinion, Math.abs(weight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${weight.toFixed(2)})`,\n };\n },\n },\n depends_on: {\n direction: \"incoming\",\n handler: (source, target, _weight, metadata) => {\n const sourceOpinion = mkOpinion(source.b, source.d, source.u, source.a);\n const targetOpinion = mkOpinion(target.b, target.d, target.u, target.a);\n if (metadata.conditionalA && metadata.conditionalNotA) {\n return {\n opinion: conditionalDeduction(\n sourceOpinion,\n mkOpinion(\n metadata.conditionalA.b,\n metadata.conditionalA.d,\n metadata.conditionalA.u,\n metadata.conditionalA.a\n ),\n mkOpinion(\n metadata.conditionalNotA.b,\n metadata.conditionalNotA.d,\n metadata.conditionalNotA.u,\n metadata.conditionalNotA.a\n ),\n targetOpinion.a\n ),\n operator: \"conditional_deduction\",\n rationale: `Conditional deduction: prerequisite at ${project(\n sourceOpinion\n ).toFixed(2)}`,\n };\n }\n\n return dampedDependencyCascade(\n sourceOpinion,\n targetOpinion,\n metadata.propagation ?? \"continuous\"\n );\n },\n },\n derived_from: {\n direction: \"incoming\",\n handler: (_source, target) => ({\n opinion: target,\n operator: \"trust_discount\",\n rationale: \"Provenance edge — no confidence propagation\",\n }),\n },\n contains: {\n direction: \"outgoing\",\n handler: (_source, target) => ({\n opinion: target,\n operator: \"trust_discount\",\n rationale: \"Containment edge — no confidence propagation\",\n }),\n },\n tests: {\n direction: \"outgoing\",\n handler: (_source, target) => ({\n opinion: target,\n operator: \"trust_discount\",\n rationale: \"Testing edge — no confidence propagation\",\n }),\n },\n} satisfies Record<string, EdgePropagationRule>;\n\nexport type PropagationEdgeType = keyof typeof EDGE_PROPAGATION_RULES;\n\nexport interface PropagationTraversalSpec {\n direction: PropagationTraversalDirection;\n edgeType: PropagationEdgeType;\n}\n\nexport const PROPAGATION_TRAVERSAL_SPECS: readonly PropagationTraversalSpec[] =\n Object.entries(EDGE_PROPAGATION_RULES).map(([edgeType, rule]) => ({\n edgeType: edgeType as PropagationEdgeType,\n direction: rule.direction,\n }));\n\nexport function isPropagationEdgeType(\n edgeType: string\n): edgeType is PropagationEdgeType {\n return edgeType in EDGE_PROPAGATION_RULES;\n}\n\nexport function getPropagationTraversalSpecs(): readonly PropagationTraversalSpec[] {\n return PROPAGATION_TRAVERSAL_SPECS;\n}\n\nexport function propagateThroughEdge(\n sourceOpinion: Opinion,\n targetOpinion: Opinion,\n edgeType: string,\n weight = 1,\n metadata: EdgeMetadata = {}\n): PropagationResult {\n const handler = isPropagationEdgeType(edgeType)\n ? EDGE_PROPAGATION_RULES[edgeType].handler\n : undefined;\n if (!handler) {\n return {\n opinion: targetOpinion,\n operator: \"no_op\",\n rationale: `Unknown edge type: ${edgeType} — no propagation`,\n };\n }\n return handler(sourceOpinion, targetOpinion, weight, metadata);\n}\n\nexport function propagateAllEdges(\n currentOpinion: Opinion,\n incomingEdges: Array<{\n sourceOpinion: Opinion;\n edgeType: string;\n weight: number;\n metadata: EdgeMetadata;\n }>\n): PropagationResult {\n let result = currentOpinion;\n const rationales: string[] = [];\n\n for (const edgeType of [\"depends_on\", \"informs\", \"supports\"]) {\n for (const incoming of incomingEdges.filter(\n (edge) => edge.edgeType === edgeType\n )) {\n const propagated = propagateThroughEdge(\n incoming.sourceOpinion,\n result,\n incoming.edgeType,\n incoming.weight,\n incoming.metadata\n );\n result = propagated.opinion;\n rationales.push(propagated.rationale);\n }\n }\n\n return {\n opinion: result,\n operator: \"cumulative_fusion\" as SLOperator,\n rationale: rationales.join(\"; \"),\n };\n}\n"]}
|
|
@@ -48,7 +48,9 @@ function normalizeBaseRateVector(baseRate, size) {
|
|
|
48
48
|
const normalized = baseRate.map((value) => clampNonNegative(value));
|
|
49
49
|
const total = normalized.reduce((sum, value) => sum + value, 0);
|
|
50
50
|
if (total === 0) {
|
|
51
|
-
throw new Error(
|
|
51
|
+
throw new Error(
|
|
52
|
+
"Base-rate vector must contain at least one positive value."
|
|
53
|
+
);
|
|
52
54
|
}
|
|
53
55
|
return normalized.map((value) => value / total);
|
|
54
56
|
}
|
|
@@ -72,11 +74,10 @@ function opinionFromDirichlet(alpha, nonInformativeWeight, baseRate) {
|
|
|
72
74
|
};
|
|
73
75
|
}
|
|
74
76
|
function opinionFromBeta(alpha, beta, nonInformativeWeight, baseRate) {
|
|
75
|
-
const dirichlet = opinionFromDirichlet(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
);
|
|
77
|
+
const dirichlet = opinionFromDirichlet([alpha, beta], nonInformativeWeight, [
|
|
78
|
+
clamp01(baseRate),
|
|
79
|
+
1 - clamp01(baseRate)
|
|
80
|
+
]);
|
|
80
81
|
return mkOpinion(
|
|
81
82
|
dirichlet.b[0] ?? 0,
|
|
82
83
|
dirichlet.b[1] ?? 0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/v1/operations/subjectiveLogic/index.ts","../../../../src/v1/operations/bridge/index.ts","../../../../src/v1/operations/dynamics/revision.ts"],"names":["clamp01"],"mappings":";AAEO,SAAS,OAAA,CACd,MAAA,EACA,SAAA,EACA,WAAA,EACA,QAAA,EACW;AACX,EAAA,MAAM,CAAA,GAAI,OAAO,QAAA,CAAS,MAAM,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAM,CAAA,GAAI,CAAA;AAC1D,EAAA,MAAM,CAAA,GAAI,OAAO,QAAA,CAAS,SAAS,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,SAAS,CAAA,GAAI,CAAA;AAChE,EAAA,MAAM,CAAA,GAAI,OAAO,QAAA,CAAS,WAAW,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,WAAW,CAAA,GAAI,CAAA;AACpE,EAAA,MAAM,CAAA,GAAI,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,CAAC,CAAA;AAC3C,EAAA,MAAM,GAAA,GAAM,IAAI,CAAA,GAAI,CAAA;AAEpB,EAAA,IAAI,QAAQ,CAAA,EAAG;AACb,IAAA,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAE;AAAA,EAC/B;AAEA,EAAA,OAAO;AAAA,IACL,GAAG,CAAA,GAAI,GAAA;AAAA,IACP,GAAG,CAAA,GAAI,GAAA;AAAA,IACP,GAAG,CAAA,GAAI,GAAA;AAAA,IACP;AAAA,GACF;AACF;AAEO,SAAS,SAAA,CACd,MAAA,EACA,SAAA,EACA,WAAA,EACA,QAAA,EACW;AACX,EAAA,OAAO,OAAA,CAAQ,MAAA,EAAQ,SAAA,EAAW,WAAA,EAAa,QAAQ,CAAA;AACzD;AAWO,SAAS,QAAQ,CAAA,EAAsB;AAC5C,EAAA,OAAO,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA;AACvB;;;AC3CO,IAAM,8BAAA,GAAiC,CAAA;AAE9C,SAAS,QAAQ,KAAA,EAAuB;AACtC,EAAA,OAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,CAAC,CAAA;AACvC;AAEA,SAAS,iBAAiB,KAAA,EAAuB;AAC/C,EAAA,OAAO,MAAA,CAAO,SAAS,KAAK,CAAA,GAAI,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,CAAA,GAAI,CAAA;AACvD;AAEA,SAAS,8BAA8B,MAAA,EAAyB;AAC9D,EAAA,IAAI,WAAW,MAAA,EAAW;AACxB,IAAA,OAAO,8BAAA;AAAA,EACT;AACA,EAAA,OAAO,MAAA,CAAO,SAAS,MAAM,CAAA,GACzB,KAAK,GAAA,CAAI,CAAA,EAAG,MAAM,CAAA,GAClB,8BAAA;AACN;AAEA,SAAS,uBAAA,CACP,UACA,IAAA,EACU;AACV,EAAA,IAAI,SAAS,CAAA,EAAG;AACd,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,IAAI,QAAA,CAAS,WAAW,IAAA,EAAM;AAC5B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,wBAAA,EAA2B,QAAA,CAAS,MAAM,CAAA,mCAAA,EAAsC,IAAI,CAAA,CAAA;AAAA,KACtF;AAAA,EACF;AAEA,EAAA,MAAM,aAAa,QAAA,CAAS,GAAA,CAAI,CAAC,KAAA,KAAU,gBAAA,CAAiB,KAAK,CAAC,CAAA;AAClE,EAAA,MAAM,KAAA,GAAQ,WAAW,MAAA,CAAO,CAAC,KAAK,KAAA,KAAU,GAAA,GAAM,OAAO,CAAC,CAAA;AAE9D,EAAA,IAAI,UAAU,CAAA,EAAG;AACf,IAAA,MAAM,IAAI,MAAM,4DAA4D,CAAA;AAAA,EAC9E;AAEA,EAAA,OAAO,UAAA,CAAW,GAAA,CAAI,CAAC,KAAA,KAAU,QAAQ,KAAK,CAAA;AAChD;AAEO,SAAS,oBAAA,CACd,KAAA,EACA,oBAAA,EACA,QAAA,EACkB;AAClB,EAAA,MAAM,WAAW,KAAA,CAAM,GAAA,CAAI,CAAC,KAAA,KAAU,gBAAA,CAAiB,KAAK,CAAC,CAAA;AAC7D,EAAA,MAAM,UAAA,GAAa,8BAA8B,oBAAoB,CAAA;AACrE,EAAA,MAAM,kBAAA,GAAqB,uBAAA,CAAwB,QAAA,EAAU,QAAA,CAAS,MAAM,CAAA;AAC5E,EAAA,MAAM,aAAA,GAAgB,SAAS,MAAA,CAAO,CAAC,KAAK,KAAA,KAAU,GAAA,GAAM,OAAO,CAAC,CAAA;AACpE,EAAA,MAAM,cAAc,aAAA,GAAgB,UAAA;AAEpC,EAAA,IAAI,gBAAgB,CAAA,EAAG;AACrB,IAAA,OAAO;AAAA,MACL,CAAA,EAAG,QAAA,CAAS,GAAA,CAAI,MAAM,CAAC,CAAA;AAAA,MACvB,CAAA,EAAG,CAAA;AAAA,MACH,CAAA,EAAG;AAAA,KACL;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,GAAG,QAAA,CAAS,GAAA,CAAI,CAAC,KAAA,KAAU,QAAQ,WAAW,CAAA;AAAA,IAC9C,GAAG,UAAA,GAAa,WAAA;AAAA,IAChB,CAAA,EAAG;AAAA,GACL;AACF;AAQO,SAAS,eAAA,CACd,KAAA,EACA,IAAA,EACA,oBAAA,EACA,QAAA,EACW;AACX,EAAA,MAAM,SAAA,GAAY,oBAAA;AAAA,IAChB,CAAC,OAAO,IAAI,CAAA;AAAA,IACZ,oBAAA;AAAA,IACA,CAAC,OAAA,CAAQ,QAAQ,GAAG,CAAA,GAAI,OAAA,CAAQ,QAAQ,CAAC;AAAA,GAC3C;AAEA,EAAA,OAAO,SAAA;AAAA,IACL,SAAA,CAAU,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA;AAAA,IAClB,SAAA,CAAU,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA;AAAA,IAClB,SAAA,CAAU,CAAA;AAAA,IACV,SAAA,CAAU,CAAA,CAAE,CAAC,CAAA,IAAK,QAAQ,QAAQ;AAAA,GACpC;AACF;;;ACzFA,SAASA,SAAQ,KAAA,EAAuB;AACtC,EAAA,OAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,CAAC,CAAA;AACvC;AAEA,SAAS,UAAA,CAAW,aAAqB,MAAA,EAGvC;AACA,EAAA,MAAM,eAAA,GAAkBA,SAAQ,WAAW,CAAA;AAC3C,EAAA,MAAM,UAAA,GAAa,OAAO,QAAA,CAAS,MAAM,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAM,CAAA,GAAI,CAAA;AAEnE,EAAA,OAAO;AAAA,IACL,OAAO,eAAA,GAAkB,UAAA;AAAA,IACzB,IAAA,EAAA,CAAO,IAAI,eAAA,IAAmB;AAAA,GAChC;AACF;AAEO,SAAS,cAAA,CACd,eAAA,EACA,WAAA,EACA,aAAA,EACA,WACA,OAAA,EAIQ;AACR,EAAA,OAAO,gBAAA,CAAiB;AAAA,IACtB,eAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAU,OAAA,EAAS,QAAA;AAAA,IACnB,sBAAsB,OAAA,EAAS;AAAA,GAChC,CAAA;AACH;AAEO,SAAS,iBAAiB,IAAA,EAOtB;AACT,EAAA,OAAO,OAAA,CAAQ,uBAAA,CAAwB,IAAI,CAAC,CAAA;AAC9C;AAEO,SAAS,wBAAwB,IAAA,EAO1B;AACZ,EAAA,MAAM,aAAA,GAAgB,UAAA,CAAW,IAAA,CAAK,eAAA,EAAiB,KAAK,WAAW,CAAA;AACvE,EAAA,MAAM,cAAc,UAAA,CAAW,IAAA,CAAK,aAAA,EAAe,IAAA,CAAK,aAAa,CAAC,CAAA;AAEtE,EAAA,OAAO,eAAA;AAAA,IACL,aAAA,CAAc,QAAQ,WAAA,CAAY,KAAA;AAAA,IAClC,aAAA,CAAc,OAAO,WAAA,CAAY,IAAA;AAAA,IACjC,KAAK,oBAAA,IAAwB,8BAAA;AAAA,IAC7B,IAAA,CAAK;AAAA,GACP;AACF","file":"revision.js","sourcesContent":["import type { SLOpinion } from \"../../types\";\n\nexport function opinion(\n belief: number,\n disbelief: number,\n uncertainty: number,\n baseRate: number\n): SLOpinion {\n const b = Number.isFinite(belief) ? Math.max(0, belief) : 0;\n const d = Number.isFinite(disbelief) ? Math.max(0, disbelief) : 0;\n const u = Number.isFinite(uncertainty) ? Math.max(0, uncertainty) : 0;\n const a = Math.max(0, Math.min(1, baseRate));\n const sum = b + d + u;\n\n if (sum === 0) {\n return { b: 0, d: 0, u: 1, a } as SLOpinion;\n }\n\n return {\n b: b / sum,\n d: d / sum,\n u: u / sum,\n a,\n } as SLOpinion;\n}\n\nexport function mkOpinion(\n belief: number,\n disbelief: number,\n uncertainty: number,\n baseRate: number\n): SLOpinion {\n return opinion(belief, disbelief, uncertainty, baseRate);\n}\n\nexport function vacuous(baseRate: number): SLOpinion {\n return mkOpinion(0, 0, 1, baseRate);\n}\n\nexport function dogmatic(probability: number, baseRate: number): SLOpinion {\n const p = Math.max(0, Math.min(1, probability));\n return mkOpinion(p, 1 - p, 0, baseRate);\n}\n\nexport function project(o: SLOpinion): number {\n return o.b + o.a * o.u;\n}\n\nexport function confidenceLevel(o: SLOpinion): \"high\" | \"medium\" | \"low\" {\n const projected = project(o);\n if (o.u > 0.5) {\n return \"low\";\n }\n if (projected >= 0.8 && o.u < 0.2) {\n return \"high\";\n }\n if (projected >= 0.6) {\n return \"medium\";\n }\n return \"low\";\n}\n\nconst VACUOUS_IDENTITY_EPSILON = 1e-12;\n\n/**\n * Associative, vacuous-identity-preserving base rate for a fused opinion.\n *\n * The legacy `(left.a + right.a) / 2` arithmetic mean was the shared root of\n * RR.7 F1 (projected-confidence non-associativity) and F2 (a vacuous opinion of\n * a different base rate was not a fusion identity): averaging always pulled the\n * fused base rate toward the other operand even when that operand carried no\n * evidence. Subjective Logic requires every opinion over the same frame to share\n * one canonical base rate, so a correct fusion never *invents* a new base rate\n * from the operands' priors. We therefore:\n *\n * - return the informative operand's base rate when exactly one operand is\n * vacuous (the vacuous operand contributes no prior), making `vacuous(a)` a\n * true identity for any `a`; and\n * - require equal base rates otherwise (the canonical-frame contract). When\n * they coincide the result is that shared value — trivially associative.\n *\n * If two informative opinions carry genuinely different base rates they are not\n * opinions over the same frame and must be reconciled before fusion; we fall\n * back to the arithmetic mean ONLY in that ill-posed case to stay total, and the\n * property suite documents that this path is outside the order-independence\n * guarantee.\n */\nfunction fusedBaseRate(left: SLOpinion, right: SLOpinion): number {\n const leftVacuous = 1 - left.u <= VACUOUS_IDENTITY_EPSILON;\n const rightVacuous = 1 - right.u <= VACUOUS_IDENTITY_EPSILON;\n if (leftVacuous && !rightVacuous) {\n return right.a;\n }\n if (rightVacuous && !leftVacuous) {\n return left.a;\n }\n if (Math.abs(left.a - right.a) <= VACUOUS_IDENTITY_EPSILON) {\n return left.a;\n }\n return (left.a + right.a) / 2;\n}\n\nexport function cumulativeFusion(left: SLOpinion, right: SLOpinion): SLOpinion {\n const a = fusedBaseRate(left, right);\n\n // F2: a vacuous operand is the identity element of cumulative fusion. Return\n // the other operand verbatim (including its base rate) so fusion with the\n // vacuous opinion is a true no-op regardless of differing priors.\n if (1 - left.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(right.b, right.d, right.u, a);\n }\n if (1 - right.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(left.b, left.d, left.u, a);\n }\n\n // F4: dogmatic pair handled via the ε-limit of the cumulative rule rather than\n // the standalone `(b+d)/2` shortcut. As both uncertainties shrink at the same\n // rate, the cumulative formula's `(b_L·u_R + b_R·u_L)/k` term converges to the\n // arithmetic mean of the masses; deriving it from the same limit the interior\n // formula uses keeps mass-associativity intact (no special-case discontinuity).\n if (left.u <= VACUOUS_IDENTITY_EPSILON && right.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion((left.b + right.b) / 2, (left.d + right.d) / 2, 0, a);\n }\n\n const k = left.u + right.u - left.u * right.u;\n if (k === 0) {\n return vacuous(a);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (left.u * right.u) / k,\n a\n );\n}\n\nexport function averagingFusion(left: SLOpinion, right: SLOpinion): SLOpinion {\n const a = fusedBaseRate(left, right);\n\n // F2: vacuous identity, mirroring cumulativeFusion.\n if (1 - left.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(right.b, right.d, right.u, a);\n }\n if (1 - right.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(left.b, left.d, left.u, a);\n }\n\n // F4: dogmatic pair via the ε-limit of the averaging rule.\n if (left.u <= VACUOUS_IDENTITY_EPSILON && right.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion((left.b + right.b) / 2, (left.d + right.d) / 2, 0, a);\n }\n\n const k = left.u + right.u;\n if (k === 0) {\n return vacuous(a);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (2 * left.u * right.u) / k,\n a\n );\n}\n\nexport function trustDiscount(sourceOpinion: SLOpinion, trust: number): SLOpinion {\n const weight = Math.max(0, Math.min(1, Math.abs(trust)));\n return opinion(\n weight * sourceOpinion.b,\n weight * sourceOpinion.d,\n 1 - weight * (sourceOpinion.b + sourceOpinion.d),\n sourceOpinion.a\n );\n}\n\nconst EPSILON = 1e-9;\n\nfunction childBaseRateFallback(\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate: number | undefined\n): number {\n if (fallbackBaseRate !== undefined) {\n return Math.max(0, Math.min(1, fallbackBaseRate));\n }\n\n if (Math.abs(ifTrue.a - ifFalse.a) <= EPSILON) {\n return ifTrue.a;\n }\n\n return (ifTrue.a + ifFalse.a) / 2;\n}\n\nfunction computeConditionalDeductionBaseRate(\n opinionA: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate: number\n): number {\n const denominator =\n 1 - opinionA.a * ifTrue.u - (1 - opinionA.a) * ifFalse.u;\n\n if (ifTrue.u + ifFalse.u < 2 - EPSILON && Math.abs(denominator) > EPSILON) {\n const baseRate =\n (opinionA.a * ifTrue.b + (1 - opinionA.a) * ifFalse.b) / denominator;\n if (baseRate >= -EPSILON && baseRate <= 1 + EPSILON) {\n return Math.max(0, Math.min(1, baseRate));\n }\n }\n\n return fallbackBaseRate;\n}\n\nfunction safeCorrectionTerm(\n numerator: number,\n denominator: number\n): number | undefined {\n if (Math.abs(denominator) <= EPSILON) {\n return undefined;\n }\n\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n return undefined;\n }\n\n return Math.max(0, value);\n}\n\nexport function conditionalDeduction(\n opinionA: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate?: number\n): SLOpinion {\n const fallbackChildBaseRate = childBaseRateFallback(\n ifTrue,\n ifFalse,\n fallbackBaseRate\n );\n const childBaseRate = computeConditionalDeductionBaseRate(\n opinionA,\n ifTrue,\n ifFalse,\n fallbackChildBaseRate\n );\n const projectedAntecedent = project(opinionA);\n const projectedAntecedentComplement = 1 - projectedAntecedent;\n const intermediateBelief =\n opinionA.b * ifTrue.b +\n opinionA.d * ifFalse.b +\n opinionA.u * (ifTrue.b * opinionA.a + ifFalse.b * (1 - opinionA.a));\n const intermediateDisbelief =\n opinionA.b * ifTrue.d +\n opinionA.d * ifFalse.d +\n opinionA.u * (ifTrue.d * opinionA.a + ifFalse.d * (1 - opinionA.a));\n const intermediateUncertainty =\n opinionA.b * ifTrue.u +\n opinionA.d * ifFalse.u +\n opinionA.u * (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedVacuousDeduction =\n ifTrue.b * opinionA.a +\n ifFalse.b * (1 - opinionA.a) +\n childBaseRate *\n (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedConditionalA =\n ifTrue.b + childBaseRate * (1 - ifTrue.b - ifTrue.d);\n let correction = 0;\n\n if (\n (ifTrue.b > ifFalse.b && ifTrue.d > ifFalse.d) ||\n (ifTrue.b <= ifFalse.b && ifTrue.d <= ifFalse.d)\n ) {\n correction = 0;\n } else if (ifTrue.b > ifFalse.b && ifTrue.d <= ifFalse.d) {\n const beliefGap = ifTrue.b - ifFalse.b;\n const disbeliefGap = ifFalse.d - ifTrue.d;\n\n if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateBelief - ifTrue.b),\n projectedAntecedent * childBaseRate\n ) ?? 0;\n } else if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent > opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d) * beliefGap,\n projectedAntecedentComplement * childBaseRate * disbeliefGap\n ) ?? 0;\n } else if (\n projectedVacuousDeduction > projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) *\n opinionA.u *\n (intermediateBelief - ifTrue.b) *\n disbeliefGap,\n projectedAntecedent * (1 - childBaseRate) * beliefGap\n ) ?? 0;\n } else {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) * opinionA.u * (intermediateDisbelief - ifTrue.d),\n projectedAntecedentComplement * (1 - childBaseRate)\n ) ?? 0;\n }\n } else {\n const beliefGap = ifFalse.b - ifTrue.b;\n const disbeliefGap = ifTrue.d - ifFalse.d;\n\n if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) *\n opinionA.u *\n (intermediateDisbelief - ifTrue.d) *\n beliefGap,\n projectedAntecedent * childBaseRate * disbeliefGap\n ) ?? 0;\n } else if (\n projectedVacuousDeduction <= projectedConditionalA &&\n projectedAntecedent > opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n (1 - opinionA.a) * opinionA.u * (intermediateBelief - ifTrue.b),\n projectedAntecedentComplement * childBaseRate\n ) ?? 0;\n } else if (\n projectedVacuousDeduction > projectedConditionalA &&\n projectedAntecedent <= opinionA.a\n ) {\n correction =\n safeCorrectionTerm(\n opinionA.a * opinionA.u * (intermediateDisbelief - ifTrue.d),\n projectedAntecedent * (1 - childBaseRate)\n ) ?? 0;\n } else {\n correction =\n safeCorrectionTerm(\n opinionA.a *\n opinionA.u *\n (intermediateBelief - ifTrue.b) *\n disbeliefGap,\n projectedAntecedentComplement * (1 - childBaseRate) * beliefGap\n ) ?? 0;\n }\n }\n\n return opinion(\n intermediateBelief - childBaseRate * correction,\n intermediateDisbelief - (1 - childBaseRate) * correction,\n intermediateUncertainty + correction,\n childBaseRate\n );\n}\n\n/**\n * Abductive inference over a conditional.\n * Given an opinion on Y and conditionals P(Y|X), P(Y|~X), infer an opinion on X.\n */\nexport function conditionalAbduction(\n opinionY: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n baseRateX: number\n): SLOpinion {\n const priorX = Math.max(0, Math.min(1, baseRateX));\n const probabilityY = project(opinionY);\n const probabilityGivenTrue = project(ifTrue);\n const probabilityGivenFalse = project(ifFalse);\n\n const posteriorIfYDenominator =\n probabilityGivenTrue * priorX +\n probabilityGivenFalse * (1 - priorX);\n const posteriorIfY =\n posteriorIfYDenominator === 0\n ? priorX\n : (probabilityGivenTrue * priorX) / posteriorIfYDenominator;\n\n const posteriorIfNotYDenominator =\n (1 - probabilityGivenTrue) * priorX +\n (1 - probabilityGivenFalse) * (1 - priorX);\n const posteriorIfNotY =\n posteriorIfNotYDenominator === 0\n ? priorX\n : ((1 - probabilityGivenTrue) * priorX) / posteriorIfNotYDenominator;\n\n const projectedX =\n probabilityY * posteriorIfY + (1 - probabilityY) * posteriorIfNotY;\n const uncertainty = Math.max(\n opinionY.u * 0.5,\n probabilityY * ifTrue.u + (1 - probabilityY) * ifFalse.u\n );\n\n return opinion(\n projectedX * (1 - uncertainty),\n (1 - projectedX) * (1 - uncertainty),\n uncertainty,\n priorX\n );\n}\n\nexport function negate(o: SLOpinion): SLOpinion {\n return mkOpinion(o.d, o.b, o.u, 1 - o.a);\n}\n\nexport function constraintFusion(\n left: SLOpinion,\n right: SLOpinion,\n mode: \"pressure\" | \"redistribute\" = \"pressure\"\n): { o1: SLOpinion; o2: SLOpinion } {\n if (mode === \"redistribute\") {\n const leftProjected = project(left);\n const rightProjected = project(right);\n const total = leftProjected + rightProjected;\n\n if (total <= 1) {\n return { o1: left, o2: right };\n }\n\n const scale = 1 / total;\n return {\n o1: opinion(\n left.b * scale,\n left.d + left.b * (1 - scale),\n left.u,\n left.a\n ),\n o2: opinion(\n right.b * scale,\n right.d + right.b * (1 - scale),\n right.u,\n right.a\n ),\n };\n }\n\n const pressureLeft = right.b * 0.5;\n const pressureRight = left.b * 0.5;\n\n return {\n o1: opinion(\n left.b - pressureLeft * 0.3,\n left.d + pressureLeft * 0.3,\n left.u,\n left.a\n ),\n o2: opinion(\n right.b - pressureRight * 0.3,\n right.d + pressureRight * 0.3,\n right.u,\n right.a\n ),\n };\n}\n\nexport function evidenceBalance(o: SLOpinion): number {\n const total = o.b + o.d;\n if (total === 0) {\n return 0;\n }\n return (o.b - o.d) / total;\n}\n\nexport function areTensioned(left: SLOpinion, right: SLOpinion): boolean {\n return (\n project(left) > 0.5 &&\n project(right) > 0.5 &&\n (left.d > 0.2 || right.d > 0.2)\n );\n}\n\nexport function informationGain(o: SLOpinion): number {\n if (o.u === 0) {\n return 0;\n }\n if (o.u === 1) {\n return 1;\n }\n return o.u * (1 - Math.abs(o.b - o.d));\n}\n","import type { DirichletOpinion, Opinion, SLOpinion } from \"../../types\";\nimport { mkOpinion } from \"../subjectiveLogic\";\n\nexport const DEFAULT_NON_INFORMATIVE_WEIGHT = 2;\n\nfunction clamp01(value: number): number {\n return Math.max(0, Math.min(1, value));\n}\n\nfunction clampNonNegative(value: number): number {\n return Number.isFinite(value) ? Math.max(0, value) : 0;\n}\n\nfunction normalizeNonInformativeWeight(weight?: number): number {\n if (weight === undefined) {\n return DEFAULT_NON_INFORMATIVE_WEIGHT;\n }\n return Number.isFinite(weight)\n ? Math.max(0, weight)\n : DEFAULT_NON_INFORMATIVE_WEIGHT;\n}\n\nfunction normalizeBaseRateVector(\n baseRate: readonly number[],\n size: number\n): number[] {\n if (size === 0) {\n return [];\n }\n\n if (baseRate.length !== size) {\n throw new Error(\n `Base-rate vector length ${baseRate.length} must match evidence vector length ${size}.`\n );\n }\n\n const normalized = baseRate.map((value) => clampNonNegative(value));\n const total = normalized.reduce((sum, value) => sum + value, 0);\n\n if (total === 0) {\n throw new Error(\"Base-rate vector must contain at least one positive value.\");\n }\n\n return normalized.map((value) => value / total);\n}\n\nexport function opinionFromDirichlet(\n alpha: readonly number[],\n nonInformativeWeight: number,\n baseRate: readonly number[]\n): DirichletOpinion {\n const evidence = alpha.map((value) => clampNonNegative(value));\n const safeWeight = normalizeNonInformativeWeight(nonInformativeWeight);\n const normalizedBaseRate = normalizeBaseRateVector(baseRate, evidence.length);\n const totalEvidence = evidence.reduce((sum, value) => sum + value, 0);\n const denominator = totalEvidence + safeWeight;\n\n if (denominator === 0) {\n return {\n b: evidence.map(() => 0),\n u: 1,\n a: normalizedBaseRate,\n };\n }\n\n return {\n b: evidence.map((value) => value / denominator),\n u: safeWeight / denominator,\n a: normalizedBaseRate,\n };\n}\n\nexport function projectDirichletOpinion(opinion: DirichletOpinion): number[] {\n return opinion.b.map(\n (belief, index) => belief + (opinion.a[index] ?? 0) * opinion.u\n );\n}\n\nexport function opinionFromBeta(\n alpha: number,\n beta: number,\n nonInformativeWeight: number,\n baseRate: number\n): SLOpinion {\n const dirichlet = opinionFromDirichlet(\n [alpha, beta],\n nonInformativeWeight,\n [clamp01(baseRate), 1 - clamp01(baseRate)]\n );\n\n return mkOpinion(\n dirichlet.b[0] ?? 0,\n dirichlet.b[1] ?? 0,\n dirichlet.u,\n dirichlet.a[0] ?? clamp01(baseRate)\n );\n}\n\nexport function betaFromOpinion(\n opinion: Opinion,\n nonInformativeWeight: number = DEFAULT_NON_INFORMATIVE_WEIGHT\n): { alpha: number; beta: number } {\n if (opinion.u === 0) {\n return {\n alpha: Number.POSITIVE_INFINITY,\n beta: Number.POSITIVE_INFINITY,\n };\n }\n\n const safeWeight = normalizeNonInformativeWeight(nonInformativeWeight);\n const scale = safeWeight / opinion.u;\n\n return {\n alpha: opinion.b * scale,\n beta: opinion.d * scale,\n };\n}\n","import type { SLOpinion } from \"../../types\";\nimport {\n DEFAULT_NON_INFORMATIVE_WEIGHT,\n opinionFromBeta,\n} from \"../bridge\";\nimport { project } from \"../subjectiveLogic\";\n\nfunction clamp01(value: number): number {\n return Math.max(0, Math.min(1, value));\n}\n\nfunction toEvidence(probability: number, weight: number): {\n alpha: number;\n beta: number;\n} {\n const safeProbability = clamp01(probability);\n const safeWeight = Number.isFinite(weight) ? Math.max(0, weight) : 0;\n\n return {\n alpha: safeProbability * safeWeight,\n beta: (1 - safeProbability) * safeWeight,\n };\n}\n\nexport function bayesianUpdate(\n priorConfidence: number,\n priorWeight: number,\n newAssessment: number,\n newWeight: number,\n options: {\n baseRate: number;\n nonInformativeWeight?: number;\n }\n): number {\n return reviseConfidence({\n priorConfidence,\n priorWeight,\n newAssessment,\n newWeight,\n baseRate: options?.baseRate,\n nonInformativeWeight: options?.nonInformativeWeight,\n });\n}\n\nexport function reviseConfidence(args: {\n priorConfidence: number;\n priorWeight: number;\n newAssessment: number;\n newWeight?: number;\n baseRate: number;\n nonInformativeWeight?: number;\n}): number {\n return project(reviseConfidenceOpinion(args));\n}\n\nexport function reviseConfidenceOpinion(args: {\n priorConfidence: number;\n priorWeight: number;\n newAssessment: number;\n newWeight?: number;\n baseRate: number;\n nonInformativeWeight?: number;\n}): SLOpinion {\n const priorEvidence = toEvidence(args.priorConfidence, args.priorWeight);\n const newEvidence = toEvidence(args.newAssessment, args.newWeight ?? 1);\n\n return opinionFromBeta(\n priorEvidence.alpha + newEvidence.alpha,\n priorEvidence.beta + newEvidence.beta,\n args.nonInformativeWeight ?? DEFAULT_NON_INFORMATIVE_WEIGHT,\n args.baseRate\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/v1/operations/subjectiveLogic/index.ts","../../../../src/v1/operations/bridge/index.ts","../../../../src/v1/operations/dynamics/revision.ts"],"names":["clamp01"],"mappings":";AAEO,SAAS,OAAA,CACd,MAAA,EACA,SAAA,EACA,WAAA,EACA,QAAA,EACW;AACX,EAAA,MAAM,CAAA,GAAI,OAAO,QAAA,CAAS,MAAM,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAM,CAAA,GAAI,CAAA;AAC1D,EAAA,MAAM,CAAA,GAAI,OAAO,QAAA,CAAS,SAAS,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,SAAS,CAAA,GAAI,CAAA;AAChE,EAAA,MAAM,CAAA,GAAI,OAAO,QAAA,CAAS,WAAW,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,WAAW,CAAA,GAAI,CAAA;AACpE,EAAA,MAAM,CAAA,GAAI,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,CAAC,CAAA;AAC3C,EAAA,MAAM,GAAA,GAAM,IAAI,CAAA,GAAI,CAAA;AAEpB,EAAA,IAAI,QAAQ,CAAA,EAAG;AACb,IAAA,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAE;AAAA,EAC/B;AAEA,EAAA,OAAO;AAAA,IACL,GAAG,CAAA,GAAI,GAAA;AAAA,IACP,GAAG,CAAA,GAAI,GAAA;AAAA,IACP,GAAG,CAAA,GAAI,GAAA;AAAA,IACP;AAAA,GACF;AACF;AAEO,SAAS,SAAA,CACd,MAAA,EACA,SAAA,EACA,WAAA,EACA,QAAA,EACW;AACX,EAAA,OAAO,OAAA,CAAQ,MAAA,EAAQ,SAAA,EAAW,WAAA,EAAa,QAAQ,CAAA;AACzD;AAWO,SAAS,QAAQ,CAAA,EAAsB;AAC5C,EAAA,OAAO,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,CAAA;AACvB;;;AC3CO,IAAM,8BAAA,GAAiC,CAAA;AAE9C,SAAS,QAAQ,KAAA,EAAuB;AACtC,EAAA,OAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,CAAC,CAAA;AACvC;AAEA,SAAS,iBAAiB,KAAA,EAAuB;AAC/C,EAAA,OAAO,MAAA,CAAO,SAAS,KAAK,CAAA,GAAI,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,CAAA,GAAI,CAAA;AACvD;AAEA,SAAS,8BAA8B,MAAA,EAAyB;AAC9D,EAAA,IAAI,WAAW,MAAA,EAAW;AACxB,IAAA,OAAO,8BAAA;AAAA,EACT;AACA,EAAA,OAAO,MAAA,CAAO,SAAS,MAAM,CAAA,GACzB,KAAK,GAAA,CAAI,CAAA,EAAG,MAAM,CAAA,GAClB,8BAAA;AACN;AAEA,SAAS,uBAAA,CACP,UACA,IAAA,EACU;AACV,EAAA,IAAI,SAAS,CAAA,EAAG;AACd,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,IAAI,QAAA,CAAS,WAAW,IAAA,EAAM;AAC5B,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,wBAAA,EAA2B,QAAA,CAAS,MAAM,CAAA,mCAAA,EAAsC,IAAI,CAAA,CAAA;AAAA,KACtF;AAAA,EACF;AAEA,EAAA,MAAM,aAAa,QAAA,CAAS,GAAA,CAAI,CAAC,KAAA,KAAU,gBAAA,CAAiB,KAAK,CAAC,CAAA;AAClE,EAAA,MAAM,KAAA,GAAQ,WAAW,MAAA,CAAO,CAAC,KAAK,KAAA,KAAU,GAAA,GAAM,OAAO,CAAC,CAAA;AAE9D,EAAA,IAAI,UAAU,CAAA,EAAG;AACf,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO,UAAA,CAAW,GAAA,CAAI,CAAC,KAAA,KAAU,QAAQ,KAAK,CAAA;AAChD;AAEO,SAAS,oBAAA,CACd,KAAA,EACA,oBAAA,EACA,QAAA,EACkB;AAClB,EAAA,MAAM,WAAW,KAAA,CAAM,GAAA,CAAI,CAAC,KAAA,KAAU,gBAAA,CAAiB,KAAK,CAAC,CAAA;AAC7D,EAAA,MAAM,UAAA,GAAa,8BAA8B,oBAAoB,CAAA;AACrE,EAAA,MAAM,kBAAA,GAAqB,uBAAA,CAAwB,QAAA,EAAU,QAAA,CAAS,MAAM,CAAA;AAC5E,EAAA,MAAM,aAAA,GAAgB,SAAS,MAAA,CAAO,CAAC,KAAK,KAAA,KAAU,GAAA,GAAM,OAAO,CAAC,CAAA;AACpE,EAAA,MAAM,cAAc,aAAA,GAAgB,UAAA;AAEpC,EAAA,IAAI,gBAAgB,CAAA,EAAG;AACrB,IAAA,OAAO;AAAA,MACL,CAAA,EAAG,QAAA,CAAS,GAAA,CAAI,MAAM,CAAC,CAAA;AAAA,MACvB,CAAA,EAAG,CAAA;AAAA,MACH,CAAA,EAAG;AAAA,KACL;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,GAAG,QAAA,CAAS,GAAA,CAAI,CAAC,KAAA,KAAU,QAAQ,WAAW,CAAA;AAAA,IAC9C,GAAG,UAAA,GAAa,WAAA;AAAA,IAChB,CAAA,EAAG;AAAA,GACL;AACF;AAQO,SAAS,eAAA,CACd,KAAA,EACA,IAAA,EACA,oBAAA,EACA,QAAA,EACW;AACX,EAAA,MAAM,YAAY,oBAAA,CAAqB,CAAC,KAAA,EAAO,IAAI,GAAG,oBAAA,EAAsB;AAAA,IAC1E,QAAQ,QAAQ,CAAA;AAAA,IAChB,CAAA,GAAI,QAAQ,QAAQ;AAAA,GACrB,CAAA;AAED,EAAA,OAAO,SAAA;AAAA,IACL,SAAA,CAAU,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA;AAAA,IAClB,SAAA,CAAU,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA;AAAA,IAClB,SAAA,CAAU,CAAA;AAAA,IACV,SAAA,CAAU,CAAA,CAAE,CAAC,CAAA,IAAK,QAAQ,QAAQ;AAAA,GACpC;AACF;;;AC7FA,SAASA,SAAQ,KAAA,EAAuB;AACtC,EAAA,OAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,CAAC,CAAA;AACvC;AAEA,SAAS,UAAA,CACP,aACA,MAAA,EAIA;AACA,EAAA,MAAM,eAAA,GAAkBA,SAAQ,WAAW,CAAA;AAC3C,EAAA,MAAM,UAAA,GAAa,OAAO,QAAA,CAAS,MAAM,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAM,CAAA,GAAI,CAAA;AAEnE,EAAA,OAAO;AAAA,IACL,OAAO,eAAA,GAAkB,UAAA;AAAA,IACzB,IAAA,EAAA,CAAO,IAAI,eAAA,IAAmB;AAAA,GAChC;AACF;AAEO,SAAS,cAAA,CACd,eAAA,EACA,WAAA,EACA,aAAA,EACA,WACA,OAAA,EAIQ;AACR,EAAA,OAAO,gBAAA,CAAiB;AAAA,IACtB,eAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAU,OAAA,EAAS,QAAA;AAAA,IACnB,sBAAsB,OAAA,EAAS;AAAA,GAChC,CAAA;AACH;AAEO,SAAS,iBAAiB,IAAA,EAOtB;AACT,EAAA,OAAO,OAAA,CAAQ,uBAAA,CAAwB,IAAI,CAAC,CAAA;AAC9C;AAEO,SAAS,wBAAwB,IAAA,EAO1B;AACZ,EAAA,MAAM,aAAA,GAAgB,UAAA,CAAW,IAAA,CAAK,eAAA,EAAiB,KAAK,WAAW,CAAA;AACvE,EAAA,MAAM,cAAc,UAAA,CAAW,IAAA,CAAK,aAAA,EAAe,IAAA,CAAK,aAAa,CAAC,CAAA;AAEtE,EAAA,OAAO,eAAA;AAAA,IACL,aAAA,CAAc,QAAQ,WAAA,CAAY,KAAA;AAAA,IAClC,aAAA,CAAc,OAAO,WAAA,CAAY,IAAA;AAAA,IACjC,KAAK,oBAAA,IAAwB,8BAAA;AAAA,IAC7B,IAAA,CAAK;AAAA,GACP;AACF","file":"revision.js","sourcesContent":["import type { SLOpinion } from \"../../types\";\n\nexport function opinion(\n belief: number,\n disbelief: number,\n uncertainty: number,\n baseRate: number\n): SLOpinion {\n const b = Number.isFinite(belief) ? Math.max(0, belief) : 0;\n const d = Number.isFinite(disbelief) ? Math.max(0, disbelief) : 0;\n const u = Number.isFinite(uncertainty) ? Math.max(0, uncertainty) : 0;\n const a = Math.max(0, Math.min(1, baseRate));\n const sum = b + d + u;\n\n if (sum === 0) {\n return { b: 0, d: 0, u: 1, a } as SLOpinion;\n }\n\n return {\n b: b / sum,\n d: d / sum,\n u: u / sum,\n a,\n } as SLOpinion;\n}\n\nexport function mkOpinion(\n belief: number,\n disbelief: number,\n uncertainty: number,\n baseRate: number\n): SLOpinion {\n return opinion(belief, disbelief, uncertainty, baseRate);\n}\n\nexport function vacuous(baseRate: number): SLOpinion {\n return mkOpinion(0, 0, 1, baseRate);\n}\n\nexport function dogmatic(probability: number, baseRate: number): SLOpinion {\n const p = Math.max(0, Math.min(1, probability));\n return mkOpinion(p, 1 - p, 0, baseRate);\n}\n\nexport function project(o: SLOpinion): number {\n return o.b + o.a * o.u;\n}\n\nexport function confidenceLevel(o: SLOpinion): \"high\" | \"medium\" | \"low\" {\n const projected = project(o);\n if (o.u > 0.5) {\n return \"low\";\n }\n if (projected >= 0.8 && o.u < 0.2) {\n return \"high\";\n }\n if (projected >= 0.6) {\n return \"medium\";\n }\n return \"low\";\n}\n\nconst VACUOUS_IDENTITY_EPSILON = 1e-12;\n\n/**\n * Associative, vacuous-identity-preserving base rate for a fused opinion.\n *\n * The legacy `(left.a + right.a) / 2` arithmetic mean was the shared root of\n * RR.7 F1 (projected-confidence non-associativity) and F2 (a vacuous opinion of\n * a different base rate was not a fusion identity): averaging always pulled the\n * fused base rate toward the other operand even when that operand carried no\n * evidence. Subjective Logic requires every opinion over the same frame to share\n * one canonical base rate, so a correct fusion never *invents* a new base rate\n * from the operands' priors. We therefore:\n *\n * - return the informative operand's base rate when exactly one operand is\n * vacuous (the vacuous operand contributes no prior), making `vacuous(a)` a\n * true identity for any `a`; and\n * - require equal base rates otherwise (the canonical-frame contract). When\n * they coincide the result is that shared value — trivially associative.\n *\n * If two informative opinions carry genuinely different base rates they are not\n * opinions over the same frame and must be reconciled before fusion; we fall\n * back to the arithmetic mean ONLY in that ill-posed case to stay total, and the\n * property suite documents that this path is outside the order-independence\n * guarantee.\n */\nfunction fusedBaseRate(left: SLOpinion, right: SLOpinion): number {\n const leftVacuous = 1 - left.u <= VACUOUS_IDENTITY_EPSILON;\n const rightVacuous = 1 - right.u <= VACUOUS_IDENTITY_EPSILON;\n if (leftVacuous && !rightVacuous) {\n return right.a;\n }\n if (rightVacuous && !leftVacuous) {\n return left.a;\n }\n if (Math.abs(left.a - right.a) <= VACUOUS_IDENTITY_EPSILON) {\n return left.a;\n }\n return (left.a + right.a) / 2;\n}\n\nexport function cumulativeFusion(left: SLOpinion, right: SLOpinion): SLOpinion {\n const a = fusedBaseRate(left, right);\n\n // F2: a vacuous operand is the identity element of cumulative fusion. Return\n // the other operand verbatim (including its base rate) so fusion with the\n // vacuous opinion is a true no-op regardless of differing priors.\n if (1 - left.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(right.b, right.d, right.u, a);\n }\n if (1 - right.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(left.b, left.d, left.u, a);\n }\n\n // F4: dogmatic pair handled via the ε-limit of the cumulative rule rather than\n // the standalone `(b+d)/2` shortcut. As both uncertainties shrink at the same\n // rate, the cumulative formula's `(b_L·u_R + b_R·u_L)/k` term converges to the\n // arithmetic mean of the masses; deriving it from the same limit the interior\n // formula uses keeps mass-associativity intact (no special-case discontinuity).\n if (\n left.u <= VACUOUS_IDENTITY_EPSILON &&\n right.u <= VACUOUS_IDENTITY_EPSILON\n ) {\n return opinion((left.b + right.b) / 2, (left.d + right.d) / 2, 0, a);\n }\n\n const k = left.u + right.u - left.u * right.u;\n if (k === 0) {\n return vacuous(a);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (left.u * right.u) / k,\n a\n );\n}\n\nexport function averagingFusion(left: SLOpinion, right: SLOpinion): SLOpinion {\n const a = fusedBaseRate(left, right);\n\n // F2: vacuous identity, mirroring cumulativeFusion.\n if (1 - left.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(right.b, right.d, right.u, a);\n }\n if (1 - right.u <= VACUOUS_IDENTITY_EPSILON) {\n return opinion(left.b, left.d, left.u, a);\n }\n\n // F4: dogmatic pair via the ε-limit of the averaging rule.\n if (\n left.u <= VACUOUS_IDENTITY_EPSILON &&\n right.u <= VACUOUS_IDENTITY_EPSILON\n ) {\n return opinion((left.b + right.b) / 2, (left.d + right.d) / 2, 0, a);\n }\n\n const k = left.u + right.u;\n if (k === 0) {\n return vacuous(a);\n }\n\n return opinion(\n (left.b * right.u + right.b * left.u) / k,\n (left.d * right.u + right.d * left.u) / k,\n (2 * left.u * right.u) / k,\n a\n );\n}\n\nexport function trustDiscount(\n sourceOpinion: SLOpinion,\n trust: number\n): SLOpinion {\n const weight = Math.max(0, Math.min(1, Math.abs(trust)));\n return opinion(\n weight * sourceOpinion.b,\n weight * sourceOpinion.d,\n 1 - weight * (sourceOpinion.b + sourceOpinion.d),\n sourceOpinion.a\n );\n}\n\nconst EPSILON = 1e-9;\n\nfunction childBaseRateFallback(\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate: number | undefined\n): number {\n if (fallbackBaseRate !== undefined) {\n return Math.max(0, Math.min(1, fallbackBaseRate));\n }\n\n if (Math.abs(ifTrue.a - ifFalse.a) <= EPSILON) {\n return ifTrue.a;\n }\n\n return (ifTrue.a + ifFalse.a) / 2;\n}\n\nfunction computeConditionalDeductionBaseRate(\n opinionA: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate: number\n): number {\n const denominator = 1 - opinionA.a * ifTrue.u - (1 - opinionA.a) * ifFalse.u;\n\n if (ifTrue.u + ifFalse.u < 2 - EPSILON && Math.abs(denominator) > EPSILON) {\n const baseRate =\n (opinionA.a * ifTrue.b + (1 - opinionA.a) * ifFalse.b) / denominator;\n if (baseRate >= -EPSILON && baseRate <= 1 + EPSILON) {\n return Math.max(0, Math.min(1, baseRate));\n }\n }\n\n return fallbackBaseRate;\n}\n\nfunction safeCorrectionTerm(\n numerator: number,\n denominator: number\n): number | undefined {\n if (Math.abs(denominator) <= EPSILON) {\n return;\n }\n\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n return;\n }\n\n return Math.max(0, value);\n}\n\ninterface ConditionalDeductionCorrectionContext {\n childBaseRate: number;\n ifFalse: SLOpinion;\n ifTrue: SLOpinion;\n intermediateBelief: number;\n intermediateDisbelief: number;\n opinionA: SLOpinion;\n projectedAntecedent: number;\n projectedAntecedentComplement: number;\n projectedConditionalA: number;\n projectedVacuousDeduction: number;\n}\n\nfunction correctionOrZero(numerator: number, denominator: number): number {\n return safeCorrectionTerm(numerator, denominator) ?? 0;\n}\n\nfunction hasNoConditionalDeductionCorrection(\n ifTrue: SLOpinion,\n ifFalse: SLOpinion\n): boolean {\n return (\n (ifTrue.b > ifFalse.b && ifTrue.d > ifFalse.d) ||\n (ifTrue.b <= ifFalse.b && ifTrue.d <= ifFalse.d)\n );\n}\n\nfunction usesLowerVacuousBranch(\n context: ConditionalDeductionCorrectionContext\n): boolean {\n return context.projectedVacuousDeduction <= context.projectedConditionalA;\n}\n\nfunction usesLowerAntecedentBranch(\n context: ConditionalDeductionCorrectionContext\n): boolean {\n return context.projectedAntecedent <= context.opinionA.a;\n}\n\nfunction computeTrueDominantDeductionCorrection(\n context: ConditionalDeductionCorrectionContext\n): number {\n const beliefGap = context.ifTrue.b - context.ifFalse.b;\n const disbeliefGap = context.ifFalse.d - context.ifTrue.d;\n const lowerVacuous = usesLowerVacuousBranch(context);\n const lowerAntecedent = usesLowerAntecedentBranch(context);\n\n if (lowerVacuous && lowerAntecedent) {\n return correctionOrZero(\n context.opinionA.a *\n context.opinionA.u *\n (context.intermediateBelief - context.ifTrue.b),\n context.projectedAntecedent * context.childBaseRate\n );\n }\n\n if (lowerVacuous) {\n return correctionOrZero(\n context.opinionA.a *\n context.opinionA.u *\n (context.intermediateDisbelief - context.ifTrue.d) *\n beliefGap,\n context.projectedAntecedentComplement *\n context.childBaseRate *\n disbeliefGap\n );\n }\n\n if (lowerAntecedent) {\n return correctionOrZero(\n (1 - context.opinionA.a) *\n context.opinionA.u *\n (context.intermediateBelief - context.ifTrue.b) *\n disbeliefGap,\n context.projectedAntecedent * (1 - context.childBaseRate) * beliefGap\n );\n }\n\n return correctionOrZero(\n (1 - context.opinionA.a) *\n context.opinionA.u *\n (context.intermediateDisbelief - context.ifTrue.d),\n context.projectedAntecedentComplement * (1 - context.childBaseRate)\n );\n}\n\nfunction computeFalseDominantDeductionCorrection(\n context: ConditionalDeductionCorrectionContext\n): number {\n const beliefGap = context.ifFalse.b - context.ifTrue.b;\n const disbeliefGap = context.ifTrue.d - context.ifFalse.d;\n const lowerVacuous = usesLowerVacuousBranch(context);\n const lowerAntecedent = usesLowerAntecedentBranch(context);\n\n if (lowerVacuous && lowerAntecedent) {\n return correctionOrZero(\n (1 - context.opinionA.a) *\n context.opinionA.u *\n (context.intermediateDisbelief - context.ifTrue.d) *\n beliefGap,\n context.projectedAntecedent * context.childBaseRate * disbeliefGap\n );\n }\n\n if (lowerVacuous) {\n return correctionOrZero(\n (1 - context.opinionA.a) *\n context.opinionA.u *\n (context.intermediateBelief - context.ifTrue.b),\n context.projectedAntecedentComplement * context.childBaseRate\n );\n }\n\n if (lowerAntecedent) {\n return correctionOrZero(\n context.opinionA.a *\n context.opinionA.u *\n (context.intermediateDisbelief - context.ifTrue.d),\n context.projectedAntecedent * (1 - context.childBaseRate)\n );\n }\n\n return correctionOrZero(\n context.opinionA.a *\n context.opinionA.u *\n (context.intermediateBelief - context.ifTrue.b) *\n disbeliefGap,\n context.projectedAntecedentComplement *\n (1 - context.childBaseRate) *\n beliefGap\n );\n}\n\nfunction computeConditionalDeductionCorrection(\n context: ConditionalDeductionCorrectionContext\n): number {\n if (hasNoConditionalDeductionCorrection(context.ifTrue, context.ifFalse)) {\n return 0;\n }\n\n if (\n context.ifTrue.b > context.ifFalse.b &&\n context.ifTrue.d <= context.ifFalse.d\n ) {\n return computeTrueDominantDeductionCorrection(context);\n }\n\n return computeFalseDominantDeductionCorrection(context);\n}\n\nexport function conditionalDeduction(\n opinionA: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n fallbackBaseRate?: number\n): SLOpinion {\n const fallbackChildBaseRate = childBaseRateFallback(\n ifTrue,\n ifFalse,\n fallbackBaseRate\n );\n const childBaseRate = computeConditionalDeductionBaseRate(\n opinionA,\n ifTrue,\n ifFalse,\n fallbackChildBaseRate\n );\n const projectedAntecedent = project(opinionA);\n const projectedAntecedentComplement = 1 - projectedAntecedent;\n const intermediateBelief =\n opinionA.b * ifTrue.b +\n opinionA.d * ifFalse.b +\n opinionA.u * (ifTrue.b * opinionA.a + ifFalse.b * (1 - opinionA.a));\n const intermediateDisbelief =\n opinionA.b * ifTrue.d +\n opinionA.d * ifFalse.d +\n opinionA.u * (ifTrue.d * opinionA.a + ifFalse.d * (1 - opinionA.a));\n const intermediateUncertainty =\n opinionA.b * ifTrue.u +\n opinionA.d * ifFalse.u +\n opinionA.u * (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedVacuousDeduction =\n ifTrue.b * opinionA.a +\n ifFalse.b * (1 - opinionA.a) +\n childBaseRate * (ifTrue.u * opinionA.a + ifFalse.u * (1 - opinionA.a));\n const projectedConditionalA =\n ifTrue.b + childBaseRate * (1 - ifTrue.b - ifTrue.d);\n const correction = computeConditionalDeductionCorrection({\n childBaseRate,\n ifFalse,\n ifTrue,\n intermediateBelief,\n intermediateDisbelief,\n opinionA,\n projectedAntecedent,\n projectedAntecedentComplement,\n projectedConditionalA,\n projectedVacuousDeduction,\n });\n\n return opinion(\n intermediateBelief - childBaseRate * correction,\n intermediateDisbelief - (1 - childBaseRate) * correction,\n intermediateUncertainty + correction,\n childBaseRate\n );\n}\n\n/**\n * Abductive inference over a conditional.\n * Given an opinion on Y and conditionals P(Y|X), P(Y|~X), infer an opinion on X.\n */\nexport function conditionalAbduction(\n opinionY: SLOpinion,\n ifTrue: SLOpinion,\n ifFalse: SLOpinion,\n baseRateX: number\n): SLOpinion {\n const priorX = Math.max(0, Math.min(1, baseRateX));\n const probabilityY = project(opinionY);\n const probabilityGivenTrue = project(ifTrue);\n const probabilityGivenFalse = project(ifFalse);\n\n const posteriorIfYDenominator =\n probabilityGivenTrue * priorX + probabilityGivenFalse * (1 - priorX);\n const posteriorIfY =\n posteriorIfYDenominator === 0\n ? priorX\n : (probabilityGivenTrue * priorX) / posteriorIfYDenominator;\n\n const posteriorIfNotYDenominator =\n (1 - probabilityGivenTrue) * priorX +\n (1 - probabilityGivenFalse) * (1 - priorX);\n const posteriorIfNotY =\n posteriorIfNotYDenominator === 0\n ? priorX\n : ((1 - probabilityGivenTrue) * priorX) / posteriorIfNotYDenominator;\n\n const projectedX =\n probabilityY * posteriorIfY + (1 - probabilityY) * posteriorIfNotY;\n const uncertainty = Math.max(\n opinionY.u * 0.5,\n probabilityY * ifTrue.u + (1 - probabilityY) * ifFalse.u\n );\n\n return opinion(\n projectedX * (1 - uncertainty),\n (1 - projectedX) * (1 - uncertainty),\n uncertainty,\n priorX\n );\n}\n\nexport function negate(o: SLOpinion): SLOpinion {\n return mkOpinion(o.d, o.b, o.u, 1 - o.a);\n}\n\nexport function constraintFusion(\n left: SLOpinion,\n right: SLOpinion,\n mode: \"pressure\" | \"redistribute\" = \"pressure\"\n): { o1: SLOpinion; o2: SLOpinion } {\n if (mode === \"redistribute\") {\n const leftProjected = project(left);\n const rightProjected = project(right);\n const total = leftProjected + rightProjected;\n\n if (total <= 1) {\n return { o1: left, o2: right };\n }\n\n const scale = 1 / total;\n return {\n o1: opinion(\n left.b * scale,\n left.d + left.b * (1 - scale),\n left.u,\n left.a\n ),\n o2: opinion(\n right.b * scale,\n right.d + right.b * (1 - scale),\n right.u,\n right.a\n ),\n };\n }\n\n const pressureLeft = right.b * 0.5;\n const pressureRight = left.b * 0.5;\n\n return {\n o1: opinion(\n left.b - pressureLeft * 0.3,\n left.d + pressureLeft * 0.3,\n left.u,\n left.a\n ),\n o2: opinion(\n right.b - pressureRight * 0.3,\n right.d + pressureRight * 0.3,\n right.u,\n right.a\n ),\n };\n}\n\nexport function evidenceBalance(o: SLOpinion): number {\n const total = o.b + o.d;\n if (total === 0) {\n return 0;\n }\n return (o.b - o.d) / total;\n}\n\nexport function areTensioned(left: SLOpinion, right: SLOpinion): boolean {\n return (\n project(left) > 0.5 &&\n project(right) > 0.5 &&\n (left.d > 0.2 || right.d > 0.2)\n );\n}\n\nexport function informationGain(o: SLOpinion): number {\n if (o.u === 0) {\n return 0;\n }\n if (o.u === 1) {\n return 1;\n }\n return o.u * (1 - Math.abs(o.b - o.d));\n}\n","import type { DirichletOpinion, Opinion, SLOpinion } from \"../../types\";\nimport { mkOpinion } from \"../subjectiveLogic\";\n\nexport const DEFAULT_NON_INFORMATIVE_WEIGHT = 2;\n\nfunction clamp01(value: number): number {\n return Math.max(0, Math.min(1, value));\n}\n\nfunction clampNonNegative(value: number): number {\n return Number.isFinite(value) ? Math.max(0, value) : 0;\n}\n\nfunction normalizeNonInformativeWeight(weight?: number): number {\n if (weight === undefined) {\n return DEFAULT_NON_INFORMATIVE_WEIGHT;\n }\n return Number.isFinite(weight)\n ? Math.max(0, weight)\n : DEFAULT_NON_INFORMATIVE_WEIGHT;\n}\n\nfunction normalizeBaseRateVector(\n baseRate: readonly number[],\n size: number\n): number[] {\n if (size === 0) {\n return [];\n }\n\n if (baseRate.length !== size) {\n throw new Error(\n `Base-rate vector length ${baseRate.length} must match evidence vector length ${size}.`\n );\n }\n\n const normalized = baseRate.map((value) => clampNonNegative(value));\n const total = normalized.reduce((sum, value) => sum + value, 0);\n\n if (total === 0) {\n throw new Error(\n \"Base-rate vector must contain at least one positive value.\"\n );\n }\n\n return normalized.map((value) => value / total);\n}\n\nexport function opinionFromDirichlet(\n alpha: readonly number[],\n nonInformativeWeight: number,\n baseRate: readonly number[]\n): DirichletOpinion {\n const evidence = alpha.map((value) => clampNonNegative(value));\n const safeWeight = normalizeNonInformativeWeight(nonInformativeWeight);\n const normalizedBaseRate = normalizeBaseRateVector(baseRate, evidence.length);\n const totalEvidence = evidence.reduce((sum, value) => sum + value, 0);\n const denominator = totalEvidence + safeWeight;\n\n if (denominator === 0) {\n return {\n b: evidence.map(() => 0),\n u: 1,\n a: normalizedBaseRate,\n };\n }\n\n return {\n b: evidence.map((value) => value / denominator),\n u: safeWeight / denominator,\n a: normalizedBaseRate,\n };\n}\n\nexport function projectDirichletOpinion(opinion: DirichletOpinion): number[] {\n return opinion.b.map(\n (belief, index) => belief + (opinion.a[index] ?? 0) * opinion.u\n );\n}\n\nexport function opinionFromBeta(\n alpha: number,\n beta: number,\n nonInformativeWeight: number,\n baseRate: number\n): SLOpinion {\n const dirichlet = opinionFromDirichlet([alpha, beta], nonInformativeWeight, [\n clamp01(baseRate),\n 1 - clamp01(baseRate),\n ]);\n\n return mkOpinion(\n dirichlet.b[0] ?? 0,\n dirichlet.b[1] ?? 0,\n dirichlet.u,\n dirichlet.a[0] ?? clamp01(baseRate)\n );\n}\n\nexport function betaFromOpinion(\n opinion: Opinion,\n nonInformativeWeight: number = DEFAULT_NON_INFORMATIVE_WEIGHT\n): { alpha: number; beta: number } {\n if (opinion.u === 0) {\n return {\n alpha: Number.POSITIVE_INFINITY,\n beta: Number.POSITIVE_INFINITY,\n };\n }\n\n const safeWeight = normalizeNonInformativeWeight(nonInformativeWeight);\n const scale = safeWeight / opinion.u;\n\n return {\n alpha: opinion.b * scale,\n beta: opinion.d * scale,\n };\n}\n","import type { SLOpinion } from \"../../types\";\nimport { DEFAULT_NON_INFORMATIVE_WEIGHT, opinionFromBeta } from \"../bridge\";\nimport { project } from \"../subjectiveLogic\";\n\nfunction clamp01(value: number): number {\n return Math.max(0, Math.min(1, value));\n}\n\nfunction toEvidence(\n probability: number,\n weight: number\n): {\n alpha: number;\n beta: number;\n} {\n const safeProbability = clamp01(probability);\n const safeWeight = Number.isFinite(weight) ? Math.max(0, weight) : 0;\n\n return {\n alpha: safeProbability * safeWeight,\n beta: (1 - safeProbability) * safeWeight,\n };\n}\n\nexport function bayesianUpdate(\n priorConfidence: number,\n priorWeight: number,\n newAssessment: number,\n newWeight: number,\n options: {\n baseRate: number;\n nonInformativeWeight?: number;\n }\n): number {\n return reviseConfidence({\n priorConfidence,\n priorWeight,\n newAssessment,\n newWeight,\n baseRate: options?.baseRate,\n nonInformativeWeight: options?.nonInformativeWeight,\n });\n}\n\nexport function reviseConfidence(args: {\n priorConfidence: number;\n priorWeight: number;\n newAssessment: number;\n newWeight?: number;\n baseRate: number;\n nonInformativeWeight?: number;\n}): number {\n return project(reviseConfidenceOpinion(args));\n}\n\nexport function reviseConfidenceOpinion(args: {\n priorConfidence: number;\n priorWeight: number;\n newAssessment: number;\n newWeight?: number;\n baseRate: number;\n nonInformativeWeight?: number;\n}): SLOpinion {\n const priorEvidence = toEvidence(args.priorConfidence, args.priorWeight);\n const newEvidence = toEvidence(args.newAssessment, args.newWeight ?? 1);\n\n return opinionFromBeta(\n priorEvidence.alpha + newEvidence.alpha,\n priorEvidence.beta + newEvidence.beta,\n args.nonInformativeWeight ?? DEFAULT_NON_INFORMATIVE_WEIGHT,\n args.baseRate\n );\n}\n"]}
|
|
@@ -38,7 +38,7 @@ function toEpochMs(value) {
|
|
|
38
38
|
const epochMs = value.getTime();
|
|
39
39
|
return Number.isFinite(epochMs) ? epochMs : void 0;
|
|
40
40
|
}
|
|
41
|
-
return
|
|
41
|
+
return;
|
|
42
42
|
}
|
|
43
43
|
function normalizeHalfLifeMs(halfLifeMs) {
|
|
44
44
|
if (halfLifeMs === void 0 || !Number.isFinite(halfLifeMs)) {
|
|
@@ -60,9 +60,14 @@ function temporalDecay(sourceOpinion, now, decayParams) {
|
|
|
60
60
|
if (ageMs === 0) {
|
|
61
61
|
return { ...sourceOpinion };
|
|
62
62
|
}
|
|
63
|
-
const retainedEvidenceWeight =
|
|
63
|
+
const retainedEvidenceWeight = 0.5 ** (ageMs / halfLifeMs);
|
|
64
64
|
return trustDiscount(
|
|
65
|
-
mkOpinion(
|
|
65
|
+
mkOpinion(
|
|
66
|
+
sourceOpinion.b,
|
|
67
|
+
sourceOpinion.d,
|
|
68
|
+
sourceOpinion.u,
|
|
69
|
+
sourceOpinion.a
|
|
70
|
+
),
|
|
66
71
|
retainedEvidenceWeight
|
|
67
72
|
);
|
|
68
73
|
}
|