@lucern/graph-primitives 0.3.0-alpha.0 → 0.3.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{beliefDecay-Q_26RTc-.d.ts → beliefDecay-DZ6tkLYq.d.ts} +1 -1
- package/dist/beliefDecay.d.ts +1 -1
- package/dist/beliefDecay.js +188 -1144
- package/dist/beliefDecay.js.map +1 -1
- package/dist/{beliefEvidenceLinks-42FlR48t.d.ts → beliefEvidenceLinks-CWOXxxJg.d.ts} +1 -1
- package/dist/beliefEvidenceLinks.d.ts +1 -1
- package/dist/beliefEvidenceLinks.js +186 -871
- package/dist/beliefEvidenceLinks.js.map +1 -1
- package/dist/{beliefLifecycle-C-AehZgF.d.ts → beliefLifecycle-y8WLXqQj.d.ts} +1 -1
- package/dist/beliefLifecycle.d.ts +1 -1
- package/dist/confidencePropagationDispatch.d.ts +4 -4
- package/dist/confidencePropagationDispatch.js +31 -311
- package/dist/confidencePropagationDispatch.js.map +1 -1
- package/dist/{contradictions-Hdwl7zid.d.ts → contradictions-51VLsESq.d.ts} +1 -1
- package/dist/contradictions.d.ts +1 -1
- package/dist/contradictions.js +67 -800
- package/dist/contradictions.js.map +1 -1
- package/dist/debug.d.ts +4 -0
- package/dist/debug.js +34 -0
- package/dist/debug.js.map +1 -0
- package/dist/edges/contradicts.js +1 -122
- package/dist/edges/contradicts.js.map +1 -1
- package/dist/edges/dependsOn.js +14 -172
- package/dist/edges/dependsOn.js.map +1 -1
- package/dist/edges/elaborates.js +1 -49
- package/dist/edges/elaborates.js.map +1 -1
- package/dist/edges/index.js +15 -280
- package/dist/edges/index.js.map +1 -1
- package/dist/edges/informs.js +2 -65
- package/dist/edges/informs.js.map +1 -1
- package/dist/edges/propagationTypes.d.ts +2 -2
- package/dist/edges/propagationTypes.js.map +1 -1
- package/dist/edges/refutes.js +2 -65
- package/dist/edges/refutes.js.map +1 -1
- package/dist/edges/supports.js +1 -122
- package/dist/edges/supports.js.map +1 -1
- package/dist/edges/utils.d.ts +7 -7
- package/dist/edges/utils.js +2 -133
- package/dist/edges/utils.js.map +1 -1
- package/dist/embeddingTrigger.js +21 -1
- package/dist/embeddingTrigger.js.map +1 -1
- package/dist/entityBridge.js +3 -18
- package/dist/entityBridge.js.map +1 -1
- package/dist/{entityLifecycle-BkhRJ-XI.d.ts → entityLifecycle-CvgSK5FV.d.ts} +1 -1
- package/dist/entityLifecycle.d.ts +1 -1
- package/dist/entityLifecycle.js +193 -892
- package/dist/entityLifecycle.js.map +1 -1
- package/dist/{epistemicAnswers-DSP1slZ9.d.ts → epistemicAnswers-C5ib4z6_.d.ts} +1 -1
- package/dist/epistemicAnswers.d.ts +1 -1
- package/dist/epistemicAnswers.js +73 -810
- package/dist/epistemicAnswers.js.map +1 -1
- package/dist/{epistemicBeliefs-DtFVTp-k.d.ts → epistemicBeliefs-DzKjZAeC.d.ts} +3 -3
- package/dist/epistemicBeliefs.d.ts +2 -2
- package/dist/epistemicBeliefs.js +404 -1698
- package/dist/epistemicBeliefs.js.map +1 -1
- package/dist/epistemicContractHelpers.js +1 -318
- package/dist/epistemicContractHelpers.js.map +1 -1
- package/dist/epistemicContracts.d.ts +1 -1
- package/dist/epistemicContracts.js +417 -1980
- package/dist/epistemicContracts.js.map +1 -1
- package/dist/{epistemicEdges-DcA8ErUG.d.ts → epistemicEdges-CD5vxmlH.d.ts} +3 -3
- package/dist/epistemicEdges.d.ts +1 -1
- package/dist/epistemicEdges.js +248 -919
- package/dist/epistemicEdges.js.map +1 -1
- package/dist/{epistemicEvidence-Bo638XDP.d.ts → epistemicEvidence-xw6UUrwh.d.ts} +1 -1
- package/dist/epistemicEvidence.d.ts +1 -1
- package/dist/epistemicEvidence.js +229 -1087
- package/dist/epistemicEvidence.js.map +1 -1
- package/dist/{epistemicHelpers-Bd9xbaib.d.ts → epistemicHelpers-DevrYgPN.d.ts} +1 -1
- package/dist/epistemicHelpers.d.ts +1 -1
- package/dist/{epistemicLinking-CyeLOIzN.d.ts → epistemicLinking-CfE00tHJ.d.ts} +1 -1
- package/dist/epistemicLinking.d.ts +1 -1
- package/dist/epistemicLinking.js +3 -786
- package/dist/epistemicLinking.js.map +1 -1
- package/dist/{epistemicNodes-BpD6Koud.d.ts → epistemicNodes-NBrPW7fk.d.ts} +2 -2
- package/dist/epistemicNodes.d.ts +1 -1
- package/dist/epistemicNodes.js +172 -899
- package/dist/epistemicNodes.js.map +1 -1
- package/dist/{epistemicQuestions-CmEeY6zQ.d.ts → epistemicQuestions-B_nUclrH.d.ts} +1 -1
- package/dist/epistemicQuestions.d.ts +1 -1
- package/dist/epistemicQuestions.js +369 -1125
- package/dist/epistemicQuestions.js.map +1 -1
- package/dist/{epistemicSources-ZazxHOK1.d.ts → epistemicSources-dlKj58Jp.d.ts} +1 -1
- package/dist/epistemicSources.d.ts +1 -1
- package/dist/epistemicSources.js +86 -886
- package/dist/epistemicSources.js.map +1 -1
- package/dist/evaluators/index.js +417 -1980
- package/dist/evaluators/index.js.map +1 -1
- package/dist/evaluators/lintCheckerEvaluator.js.map +1 -1
- package/dist/evaluators/sentryCheckerEvaluator.js.map +1 -1
- package/dist/evaluators/shared.js +20 -1
- package/dist/evaluators/shared.js.map +1 -1
- package/dist/evaluators/testRunnerEvaluator.js +20 -1
- package/dist/evaluators/testRunnerEvaluator.js.map +1 -1
- package/dist/evaluators/tscCheckerEvaluator.js.map +1 -1
- package/dist/index.d.ts +20 -20
- package/dist/index.js +965 -3004
- package/dist/index.js.map +1 -1
- package/dist/{ontology-matching-Buhu23ss.d.ts → ontology-matching-C6rrz2VP.d.ts} +1 -1
- package/dist/ontology-matching.d.ts +1 -1
- package/dist/ontology-matching.js +1 -344
- package/dist/ontology-matching.js.map +1 -1
- package/dist/{ontologyApproval-Ba0Jjk1k.d.ts → ontologyApproval-CFYmqKmk.d.ts} +1 -1
- package/dist/ontologyApproval.d.ts +1 -1
- package/dist/ontologyApproval.js +1 -13
- package/dist/ontologyApproval.js.map +1 -1
- package/dist/ontologyDefinitions.js +6 -20
- package/dist/ontologyDefinitions.js.map +1 -1
- package/dist/ontologyHelpers.d.ts +1 -1
- package/dist/ontologyHelpers.js +4 -3
- package/dist/ontologyHelpers.js.map +1 -1
- package/dist/ontologyRegistry.js +2 -17
- package/dist/ontologyRegistry.js.map +1 -1
- package/dist/{projectionReconciliation-CxrXYGaB.d.ts → projectionReconciliation-jww2fBI0.d.ts} +1 -1
- package/dist/projectionReconciliation.d.ts +1 -1
- package/dist/projectionReconciliation.js +16 -37
- package/dist/projectionReconciliation.js.map +1 -1
- package/dist/{projectionStaleness-CAdpIsaW.d.ts → projectionStaleness-CmdbpjVK.d.ts} +1 -1
- package/dist/projectionStaleness.d.ts +1 -1
- package/dist/{questionEvidenceLinks-BdQD0TkM.d.ts → questionEvidenceLinks-DFlyPpAj.d.ts} +1 -1
- package/dist/questionEvidenceLinks.d.ts +1 -1
- package/dist/questionEvidenceLinks.js +199 -881
- package/dist/questionEvidenceLinks.js.map +1 -1
- package/dist/resolvers.js +86 -37
- package/dist/resolvers.js.map +1 -1
- package/dist/scopeResolverCompat.js +64 -7
- package/dist/scopeResolverCompat.js.map +1 -1
- package/dist/{text-matching-CMn2WnVD.d.ts → text-matching-DNg4M5Wd.d.ts} +1 -1
- package/dist/text-matching.d.ts +1 -1
- package/dist/text-matching.js +1 -244
- package/dist/text-matching.js.map +1 -1
- package/dist/topicProjectOverlay.js +56 -13
- package/dist/topicProjectOverlay.js.map +1 -1
- package/dist/topicScope.js +55 -6
- package/dist/topicScope.js.map +1 -1
- package/dist/workflowBridge.d.ts +27 -0
- package/dist/workflowBridge.js +352 -0
- package/dist/workflowBridge.js.map +1 -0
- package/dist/workspaceIsolation.js +56 -57
- package/dist/workspaceIsolation.js.map +1 -1
- package/package.json +6 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/edges/propagationTypes.ts"],"names":[],"mappings":";AA4DO,SAAS,gCACd,SAAA,EAC4C;AAC5C,EAAA,OAAO,SAAA,KAAc,cAAc,SAAA,KAAc,UAAA;AACnD;AAEO,SAAS,cAAA,CACd,MACA,OAAA,EACS;AACT,EAAA,OAAO,IAAA,CAAK,OAAA,KAAY,WAAA,IAAe,OAAA,IAAW,IAAA,CAAK,OAAA;AACzD;AAEO,SAAS,uBAAA,CACd,MACA,UAAA,EACS;AACT,EAAA,IAAI,IAAA,CAAK,iBAAiB,MAAA,EAAQ;AAChC,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,OAAO,IAAA,CAAK,OAAA,KAAY,WAAA,IAAe,UAAA,GAAa,IAAA,CAAK,OAAA;AAC3D","file":"propagationTypes.js","sourcesContent":["import type {\n EdgeMetadata,\n
|
|
1
|
+
{"version":3,"sources":["../../src/edges/propagationTypes.ts"],"names":[],"mappings":";AA4DO,SAAS,gCACd,SAAA,EAC4C;AAC5C,EAAA,OAAO,SAAA,KAAc,cAAc,SAAA,KAAc,UAAA;AACnD;AAEO,SAAS,cAAA,CACd,MACA,OAAA,EACS;AACT,EAAA,OAAO,IAAA,CAAK,OAAA,KAAY,WAAA,IAAe,OAAA,IAAW,IAAA,CAAK,OAAA;AACzD;AAEO,SAAS,uBAAA,CACd,MACA,UAAA,EACS;AACT,EAAA,IAAI,IAAA,CAAK,iBAAiB,MAAA,EAAQ;AAChC,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,OAAO,IAAA,CAAK,OAAA,KAAY,WAAA,IAAe,UAAA,GAAa,IAAA,CAAK,OAAA;AAC3D","file":"propagationTypes.js","sourcesContent":["import type {\n EdgeMetadata,\n PropagationResult,\n SLOpinion,\n} from \"@lucern/confidence\";\n\nexport type PropagationTraversalDirection = \"outgoing\" | \"incoming\";\n\nexport type PropagationSpecDirection =\n | PropagationTraversalDirection\n | \"bidirectional\";\n\nexport type PropagationTransitivity = \"none\" | \"damped\" | \"full\";\n\nexport type PropagationEdgeType =\n | \"supports\"\n | \"depends_on\"\n | \"informs\"\n | \"contains\"\n | \"tests\"\n | \"derived_from\"\n | \"contradicts\"\n | \"refutes\"\n | \"elaborates\";\n\nexport type PropagationEdgeRecord<TNodeId extends string = string> = {\n fromNodeId?: TNodeId | null;\n toNodeId?: TNodeId | null;\n edgeType: string;\n weight?: number | null;\n constraint?: EdgeMetadata[\"constraint\"] | null;\n normalization?: EdgeMetadata[\"normalization\"] | null;\n propagation?: EdgeMetadata[\"propagation\"] | null;\n conditionalA?: EdgeMetadata[\"conditionalA\"] | null;\n conditionalNotA?: EdgeMetadata[\"conditionalNotA\"] | null;\n tenantId?: string;\n workspaceId?: string;\n};\n\nexport type EdgePropagationSpec<TNodeId extends string = string> = {\n edgeType: PropagationEdgeType;\n direction: PropagationSpecDirection;\n transitivity: PropagationTransitivity;\n damping: number;\n maxHops: number | \"unbounded\";\n operator: (\n sourceOpinion: SLOpinion,\n targetOpinion: SLOpinion,\n edge: PropagationEdgeRecord<TNodeId>,\n context: {\n hop: number;\n sourceNodeId: TNodeId;\n targetNodeId: TNodeId;\n traversedDirection: PropagationTraversalDirection;\n spec: EdgePropagationSpec<TNodeId>;\n }\n ) => PropagationResult | null;\n description: string;\n};\n\nexport function isPropagationTraversalDirection(\n direction: string\n): direction is PropagationTraversalDirection {\n return direction === \"outgoing\" || direction === \"incoming\";\n}\n\nexport function canTraverseHop<TNodeId extends string>(\n spec: EdgePropagationSpec<TNodeId>,\n nextHop: number\n): boolean {\n return spec.maxHops === \"unbounded\" || nextHop <= spec.maxHops;\n}\n\nexport function canContinueTransitively<TNodeId extends string>(\n spec: EdgePropagationSpec<TNodeId>,\n currentHop: number\n): boolean {\n if (spec.transitivity === \"none\") {\n return false;\n }\n\n return spec.maxHops === \"unbounded\" || currentHop < spec.maxHops;\n}\n"]}
|
package/dist/edges/refutes.js
CHANGED
|
@@ -1,65 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
function opinion(belief, disbelief, uncertainty, baseRate = 0.5) {
|
|
3
|
-
const b = Math.max(0, Math.min(1, belief));
|
|
4
|
-
const d = Math.max(0, Math.min(1, disbelief));
|
|
5
|
-
const u = Math.max(0, Math.min(1, uncertainty));
|
|
6
|
-
const a = Math.max(0, Math.min(1, baseRate));
|
|
7
|
-
const sum = b + d + u;
|
|
8
|
-
if (sum === 0) {
|
|
9
|
-
return { b: 0, d: 0, u: 1, a };
|
|
10
|
-
}
|
|
11
|
-
return {
|
|
12
|
-
b: b / sum,
|
|
13
|
-
d: d / sum,
|
|
14
|
-
u: u / sum,
|
|
15
|
-
a
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
function vacuous(baseRate = 0.5) {
|
|
19
|
-
return { b: 0, d: 0, u: 1, a: baseRate };
|
|
20
|
-
}
|
|
21
|
-
function cumulativeFusion(left, right) {
|
|
22
|
-
if (left.u === 0 && right.u === 0) {
|
|
23
|
-
return opinion(
|
|
24
|
-
(left.b + right.b) / 2,
|
|
25
|
-
(left.d + right.d) / 2,
|
|
26
|
-
0,
|
|
27
|
-
(left.a + right.a) / 2
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
const k = left.u + right.u - left.u * right.u;
|
|
31
|
-
if (k === 0) {
|
|
32
|
-
return vacuous((left.a + right.a) / 2);
|
|
33
|
-
}
|
|
34
|
-
return opinion(
|
|
35
|
-
(left.b * right.u + right.b * left.u) / k,
|
|
36
|
-
(left.d * right.u + right.d * left.u) / k,
|
|
37
|
-
left.u * right.u / k,
|
|
38
|
-
(left.a + right.a) / 2
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
function trustDiscount(sourceOpinion, trust) {
|
|
42
|
-
const weight = Math.max(0, Math.min(1, Math.abs(trust)));
|
|
43
|
-
return opinion(
|
|
44
|
-
weight * sourceOpinion.b,
|
|
45
|
-
weight * sourceOpinion.d,
|
|
46
|
-
1 - weight * (sourceOpinion.b + sourceOpinion.d),
|
|
47
|
-
sourceOpinion.a
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
function negate(o) {
|
|
51
|
-
return { b: o.d, d: o.b, u: o.u, a: 1 - o.a };
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// ../confidence/src/v1/operations/dynamics/defeat.ts
|
|
55
|
-
function applyNegativeEvidence(source, target, weight) {
|
|
56
|
-
const discounted = trustDiscount(negate(source), Math.abs(weight));
|
|
57
|
-
return {
|
|
58
|
-
opinion: cumulativeFusion(target, discounted),
|
|
59
|
-
operator: "cumulative_fusion",
|
|
60
|
-
rationale: `Contradicting evidence (weight=${weight.toFixed(2)})`
|
|
61
|
-
};
|
|
62
|
-
}
|
|
1
|
+
import { trustDiscount, applyNegativeEvidence } from '@lucern/confidence';
|
|
63
2
|
|
|
64
3
|
// src/edges/utils.ts
|
|
65
4
|
function applyPerHopDamping(sourceOpinion, damping) {
|
|
@@ -76,9 +15,7 @@ function annotateRationale(result, spec, hop) {
|
|
|
76
15
|
)} :: ${result.rationale}`
|
|
77
16
|
};
|
|
78
17
|
}
|
|
79
|
-
|
|
80
|
-
return applyNegativeEvidence(sourceOpinion, targetOpinion, edgeWeight);
|
|
81
|
-
}
|
|
18
|
+
var propagateNegativeInform = applyNegativeEvidence;
|
|
82
19
|
|
|
83
20
|
// src/edges/refutes.ts
|
|
84
21
|
var refutesPropagationSpec = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../confidence/src/v1/operations/subjectiveLogic/index.ts","../../../confidence/src/v1/operations/dynamics/defeat.ts","../../src/edges/utils.ts","../../src/edges/refutes.ts"],"names":[],"mappings":"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","file":"refutes.js","sourcesContent":["import type { Opinion } from \"../../types\";\n\nexport function opinion(\n belief: number,\n disbelief: number,\n uncertainty: number,\n baseRate: number = 0.5\n): Opinion {\n const b = Math.max(0, Math.min(1, belief));\n const d = Math.max(0, Math.min(1, disbelief));\n const u = Math.max(0, Math.min(1, uncertainty));\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 };\n }\n\n return {\n b: b / sum,\n d: d / sum,\n u: u / sum,\n a,\n };\n}\n\nexport function vacuous(baseRate: number = 0.5): Opinion {\n return { b: 0, d: 0, u: 1, a: baseRate };\n}\n\nexport function dogmatic(probability: number, baseRate: number = 0.5): Opinion {\n const p = Math.max(0, Math.min(1, probability));\n return { b: p, d: 1 - p, u: 0, a: baseRate };\n}\n\nexport function project(o: Opinion): number {\n return o.b + o.a * o.u;\n}\n\nexport function confidenceLevel(o: Opinion): \"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\nexport function cumulativeFusion(left: Opinion, right: Opinion): Opinion {\n if (left.u === 0 && right.u === 0) {\n return opinion(\n (left.b + right.b) / 2,\n (left.d + right.d) / 2,\n 0,\n (left.a + right.a) / 2\n );\n }\n\n const k = left.u + right.u - left.u * right.u;\n if (k === 0) {\n return vacuous((left.a + right.a) / 2);\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 (left.a + right.a) / 2\n );\n}\n\nexport function averagingFusion(left: Opinion, right: Opinion): Opinion {\n if (left.u === 0 && right.u === 0) {\n return opinion(\n (left.b + right.b) / 2,\n (left.d + right.d) / 2,\n 0,\n (left.a + right.a) / 2\n );\n }\n\n const k = left.u + right.u;\n if (k === 0) {\n return vacuous((left.a + right.a) / 2);\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 (left.a + right.a) / 2\n );\n}\n\nexport function trustDiscount(sourceOpinion: Opinion, trust: number): Opinion {\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: Opinion,\n ifFalse: Opinion,\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: Opinion,\n ifTrue: Opinion,\n ifFalse: Opinion,\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: Opinion,\n ifTrue: Opinion,\n ifFalse: Opinion,\n fallbackBaseRate?: number\n): Opinion {\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: Opinion,\n ifTrue: Opinion,\n ifFalse: Opinion,\n baseRateX: number\n): Opinion {\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: Opinion): Opinion {\n return { b: o.d, d: o.b, u: o.u, a: 1 - o.a };\n}\n\nexport function constraintFusion(\n left: Opinion,\n right: Opinion,\n mode: \"pressure\" | \"redistribute\" = \"pressure\"\n): { o1: Opinion; o2: Opinion } {\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: Opinion): 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: Opinion, right: Opinion): 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: Opinion): 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 { EdgeMetadata, Opinion, PropagationResult } from \"../../types\";\nimport {\n constraintFusion,\n cumulativeFusion,\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 if (metadata.constraint === \"xor\") {\n const result = constraintFusion(\n source,\n target,\n metadata.normalization ?? \"pressure\"\n );\n return {\n opinion: result.o2,\n operator: \"constraint_fusion\",\n rationale: `XOR constraint: source belief at ${project(source).toFixed(\n 2\n )} pressures target`,\n };\n }\n\n const discounted = trustDiscount(negate(source), Math.abs(weight));\n return {\n opinion: cumulativeFusion(target, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Contradicting evidence (weight=${weight.toFixed(\n 2\n )}) from source at ${project(source).toFixed(2)}`,\n };\n}\n\nexport function applyNegativeEvidence(\n source: Opinion,\n target: Opinion,\n weight: number\n): PropagationResult {\n const discounted = trustDiscount(negate(source), Math.abs(weight));\n return {\n opinion: cumulativeFusion(target, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Contradicting evidence (weight=${weight.toFixed(2)})`,\n };\n}\n","import {\n applyNegativeEvidence,\n applyNegativeSupport,\n cumulativeFusion,\n project,\n trustDiscount,\n type EdgeMetadata,\n type Opinion,\n type PropagationResult,\n} from \"@lucern/confidence\";\nimport type {\n EdgePropagationSpec,\n PropagationEdgeRecord,\n} from \"./propagationTypes\";\n\nexport function readEdgeMetadata<TNodeId extends string>(\n edge: PropagationEdgeRecord<TNodeId>\n): EdgeMetadata {\n return {\n constraint: edge.constraint ?? undefined,\n normalization: edge.normalization ?? undefined,\n propagation: edge.propagation ?? undefined,\n conditionalA: edge.conditionalA ?? undefined,\n conditionalNotA: edge.conditionalNotA ?? undefined,\n };\n}\n\nexport function applyPerHopDamping(\n sourceOpinion: Opinion,\n damping: number\n): Opinion {\n if (damping >= 1) {\n return sourceOpinion;\n }\n\n return trustDiscount(sourceOpinion, Math.max(0, damping));\n}\n\nexport function annotateRationale(\n result: PropagationResult,\n spec: EdgePropagationSpec,\n hop: number\n): PropagationResult {\n return {\n ...result,\n rationale: `hop=${hop} edge=${spec.edgeType} damping=${spec.damping.toFixed(\n 2\n )} :: ${result.rationale}`,\n };\n}\n\nexport function propagatePositiveSupport(\n sourceOpinion: Opinion,\n targetOpinion: Opinion,\n edgeWeight: number\n): PropagationResult {\n const discounted = trustDiscount(sourceOpinion, Math.abs(edgeWeight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${edgeWeight.toFixed(\n 2\n )}) from source at ${project(sourceOpinion).toFixed(2)}`,\n };\n}\n\nexport function propagatePositiveInform(\n sourceOpinion: Opinion,\n targetOpinion: Opinion,\n edgeWeight: number\n): PropagationResult {\n const discounted = trustDiscount(sourceOpinion, Math.abs(edgeWeight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${edgeWeight.toFixed(2)})`,\n };\n}\n\nexport function propagateNegativeSupportWithMetadata(\n sourceOpinion: Opinion,\n targetOpinion: Opinion,\n edgeWeight: number,\n edge: PropagationEdgeRecord\n): PropagationResult {\n return applyNegativeSupport(\n sourceOpinion,\n targetOpinion,\n edgeWeight,\n readEdgeMetadata(edge)\n );\n}\n\nexport function propagateNegativeInform(\n sourceOpinion: Opinion,\n targetOpinion: Opinion,\n edgeWeight: number\n): PropagationResult {\n return applyNegativeEvidence(sourceOpinion, targetOpinion, edgeWeight);\n}\n\n","import type { EdgePropagationSpec } from \"./propagationTypes\";\nimport {\n annotateRationale,\n applyPerHopDamping,\n propagateNegativeInform,\n} from \"./utils\";\n\nexport const refutesPropagationSpec: EdgePropagationSpec = {\n edgeType: \"refutes\",\n direction: \"outgoing\",\n transitivity: \"none\",\n damping: 0.9,\n maxHops: 1,\n operator: (sourceOpinion, targetOpinion, edge, context) => {\n const dampedSource = applyPerHopDamping(\n sourceOpinion,\n context.spec.damping\n );\n const negativeWeight = -Math.abs(edge.weight ?? 1);\n const result = propagateNegativeInform(\n dampedSource,\n targetOpinion,\n negativeWeight\n );\n\n return annotateRationale(result, context.spec, context.hop);\n },\n description:\n \"Explicit negative evidence semantics. Refutes is treated as strong one-hop counter-evidence.\",\n};\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/edges/utils.ts","../../src/edges/refutes.ts"],"names":[],"mappings":";;;AA2BO,SAAS,kBAAA,CACd,eACA,OAAA,EACW;AACX,EAAA,IAAI,WAAW,CAAA,EAAG;AAChB,IAAA,OAAO,aAAA;AAAA,EACT;AAEA,EAAA,OAAO,cAAc,aAAA,EAAe,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAO,CAAC,CAAA;AAC1D;AAEO,SAAS,iBAAA,CACd,MAAA,EACA,IAAA,EACA,GAAA,EACmB;AACnB,EAAA,OAAO;AAAA,IACL,GAAG,MAAA;AAAA,IACH,SAAA,EAAW,OAAO,GAAG,CAAA,MAAA,EAAS,KAAK,QAAQ,CAAA,SAAA,EAAY,KAAK,OAAA,CAAQ,OAAA;AAAA,MAClE;AAAA,KACD,CAAA,IAAA,EAAO,MAAA,CAAO,SAAS,CAAA;AAAA,GAC1B;AACF;AA4CO,IAAM,uBAAA,GAA0B,qBAAA;;;ACtFhC,IAAM,sBAAA,GAA8C;AAAA,EACzD,QAAA,EAAU,SAAA;AAAA,EACV,SAAA,EAAW,UAAA;AAAA,EACX,YAAA,EAAc,MAAA;AAAA,EACd,OAAA,EAAS,GAAA;AAAA,EACT,OAAA,EAAS,CAAA;AAAA,EACT,QAAA,EAAU,CAAC,aAAA,EAAe,aAAA,EAAe,MAAM,OAAA,KAAY;AACzD,IAAA,MAAM,YAAA,GAAe,kBAAA;AAAA,MACnB,aAAA;AAAA,MACA,QAAQ,IAAA,CAAK;AAAA,KACf;AACA,IAAA,MAAM,iBAAiB,CAAC,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,UAAU,CAAC,CAAA;AACjD,IAAA,MAAM,MAAA,GAAS,uBAAA;AAAA,MACb,YAAA;AAAA,MACA,aAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,OAAO,iBAAA,CAAkB,MAAA,EAAQ,OAAA,CAAQ,IAAA,EAAM,QAAQ,GAAG,CAAA;AAAA,EAC5D,CAAA;AAAA,EACA,WAAA,EACE;AACJ","file":"refutes.js","sourcesContent":["import {\n applyNegativeEvidence,\n applyNegativeSupport,\n cumulativeFusion,\n project,\n trustDiscount,\n type EdgeMetadata,\n type PropagationResult,\n type SLOpinion,\n} from \"@lucern/confidence\";\nimport type {\n EdgePropagationSpec,\n PropagationEdgeRecord,\n} from \"./propagationTypes\";\n\nexport function readEdgeMetadata<TNodeId extends string>(\n edge: PropagationEdgeRecord<TNodeId>\n): EdgeMetadata {\n return {\n constraint: edge.constraint ?? undefined,\n normalization: edge.normalization ?? undefined,\n propagation: edge.propagation ?? undefined,\n conditionalA: edge.conditionalA ?? undefined,\n conditionalNotA: edge.conditionalNotA ?? undefined,\n };\n}\n\nexport function applyPerHopDamping(\n sourceOpinion: SLOpinion,\n damping: number\n): SLOpinion {\n if (damping >= 1) {\n return sourceOpinion;\n }\n\n return trustDiscount(sourceOpinion, Math.max(0, damping));\n}\n\nexport function annotateRationale(\n result: PropagationResult,\n spec: EdgePropagationSpec,\n hop: number\n): PropagationResult {\n return {\n ...result,\n rationale: `hop=${hop} edge=${spec.edgeType} damping=${spec.damping.toFixed(\n 2\n )} :: ${result.rationale}`,\n };\n}\n\nexport function propagatePositiveSupport(\n sourceOpinion: SLOpinion,\n targetOpinion: SLOpinion,\n edgeWeight: number\n): PropagationResult {\n const discounted = trustDiscount(sourceOpinion, Math.abs(edgeWeight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${edgeWeight.toFixed(\n 2\n )}) from source at ${project(sourceOpinion).toFixed(2)}`,\n };\n}\n\nexport function propagatePositiveInform(\n sourceOpinion: SLOpinion,\n targetOpinion: SLOpinion,\n edgeWeight: number\n): PropagationResult {\n const discounted = trustDiscount(sourceOpinion, Math.abs(edgeWeight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${edgeWeight.toFixed(2)})`,\n };\n}\n\nexport function propagateNegativeSupportWithMetadata(\n sourceOpinion: SLOpinion,\n targetOpinion: SLOpinion,\n edgeWeight: number,\n edge: PropagationEdgeRecord\n): PropagationResult {\n return applyNegativeSupport(\n sourceOpinion,\n targetOpinion,\n edgeWeight,\n readEdgeMetadata(edge)\n );\n}\n\nexport const propagateNegativeInform = applyNegativeEvidence;\n","import type { EdgePropagationSpec } from \"./propagationTypes\";\nimport {\n annotateRationale,\n applyPerHopDamping,\n propagateNegativeInform,\n} from \"./utils\";\n\nexport const refutesPropagationSpec: EdgePropagationSpec = {\n edgeType: \"refutes\",\n direction: \"outgoing\",\n transitivity: \"none\",\n damping: 0.9,\n maxHops: 1,\n operator: (sourceOpinion, targetOpinion, edge, context) => {\n const dampedSource = applyPerHopDamping(\n sourceOpinion,\n context.spec.damping\n );\n const negativeWeight = -Math.abs(edge.weight ?? 1);\n const result = propagateNegativeInform(\n dampedSource,\n targetOpinion,\n negativeWeight\n );\n\n return annotateRationale(result, context.spec, context.hop);\n },\n description:\n \"Explicit negative evidence semantics. Refutes is treated as strong one-hop counter-evidence.\",\n};\n\n"]}
|
package/dist/edges/supports.js
CHANGED
|
@@ -1,125 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
function opinion(belief, disbelief, uncertainty, baseRate = 0.5) {
|
|
3
|
-
const b = Math.max(0, Math.min(1, belief));
|
|
4
|
-
const d = Math.max(0, Math.min(1, disbelief));
|
|
5
|
-
const u = Math.max(0, Math.min(1, uncertainty));
|
|
6
|
-
const a = Math.max(0, Math.min(1, baseRate));
|
|
7
|
-
const sum = b + d + u;
|
|
8
|
-
if (sum === 0) {
|
|
9
|
-
return { b: 0, d: 0, u: 1, a };
|
|
10
|
-
}
|
|
11
|
-
return {
|
|
12
|
-
b: b / sum,
|
|
13
|
-
d: d / sum,
|
|
14
|
-
u: u / sum,
|
|
15
|
-
a
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
function vacuous(baseRate = 0.5) {
|
|
19
|
-
return { b: 0, d: 0, u: 1, a: baseRate };
|
|
20
|
-
}
|
|
21
|
-
function project(o) {
|
|
22
|
-
return o.b + o.a * o.u;
|
|
23
|
-
}
|
|
24
|
-
function cumulativeFusion(left, right) {
|
|
25
|
-
if (left.u === 0 && right.u === 0) {
|
|
26
|
-
return opinion(
|
|
27
|
-
(left.b + right.b) / 2,
|
|
28
|
-
(left.d + right.d) / 2,
|
|
29
|
-
0,
|
|
30
|
-
(left.a + right.a) / 2
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
const k = left.u + right.u - left.u * right.u;
|
|
34
|
-
if (k === 0) {
|
|
35
|
-
return vacuous((left.a + right.a) / 2);
|
|
36
|
-
}
|
|
37
|
-
return opinion(
|
|
38
|
-
(left.b * right.u + right.b * left.u) / k,
|
|
39
|
-
(left.d * right.u + right.d * left.u) / k,
|
|
40
|
-
left.u * right.u / k,
|
|
41
|
-
(left.a + right.a) / 2
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
function trustDiscount(sourceOpinion, trust) {
|
|
45
|
-
const weight = Math.max(0, Math.min(1, Math.abs(trust)));
|
|
46
|
-
return opinion(
|
|
47
|
-
weight * sourceOpinion.b,
|
|
48
|
-
weight * sourceOpinion.d,
|
|
49
|
-
1 - weight * (sourceOpinion.b + sourceOpinion.d),
|
|
50
|
-
sourceOpinion.a
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
function negate(o) {
|
|
54
|
-
return { b: o.d, d: o.b, u: o.u, a: 1 - o.a };
|
|
55
|
-
}
|
|
56
|
-
function constraintFusion(left, right, mode = "pressure") {
|
|
57
|
-
if (mode === "redistribute") {
|
|
58
|
-
const leftProjected = project(left);
|
|
59
|
-
const rightProjected = project(right);
|
|
60
|
-
const total = leftProjected + rightProjected;
|
|
61
|
-
if (total <= 1) {
|
|
62
|
-
return { o1: left, o2: right };
|
|
63
|
-
}
|
|
64
|
-
const scale = 1 / total;
|
|
65
|
-
return {
|
|
66
|
-
o1: opinion(
|
|
67
|
-
left.b * scale,
|
|
68
|
-
left.d + left.b * (1 - scale),
|
|
69
|
-
left.u,
|
|
70
|
-
left.a
|
|
71
|
-
),
|
|
72
|
-
o2: opinion(
|
|
73
|
-
right.b * scale,
|
|
74
|
-
right.d + right.b * (1 - scale),
|
|
75
|
-
right.u,
|
|
76
|
-
right.a
|
|
77
|
-
)
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
const pressureLeft = right.b * 0.5;
|
|
81
|
-
const pressureRight = left.b * 0.5;
|
|
82
|
-
return {
|
|
83
|
-
o1: opinion(
|
|
84
|
-
left.b - pressureLeft * 0.3,
|
|
85
|
-
left.d + pressureLeft * 0.3,
|
|
86
|
-
left.u,
|
|
87
|
-
left.a
|
|
88
|
-
),
|
|
89
|
-
o2: opinion(
|
|
90
|
-
right.b - pressureRight * 0.3,
|
|
91
|
-
right.d + pressureRight * 0.3,
|
|
92
|
-
right.u,
|
|
93
|
-
right.a
|
|
94
|
-
)
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// ../confidence/src/v1/operations/dynamics/defeat.ts
|
|
99
|
-
function applyNegativeSupport(source, target, weight, metadata = {}) {
|
|
100
|
-
if (metadata.constraint === "xor") {
|
|
101
|
-
const result = constraintFusion(
|
|
102
|
-
source,
|
|
103
|
-
target,
|
|
104
|
-
metadata.normalization ?? "pressure"
|
|
105
|
-
);
|
|
106
|
-
return {
|
|
107
|
-
opinion: result.o2,
|
|
108
|
-
operator: "constraint_fusion",
|
|
109
|
-
rationale: `XOR constraint: source belief at ${project(source).toFixed(
|
|
110
|
-
2
|
|
111
|
-
)} pressures target`
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
const discounted = trustDiscount(negate(source), Math.abs(weight));
|
|
115
|
-
return {
|
|
116
|
-
opinion: cumulativeFusion(target, discounted),
|
|
117
|
-
operator: "cumulative_fusion",
|
|
118
|
-
rationale: `Contradicting evidence (weight=${weight.toFixed(
|
|
119
|
-
2
|
|
120
|
-
)}) from source at ${project(source).toFixed(2)}`
|
|
121
|
-
};
|
|
122
|
-
}
|
|
1
|
+
import { trustDiscount, applyNegativeSupport, project, cumulativeFusion } from '@lucern/confidence';
|
|
123
2
|
|
|
124
3
|
// src/edges/utils.ts
|
|
125
4
|
function readEdgeMetadata(edge) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../confidence/src/v1/operations/subjectiveLogic/index.ts","../../../confidence/src/v1/operations/dynamics/defeat.ts","../../src/edges/utils.ts","../../src/edges/supports.ts"],"names":[],"mappings":"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","file":"supports.js","sourcesContent":["import type { Opinion } from \"../../types\";\n\nexport function opinion(\n belief: number,\n disbelief: number,\n uncertainty: number,\n baseRate: number = 0.5\n): Opinion {\n const b = Math.max(0, Math.min(1, belief));\n const d = Math.max(0, Math.min(1, disbelief));\n const u = Math.max(0, Math.min(1, uncertainty));\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 };\n }\n\n return {\n b: b / sum,\n d: d / sum,\n u: u / sum,\n a,\n };\n}\n\nexport function vacuous(baseRate: number = 0.5): Opinion {\n return { b: 0, d: 0, u: 1, a: baseRate };\n}\n\nexport function dogmatic(probability: number, baseRate: number = 0.5): Opinion {\n const p = Math.max(0, Math.min(1, probability));\n return { b: p, d: 1 - p, u: 0, a: baseRate };\n}\n\nexport function project(o: Opinion): number {\n return o.b + o.a * o.u;\n}\n\nexport function confidenceLevel(o: Opinion): \"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\nexport function cumulativeFusion(left: Opinion, right: Opinion): Opinion {\n if (left.u === 0 && right.u === 0) {\n return opinion(\n (left.b + right.b) / 2,\n (left.d + right.d) / 2,\n 0,\n (left.a + right.a) / 2\n );\n }\n\n const k = left.u + right.u - left.u * right.u;\n if (k === 0) {\n return vacuous((left.a + right.a) / 2);\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 (left.a + right.a) / 2\n );\n}\n\nexport function averagingFusion(left: Opinion, right: Opinion): Opinion {\n if (left.u === 0 && right.u === 0) {\n return opinion(\n (left.b + right.b) / 2,\n (left.d + right.d) / 2,\n 0,\n (left.a + right.a) / 2\n );\n }\n\n const k = left.u + right.u;\n if (k === 0) {\n return vacuous((left.a + right.a) / 2);\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 (left.a + right.a) / 2\n );\n}\n\nexport function trustDiscount(sourceOpinion: Opinion, trust: number): Opinion {\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: Opinion,\n ifFalse: Opinion,\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: Opinion,\n ifTrue: Opinion,\n ifFalse: Opinion,\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: Opinion,\n ifTrue: Opinion,\n ifFalse: Opinion,\n fallbackBaseRate?: number\n): Opinion {\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: Opinion,\n ifTrue: Opinion,\n ifFalse: Opinion,\n baseRateX: number\n): Opinion {\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: Opinion): Opinion {\n return { b: o.d, d: o.b, u: o.u, a: 1 - o.a };\n}\n\nexport function constraintFusion(\n left: Opinion,\n right: Opinion,\n mode: \"pressure\" | \"redistribute\" = \"pressure\"\n): { o1: Opinion; o2: Opinion } {\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: Opinion): 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: Opinion, right: Opinion): 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: Opinion): 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 { EdgeMetadata, Opinion, PropagationResult } from \"../../types\";\nimport {\n constraintFusion,\n cumulativeFusion,\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 if (metadata.constraint === \"xor\") {\n const result = constraintFusion(\n source,\n target,\n metadata.normalization ?? \"pressure\"\n );\n return {\n opinion: result.o2,\n operator: \"constraint_fusion\",\n rationale: `XOR constraint: source belief at ${project(source).toFixed(\n 2\n )} pressures target`,\n };\n }\n\n const discounted = trustDiscount(negate(source), Math.abs(weight));\n return {\n opinion: cumulativeFusion(target, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Contradicting evidence (weight=${weight.toFixed(\n 2\n )}) from source at ${project(source).toFixed(2)}`,\n };\n}\n\nexport function applyNegativeEvidence(\n source: Opinion,\n target: Opinion,\n weight: number\n): PropagationResult {\n const discounted = trustDiscount(negate(source), Math.abs(weight));\n return {\n opinion: cumulativeFusion(target, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Contradicting evidence (weight=${weight.toFixed(2)})`,\n };\n}\n","import {\n applyNegativeEvidence,\n applyNegativeSupport,\n cumulativeFusion,\n project,\n trustDiscount,\n type EdgeMetadata,\n type Opinion,\n type PropagationResult,\n} from \"@lucern/confidence\";\nimport type {\n EdgePropagationSpec,\n PropagationEdgeRecord,\n} from \"./propagationTypes\";\n\nexport function readEdgeMetadata<TNodeId extends string>(\n edge: PropagationEdgeRecord<TNodeId>\n): EdgeMetadata {\n return {\n constraint: edge.constraint ?? undefined,\n normalization: edge.normalization ?? undefined,\n propagation: edge.propagation ?? undefined,\n conditionalA: edge.conditionalA ?? undefined,\n conditionalNotA: edge.conditionalNotA ?? undefined,\n };\n}\n\nexport function applyPerHopDamping(\n sourceOpinion: Opinion,\n damping: number\n): Opinion {\n if (damping >= 1) {\n return sourceOpinion;\n }\n\n return trustDiscount(sourceOpinion, Math.max(0, damping));\n}\n\nexport function annotateRationale(\n result: PropagationResult,\n spec: EdgePropagationSpec,\n hop: number\n): PropagationResult {\n return {\n ...result,\n rationale: `hop=${hop} edge=${spec.edgeType} damping=${spec.damping.toFixed(\n 2\n )} :: ${result.rationale}`,\n };\n}\n\nexport function propagatePositiveSupport(\n sourceOpinion: Opinion,\n targetOpinion: Opinion,\n edgeWeight: number\n): PropagationResult {\n const discounted = trustDiscount(sourceOpinion, Math.abs(edgeWeight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${edgeWeight.toFixed(\n 2\n )}) from source at ${project(sourceOpinion).toFixed(2)}`,\n };\n}\n\nexport function propagatePositiveInform(\n sourceOpinion: Opinion,\n targetOpinion: Opinion,\n edgeWeight: number\n): PropagationResult {\n const discounted = trustDiscount(sourceOpinion, Math.abs(edgeWeight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${edgeWeight.toFixed(2)})`,\n };\n}\n\nexport function propagateNegativeSupportWithMetadata(\n sourceOpinion: Opinion,\n targetOpinion: Opinion,\n edgeWeight: number,\n edge: PropagationEdgeRecord\n): PropagationResult {\n return applyNegativeSupport(\n sourceOpinion,\n targetOpinion,\n edgeWeight,\n readEdgeMetadata(edge)\n );\n}\n\nexport function propagateNegativeInform(\n sourceOpinion: Opinion,\n targetOpinion: Opinion,\n edgeWeight: number\n): PropagationResult {\n return applyNegativeEvidence(sourceOpinion, targetOpinion, edgeWeight);\n}\n\n","import type { EdgePropagationSpec } from \"./propagationTypes\";\nimport {\n annotateRationale,\n applyPerHopDamping,\n propagateNegativeSupportWithMetadata,\n propagatePositiveSupport,\n} from \"./utils\";\n\nexport const supportsPropagationSpec: EdgePropagationSpec = {\n edgeType: \"supports\",\n direction: \"outgoing\",\n transitivity: \"full\",\n damping: 0.85,\n maxHops: \"unbounded\",\n operator: (sourceOpinion, targetOpinion, edge, context) => {\n const dampedSource = applyPerHopDamping(\n sourceOpinion,\n context.spec.damping\n );\n const weight = edge.weight ?? 1;\n const result =\n weight < 0\n ? propagateNegativeSupportWithMetadata(\n dampedSource,\n targetOpinion,\n weight,\n edge\n )\n : propagatePositiveSupport(dampedSource, targetOpinion, weight);\n\n return annotateRationale(result, context.spec, context.hop);\n },\n description:\n \"Belief-to-belief influence. Supports chains transitively with moderate per-hop damping.\",\n};\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/edges/utils.ts","../../src/edges/supports.ts"],"names":[],"mappings":";;;AAeO,SAAS,iBACd,IAAA,EACc;AACd,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,KAAK,UAAA,IAAc,MAAA;AAAA,IAC/B,aAAA,EAAe,KAAK,aAAA,IAAiB,MAAA;AAAA,IACrC,WAAA,EAAa,KAAK,WAAA,IAAe,MAAA;AAAA,IACjC,YAAA,EAAc,KAAK,YAAA,IAAgB,MAAA;AAAA,IACnC,eAAA,EAAiB,KAAK,eAAA,IAAmB;AAAA,GAC3C;AACF;AAEO,SAAS,kBAAA,CACd,eACA,OAAA,EACW;AACX,EAAA,IAAI,WAAW,CAAA,EAAG;AAChB,IAAA,OAAO,aAAA;AAAA,EACT;AAEA,EAAA,OAAO,cAAc,aAAA,EAAe,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAO,CAAC,CAAA;AAC1D;AAEO,SAAS,iBAAA,CACd,MAAA,EACA,IAAA,EACA,GAAA,EACmB;AACnB,EAAA,OAAO;AAAA,IACL,GAAG,MAAA;AAAA,IACH,SAAA,EAAW,OAAO,GAAG,CAAA,MAAA,EAAS,KAAK,QAAQ,CAAA,SAAA,EAAY,KAAK,OAAA,CAAQ,OAAA;AAAA,MAClE;AAAA,KACD,CAAA,IAAA,EAAO,MAAA,CAAO,SAAS,CAAA;AAAA,GAC1B;AACF;AAEO,SAAS,wBAAA,CACd,aAAA,EACA,aAAA,EACA,UAAA,EACmB;AACnB,EAAA,MAAM,aAAa,aAAA,CAAc,aAAA,EAAe,IAAA,CAAK,GAAA,CAAI,UAAU,CAAC,CAAA;AACpE,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,gBAAA,CAAiB,aAAA,EAAe,UAAU,CAAA;AAAA,IACnD,QAAA,EAAU,mBAAA;AAAA,IACV,SAAA,EAAW,+BAA+B,UAAA,CAAW,OAAA;AAAA,MACnD;AAAA,KACD,CAAA,iBAAA,EAAoB,OAAA,CAAQ,aAAa,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAA;AAAA,GACxD;AACF;AAeO,SAAS,oCAAA,CACd,aAAA,EACA,aAAA,EACA,UAAA,EACA,IAAA,EACmB;AACnB,EAAA,OAAO,oBAAA;AAAA,IACL,aAAA;AAAA,IACA,aAAA;AAAA,IACA,UAAA;AAAA,IACA,iBAAiB,IAAI;AAAA,GACvB;AACF;;;ACnFO,IAAM,uBAAA,GAA+C;AAAA,EAC1D,QAAA,EAAU,UAAA;AAAA,EACV,SAAA,EAAW,UAAA;AAAA,EACX,YAAA,EAAc,MAAA;AAAA,EACd,OAAA,EAAS,IAAA;AAAA,EACT,OAAA,EAAS,WAAA;AAAA,EACT,QAAA,EAAU,CAAC,aAAA,EAAe,aAAA,EAAe,MAAM,OAAA,KAAY;AACzD,IAAA,MAAM,YAAA,GAAe,kBAAA;AAAA,MACnB,aAAA;AAAA,MACA,QAAQ,IAAA,CAAK;AAAA,KACf;AACA,IAAA,MAAM,MAAA,GAAS,KAAK,MAAA,IAAU,CAAA;AAC9B,IAAA,MAAM,MAAA,GACJ,SAAS,CAAA,GACL,oCAAA;AAAA,MACE,YAAA;AAAA,MACA,aAAA;AAAA,MACA,MAAA;AAAA,MACA;AAAA,KACF,GACA,wBAAA,CAAyB,YAAA,EAAc,aAAA,EAAe,MAAM,CAAA;AAElE,IAAA,OAAO,iBAAA,CAAkB,MAAA,EAAQ,OAAA,CAAQ,IAAA,EAAM,QAAQ,GAAG,CAAA;AAAA,EAC5D,CAAA;AAAA,EACA,WAAA,EACE;AACJ","file":"supports.js","sourcesContent":["import {\n applyNegativeEvidence,\n applyNegativeSupport,\n cumulativeFusion,\n project,\n trustDiscount,\n type EdgeMetadata,\n type PropagationResult,\n type SLOpinion,\n} from \"@lucern/confidence\";\nimport type {\n EdgePropagationSpec,\n PropagationEdgeRecord,\n} from \"./propagationTypes\";\n\nexport function readEdgeMetadata<TNodeId extends string>(\n edge: PropagationEdgeRecord<TNodeId>\n): EdgeMetadata {\n return {\n constraint: edge.constraint ?? undefined,\n normalization: edge.normalization ?? undefined,\n propagation: edge.propagation ?? undefined,\n conditionalA: edge.conditionalA ?? undefined,\n conditionalNotA: edge.conditionalNotA ?? undefined,\n };\n}\n\nexport function applyPerHopDamping(\n sourceOpinion: SLOpinion,\n damping: number\n): SLOpinion {\n if (damping >= 1) {\n return sourceOpinion;\n }\n\n return trustDiscount(sourceOpinion, Math.max(0, damping));\n}\n\nexport function annotateRationale(\n result: PropagationResult,\n spec: EdgePropagationSpec,\n hop: number\n): PropagationResult {\n return {\n ...result,\n rationale: `hop=${hop} edge=${spec.edgeType} damping=${spec.damping.toFixed(\n 2\n )} :: ${result.rationale}`,\n };\n}\n\nexport function propagatePositiveSupport(\n sourceOpinion: SLOpinion,\n targetOpinion: SLOpinion,\n edgeWeight: number\n): PropagationResult {\n const discounted = trustDiscount(sourceOpinion, Math.abs(edgeWeight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${edgeWeight.toFixed(\n 2\n )}) from source at ${project(sourceOpinion).toFixed(2)}`,\n };\n}\n\nexport function propagatePositiveInform(\n sourceOpinion: SLOpinion,\n targetOpinion: SLOpinion,\n edgeWeight: number\n): PropagationResult {\n const discounted = trustDiscount(sourceOpinion, Math.abs(edgeWeight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${edgeWeight.toFixed(2)})`,\n };\n}\n\nexport function propagateNegativeSupportWithMetadata(\n sourceOpinion: SLOpinion,\n targetOpinion: SLOpinion,\n edgeWeight: number,\n edge: PropagationEdgeRecord\n): PropagationResult {\n return applyNegativeSupport(\n sourceOpinion,\n targetOpinion,\n edgeWeight,\n readEdgeMetadata(edge)\n );\n}\n\nexport const propagateNegativeInform = applyNegativeEvidence;\n","import type { EdgePropagationSpec } from \"./propagationTypes\";\nimport {\n annotateRationale,\n applyPerHopDamping,\n propagateNegativeSupportWithMetadata,\n propagatePositiveSupport,\n} from \"./utils\";\n\nexport const supportsPropagationSpec: EdgePropagationSpec = {\n edgeType: \"supports\",\n direction: \"outgoing\",\n transitivity: \"full\",\n damping: 0.85,\n maxHops: \"unbounded\",\n operator: (sourceOpinion, targetOpinion, edge, context) => {\n const dampedSource = applyPerHopDamping(\n sourceOpinion,\n context.spec.damping\n );\n const weight = edge.weight ?? 1;\n const result =\n weight < 0\n ? propagateNegativeSupportWithMetadata(\n dampedSource,\n targetOpinion,\n weight,\n edge\n )\n : propagatePositiveSupport(dampedSource, targetOpinion, weight);\n\n return annotateRationale(result, context.spec, context.hop);\n },\n description:\n \"Belief-to-belief influence. Supports chains transitively with moderate per-hop damping.\",\n};\n\n"]}
|
package/dist/edges/utils.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { PropagationResult, SLOpinion, applyNegativeEvidence, EdgeMetadata } from '@lucern/confidence';
|
|
2
|
+
import { EdgePropagationSpec, PropagationEdgeRecord } from './propagationTypes.js';
|
|
3
3
|
|
|
4
4
|
declare function readEdgeMetadata<TNodeId extends string>(edge: PropagationEdgeRecord<TNodeId>): EdgeMetadata;
|
|
5
|
-
declare function applyPerHopDamping(sourceOpinion:
|
|
5
|
+
declare function applyPerHopDamping(sourceOpinion: SLOpinion, damping: number): SLOpinion;
|
|
6
6
|
declare function annotateRationale(result: PropagationResult, spec: EdgePropagationSpec, hop: number): PropagationResult;
|
|
7
|
-
declare function propagatePositiveSupport(sourceOpinion:
|
|
8
|
-
declare function propagatePositiveInform(sourceOpinion:
|
|
9
|
-
declare function propagateNegativeSupportWithMetadata(sourceOpinion:
|
|
10
|
-
declare
|
|
7
|
+
declare function propagatePositiveSupport(sourceOpinion: SLOpinion, targetOpinion: SLOpinion, edgeWeight: number): PropagationResult;
|
|
8
|
+
declare function propagatePositiveInform(sourceOpinion: SLOpinion, targetOpinion: SLOpinion, edgeWeight: number): PropagationResult;
|
|
9
|
+
declare function propagateNegativeSupportWithMetadata(sourceOpinion: SLOpinion, targetOpinion: SLOpinion, edgeWeight: number, edge: PropagationEdgeRecord): PropagationResult;
|
|
10
|
+
declare const propagateNegativeInform: typeof applyNegativeEvidence;
|
|
11
11
|
|
|
12
12
|
export { annotateRationale, applyPerHopDamping, propagateNegativeInform, propagateNegativeSupportWithMetadata, propagatePositiveInform, propagatePositiveSupport, readEdgeMetadata };
|
package/dist/edges/utils.js
CHANGED
|
@@ -1,133 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
function opinion(belief, disbelief, uncertainty, baseRate = 0.5) {
|
|
3
|
-
const b = Math.max(0, Math.min(1, belief));
|
|
4
|
-
const d = Math.max(0, Math.min(1, disbelief));
|
|
5
|
-
const u = Math.max(0, Math.min(1, uncertainty));
|
|
6
|
-
const a = Math.max(0, Math.min(1, baseRate));
|
|
7
|
-
const sum = b + d + u;
|
|
8
|
-
if (sum === 0) {
|
|
9
|
-
return { b: 0, d: 0, u: 1, a };
|
|
10
|
-
}
|
|
11
|
-
return {
|
|
12
|
-
b: b / sum,
|
|
13
|
-
d: d / sum,
|
|
14
|
-
u: u / sum,
|
|
15
|
-
a
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
function vacuous(baseRate = 0.5) {
|
|
19
|
-
return { b: 0, d: 0, u: 1, a: baseRate };
|
|
20
|
-
}
|
|
21
|
-
function project(o) {
|
|
22
|
-
return o.b + o.a * o.u;
|
|
23
|
-
}
|
|
24
|
-
function cumulativeFusion(left, right) {
|
|
25
|
-
if (left.u === 0 && right.u === 0) {
|
|
26
|
-
return opinion(
|
|
27
|
-
(left.b + right.b) / 2,
|
|
28
|
-
(left.d + right.d) / 2,
|
|
29
|
-
0,
|
|
30
|
-
(left.a + right.a) / 2
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
const k = left.u + right.u - left.u * right.u;
|
|
34
|
-
if (k === 0) {
|
|
35
|
-
return vacuous((left.a + right.a) / 2);
|
|
36
|
-
}
|
|
37
|
-
return opinion(
|
|
38
|
-
(left.b * right.u + right.b * left.u) / k,
|
|
39
|
-
(left.d * right.u + right.d * left.u) / k,
|
|
40
|
-
left.u * right.u / k,
|
|
41
|
-
(left.a + right.a) / 2
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
function trustDiscount(sourceOpinion, trust) {
|
|
45
|
-
const weight = Math.max(0, Math.min(1, Math.abs(trust)));
|
|
46
|
-
return opinion(
|
|
47
|
-
weight * sourceOpinion.b,
|
|
48
|
-
weight * sourceOpinion.d,
|
|
49
|
-
1 - weight * (sourceOpinion.b + sourceOpinion.d),
|
|
50
|
-
sourceOpinion.a
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
function negate(o) {
|
|
54
|
-
return { b: o.d, d: o.b, u: o.u, a: 1 - o.a };
|
|
55
|
-
}
|
|
56
|
-
function constraintFusion(left, right, mode = "pressure") {
|
|
57
|
-
if (mode === "redistribute") {
|
|
58
|
-
const leftProjected = project(left);
|
|
59
|
-
const rightProjected = project(right);
|
|
60
|
-
const total = leftProjected + rightProjected;
|
|
61
|
-
if (total <= 1) {
|
|
62
|
-
return { o1: left, o2: right };
|
|
63
|
-
}
|
|
64
|
-
const scale = 1 / total;
|
|
65
|
-
return {
|
|
66
|
-
o1: opinion(
|
|
67
|
-
left.b * scale,
|
|
68
|
-
left.d + left.b * (1 - scale),
|
|
69
|
-
left.u,
|
|
70
|
-
left.a
|
|
71
|
-
),
|
|
72
|
-
o2: opinion(
|
|
73
|
-
right.b * scale,
|
|
74
|
-
right.d + right.b * (1 - scale),
|
|
75
|
-
right.u,
|
|
76
|
-
right.a
|
|
77
|
-
)
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
const pressureLeft = right.b * 0.5;
|
|
81
|
-
const pressureRight = left.b * 0.5;
|
|
82
|
-
return {
|
|
83
|
-
o1: opinion(
|
|
84
|
-
left.b - pressureLeft * 0.3,
|
|
85
|
-
left.d + pressureLeft * 0.3,
|
|
86
|
-
left.u,
|
|
87
|
-
left.a
|
|
88
|
-
),
|
|
89
|
-
o2: opinion(
|
|
90
|
-
right.b - pressureRight * 0.3,
|
|
91
|
-
right.d + pressureRight * 0.3,
|
|
92
|
-
right.u,
|
|
93
|
-
right.a
|
|
94
|
-
)
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// ../confidence/src/v1/operations/dynamics/defeat.ts
|
|
99
|
-
function applyNegativeSupport(source, target, weight, metadata = {}) {
|
|
100
|
-
if (metadata.constraint === "xor") {
|
|
101
|
-
const result = constraintFusion(
|
|
102
|
-
source,
|
|
103
|
-
target,
|
|
104
|
-
metadata.normalization ?? "pressure"
|
|
105
|
-
);
|
|
106
|
-
return {
|
|
107
|
-
opinion: result.o2,
|
|
108
|
-
operator: "constraint_fusion",
|
|
109
|
-
rationale: `XOR constraint: source belief at ${project(source).toFixed(
|
|
110
|
-
2
|
|
111
|
-
)} pressures target`
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
const discounted = trustDiscount(negate(source), Math.abs(weight));
|
|
115
|
-
return {
|
|
116
|
-
opinion: cumulativeFusion(target, discounted),
|
|
117
|
-
operator: "cumulative_fusion",
|
|
118
|
-
rationale: `Contradicting evidence (weight=${weight.toFixed(
|
|
119
|
-
2
|
|
120
|
-
)}) from source at ${project(source).toFixed(2)}`
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
function applyNegativeEvidence(source, target, weight) {
|
|
124
|
-
const discounted = trustDiscount(negate(source), Math.abs(weight));
|
|
125
|
-
return {
|
|
126
|
-
opinion: cumulativeFusion(target, discounted),
|
|
127
|
-
operator: "cumulative_fusion",
|
|
128
|
-
rationale: `Contradicting evidence (weight=${weight.toFixed(2)})`
|
|
129
|
-
};
|
|
130
|
-
}
|
|
1
|
+
import { applyNegativeEvidence, trustDiscount, project, cumulativeFusion, applyNegativeSupport } from '@lucern/confidence';
|
|
131
2
|
|
|
132
3
|
// src/edges/utils.ts
|
|
133
4
|
function readEdgeMetadata(edge) {
|
|
@@ -179,9 +50,7 @@ function propagateNegativeSupportWithMetadata(sourceOpinion, targetOpinion, edge
|
|
|
179
50
|
readEdgeMetadata(edge)
|
|
180
51
|
);
|
|
181
52
|
}
|
|
182
|
-
|
|
183
|
-
return applyNegativeEvidence(sourceOpinion, targetOpinion, edgeWeight);
|
|
184
|
-
}
|
|
53
|
+
var propagateNegativeInform = applyNegativeEvidence;
|
|
185
54
|
|
|
186
55
|
export { annotateRationale, applyPerHopDamping, propagateNegativeInform, propagateNegativeSupportWithMetadata, propagatePositiveInform, propagatePositiveSupport, readEdgeMetadata };
|
|
187
56
|
//# sourceMappingURL=utils.js.map
|
package/dist/edges/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../confidence/src/v1/operations/subjectiveLogic/index.ts","../../../confidence/src/v1/operations/dynamics/defeat.ts","../../src/edges/utils.ts"],"names":[],"mappings":"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","file":"utils.js","sourcesContent":["import type { Opinion } from \"../../types\";\n\nexport function opinion(\n belief: number,\n disbelief: number,\n uncertainty: number,\n baseRate: number = 0.5\n): Opinion {\n const b = Math.max(0, Math.min(1, belief));\n const d = Math.max(0, Math.min(1, disbelief));\n const u = Math.max(0, Math.min(1, uncertainty));\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 };\n }\n\n return {\n b: b / sum,\n d: d / sum,\n u: u / sum,\n a,\n };\n}\n\nexport function vacuous(baseRate: number = 0.5): Opinion {\n return { b: 0, d: 0, u: 1, a: baseRate };\n}\n\nexport function dogmatic(probability: number, baseRate: number = 0.5): Opinion {\n const p = Math.max(0, Math.min(1, probability));\n return { b: p, d: 1 - p, u: 0, a: baseRate };\n}\n\nexport function project(o: Opinion): number {\n return o.b + o.a * o.u;\n}\n\nexport function confidenceLevel(o: Opinion): \"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\nexport function cumulativeFusion(left: Opinion, right: Opinion): Opinion {\n if (left.u === 0 && right.u === 0) {\n return opinion(\n (left.b + right.b) / 2,\n (left.d + right.d) / 2,\n 0,\n (left.a + right.a) / 2\n );\n }\n\n const k = left.u + right.u - left.u * right.u;\n if (k === 0) {\n return vacuous((left.a + right.a) / 2);\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 (left.a + right.a) / 2\n );\n}\n\nexport function averagingFusion(left: Opinion, right: Opinion): Opinion {\n if (left.u === 0 && right.u === 0) {\n return opinion(\n (left.b + right.b) / 2,\n (left.d + right.d) / 2,\n 0,\n (left.a + right.a) / 2\n );\n }\n\n const k = left.u + right.u;\n if (k === 0) {\n return vacuous((left.a + right.a) / 2);\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 (left.a + right.a) / 2\n );\n}\n\nexport function trustDiscount(sourceOpinion: Opinion, trust: number): Opinion {\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: Opinion,\n ifFalse: Opinion,\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: Opinion,\n ifTrue: Opinion,\n ifFalse: Opinion,\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: Opinion,\n ifTrue: Opinion,\n ifFalse: Opinion,\n fallbackBaseRate?: number\n): Opinion {\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: Opinion,\n ifTrue: Opinion,\n ifFalse: Opinion,\n baseRateX: number\n): Opinion {\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: Opinion): Opinion {\n return { b: o.d, d: o.b, u: o.u, a: 1 - o.a };\n}\n\nexport function constraintFusion(\n left: Opinion,\n right: Opinion,\n mode: \"pressure\" | \"redistribute\" = \"pressure\"\n): { o1: Opinion; o2: Opinion } {\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: Opinion): 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: Opinion, right: Opinion): 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: Opinion): 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 { EdgeMetadata, Opinion, PropagationResult } from \"../../types\";\nimport {\n constraintFusion,\n cumulativeFusion,\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 if (metadata.constraint === \"xor\") {\n const result = constraintFusion(\n source,\n target,\n metadata.normalization ?? \"pressure\"\n );\n return {\n opinion: result.o2,\n operator: \"constraint_fusion\",\n rationale: `XOR constraint: source belief at ${project(source).toFixed(\n 2\n )} pressures target`,\n };\n }\n\n const discounted = trustDiscount(negate(source), Math.abs(weight));\n return {\n opinion: cumulativeFusion(target, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Contradicting evidence (weight=${weight.toFixed(\n 2\n )}) from source at ${project(source).toFixed(2)}`,\n };\n}\n\nexport function applyNegativeEvidence(\n source: Opinion,\n target: Opinion,\n weight: number\n): PropagationResult {\n const discounted = trustDiscount(negate(source), Math.abs(weight));\n return {\n opinion: cumulativeFusion(target, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Contradicting evidence (weight=${weight.toFixed(2)})`,\n };\n}\n","import {\n applyNegativeEvidence,\n applyNegativeSupport,\n cumulativeFusion,\n project,\n trustDiscount,\n type EdgeMetadata,\n type Opinion,\n type PropagationResult,\n} from \"@lucern/confidence\";\nimport type {\n EdgePropagationSpec,\n PropagationEdgeRecord,\n} from \"./propagationTypes\";\n\nexport function readEdgeMetadata<TNodeId extends string>(\n edge: PropagationEdgeRecord<TNodeId>\n): EdgeMetadata {\n return {\n constraint: edge.constraint ?? undefined,\n normalization: edge.normalization ?? undefined,\n propagation: edge.propagation ?? undefined,\n conditionalA: edge.conditionalA ?? undefined,\n conditionalNotA: edge.conditionalNotA ?? undefined,\n };\n}\n\nexport function applyPerHopDamping(\n sourceOpinion: Opinion,\n damping: number\n): Opinion {\n if (damping >= 1) {\n return sourceOpinion;\n }\n\n return trustDiscount(sourceOpinion, Math.max(0, damping));\n}\n\nexport function annotateRationale(\n result: PropagationResult,\n spec: EdgePropagationSpec,\n hop: number\n): PropagationResult {\n return {\n ...result,\n rationale: `hop=${hop} edge=${spec.edgeType} damping=${spec.damping.toFixed(\n 2\n )} :: ${result.rationale}`,\n };\n}\n\nexport function propagatePositiveSupport(\n sourceOpinion: Opinion,\n targetOpinion: Opinion,\n edgeWeight: number\n): PropagationResult {\n const discounted = trustDiscount(sourceOpinion, Math.abs(edgeWeight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${edgeWeight.toFixed(\n 2\n )}) from source at ${project(sourceOpinion).toFixed(2)}`,\n };\n}\n\nexport function propagatePositiveInform(\n sourceOpinion: Opinion,\n targetOpinion: Opinion,\n edgeWeight: number\n): PropagationResult {\n const discounted = trustDiscount(sourceOpinion, Math.abs(edgeWeight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${edgeWeight.toFixed(2)})`,\n };\n}\n\nexport function propagateNegativeSupportWithMetadata(\n sourceOpinion: Opinion,\n targetOpinion: Opinion,\n edgeWeight: number,\n edge: PropagationEdgeRecord\n): PropagationResult {\n return applyNegativeSupport(\n sourceOpinion,\n targetOpinion,\n edgeWeight,\n readEdgeMetadata(edge)\n );\n}\n\nexport function propagateNegativeInform(\n sourceOpinion: Opinion,\n targetOpinion: Opinion,\n edgeWeight: number\n): PropagationResult {\n return applyNegativeEvidence(sourceOpinion, targetOpinion, edgeWeight);\n}\n\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/edges/utils.ts"],"names":[],"mappings":";;;AAeO,SAAS,iBACd,IAAA,EACc;AACd,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,KAAK,UAAA,IAAc,MAAA;AAAA,IAC/B,aAAA,EAAe,KAAK,aAAA,IAAiB,MAAA;AAAA,IACrC,WAAA,EAAa,KAAK,WAAA,IAAe,MAAA;AAAA,IACjC,YAAA,EAAc,KAAK,YAAA,IAAgB,MAAA;AAAA,IACnC,eAAA,EAAiB,KAAK,eAAA,IAAmB;AAAA,GAC3C;AACF;AAEO,SAAS,kBAAA,CACd,eACA,OAAA,EACW;AACX,EAAA,IAAI,WAAW,CAAA,EAAG;AAChB,IAAA,OAAO,aAAA;AAAA,EACT;AAEA,EAAA,OAAO,cAAc,aAAA,EAAe,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAO,CAAC,CAAA;AAC1D;AAEO,SAAS,iBAAA,CACd,MAAA,EACA,IAAA,EACA,GAAA,EACmB;AACnB,EAAA,OAAO;AAAA,IACL,GAAG,MAAA;AAAA,IACH,SAAA,EAAW,OAAO,GAAG,CAAA,MAAA,EAAS,KAAK,QAAQ,CAAA,SAAA,EAAY,KAAK,OAAA,CAAQ,OAAA;AAAA,MAClE;AAAA,KACD,CAAA,IAAA,EAAO,MAAA,CAAO,SAAS,CAAA;AAAA,GAC1B;AACF;AAEO,SAAS,wBAAA,CACd,aAAA,EACA,aAAA,EACA,UAAA,EACmB;AACnB,EAAA,MAAM,aAAa,aAAA,CAAc,aAAA,EAAe,IAAA,CAAK,GAAA,CAAI,UAAU,CAAC,CAAA;AACpE,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,gBAAA,CAAiB,aAAA,EAAe,UAAU,CAAA;AAAA,IACnD,QAAA,EAAU,mBAAA;AAAA,IACV,SAAA,EAAW,+BAA+B,UAAA,CAAW,OAAA;AAAA,MACnD;AAAA,KACD,CAAA,iBAAA,EAAoB,OAAA,CAAQ,aAAa,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAA;AAAA,GACxD;AACF;AAEO,SAAS,uBAAA,CACd,aAAA,EACA,aAAA,EACA,UAAA,EACmB;AACnB,EAAA,MAAM,aAAa,aAAA,CAAc,aAAA,EAAe,IAAA,CAAK,GAAA,CAAI,UAAU,CAAC,CAAA;AACpE,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,gBAAA,CAAiB,aAAA,EAAe,UAAU,CAAA;AAAA,IACnD,QAAA,EAAU,mBAAA;AAAA,IACV,SAAA,EAAW,CAAA,4BAAA,EAA+B,UAAA,CAAW,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA;AAAA,GACjE;AACF;AAEO,SAAS,oCAAA,CACd,aAAA,EACA,aAAA,EACA,UAAA,EACA,IAAA,EACmB;AACnB,EAAA,OAAO,oBAAA;AAAA,IACL,aAAA;AAAA,IACA,aAAA;AAAA,IACA,UAAA;AAAA,IACA,iBAAiB,IAAI;AAAA,GACvB;AACF;AAEO,IAAM,uBAAA,GAA0B","file":"utils.js","sourcesContent":["import {\n applyNegativeEvidence,\n applyNegativeSupport,\n cumulativeFusion,\n project,\n trustDiscount,\n type EdgeMetadata,\n type PropagationResult,\n type SLOpinion,\n} from \"@lucern/confidence\";\nimport type {\n EdgePropagationSpec,\n PropagationEdgeRecord,\n} from \"./propagationTypes\";\n\nexport function readEdgeMetadata<TNodeId extends string>(\n edge: PropagationEdgeRecord<TNodeId>\n): EdgeMetadata {\n return {\n constraint: edge.constraint ?? undefined,\n normalization: edge.normalization ?? undefined,\n propagation: edge.propagation ?? undefined,\n conditionalA: edge.conditionalA ?? undefined,\n conditionalNotA: edge.conditionalNotA ?? undefined,\n };\n}\n\nexport function applyPerHopDamping(\n sourceOpinion: SLOpinion,\n damping: number\n): SLOpinion {\n if (damping >= 1) {\n return sourceOpinion;\n }\n\n return trustDiscount(sourceOpinion, Math.max(0, damping));\n}\n\nexport function annotateRationale(\n result: PropagationResult,\n spec: EdgePropagationSpec,\n hop: number\n): PropagationResult {\n return {\n ...result,\n rationale: `hop=${hop} edge=${spec.edgeType} damping=${spec.damping.toFixed(\n 2\n )} :: ${result.rationale}`,\n };\n}\n\nexport function propagatePositiveSupport(\n sourceOpinion: SLOpinion,\n targetOpinion: SLOpinion,\n edgeWeight: number\n): PropagationResult {\n const discounted = trustDiscount(sourceOpinion, Math.abs(edgeWeight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${edgeWeight.toFixed(\n 2\n )}) from source at ${project(sourceOpinion).toFixed(2)}`,\n };\n}\n\nexport function propagatePositiveInform(\n sourceOpinion: SLOpinion,\n targetOpinion: SLOpinion,\n edgeWeight: number\n): PropagationResult {\n const discounted = trustDiscount(sourceOpinion, Math.abs(edgeWeight));\n return {\n opinion: cumulativeFusion(targetOpinion, discounted),\n operator: \"cumulative_fusion\",\n rationale: `Supporting evidence (weight=${edgeWeight.toFixed(2)})`,\n };\n}\n\nexport function propagateNegativeSupportWithMetadata(\n sourceOpinion: SLOpinion,\n targetOpinion: SLOpinion,\n edgeWeight: number,\n edge: PropagationEdgeRecord\n): PropagationResult {\n return applyNegativeSupport(\n sourceOpinion,\n targetOpinion,\n edgeWeight,\n readEdgeMetadata(edge)\n );\n}\n\nexport const propagateNegativeInform = applyNegativeEvidence;\n"]}
|
package/dist/embeddingTrigger.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
// src/debug.ts
|
|
2
|
+
function isGraphPrimitiveDebugEnabled() {
|
|
3
|
+
const env = globalThis.process?.env;
|
|
4
|
+
return env?.LUCERN_COMPAT_FALLBACK_DEBUG === "1" || env?.LUCERN_GRAPH_DEBUG === "1";
|
|
5
|
+
}
|
|
6
|
+
function debugGraphPrimitiveFallback(message, context) {
|
|
7
|
+
if (!isGraphPrimitiveDebugEnabled()) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
console.debug(message, context ?? {});
|
|
11
|
+
}
|
|
12
|
+
|
|
1
13
|
// src/embeddingTrigger.ts
|
|
2
14
|
async function scheduleEmbeddingGeneration(args) {
|
|
3
15
|
try {
|
|
@@ -15,7 +27,15 @@ async function scheduleEmbeddingGeneration(args) {
|
|
|
15
27
|
confidence: args.confidence
|
|
16
28
|
}
|
|
17
29
|
);
|
|
18
|
-
} catch {
|
|
30
|
+
} catch (error) {
|
|
31
|
+
debugGraphPrimitiveFallback(
|
|
32
|
+
"[embeddingTrigger] Failed to schedule embedding generation",
|
|
33
|
+
{
|
|
34
|
+
error,
|
|
35
|
+
nodeId: String(args.nodeId),
|
|
36
|
+
nodeType: args.nodeType
|
|
37
|
+
}
|
|
38
|
+
);
|
|
19
39
|
}
|
|
20
40
|
}
|
|
21
41
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/embeddingTrigger.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../src/debug.ts","../src/embeddingTrigger.ts"],"names":[],"mappings":";AAMA,SAAS,4BAAA,GAAwC;AAC/C,EAAA,MAAM,GAAA,GAAO,WAA8C,OAAA,EAAS,GAAA;AACpE,EAAA,OACE,GAAA,EAAK,4BAAA,KAAiC,GAAA,IACtC,GAAA,EAAK,kBAAA,KAAuB,GAAA;AAEhC;AAsBO,SAAS,2BAAA,CACd,SACA,OAAA,EACM;AACN,EAAA,IAAI,CAAC,8BAA6B,EAAG;AACnC,IAAA;AAAA,EACF;AACA,EAAA,OAAA,CAAQ,KAAA,CAAM,OAAA,EAAS,OAAA,IAAW,EAAE,CAAA;AACtC;;;ACbA,eAAsB,4BACpB,IAAA,EACe;AACf,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,CAAK,IAAI,SAAA,CAAU,QAAA;AAAA,MACvB,CAAA;AAAA,MACA,iDAAA;AAAA,MACA;AAAA,QACE,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,WAAW,IAAA,CAAK,SAAA,GAAY,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,GAAI,KAAA,CAAA;AAAA,QACrD,SAAS,IAAA,CAAK,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA,GAAI,KAAA,CAAA;AAAA,QAC/C,WAAW,IAAA,CAAK,SAAA;AAAA,QAChB,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,GAAG,GAAM,CAAA;AAAA,QAC/B,WAAW,IAAA,CAAK,SAAA;AAAA,QAChB,YAAY,IAAA,CAAK;AAAA;AACnB,KACF;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,2BAAA;AAAA,MACE,4DAAA;AAAA,MACA;AAAA,QACE,KAAA;AAAA,QACA,MAAA,EAAQ,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA;AAAA,QAC1B,UAAU,IAAA,CAAK;AAAA;AACjB,KACF;AAAA,EAEF;AACF","file":"embeddingTrigger.js","sourcesContent":["type GraphPrimitiveDebugEnvironment = {\n process?: {\n env?: Record<string, string | undefined>;\n };\n};\n\nfunction isGraphPrimitiveDebugEnabled(): boolean {\n const env = (globalThis as GraphPrimitiveDebugEnvironment).process?.env;\n return (\n env?.LUCERN_COMPAT_FALLBACK_DEBUG === \"1\" ||\n env?.LUCERN_GRAPH_DEBUG === \"1\"\n );\n}\n\nexport function formatGraphPrimitiveError(error: unknown): string {\n if (error instanceof Error) {\n return `${error.name}: ${error.message}`;\n }\n if (typeof error === \"string\") {\n return error;\n }\n if (error === null) {\n return \"null\";\n }\n if (error === undefined) {\n return \"undefined\";\n }\n try {\n return JSON.stringify(error);\n } catch {\n return Object.prototype.toString.call(error);\n }\n}\n\nexport function debugGraphPrimitiveFallback(\n message: string,\n context?: Record<string, unknown>\n): void {\n if (!isGraphPrimitiveDebugEnabled()) {\n return;\n }\n console.debug(message, context ?? {});\n}\n","/**\n * Shared helper to schedule embedding generation after epistemic node creation.\n *\n * Best-effort — failures are silently caught. The embedding generation action\n * is a public action in convex/embeddingActions.ts that calls Pinecone.\n */\n\nimport type { Id } from \"./convex\";\nimport { debugGraphPrimitiveFallback } from \"./debug\";\n\ninterface EmbeddingTriggerArgs {\n ctx: any;\n nodeId: Id<\"epistemicNodes\">;\n projectId?: string | null;\n topicId?: string | null;\n createdBy: string;\n nodeType:\n | \"belief\"\n | \"question\"\n | \"evidence\"\n | \"answer\"\n | \"synthesis\"\n | \"theme\"\n | \"source\";\n text: string;\n hasAnswer?: boolean;\n confidence?: number;\n}\n\nexport async function scheduleEmbeddingGeneration(\n args: EmbeddingTriggerArgs,\n): Promise<void> {\n try {\n await args.ctx.scheduler.runAfter(\n 0,\n \"embeddingActions:generateEpistemicNodeEmbedding\" as any,\n {\n nodeId: args.nodeId,\n projectId: args.projectId ? String(args.projectId) : undefined,\n topicId: args.topicId ? String(args.topicId) : undefined,\n createdBy: args.createdBy,\n nodeType: args.nodeType,\n text: args.text.slice(0, 20_000),\n hasAnswer: args.hasAnswer,\n confidence: args.confidence,\n },\n );\n } catch (error) {\n debugGraphPrimitiveFallback(\n \"[embeddingTrigger] Failed to schedule embedding generation\",\n {\n error,\n nodeId: String(args.nodeId),\n nodeType: args.nodeType,\n },\n );\n // Embedding generation is best-effort — never block node creation\n }\n}\n"]}
|