Federation: when standpoints disagree
Area: Standpoints & federation Teaches:
across [...]joins standpoints by the four-valued information-join (FDE / Truth4). When two sources speak to the same individual, the join surfaces all four values —is,not,can, and cruciallyboth, which arises only from one source asserting while another refutes. Prerequisites: standpoint visibility (DEFAULT vs scoped facts). Run:ox build examples/federation_disagreement && ox query examples/federation_disagreement --with-truth4
Two data sources rarely agree on everything. Most systems force you to pick a winner or crash on the conflict. Argon does neither: it federates them and reports the disagreement as a value. The four-valued truth space — is (asserted), not (refuted), can (neither), both (asserted and refuted) — is a bilattice, and across [...] combines standpoints by the information-join over it. A conflict does not corrupt the answer; it becomes both.
What to read in federation.ar
Two standpoints, each its own source of truth:
pub type Person;
pub standpoint historical;
pub standpoint public_record;
One source asserts with fact; the other refutes with not_fact (strong negation):
pub standpoint historical {
pub fact Person(alice);
pub fact Person(bob);
}
pub standpoint public_record {
pub not_fact Person(alice);
pub not_fact Person(carol);
pub fact Person(dave);
}
not_fact is not absence — it is a positive refutation. historical says alice is a Person; public_record says alice is not. They overlap on alice and clash.
The federated query joins both sources:
pub query everyone() -> Person across [historical, public_record];
Running it
The query returns one row per individual, each tagged with the joined four-valued status:
alice → Both (historical asserts Person, public_record refutes)
bob → Is (only historical asserts)
carol → Not (only public_record refutes)
dave → Is (only public_record asserts)
All four Truth4 values appear in a single query. The decisive row is alice → Both: she is the only individual both asserted (by historical) and refuted (by public_record), and the information-join carries both polarities rather than discarding either. bob and dave are Is because exactly one source asserts and nothing refutes; carol is Not because she is refuted with no countervailing assertion. The can value is the join’s bottom — neither asserted nor refuted — and is what an individual no source mentions would read.
Honest caveats (what runs today)
- This is the default paraconsistent federation policy: a conflict is preserved as
Bothrather than resolved or rejected. A source declaring a contradiction does not poison the whole query. - Rows are reported by individual id; the name mapping above is how the package declares its facts.
This example is compiled and run in CI; the per-row Truth4 verdicts under federation are pinned by a corpus test (oxc-runtime/tests/examples_corpus.rs), so the information-join can’t drift from the language.