Or

Posted on 2018-01-17 by nbloomf
Tags: arithmetic-made-difficult, literate-haskell

This page is part of a series on Arithmetic Made Difficult.

This post is literate Haskell; you can load the source into GHCi and play along.


{-# LANGUAGE NoImplicitPrelude #-}
module Or (
  or, _test_or, main_or
) where

import Testing
import Booleans
import Not
import And

Finally, \(\bor\).

We define \(\bor : \bool \rightarrow \bool \rightarrow \bool\) by \[\bor(p,q) = \bif{p}{\btrue}{\bif{q}{\btrue}{\bfalse}}.\]

In Haskell:

We can compute \(\bor\) explicitly.

We have \[\begin{eqnarray*} \bor(\btrue,\btrue) & = & \btrue \\ \bor(\btrue,\bfalse) & = & \btrue \\ \bor(\bfalse,\btrue) & = & \btrue \\ \bor(\bfalse,\bfalse) & = & \bfalse. \end{eqnarray*}\]

Note that \[\begin{eqnarray*} & & \bor(\btrue,\btrue) \\ & \href{/posts/arithmetic-made-difficult/Or.html#def-or} = & \bif{\btrue}{\btrue}{\bif{\btrue}{\btrue}{\bfalse}} \\ & \href{/posts/arithmetic-made-difficult/Booleans.html#cor-if-true} = & \btrue \end{eqnarray*}\] that \[\begin{eqnarray*} & & \bor(\btrue,\bfalse) \\ & \href{/posts/arithmetic-made-difficult/Or.html#def-or} = & \bif{\btrue}{\btrue}{\bif{\bfalse}{\btrue}{\bfalse}} \\ & \href{/posts/arithmetic-made-difficult/Booleans.html#cor-if-true} = & \btrue \end{eqnarray*}\] that \[\begin{eqnarray*} & & \bor(\bfalse,\btrue) \\ & \href{/posts/arithmetic-made-difficult/Or.html#def-or} = & \bif{\bfalse}{\btrue}{\bif{\btrue}{\btrue}{\bfalse}} \\ & \href{/posts/arithmetic-made-difficult/Booleans.html#cor-if-true} = & \bif{\bfalse}{\btrue}{\btrue} \\ & \href{/posts/arithmetic-made-difficult/Booleans.html#cor-if-false} = & \btrue \end{eqnarray*}\] and that \[\begin{eqnarray*} & & \bor(\bfalse,\bfalse) \\ & \href{/posts/arithmetic-made-difficult/Or.html#def-or} = & \bif{\bfalse}{\btrue}{\bif{\bfalse}{\btrue}{\bfalse}} \\ & \href{/posts/arithmetic-made-difficult/Booleans.html#cor-if-false} = & \bif{\bfalse}{\btrue}{\bfalse} \\ & \href{/posts/arithmetic-made-difficult/Booleans.html#cor-if-false} = & \bfalse \end{eqnarray*}\] as claimed.

\(\btrue\) absorbs under \(\bor\).

For all \(a \in \bool\), we have \[\bor(\btrue,a) = \bor(a,\btrue) = \btrue.\]

If \(a = \btrue\), we have \[\begin{eqnarray*} & & \bor(\btrue,\btrue) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-eval-true-true} = & \btrue \end{eqnarray*}\] and if \(a = \bfalse\) we have \[\begin{eqnarray*} & & \bor(\btrue,\bfalse) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-eval-true-false} = & \btrue \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-eval-false-true} = & \bor(\bfalse,\btrue) \end{eqnarray*}\] as claimed.

\(\bfalse\) is neutral under \(\bor\).

For all \(a \in \bool\), we have \[\bor(\bfalse,a) = \bor(a,\bfalse) = a.\]

If \(a = \btrue\), we have \[\begin{eqnarray*} & & \bor(\bfalse,\btrue) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-eval-false-true} = & \btrue \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-eval-true-false} = & \bor(\btrue,\bfalse) \end{eqnarray*}\] and if \(a = \bfalse\) we have \[\begin{eqnarray*} & & \bor(\bfalse,\bfalse) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-eval-false-false} = & \bfalse \end{eqnarray*}\] as claimed.

