Skip to content

Writing business rules in plain English that translate to logic

A business rule written in plain English should translate to one Boolean formula without a committee. The discount rule below shows the habits that make that possible: named conditions with a one-line description each, one connective per clause, and brackets wherever “and” meets “or”.

The rule is (student OR senior) AND NOT expired AND (member OR coupon), five conditions. Each has a glossary description on the page: the customer has a student card, is 65 or older, the card or coupon has expired, the customer is a member, the customer presents a coupon. With those descriptions the engine's plain-language reading of the formula is a sentence a product owner can confirm or reject, and the truth table is the exhaustive version of the same sentence, thirty-two rows.

The habits that keep English and logic aligned are few. Name each condition as a statement that is true or false, not as a quantity (“over 50” becomes over_50, decided elsewhere). Write “and” and “or” one at a time and bracket every mixed group, because English has no precedence. Translate “unless” and “except” as AND NOT, “only if” as a necessary condition, and “either … or” as XOR only when “but not both” is meant. Keep negations attached to the condition they negate.

When a sentence resists translation, the sentence is usually ambiguous rather than the logic inadequate, and the two readings should be written as two formulas and compared; the equivalence checker reports the rows on which they differ, which is the question to take back to the rule's owner. The review checklist collects these points for the reviewer's side of the conversation.

Example

discount := (student OR senior) AND NOT expired AND (member OR coupon) · output

Exact checks

Always true (tautology)? No Counterexample: student = F, senior = F, expired = F, member = F, coupon = F · Exhaustively checked and solver cross-checked · 1 rows
Always false (contradiction)? No Counterexample: student = F, senior = T, expired = F, member = F, coupon = T · Exhaustively checked and solver cross-checked · 10 rows
Can be true? Yes Example assignment: student = F, senior = T, expired = F, member = F, coupon = T · Exhaustively checked and solver cross-checked · 10 rows

Truth table (32 rows)

Writing business rules in plain English that translate to logic
#studentseniorexpiredmembercoupondiscount
0FALSEFALSEFALSEFALSEFALSEFALSE
1FALSEFALSEFALSEFALSETRUEFALSE
2FALSEFALSEFALSETRUEFALSEFALSE
3FALSEFALSEFALSETRUETRUEFALSE
4FALSEFALSETRUEFALSEFALSEFALSE
5FALSEFALSETRUEFALSETRUEFALSE
6FALSEFALSETRUETRUEFALSEFALSE
7FALSEFALSETRUETRUETRUEFALSE
8FALSETRUEFALSEFALSEFALSEFALSE
9FALSETRUEFALSEFALSETRUETRUE
10FALSETRUEFALSETRUEFALSETRUE
11FALSETRUEFALSETRUETRUETRUE
12FALSETRUETRUEFALSEFALSEFALSE
13FALSETRUETRUEFALSETRUEFALSE
14FALSETRUETRUETRUEFALSEFALSE
15FALSETRUETRUETRUETRUEFALSE
16TRUEFALSEFALSEFALSEFALSEFALSE
17TRUEFALSEFALSEFALSETRUETRUE
18TRUEFALSEFALSETRUEFALSETRUE
19TRUEFALSEFALSETRUETRUETRUE
20TRUEFALSETRUEFALSEFALSEFALSE
21TRUEFALSETRUEFALSETRUEFALSE
22TRUEFALSETRUETRUEFALSEFALSE
23TRUEFALSETRUETRUETRUEFALSE
24TRUETRUEFALSEFALSEFALSEFALSE
25TRUETRUEFALSEFALSETRUETRUE
26TRUETRUEFALSETRUEFALSETRUE
27TRUETRUEFALSETRUETRUETRUE
28TRUETRUETRUEFALSEFALSEFALSE
29TRUETRUETRUEFALSETRUEFALSE
30TRUETRUETRUETRUEFALSEFALSE
31TRUETRUETRUETRUETRUEFALSE

Plain-language reading

Beginnerdiscount 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, discount 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.
Intermediatediscount 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, discount is false.
Advanceddiscount 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, discount is false.
Formal notation: (student ∨ senior) ∧ ¬expired ∧ (member ∨ coupon)

Logic diagram

Writing business rules in plain English that translate to logic Writing business rules in plain English that translate to logic student senior expired member coupon discount AND OR NOT OR
Writing business rules in plain English that translate to logic Writing business rules in plain English that translate to logic student senior expired member coupon discount AND OR NOT OR

The common slip

Translating “students and seniors get the discount” as student AND senior. The English “and” lists two groups that each qualify; the logic is student OR senior. The table makes the difference obvious, one TRUE row against three.

Questions

Should conditions be positive or negative?

Positive where possible (expired rather than not_expired), with the negation in the formula. Double negatives in condition names are where De Morgan slips start.

How do I handle numeric thresholds?

As threshold inputs: age_65_or_over is defined once as age ≥ 65 on the quantity age, and the rule keeps combining a TRUE/FALSE name. The engine derives the ordering between thresholds on the same quantity, so age_at_least_21 can never be TRUE while age_at_least_18 is FALSE, and a scenario or a test can give the number itself. Outside the app the same discipline works by hand: decide each threshold once, name it as a statement, and record its definition in the glossary where it can be read and checked.

Related

See also

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.