Skip to content

“A or B and C”: the grouping ambiguity and how to resolve it

“A or B and C” has two readings, and they are different functions. The parser reads A OR B AND C as A OR (B AND C); the other reading, (A OR B) AND C, differs on two of the eight rows.

The table compares the two. On the row A = TRUE, B = FALSE, C = FALSE the parsed reading is TRUE (A alone suffices) and the bracketed reading is FALSE (C is required); the row A = TRUE, B = TRUE, C = FALSE is the other difference. The equivalence check reports the first of these as the counterexample. Everywhere else the two agree, which is exactly why the slip survives casual testing.

The parser's choice is the standard precedence, AND before OR, the same as multiplication before addition. It is not the problem; the problem is that English has no precedence rule, so a sentence that says “admins, or editors with an unlocked document” and a sentence that says “admins or editors, with an unlocked document” sound alike and mean different rules. Only the author knows which was intended.

The cure is brackets whenever AND and OR meet, and a truth table when a rule comes from prose. The lesson on grouping and precedence practises both readings, and the precedence page prints the fully bracketed form of whatever you type so the parse is never a surprise.

as_parsed := A OR B AND C · outputother_reading := (A OR B) AND C · output
Are as_parsed and other_reading equivalent? No Counterexample: A = T, B = F, C = F · Exhaustively checked and solver cross-checked · 5 rows

Truth table

They differ on this row: #4, #6

“A or B and C”: the grouping ambiguity and how to resolve it
#ABCas_parsedother_reading
0FALSEFALSEFALSEFALSEFALSE
1FALSEFALSETRUEFALSEFALSE
2FALSETRUEFALSEFALSEFALSE
3FALSETRUETRUETRUETRUE
4TRUEFALSEFALSETRUEFALSE
5TRUEFALSETRUETRUETRUE
6TRUETRUEFALSETRUEFALSE
7TRUETRUETRUETRUETRUE

Plain-language reading

Beginneras_parsed is true exactly when at least one of the following holds (both may hold):
1. A is true
2. both B and C are true
In every other case, as_parsed is false.
About the operators:
- OR is inclusive: it is true when at least one part is true, including when several are.
- AND is true only when all of its parts are true.
Intermediateas_parsed is true exactly when at least one of the following holds (both may hold):
1. A is true
2. both B and C are true
In every other case, as_parsed is false.
Advancedas_parsed is true exactly when at least one of the following holds (both may hold) [inclusive disjunction ∨]:
1. A is true
2. both B and C are true [conjunction ∧]
In every other case, as_parsed is false.
Formal notation: A ∨ B ∧ C
“A or B and C”: the grouping ambiguity and how to resolve it “A or B and C”: the grouping ambiguity and how to resolve it A B C as_parsedPRIMARY other_reading OR AND AND OR
“A or B and C”: the grouping ambiguity and how to resolve it “A or B and C”: the grouping ambiguity and how to resolve it A B C as_parsedPRIMARY other_reading OR AND AND OR

The common slip

Writing the rule as spoken and letting precedence decide. “A or B and C” typed as A OR B AND C requires C only when A is false; if C was meant as a condition on everyone, the formula admits every A without it.

Questions

Which reading does the engine use?

AND binds before OR, so A OR B AND C is A OR (B AND C). The fully bracketed form shown on every page makes the grouping visible, and brackets you type are kept.

How many rows should I test to catch this?

The two formulas differ on exactly two rows of eight, both with A TRUE and C FALSE. A test set that never has A true while C is false cannot see the difference; the independence-pair tools pick rows that do.

Related

Guides

Tools

See also

Pitfalls

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.