\(\bor\) interacts with \(\bnot\).

For all \(a \in \bool\), we have \(\bor(p,\bnot(p)) = \btrue\).

If \(a = \btrue\), we have \[\begin{eqnarray*} & & \bor(\btrue,\bnot(\btrue)) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-left} = & \btrue \end{eqnarray*}\] and if \(a = \bfalse\) we have \[\begin{eqnarray*} & & \bor(\bfalse,\bnot(\bfalse)) \\ & \href{/posts/arithmetic-made-difficult/Not.html#thm-not-false} = & \bor(\bfalse,\btrue) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-eval-false-true} = & \btrue \end{eqnarray*}\] as claimed.

\(\bor\) is idempotent.

For all \(a \in \bool\), we have \(\bor(a,a) = a\).

If \(a = \btrue\) we have \[\begin{eqnarray*} & & \bor(\btrue,\btrue) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-eval-true-true} = & \btrue \end{eqnarray*}\] and if \(a = \bfalse\) then \[\begin{eqnarray*} & & \bor(\bfalse,\bfalse) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-eval-false-false} = & \bfalse \end{eqnarray*}\] as claimed.

\(\bor\) is commutative.

For all \(a,b \in \bool\), we have \(\bor(a,b) = \bor(b,a)\).

If \(a = \btrue\) we have \[\begin{eqnarray*} & & \bor(\btrue,b) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-left} = & \btrue \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-right} = & \bor(b,\btrue) \end{eqnarray*}\] and if \(a = \bfalse\) we have \[\begin{eqnarray*} & & \bor(\bfalse,b) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-false-left} = & b \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-false-right} = & \bor(b,\bfalse) \end{eqnarray*}\] as claimed.

\(\bor\) is associative.

For all \(a,b,c \in \bool\), we have \[\bor(\bor(a,b),c) = \bor(a,\bor(b,c)).\]

If \(a = \btrue\) we have \[\begin{eqnarray*} & & \bor(\bor(a,b),c) \\ & \let{a = \btrue} = & \bor(\bor(\btrue,b),c) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-left} = & \bor(\btrue,c) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-left} = & \btrue \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-left} = & \bor(\btrue,\bor(b,c)) \end{eqnarray*}\] as claimed. If \(a = \bfalse\), we have \[\begin{eqnarray*} & & \bor(\bor(a,b),c) \\ & \let{a = \bfalse} = & \bor(\bor(\bfalse,b),c) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-false-left} = & \bor(b,c) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-false-left} = & \bor(\bfalse,\bor(b,c)) \end{eqnarray*}\] as claimed.

DeMorgan’s laws hold for \(\bor\), \(\band\), and \(\bnot\).

