{- |
Description: Truth tables for logical expressions
Copyright: Copyright (C) 2023 Yoo Chung
License: GPL-3.0-or-later
Maintainer: dev@chungyc.org

Some solutions to "Problems.P46" of Ninety-Nine Haskell "Problems".
-}
module Solutions.P46 (
  BoolFunc,
  table,
  -- * Boolean functions
  and',
  or',
  nand',
  nor',
  xor',
  impl',
  equ',
  -- * Utility values
  functions,
  ) where

import           Problems.Logic

-- | Truth tables for logical expressions with two operands.
table :: BoolFunc -> [(Bool, Bool, Bool)]
table :: BoolFunc -> [(Bool, Bool, Bool)]
table BoolFunc
f = [(Bool
a, Bool
b, BoolFunc
f Bool
a Bool
b) | Bool
a <- [Bool
False, Bool
True], Bool
b <- [Bool
False, Bool
True]]

-- | Logical conjunction.
-- I.e., @(and' a b)@ is true if and only if both @a@ and @b@ are true.
and' :: BoolFunc
and' :: BoolFunc
and' Bool
True Bool
True = Bool
True
and' Bool
_ Bool
_       = Bool
False

-- | Logical disjuncton.
-- I.e., @(or' a b)@ is true if and only if one or both of @a@ and @b@ are true.
or' :: BoolFunc
or' :: BoolFunc
or' Bool
False Bool
False = Bool
False
or' Bool
_ Bool
_         = Bool
True

-- | Logical alternative denial.
-- I.e., @(nand' a b)@ is true if and only if @(and' a b)@ is false.
nand' :: BoolFunc
nand' :: BoolFunc
nand' Bool
True Bool
True = Bool
False
nand' Bool
_ Bool
_       = Bool
True

-- | Logical joint denial.
-- I.e., @(nor' a b)@ is true if and only if @(or' a b)@ is false.
nor' :: BoolFunc
nor' :: BoolFunc
nor' Bool
False Bool
False = Bool
True
nor' Bool
_ Bool
_         = Bool
False

-- | Logical exclusive disjunction.
-- I.e., @(xor' a b)@ is true if and only if exactly one of @a@ and @b@ is true.
xor' :: BoolFunc
xor' :: BoolFunc
xor' Bool
True Bool
False = Bool
True
xor' Bool
False Bool
True = Bool
True
xor' Bool
_ Bool
_        = Bool
False

-- | Logical implication.
-- I.e., @(impl' a b)@ being true means @b@ must be true if @a@ is true.
-- If @a@ is false, there is no implication as to what @b@ should be.
impl' :: BoolFunc
impl' :: BoolFunc
impl' Bool
False Bool
False = Bool
True
impl' Bool
False Bool
True  = Bool
True
impl' Bool
True Bool
False  = Bool
False
impl' Bool
True Bool
True   = Bool
True

-- | Logical equivalence.
-- I.e., @(equ' a b)@ being true means @a@ is true if and only if @b@ is true.
equ' :: BoolFunc
equ' :: BoolFunc
equ' Bool
False Bool
False = Bool
True
equ' Bool
True Bool
True   = Bool
True
equ' Bool
_ Bool
_         = Bool
False

-- | Functions in this module grouped together.
--
-- They are grouped together for testing or benchmarking purposes.
functions :: Functions
functions :: Functions
functions = Functions { getTable :: BoolFunc -> [(Bool, Bool, Bool)]
getTable = BoolFunc -> [(Bool, Bool, Bool)]
table
                      , getAnd :: BoolFunc
getAnd = BoolFunc
and'
                      , getOr :: BoolFunc
getOr = BoolFunc
or'
                      , getNand :: BoolFunc
getNand = BoolFunc
nand'
                      , getNor :: BoolFunc
getNor = BoolFunc
nor'
                      , getXor :: BoolFunc
getXor = BoolFunc
xor'
                      , getImpl :: BoolFunc
getImpl = BoolFunc
impl'
                      , getEqu :: BoolFunc
getEqu = BoolFunc
equ' }