This page does not represent the most current semester of this course; it is present merely as an archive.

In any expression system with more than one operator, there is a need to clarify the meaning of a multi-operator system. For example, is 23+42-3+4 equal to 33 (232-3 plus 44) or 5-5 (22 minus 3+43+4)?

In arithmetic, an order of operations is sufficient to clarify meaning. However, as more complicated structures appear it no longer suffices. For example, in the code

Python
Java
for(int x : numbers) {
    sum += x;
}
for x in numbers:
    sum += x

which operator happens first: += or for? The answer is neither: they work together iteratively.

A versatile tool for understanding expressions, even complicated ones with components like loops, is the notion of a main operator. Any expression with an operator in it can be expressed as a single main operator with smaller expressions as its operands.

1 Scope and main operators

Every operator has some scope: a portion of the expression that it directly modifies. Logic has operators with three different ways of determining scope.

Binary operators

These have two operands, which comprise the operators scope. Examples include \land, \lor, \rightarrow, \oplus, etc.

Logic does not define an order of operations for binary operators: PQRP \land Q \lor R is invalid notation; you must write either (PQ)R(P \land Q) \lor R or P(QR)P \land (Q \lor R). The only time parentheses can be omitted is when the operators are associative1, as for example in PQRP \oplus Q \oplus R.

Programming languages have parallels to many logical operators and do have operator precedence for them, so sometimes when logic is written by computer scientists they omit a few required parentheses and assume programming precedence rules apply. We won’t use that kind of omission in this class.

Not
The scope of ¬\lnot is the term that immediately follows it. Thus ¬AB\lnot A \lor B means (¬A)B(\lnot A) \lor B, not ¬(AB)\lnot (A \lor B).
Quantifiers

The scope of a q quantifier is the entire expression that follows its terminating dot, though its scope cannot escape from parentheses. Thus, x  .  AB\forall x \;.\; A \land B means x  .  (AB)\forall x \;.\; (A \land B) not (x  .  A)B(\forall x \;.\; A) \land B.

There are actually two competing notations for quantifiers. MCS and most other computing texts use a dot after the quantifier and the from here until the end scope, as described above. ∀x and some other formal logic texts write the quantifier like a function instead, following it with parentheses that define its scope.

We only use the dot-notation quantifiers in this class.

The main operator of any expression is the operator whose scope is the entire expression.

2 Logic to English with main operators

When turning logic into English, the following process will always work:

  1. Identify the main operator
  2. Write the English for that operator, with place-holders for the operands
  3. Convert each operand to English using this process
  4. Simplify the resulting English, removing variables if possible.
Logic Example English template
¬x\lnot x it is not the case that xx
xyx \land y both xx and yy
xyx \lor y either xx or yy or both
xyx \oplus y either xx or yy but not both
xyx \rightarrow y if xx then yy
xyx \leftrightarrow y xx if and only if yy
x  .  y\forall x \;.\; y for each xx it is the case that yy
x  .  y\exists x \;.\; y there exists some xx such that yy
x  .  y\nexists x \;.\; y there is no xx such that yy

Identify the main operators in each of the following:

  • (AB)(CD)(A \land B) \lor (C \land D) 2
  • (AB)(CD)(A \rightarrow B) \land (C \lor D) 3
  • ((AB)(CD))\big((A \land B) \lor (C \land D)\big) 4
  • (AB)¬(CD)(A \land B) \lor \lnot(C \land D) 5
  • ¬(AB)¬(CD)\lnot(A \land B) \lor \lnot(C \land D) 6
  • ¬((AB)(CD))\lnot\big((A \land B) \lor (C \land D)\big) 7
  • ¬AB\lnot A \rightarrow B 8
  • ¬(AB)\lnot (A \rightarrow B) 9
  • x  .  ¬A(x)B(x)\forall x \;.\; \lnot A(x) \rightarrow B(x) 10
  • ¬x  .  A(x)B(x)\lnot \forall x \;.\; A(x) \rightarrow B(x) 11
  • x  .  ¬A(x)B(x)\exists x \;.\; \lnot A(x) \rightarrow B(x) 12
  • ¬x  .  A(x)B(x)\lnot \exists x \;.\; A(x) \rightarrow B(x) 13
  • x  .  A(x)B(x)\nexists x \;.\; A(x) \rightarrow B(x) 14
  • x  .  y  .  ¬A(x)B(y)\forall x \;.\; \exists y \;.\; \lnot A(x) \rightarrow B(y) 15
  • y  .  x  .  ¬A(x)B(y)\exists y \;.\; \forall x \;.\; \lnot A(x) \rightarrow B(y) 16

Convert the following to simple clear English

Predicate Meaning
P(x)P(x) xx is a program
I(x,p)I(x,p) xx is an input to program pp
Q(p,x,y)Q(p,x,y) program pp solves input xx as part of working on input yy