The following hold for all \(a,b,c \in \bool\).

  1. \(\bnot(\band(a,b)) = \bor(\bnot(a),\bnot(b))\).
  2. \(\bnot(\bor(a,b)) = \band(\bnot(a),\bnot(b))\).
  1. If \(a = \btrue\), we have \[\begin{eqnarray*} & & \bnot(\band(a,b)) \\ & \let{a = \btrue} = & \bnot(\band(\btrue,b)) \\ & \href{/posts/arithmetic-made-difficult/And.html#thm-and-true-left} = & \bnot(b) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-false-left} = & \bor(\bfalse,\bnot(b)) \\ & \href{/posts/arithmetic-made-difficult/Not.html#thm-not-true} = & \bor(\bnot(\btrue),\bnot(b)) \\ & \let{a = \btrue} = & \bor(\bnot(a),\bnot(b)) \end{eqnarray*}\] as claimed. If \(a = \bfalse\), we have \[\begin{eqnarray*} & & \bnot(\band(a,b)) \\ & \let{a = \bfalse} = & \bnot(\band(\bfalse,b)) \\ & \href{/posts/arithmetic-made-difficult/And.html#thm-and-false-left} = & \bnot(\bfalse) \\ & \href{/posts/arithmetic-made-difficult/Not.html#thm-not-false} = & \btrue \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-left} = & \bor(\btrue,\bnot(b)) \\ & \href{/posts/arithmetic-made-difficult/Not.html#thm-not-false} = & \bor(\bnot(\bfalse),\bnot(b)) \\ & \let{a = \bfalse} = & \bor(\bnot(a),\bnot(b)) \end{eqnarray*}\] as claimed.
  2. If \(a = \btrue\), we have \[\begin{eqnarray*} & & \bnot(\bor(a,b)) \\ & \let{a = \btrue} = & \bnot(\bor(\btrue,b)) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-left} = & \bnot(\btrue) \\ & \href{/posts/arithmetic-made-difficult/Not.html#thm-not-true} = & \bfalse \\ & \href{/posts/arithmetic-made-difficult/And.html#thm-and-false-left} = & \band(\bfalse,\bnot(b)) \\ & \href{/posts/arithmetic-made-difficult/Not.html#thm-not-true} = & \band(\bnot(\btrue),\bnot(b)) \\ & \let{a = \btrue} = & \band(\bnot(a),\bnot(b)) \end{eqnarray*}\] as claimed. If \(b = \bfalse\), we have \[\begin{eqnarray*} & & \bnot(\bor(a,b)) \\ & \let{a = \bfalse} = & \bnot(\bor(\bfalse,b)) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-false-left} = & \bnot(b) \\ & \href{/posts/arithmetic-made-difficult/And.html#thm-and-true-left} = & \band(\btrue,\bnot(b)) \\ & \href{/posts/arithmetic-made-difficult/Not.html#thm-not-false} = & \band(\bnot(\bfalse),\bnot(b)) \\ & \let{a = \bfalse} = & \band(\bnot(a),\bnot(b)) \end{eqnarray*}\] as claimed.

\(\band\) and \(\bor\) distribute over each other.

The following hold for all \(a,b,c \in \bool\).

  1. \(\band(a,\bor(b,c)) = \bor(\band(a,b),\band(a,c))\).
  2. \(\bor(a,\band(b,c)) = \band(\bor(a,b),\bor(a,c))\).
  1. If \(a = \btrue\), we have \[\begin{eqnarray*} & & \band(a,\bor(b,c)) \\ & \let{a = \btrue} = & \band(\btrue,\bor(b,c)) \\ & \href{/posts/arithmetic-made-difficult/And.html#thm-and-true-left} = & \bor(b,c) \\ & \href{/posts/arithmetic-made-difficult/And.html#thm-and-true-left} = & \bor(\band(\btrue,b),c) \\ & \href{/posts/arithmetic-made-difficult/And.html#thm-and-true-left} = & \bor(\band(\btrue,b),\band(\btrue,c)) \\ & \let{a = \btrue} = & \bor(\band(a,b),\band(a,c)) \end{eqnarray*}\] as claimed. If \(a = \bfalse\), we have \[\begin{eqnarray*} & & \band(a,\bor(b,c)) \\ & \let{a = \bfalse} = & \band(\bfalse,\bor(b,c)) \\ & \href{/posts/arithmetic-made-difficult/And.html#thm-and-false-left} = & \bfalse \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-false-left} = & \bor(\bfalse,\bfalse) \\ & \href{/posts/arithmetic-made-difficult/And.html#thm-and-false-left} = & \bor(\band(\bfalse,b),\bfalse) \\ & \href{/posts/arithmetic-made-difficult/And.html#thm-and-false-left} = & \bor(\band(\bfalse,b),\band(\bfalse,c)) \\ & \let{a = \bfalse} = & \bor(\band(a,b),\band(a,c)) \end{eqnarray*}\] as claimed.
  2. If \(a = \btrue\), we have \[\begin{eqnarray*} & & \bor(a,\band(b,c)) \\ & \let{a = \btrue} = & \bor(\btrue,\band(b,c)) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-left} = & \btrue \\ & \href{/posts/arithmetic-made-difficult/And.html#thm-and-eval-true-true} = & \band(\btrue,\btrue) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-left} = & \band(\bor(\btrue,b),\btrue) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-left} = & \band(\bor(\btrue,b),\bor(\btrue,c)) \\ & \let{a = \btrue} = & \band(\bor(a,b),\bor(a,c)) \end{eqnarray*}\] as claimed. If \(a = \bfalse\), we have \[\begin{eqnarray*} & & \bor(a,\band(b,c)) \\ & \let{a = \bfalse} = & \bor(\bfalse,\band(b,c)) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-false-left} = & \band(b,c) \\ & = & \band(b,\bor(\bfalse,c)) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-false-left} = & \band(\bor(\bfalse,b),\bor(\bfalse,c)) \\ & \let{a = \bfalse} = & \band(\bor(a,b),\bor(a,c)) \end{eqnarray*}\] as claimed.

\(\bif{\ast}{\ast}{\ast}\) on booleans is equivalent to an or.

If \(p,q \in \bool\), we have \[\bif{p}{\btrue}{q} = \bor(p,q).\]

If \(p = \btrue\), we have \[\begin{eqnarray*} & & \bif{\btrue}{\btrue}{q} \\ & \href{/posts/arithmetic-made-difficult/Booleans.html#cor-if-true} = & \btrue \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-left} = & \bor(\btrue,q) \end{eqnarray*}\] and if $p = we have \[\begin{eqnarray*} & & \bif{\bfalse}{\btrue}{q} \\ & \href{/posts/arithmetic-made-difficult/Booleans.html#cor-if-false} = & q \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-false-left} = & \bor(\bfalse,q) \end{eqnarray*}\] as needed.

\(\bif{\ast}{\ast}{\ast}\) interacts with \(\bor\).

Let \(A\) be a set with \(a,b \in A\), and let \(p,q \in \bool\). Then we have \[\bif{p}{a}{\bif{q}{a}{b}} = \bif{\bor(p,q)}{a}{b}.\]

If \(p = \btrue\), we have \[\begin{eqnarray*} & & \bif{\bor(p,q)}{a}{b} \\ & \let{p = \btrue} = & \bif{\bor(\btrue,q)}{a}{b} \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-left} = & \bif{\btrue}{a}{b} \\ & \href{/posts/arithmetic-made-difficult/Booleans.html#cor-if-true} = & a \\ & \href{/posts/arithmetic-made-difficult/Booleans.html#cor-if-true} = & \bif{\btrue}{a}{\bif{q}{a}{b}} \\ & \let{p = \btrue} = & \bif{p}{a}{\bif{q}{a}{b}} \end{eqnarray*}\] as needed, and if \(p = \bfalse\) we have \[\begin{eqnarray*} & & \bif{\bor(p,q)}{a}{b} \\ & \let{p = \bfalse} = & \bif{\bor(\bfalse,q)}{a}{b} \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-false-left} = & \bif{q}{a}{b} \\ & \href{/posts/arithmetic-made-difficult/Booleans.html#cor-if-false} = & \bif{\bfalse}{a}{\bif{q}{a}{b}} \\ & \let{p = \bfalse} = & \bif{p}{a}{\bif{q}{a}{b}} \end{eqnarray*}\] as needed.

Testing

Suite:

_test_or ::
  ( Equal a, Arbitrary a, CoArbitrary a, Show a, TypeName a
  , Boolean b, Arbitrary b, Show b, Equal b, TypeName b
  )
  => b -> a -> Int -> Int -> IO ()
_test_or p x size cases = do
  testLabel2 "or" p x

  let args = testArgs size cases

  runTest args (_test_or_true_true p)
  runTest args (_test_or_true_false p)
  runTest args (_test_or_false_true p)
  runTest args (_test_or_false_false p)

  runTest args (_test_or_true p)
  runTest args (_test_or_false p)
  runTest args (_test_or_not p)
  runTest args (_test_or_idempotent p)
  runTest args (_test_or_commutative p)
  runTest args (_test_or_associative p)

  runTest args (_test_not_and p)
  runTest args (_test_not_or p)
  runTest args (_test_and_or p)
  runTest args (_test_or_and p)

  runTest args (_test_if_or x)
  runTest args (_test_if_or_nest x)

Main:

main_or :: IO ()
main_or = _test_or (true :: Bool) (true :: Bool) 20 100