Eligibility rules: the pattern, the usual exceptions and the tests
Eligibility rules share one shape: a qualifying group, a disqualifier, and a second requirement. The discount rule (student OR senior) AND NOT expired AND (member OR coupon) is the pattern with five conditions, thirty-two rows, and a predictable set of slips.
Read the rule as three clauses joined by AND: who qualifies (student OR senior), what disqualifies (NOT expired), and what else is needed (member OR coupon). Each clause is an OR of alternatives or a negated exception, which is why the pattern survives new requirements: a new way to qualify joins the first OR, a new exclusion joins the AND as another NOT, a new requirement joins as another bracketed OR. The exact checks on the page show the rule is contingent, with the witness senior = TRUE, expired = FALSE, coupon = TRUE, the others FALSE, as one eligible case.
The usual slips are the ones the pitfall pages cover: an exception written with OR instead of AND NOT (every non-expired stranger qualifies), an alternative written with AND instead of OR (only student seniors qualify), a bracket dropped so that the disqualifier binds to one alternative only (expired students qualify through the student clause, which the disqualifier no longer reaches). Each is a one-operator mistake, and each changes several rows of thirty-two.
The tests that catch them are the independence pairs: one pair per condition, about six scenarios, each showing that the condition alone changes the outcome. The rule here has five conditions and six would do; the full table is for the engine, the pairs are for the suite, and the decision-table page shows how the owner's view of the rule maps onto both.
Example
eligible := (student OR senior) AND NOT expired AND (member OR coupon) · output
Exact checks
Truth table (32 rows)
| # | student | senior | expired | member | coupon | eligible |
|---|---|---|---|---|---|---|
| 0 | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE |
| 1 | FALSE | FALSE | FALSE | FALSE | TRUE | FALSE |
| 2 | FALSE | FALSE | FALSE | TRUE | FALSE | FALSE |
| 3 | FALSE | FALSE | FALSE | TRUE | TRUE | FALSE |
| 4 | FALSE | FALSE | TRUE | FALSE | FALSE | FALSE |
| 5 | FALSE | FALSE | TRUE | FALSE | TRUE | FALSE |
| 6 | FALSE | FALSE | TRUE | TRUE | FALSE | FALSE |
| 7 | FALSE | FALSE | TRUE | TRUE | TRUE | FALSE |
| 8 | FALSE | TRUE | FALSE | FALSE | FALSE | FALSE |
| 9 | FALSE | TRUE | FALSE | FALSE | TRUE | TRUE |
| 10 | FALSE | TRUE | FALSE | TRUE | FALSE | TRUE |
| 11 | FALSE | TRUE | FALSE | TRUE | TRUE | TRUE |
| 12 | FALSE | TRUE | TRUE | FALSE | FALSE | FALSE |
| 13 | FALSE | TRUE | TRUE | FALSE | TRUE | FALSE |
| 14 | FALSE | TRUE | TRUE | TRUE | FALSE | FALSE |
| 15 | FALSE | TRUE | TRUE | TRUE | TRUE | FALSE |
| 16 | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE |
| 17 | TRUE | FALSE | FALSE | FALSE | TRUE | TRUE |
| 18 | TRUE | FALSE | FALSE | TRUE | FALSE | TRUE |
| 19 | TRUE | FALSE | FALSE | TRUE | TRUE | TRUE |
| 20 | TRUE | FALSE | TRUE | FALSE | FALSE | FALSE |
| 21 | TRUE | FALSE | TRUE | FALSE | TRUE | FALSE |
| 22 | TRUE | FALSE | TRUE | TRUE | FALSE | FALSE |
| 23 | TRUE | FALSE | TRUE | TRUE | TRUE | FALSE |
| 24 | TRUE | TRUE | FALSE | FALSE | FALSE | FALSE |
| 25 | TRUE | TRUE | FALSE | FALSE | TRUE | TRUE |
| 26 | TRUE | TRUE | FALSE | TRUE | FALSE | TRUE |
| 27 | TRUE | TRUE | FALSE | TRUE | TRUE | TRUE |
| 28 | TRUE | TRUE | TRUE | FALSE | FALSE | FALSE |
| 29 | TRUE | TRUE | TRUE | FALSE | TRUE | FALSE |
| 30 | TRUE | TRUE | TRUE | TRUE | FALSE | FALSE |
| 31 | TRUE | TRUE | TRUE | TRUE | TRUE | FALSE |
Plain-language reading
Beginnereligible is true exactly when all of the following hold:
1. at least one of student or senior is true (both may be true)
2. expired is false
3. at least one of member or coupon is true (both may be true)
In every other case, eligible is false.
About the operators:
- AND is true only when all of its parts are true.
- OR is inclusive: it is true when at least one part is true, including when several are.
- NOT reverses a value: true becomes false and false becomes true.
Intermediateeligible is true exactly when all of the following hold:
1. at least one of student or senior is true (both may be true)
2. expired is false
3. at least one of member or coupon is true (both may be true)
In every other case, eligible is false.
Advancedeligible is true exactly when all of the following hold [conjunction ∧]:
1. at least one of student or senior is true (both may be true) [inclusive disjunction ∨]
2. expired is false [negation ¬]
3. at least one of member or coupon is true (both may be true) [inclusive disjunction ∨]
In every other case, eligible is false.
Formal notation: (student ∨ senior) ∧ ¬expired ∧ (member ∨ coupon)
Logic diagram
The common slip
Letting the disqualifier bind to one alternative. student OR senior AND NOT expired reads as student OR (senior AND NOT expired), so an expired student card still qualifies. Bracket the group, and let the table confirm the row.
Questions
How do I add a second disqualifier?
As another AND NOT clause: … AND NOT expired AND NOT fraud_flag. De Morgan lets you write the pair as AND NOT (expired OR fraud_flag), which the equivalence checker will confirm.
What if two clauses overlap?
Overlaps are fine in logic (a student who is also a member qualifies twice) and only matter when the rule must be exclusive. The absorption law removes genuinely redundant clauses, and the simplifier reports them.
Related
See also
- Discount eligibility rule: (student OR senior) AND NOT expired AND (member OR coupon)
- Loan eligibility: income_ok AND (credit_ok OR guarantor) AND NOT bankrupt
- Access control rules: roles, exceptions and the banned-user slip
- Decision table testing, worked example (ISTQB Foundation 4.2.3 style)
- “Unless” in a rule: AND NOT, not OR
- “A or B and C”: the grouping ambiguity and how to resolve it
- Absorption law: A OR (A AND B) = A, with proof
- MC/DC independence pairs, worked example with the engine’s coverage report
Testing and rules
Generated from the Tangibool engine, semantics tangibool-semantics/1, engine 1.0.0, build . Every table, map, simplification and verdict on these pages was computed by the Tangibool engine when the site was built, and every claim was re-checked by the same exact checker the app uses. Limits are stated where they apply. © 2026 Foreranger LTD.