Skip to content
docs
Arxo ↗

Strict rules: pitfalls

For LLMs8 sections

Updated 3 October 2026: concept, except_when, claim, definition … sufficient, and default strength have been removed, together with their special deprecation diagnostic. References below to the former behavior and corpus sources are historical. New source uses relation, unless, duty, a strict rule, and defeasible.

Wrong forms, silent outcomes, LDC-E diagnostics, typical mistakes of formalizers and AI agents, and how to detect them. Items marked “confirmed by runs” were reproduced during this research on the installed engine.

1. Head variable bound only by comparison (confirmed by runs)

Section titled “1. Head variable bound only by comparison (confirmed by runs)”
Arxo Law
rule SmallEnterprise strict {
for e: Enterprise;
for n: Integer;
when n <= 100; // нет позитивного литерала с n
then small_enterprise(e);
}

LDC-E4101: every head variable must occur in a positive body conjunct; comparison, negation, and not_known do not bind variables. Fix: add the literal that binds the variable (employee_count(e, n)), as in the research.rule_strict.strict_guard teaching package. The AI agent often writes the guard first and forgets the binding literal.

LDC-E4110: a strict rule has no exceptions by definition, exception nodes are not generated. Fix: either the rule becomes defeasible, or the applicability condition is added to the strict body as a conjunct. The reverse mistake is making a rule defeasible “just in case” when there are no exceptions: then any defeater can remove its support.

3. Defeater against a strictly produced head

Section titled “3. Defeater against a strictly produced head”

LDC-E4112: a defeater must have a defeasible producer of the same head and polarity; a target produced only by strict rules rejects the attack at check. The older lesson about a “powerless defeater on a strict head” is outdated: such a defeater now fails to compile instead of silently not working.

4. Silent Not established, not refuted: expected refusal, got absence of inference

Section titled “4. Silent Not established, not refuted: expected refusal, got absence of inference”

If no rule fired — the answer is Not established, not refuted, not Refuted. Three different causes look the same:

  • guard not met (250 employees against a threshold of 100);
  • no fact at all;
  • premise in Contradiction — a bare literal reads as established, and a contested fact does not activate the rule.

Detection: the why-not explanation names the unestablished conjunct; a guard test on Not established, not refuted must state which of the three causes is meant, otherwise the test fixes ignorance, not behaviour.

5. Priority does not resolve a conflict of two strict rules

Section titled “5. Priority does not resolve a conflict of two strict rules”

Two strict rules with opposite heads give a preserved conflict Contradiction, and priority is powerless here — moreover, priority over a strict rule is rejected with LDC-E4105. Confirmed by runs: the research.rule_strict.strict_conflict teaching package answers Contradiction on both facts without any diagnostics. The AI agent, seeing Contradiction, first declares priority — on strict heads that is a compiler rejection, not a fix. Fix: decide which norm is actually special, and make the pair defeasible + priority (see the priority page), or recognise the conflict as substantive and keep Contradiction.

6. A separate relation for a definition name (finding, confirmed by runs)

Section titled “6. A separate relation for a definition name (finding, confirmed by runs)”
Arxo Law
relation minor(p: Person) kind institutional;
definition minor(p: Person) exact { ... } // LDC-E1201 + LDC-E1338

The name is already declared: definitions and relations share one namespace, and redeclaration is a static rejection LDC-E1201 (plus LDC-E1338 on the doubled StableId). The compiler synthesizes the relation itself: a lone definition stands without any companion relation. Do not redeclare the definition’s synthesized relation; that creates a duplicate name. If a publishable vocabulary symbol is needed, publish the definition itself.

7. No rule strength; repeated applicability clause

Section titled “7. No rule strength; repeated applicability clause”

A rule without strength (rule R { … }) or a malformed clause is a rejection LDC-E0201: strength is mandatory; choose strict, defeasible, or defeater. A repeated scope, effective, or defeat clause in one block is LDC-E1329. Detection: law engine check names the clause; fix — one clause of each kind per block.

8. Keyword name as a binder; head block without lowering

Section titled “8. Keyword name as a binder; head block without lowering”

for event: … is a rejection LDC-E0203 (event, case, calendar, action are hard keywords; state, period, window, holder are contextual words and may be names). The grammar accepts a then { a; b; } block, but the compiler does not lower it: warning LDC-E1302, zero rules in the compiled output; fix — separate then clauses, each becoming a separate head rule.

Documentation for Arxo. Writings — blog.arxo.io.

Anonymous visit counts on stats.arxo.io, no cookies.