Compose facts from two cases
Intention
Section titled “Intention”I want to join selected facts from two cases while keeping their origin.
Composing facts is separate from importing norms.
Incorrect form and why it stays silent
Section titled “Incorrect form and why it stays silent”You cannot overlay a different payload with the same id on top of an HR record.
assert not eligible(entity_ref("urn:recipe:n-package:07:p")) { id "assert-eligible-record"; origin case_input;}When a positive record with the same full StableId is attached, composition fails with LDC-E1360.
Correct form
Section titled “Correct form”The composition stand in resources/07-compose/ contains a manifest, a lock, and two exported snapshots. They are generated by resources/generate.py; no outside bytes are borrowed. Program, snapshot declarations, and case:
language "law.core" version "0.2";package recipes.n.r07 version "0.1.0";namespace "urn:recipe:n-package:07";
entity Person;relation eligible(p: Person);relation verified(p: Person);relation granted(p: Person);rule Grant strict { for p: Person; when eligible(p) and verified(p); then granted(p); }snapshot HR "snapshots/hr.json";snapshot Audit "snapshots/audit.json";case Combined { context { legal_time @2026-09-13; decision_time @2026-09-13T09:00:00+05:00; knowledge_time @2026-09-13T09:00:00+05:00; timezone "Asia/Almaty"; } use HR { record "urn:recipe:n-package:07#assert-eligible-record"; } use Audit { record "urn:recipe:n-package:07#assert-verified-record"; }}Frozen execution scene
Section titled “Frozen execution scene”| Facts | Question | Answer |
|---|---|---|
| eligible from HR, verified from Audit | granted(p) | TRUE_ONLY |
First both evaluators compose one case; then the test runner asks both. The table is not replaced by hand-rewritten asserts.
composed case yields both premises
test "composed case yields both premises" { given { context { legal_time @2026-09-13; decision_time @2026-09-13T09:00:00+05:00; knowledge_time @2026-09-13T09:00:00+05:00; timezone "Asia/Almaty"; }
} evaluate truth(granted(entity_ref("urn:recipe:n-package:07:p"))); expect truth_status == TRUE_ONLY; expect applied(Grant);}Counterfactual
Section titled “Counterfactual”teaches adds a negative payload for an existing id in Combined and runs lower-case inside a copy of the pinned package. The expected result is exactly LDC-E1360, not an error about a missing snapshot.
Boundary
Section titled “Boundary”Importing a program does not carry facts. A snapshot supplies only exported records; origin is preserved. Equal ids with equal payloads fold; when payloads differ there is no “last record wins” rule.
Pitfall
Section titled “Pitfall”Two payloads of one StableId are rejected with LDC-E1360. The scenario below reduces the example to two facts and one conflicting record, keeping both sides of the composition.
Documentation for Arxo. Writings — blog.arxo.io.
Anonymous visit counts on stats.arxo.io, no cookies.