Skip to main content

evaluate_deontic_contract

Function evaluate_deontic_contract 

Source
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:

  1. Temporal check: if expiry != 0 && now_unix > expiryExpired.
  2. Defeater probe: if has_defeater(buffer, quin)Defeated.
  3. 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 out slice.
  • Stack budget: 8 × MAX_DEFEATER_SLOTS bytes (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 in quins to avoid OutputBufferFull.

§Returns

Ok(n) where n is the number of verdicts written to out[..n].