Skip to content

docs: document composition-operator semantics (XOR = parity, self-XOR unsatisfiable, AND-before-OR precedence) #813

Description

@hf-kklein

Summary

Request to document the semantics of the composition operators (U/AND, O/OR, X/XOR) — in particular three behaviours that are logically correct but routinely surprise people reading or writing AHB expressions. These are not bug reports; the engine behaves consistently. The ask is documentation (README / operator reference / docstrings) so consumers and AHB authors aren't caught out.

All examples below were reproduced against a current deployment via parse/parse_and_evaluate (all conditions set to FULFILLED unless noted).

1. X (XOR) is odd-parity, not "exactly one of"

X chains as a fold of boolean XOR, so a chain is fulfilled iff an odd number of its operands are fulfilled — not "exactly one".

Expression all operands FULFILLED result
[1] X [2] 2 fulfilled (even) false
[1] X [2] X [3] 3 fulfilled (odd) true
[1] X [2] X [3] X [4] 4 fulfilled (even) false

The n = 3 → true case is the trap: many readers expect X to mean "mutually exclusive / exactly one", which would make three-fulfilled false. Worth stating explicitly that X is associative XOR (parity).

2. Self-XOR is unsatisfiable

[1] X [1] evaluates to false for every state of [1] (since a XOR a = false). An expression that references the same condition on both sides of an X can therefore never be fulfilled — an easy copy/paste footgun. Worth a one-line warning.

3. Operator precedence: U (AND) binds tighter than O (OR)

Muss [1] O [2] U [3] parses as [1] O ([2] U [3]), i.e. "[1] alone suffices, or both [2] and [3]" — not ([1] O [2]) U [3]. Parsed tree:

or_composition
├── [1]
└── and_composition
    ├── [2]
    └── [3]

Standard boolean precedence, but AHB expressions are read left-to-right by domain users who may not assume it. Documenting the precedence (and recommending explicit parentheses in AHBs) would prevent misreadings.

Suggested action

Notes

Purely documentation — no behavioural change requested. The engine handled every edge input cleanly (including 20-digit condition keys and repeated keys); no crash or error was observed for any of the above.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions