pub fn evaluate_deontic_contract(
quins: &[NQuin],
now_unix: u32,
out: &mut [DeonticVerdict],
) -> Result<usize, DeonticError>Expand description
Evaluate a deontic contract encoded as a &[NQuin] slice.
§Algorithm
Phase 1 — Defeater harvest (single forward pass, O(n)):
Every Quin whose predicate has DEFEATER_BIT set is identified as a
q42:unless defeater. Its fingerprint is written into the fixed-capacity
[u64; MAX_DEFEATER_SLOTS] stack buffer. Excess defeaters beyond
MAX_DEFEATER_SLOTS are silently dropped (contracts this large exceed the
42 MB Prolog Sentinel and are rejected at ingest time).
Phase 2 — Norm evaluation (single forward pass, O(n)):
Every Quin whose predicate[0..7] ∈ {OP_OBLIGATE, OP_PERMIT, OP_FORBID}
and whose DEFEATER_BIT is clear is a primary norm. For each:
- Temporal check: if
expiry != 0 && now_unix > expiry→Expired. - Defeater probe: if
has_defeater(buffer, quin)→Defeated. - Otherwise →
Active.
Non-deontic Quins (opcode not in the set above) are skipped silently.
§Constraints
- Zero heap allocation: all state lives in registers and the caller-supplied
outslice. - Stack budget:
8 × MAX_DEFEATER_SLOTSbytes (512 B) + frame overhead. - Deterministic O(n²) worst-case defeater probe, O(n) amortised for contracts with few exceptions (the common case in legal documents).
§Parameters
quins— the deontic contract encoded as a Quin slice.now_unix— current time as a truncated 32-bit Unix timestamp.out— caller-supplied verdict buffer; must be≥the number of norm Quins inquinsto avoidOutputBufferFull.
§Returns
Ok(n) where n is the number of verdicts written to out[..n].