p  .  P(p)(i  .  I(i,p)(j  .  I(j,p)Q(p,i,j)))\forall p \;.\; P(p) \rightarrow\Big(\exists i \;.\; I(i,p) \land\big(\forall j \;.\; I(j,p) \rightarrow Q(p,i,j)\big)\Big)

  1. The main operator is p\forall p,

    For each pp it is the case that …

    The remaining logic is P(p)(i  .  I(i,p)(j  .  I(j,p)Q(p,i,j)))P(p) \rightarrow \Big(\exists i \;.\; I(i,p) \land\big(\forall j \;.\; I(j,p) \rightarrow Q(p,i,j)\big)\Big)

  2. The main operator is \rightarrow

    For each pp it is the case that if … then …

    The antecedent is P(p)P(p), which is just pp is a program

    For each pp it is the case that if pp is a program then …

    We can simplify that English:

    For each program pp it is the case that …

    The consequent is (i  .  I(i,p)(j  .  I(j,p)Q(p,i,j)))\Big(\exists i \;.\; I(i,p) \land\big(\forall j \;.\; I(j,p) \rightarrow Q(p,i,j)\big)\Big)

  3. The main operator is i\exists i,

    For each program pp it is the case that there exists some ii such that …

    We can simplify that English:

    For each program pp there exists some ii such that …

    The remaining logic is I(i,p)(j  .  I(j,p)Q(p,i,j))I(i,p) \land\big(\forall j \;.\; I(j,p) \rightarrow Q(p,i,j)\big)

  4. The main operator is \land,

    For each program pp there exists some ii such that both … and …

    The first conjunct is I(i,p)I(i,p), which is just ii is an input to pp

    For each program pp there exists some ii such that both ii is an input to pp and …

    We can simplify that English:

    For each program pp has some input ii such that …

    The second conjunct is (j  .  I(j,p)Q(p,i,j))\big(\forall j \;.\; I(j,p) \rightarrow Q(p,i,j)\big)

  5. The main operator is j\forall j,

    For each program pp has some input ii such that for each jj it is the case that …

    The remaining logic is I(j,p)Q(p,i,j)I(j,p) \rightarrow Q(p,i,j)

  6. The main operator is \rightarrow

    For each program pp has some input ii such that for each jj it is the case that if … then …

    The antecedent is I(j,p)I(j,p), which is just jj is an input to pp;

    For each program pp has some input ii such that for each jj it is the case that if jj is an input to pp then …

    We can simplify that English:

    For each program pp has some input ii such that for each input jj it is the case that …

    The consequent is Q(p,i,j)Q(p,i,j), which is program pp solves input ii as part of working on input jj;

    For each program pp has some input ii such that for each input jj it is the case that program pp solves input ii as part of working on input jj.

    We can simplify that English:

    For each program pp has some input ii such that for each input jj program pp solves input ii as part of working on input jj.

  7. We have a full English sentence: For each program pp has some input ii such that for each input jj program pp solves input ii as part of working on input jj. But we’d rather not use variable in English.

    The variable pp is the only program, so we can replace it with the program or the like: Every program has some input ii such that for every input jj, the program solves ii as part of working on jj.

    Since ii and jj are both inputs, the simple the input approach will not work, meaning we need more creativity in removing them from the phrase. A few examples:

    • Every program has an input that it solves along the way to solving every input.
    • For any program you care to pick, its has some base input: an input whose solution is part of every other inputs’ solution.
    • Every program has an input it solves during the solution of every other input.

3 English to logic with main operators

When turning English into logic, the following process will always work:

  1. Identify the main operator implied by the English
  2. Write that operator as a symbol with its scope in parentheses
  3. Re-word the English to fit in the parentheses
  4. Convert each parenthesized English to logic

When doing this, be sure to look for implicit quantifiers. \forall is often omitted by making a general statement instead; \exists may be as subtle as the use of a instead of the.

Also be careful about adding \exists and if-then statements. I’ll marry someone who proposes means x\exists x . I’ll marry xx and xx proposes not x\exists x . I’ll marry xx if xx proposes; the latter is trivially true as long as there is someone somewhere who will never propose.

Identify the main operator of each of the following and re-write the sentence to use that operator as a symbol.

  • I’ll buy it if it works 17
  • I’ll buy anything that works 18
  • I’ll buy something that works 19
  • I’ll buy one that works 20
  • If a program passes all tests, it’s ready for release 21
  • If a program passes all tests, you are missing some tests 22
  • Every good program passes at least one test 23
  • There’s a test that every good program passes 24
  • You’ll need an IDE or debugger to solve this 25
  • A floating-point value is either normalized, denormalized, infinite, or NaN 26
  • This variable is either normalized, denormalized, infinite, or NaN 27
  • A floating-point value is a number 28
  • A floating-point value is missing 29
  • Using a floating-point value is a mistake 30

Convert the best program is never the cheapest program to logic

  1. This is a statement about all programs.

    p  .\forall p\;. if pp’s the cheapest, then pp is not the best

  2. This is an if-then statement.

    p  .\forall p\;. (pp’s the cheapest) \rightarrow (pp is not the best)

    The antecedent is pp is the cheapest program.

    1. This is about the absence of something (nothing is cheaper than pp).

      c  .\nexists c\;. cc is cheaper than pp

    2. This is about cost. Which is not part of logic. So we turn it into a predicate:

      Predicate Meaning
      C(x,y)C(x,y) xx is cheaper than yy

      c  .  C(c,p)\nexists c \;.\; C(c,p).

    The consequent is pp is not the best program.

    1. This is about the existence of something (something is better than pp).

      b  .\exists b\;. bb is better than pp

    2. This is about goodness. Which is not part of logic. So we turn it into a predicate:

      Predicate Meaning
      B(x,y)B(x,y) xx is better than yy

      b  .  B(b,p)\exists b \;.\; B(b,p).

  3. Putting it all together:

    Predicate Meaning
    C(x,y)C(x,y) xx is cheaper than yy
    B(x,y)B(x,y) xx is better than yy

    p  .  (c  .  C(c,p))(b  .  B(b,p))\forall p\;.\; \big(\nexists c \;.\; C(c,p)\big) \rightarrow \big(\exists b \;.\; B(b,p)\big)

Convert the best program is never the cheapest program to logic

  1. This is a statement about all programs.

    p  .\forall p\;. pp’s the best and pp is not the cheapest are never both true

  2. This is an not-and statement.

    p  .  ¬(p\forall p\;.\; \lnot\big(p’s the best \land pp is the cheapest)\big)

    The first conjunct is pp is the best program.

    1. This is about the absence of something (nothing is better than pp).

      b  .\nexists b\;. bb is better than pp

    2. This is about goodness. Which is not part of logic. So we turn it into a predicate:

      Predicate Meaning
      B(x,y)B(x,y) xx is better than yy

      b  .  B(b,p)\nexists b \;.\; B(b,p).

    The second conjunct is pp is cheapest program.

    1. This is about the absence of something (nothing is cheaper than pp).

      c  .\nexists c\;. cc is cheaper than pp

    2. This is about cost. Which is not part of logic. So we turn it into a predicate:

      Predicate Meaning
      C(x,y)C(x,y) xx is cheaper than yy

      c  .  C(c,p)\nexists c \;.\; C(c,p).

  3. Putting it all together:

    Predicate Meaning
    C(x,y)C(x,y) xx is cheaper than yy
    B(x,y)B(x,y) xx is better than yy

    p  .  ¬((b  .  B(b,p))(c  .  C(c,p)))\forall p\;.\; \lnot\Big(\big(\nexists b\;.\; B(b,p)\big) \land \big(\nexists c\;.\; C(c,p)\big)\Big)

  4. We could optionally apply De Morgan and double negation:

    p  .  ¬(b  .  B(b,p))¬(c  .  C(c,p))\forall p\;.\; \lnot\big(\nexists b\;.\; B(b,p)\big) \lor \lnot\big(\nexists c\;.\; C(c,p)\big)

    p  .  (b  .  B(b,p))(c  .  C(c,p))\forall p\;.\; \big(\exists b\;.\; B(b,p)\big) \lor \big(\exists c\;.\; C(c,p)\big)

    to get every program either has another better than it or another cheaper than it, which is also equivalent to our starting statement.


  1. Some associative operator sequences are non-intuitive; for example, P(QR)P \rightarrow (Q \lor R) and (PQ)R(P \rightarrow Q) \lor R are equivalent and hence can be written as PQRP \rightarrow Q \lor R. You don’t need to knwo this, though, as it is always permitted to include parentheses even with associative operators.↩︎

  2. \lor↩︎

  3. \land↩︎

  4. \lor↩︎

  5. \lor↩︎

  6. \lor↩︎

  7. first ¬\lnot↩︎

  8. \rightarrow↩︎

  9. ¬\lnot↩︎

  10. x\forall x↩︎

  11. ¬\lnot↩︎

  12. x\exists x↩︎

  13. ¬\lnot↩︎

  14. x\nexists x↩︎

  15. x\forall x↩︎

  16. y\exists y↩︎

  17. (it works) rightarrowrightarrow (I’ll buy it)↩︎

  18. x\forall x . (I’ll buy xx if xx works)↩︎

  19. x\exists x . (I’ll buy xx and xx works)↩︎

  20. x\exists x . (I’ll buy xx and xx works)↩︎

  21. p\forall p . (if pp passes all tests then pp is ready for release↩︎

  22. (a program passes all tests) \rightarrow (you are missing some tests)↩︎

  23. p\forall p . (if pp is good then pp passes at least one test)↩︎

  24. t\exists t . (every good program passes tt)↩︎

  25. (You’ll need an IDE to solve this) \lor (You’ll need a debugger to solve this)↩︎

  26. n\forall n . (if nn is a floating-point value then nn is either normalized, denormalized, infinite, or NaN)↩︎

  27. (this variable is normalized) \oplus (this variable is denormalized) \oplus (this variable is infinite) \oplus (this variable is NaN)↩︎

  28. n\forall n . (if nn is a floating-point value then nn is a number)↩︎

  29. n\exists n . (nn is a floating-point value and nn is missing)↩︎

  30. (using a float-point value) \rightarrow (a mistake)↩︎