Files
core/tests/integration/test-bilattice-orderings.js
T
John Dvorak 717ae1031e initial commit: @arbiter/core authorization engine with js-rigor hardening
Zanzibar-style authorization graph engine (direct/chain/TTU/defeasible/
binary modes, condensed snapshots, value relations) with 39 rigor test
campaigns. Includes fixes for snapshot binary writer/reader format
mismatch (snapshot-of-snapshot corruption), possibility write-boundary
validation, empty-graph snapshot serialization, relation lookup cache
direction collision, config-redefinition cache invalidation, binary
threshold semantics, defeasible compiled routing, and comparator
reason whitelisting.
2026-07-31 13:44:06 -07:00

257 lines
9.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Test Bilattice Orderings for Evidential Reasoning
*
* This test demonstrates the bilattice orderings (≥ᵢ, ≥ₜ) for comparing
* epistemic status of propositions in qualitative capacity systems.
*/
import { test, describe } from 'node:test';
import assert from 'node:assert';
import {
QualitativeScale,
QualitativeCapacity,
BilatticeOrderings
} from '../../src/qualitative/index.js';
describe('Bilattice Orderings', () => {
test('should implement information ordering correctly', () => {
const scale = QualitativeScale.fivePoint();
// Test information ordering: (c₁, c₁') ≥ᵢ (c₂, c₂') ⟺ c₁ ≥ c₂ and c₁' ≥ c₂'
const epistemic1 = { belief: 0.75, disbelief: 0.5 };
const epistemic2 = { belief: 0.5, disbelief: 0.25 };
const epistemic3 = { belief: 0.75, disbelief: 0.25 };
// epistemic1 should be more informative than epistemic2
assert.ok(BilatticeOrderings.informationOrdering(epistemic1, epistemic2, scale));
// epistemic1 should be more informative than epistemic3 (higher disbelief)
assert.ok(BilatticeOrderings.informationOrdering(epistemic1, epistemic3, scale));
// epistemic3 should NOT be more informative than epistemic1 (lower disbelief)
assert.ok(!BilatticeOrderings.informationOrdering(epistemic3, epistemic1, scale));
});
test('should implement truth ordering correctly', () => {
const scale = QualitativeScale.fivePoint();
const stateSpace = ['s1', 's2', 's3'];
// Create a capacity where s1 has high belief, s2 has medium belief
const qmt = new Map();
qmt.set(new Set(['s1']), 0.75); // High belief in s1
qmt.set(new Set(['s2']), 0.5); // Medium belief in s2
qmt.set(new Set(['s1', 's2']), 1); // Full belief in s1 OR s2
const capacity = new QualitativeCapacity(stateSpace, scale, qmt);
const propositionA = ['s1']; // High belief
const propositionB = ['s2']; // Medium belief
// A should be more true than B: γ(A) ≥ γ(B) and γ(Bᶜ) ≥ γ(Aᶜ)
assert.ok(BilatticeOrderings.truthOrdering(propositionA, propositionB, capacity));
// B should NOT be more true than A
assert.ok(!BilatticeOrderings.truthOrdering(propositionB, propositionA, capacity));
});
test('should compare epistemic status comprehensively', () => {
const scale = QualitativeScale.fivePoint();
const stateSpace = ['s1', 's2', 's3'];
// Create a capacity with different belief levels
const qmt = new Map();
qmt.set(new Set(['s1']), 0.75);
qmt.set(new Set(['s2']), 0.5);
qmt.set(new Set(['s3']), 0.25);
qmt.set(new Set(['s1', 's2']), 1);
qmt.set(new Set(['s1', 's2', 's3']), 1);
const capacity = new QualitativeCapacity(stateSpace, scale, qmt);
const propositionA = ['s1'];
const propositionB = ['s2'];
const comparison = BilatticeOrderings.compareEpistemicStatus(propositionA, propositionB, capacity);
// Check that we get a comprehensive comparison
assert.ok(comparison.propositionA);
assert.ok(comparison.propositionB);
assert.ok(typeof comparison.informationOrdering === 'boolean');
assert.ok(typeof comparison.truthOrdering === 'boolean');
assert.ok(typeof comparison.relationship === 'string');
assert.ok(typeof comparison.analysis === 'string');
// A should be more true than B, but not more informative
assert.ok(!comparison.informationOrdering);
assert.ok(comparison.truthOrdering);
assert.strictEqual(comparison.relationship, 'A more true than B');
});
test('should find most informative proposition', () => {
const scale = QualitativeScale.fivePoint();
const stateSpace = ['s1', 's2', 's3'];
// Create a capacity with varying belief levels
const qmt = new Map();
qmt.set(new Set(['s1']), 0.75);
qmt.set(new Set(['s2']), 0.5);
qmt.set(new Set(['s3']), 0.25);
qmt.set(new Set(['s1', 's2']), 1);
qmt.set(new Set(['s1', 's2', 's3']), 1);
const capacity = new QualitativeCapacity(stateSpace, scale, qmt);
const propositions = [['s1'], ['s2'], ['s3']];
const mostInformative = BilatticeOrderings.findMostInformative(propositions, capacity);
// s1 should be most informative (highest belief and disbelief)
assert.deepStrictEqual(mostInformative.proposition, ['s1']);
assert.strictEqual(mostInformative.rank, 1);
assert.strictEqual(mostInformative.total, 3);
assert.ok(mostInformative.analysis.includes('Most informative'));
});
test('should find most true proposition', () => {
const scale = QualitativeScale.fivePoint();
const stateSpace = ['s1', 's2', 's3'];
// Create a capacity with varying belief levels
const qmt = new Map();
qmt.set(new Set(['s1']), 0.75);
qmt.set(new Set(['s2']), 0.5);
qmt.set(new Set(['s3']), 0.25);
qmt.set(new Set(['s1', 's2']), 1);
qmt.set(new Set(['s1', 's2', 's3']), 1);
const capacity = new QualitativeCapacity(stateSpace, scale, qmt);
const propositions = [['s1'], ['s2'], ['s3']];
const mostTrue = BilatticeOrderings.findMostTrue(propositions, capacity);
// s1 should be most true (highest capacity value)
assert.deepStrictEqual(mostTrue.proposition, ['s1']);
assert.strictEqual(mostTrue.capacity, 0.75);
assert.strictEqual(mostTrue.rank, 1);
assert.strictEqual(mostTrue.total, 3);
assert.ok(mostTrue.analysis.includes('Most true'));
});
test('should rank propositions by information content', () => {
const scale = QualitativeScale.fivePoint();
const stateSpace = ['s1', 's2', 's3'];
// Create a capacity with varying belief levels
const qmt = new Map();
qmt.set(new Set(['s1']), 0.75);
qmt.set(new Set(['s2']), 0.5);
qmt.set(new Set(['s3']), 0.25);
qmt.set(new Set(['s1', 's2']), 1);
qmt.set(new Set(['s1', 's2', 's3']), 1);
const capacity = new QualitativeCapacity(stateSpace, scale, qmt);
const propositions = [['s1'], ['s2'], ['s3']];
const ranking = BilatticeOrderings.rankByInformation(propositions, capacity);
// Should have 3 ranked propositions
assert.strictEqual(ranking.length, 3);
// Check ranking structure
for (let i = 0; i < ranking.length; i++) {
assert.strictEqual(ranking[i].rank, i + 1);
assert.ok(ranking[i].proposition);
assert.ok(ranking[i].epistemic);
assert.ok(ranking[i].analysis);
}
// s1 should be ranked first (most informative)
assert.deepStrictEqual(ranking[0].proposition, ['s1']);
});
test('should rank propositions by truth content', () => {
const scale = QualitativeScale.fivePoint();
const stateSpace = ['s1', 's2', 's3'];
// Create a capacity with varying belief levels
const qmt = new Map();
qmt.set(new Set(['s1']), 0.75);
qmt.set(new Set(['s2']), 0.5);
qmt.set(new Set(['s3']), 0.25);
qmt.set(new Set(['s1', 's2']), 1);
qmt.set(new Set(['s1', 's2', 's3']), 1);
const capacity = new QualitativeCapacity(stateSpace, scale, qmt);
const propositions = [['s1'], ['s2'], ['s3']];
const ranking = BilatticeOrderings.rankByTruth(propositions, capacity);
// Should have 3 ranked propositions
assert.strictEqual(ranking.length, 3);
// Check ranking structure
for (let i = 0; i < ranking.length; i++) {
assert.strictEqual(ranking[i].rank, i + 1);
assert.ok(ranking[i].proposition);
assert.ok(typeof ranking[i].capacity === 'number');
assert.ok(ranking[i].analysis);
}
// s1 should be ranked first (most true)
assert.deepStrictEqual(ranking[0].proposition, ['s1']);
assert.strictEqual(ranking[0].capacity, 0.75);
});
test('should handle edge cases correctly', () => {
const scale = QualitativeScale.fivePoint();
const stateSpace = ['s1', 's2'];
// Create a simple capacity
const qmt = new Map();
qmt.set(new Set(['s1']), 0.5);
qmt.set(new Set(['s1', 's2']), 1);
const capacity = new QualitativeCapacity(stateSpace, scale, qmt);
// Test with single proposition
const singleProposition = [['s1']];
const mostInformative = BilatticeOrderings.findMostInformative(singleProposition, capacity);
const mostTrue = BilatticeOrderings.findMostTrue(singleProposition, capacity);
assert.deepStrictEqual(mostInformative.proposition, ['s1']);
assert.strictEqual(mostInformative.rank, 1);
assert.strictEqual(mostInformative.total, 1);
assert.deepStrictEqual(mostTrue.proposition, ['s1']);
assert.strictEqual(mostTrue.rank, 1);
assert.strictEqual(mostTrue.total, 1);
});
test('should handle incomparable propositions', () => {
const scale = QualitativeScale.fivePoint();
const stateSpace = ['s1', 's2', 's3'];
// Create a capacity where propositions are incomparable
const qmt = new Map();
qmt.set(new Set(['s1']), 0.75); // High belief, low disbelief
qmt.set(new Set(['s2']), 0.5); // Medium belief, medium disbelief
qmt.set(new Set(['s1', 's2']), 1);
qmt.set(new Set(['s1', 's2', 's3']), 1);
const capacity = new QualitativeCapacity(stateSpace, scale, qmt);
const propositionA = ['s1'];
const propositionB = ['s2'];
const comparison = BilatticeOrderings.compareEpistemicStatus(propositionA, propositionB, capacity);
// Should identify the relationship correctly
assert.ok(typeof comparison.relationship === 'string');
assert.ok(comparison.relationship !== '');
});
});