Strict rules: pitfalls
Updated 3 October 2026:
concept,except_when,claim,definition … sufficient, anddefaultstrength have been removed, together with their special deprecation diagnostic. References below to the former behavior and corpus sources are historical. New source usesrelation,unless,duty, a strict rule, anddefeasible.
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)”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.
2. unless on a strict rule
Section titled “2. unless on a strict rule”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)”relation minor(p: Person) kind institutional;definition minor(p: Person) exact { ... } // LDC-E1201 + LDC-E1338The 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.