module Problems.Logic (
BoolFunc,
printTable,
printTablen,
Functions (Functions, getTable, getAnd, getOr, getNand, getNor, getXor, getImpl, getEqu),
Formula (..),
evaluateFormula
) where
import Control.DeepSeq
import Data.List (sort)
import Data.Map (Map, (!))
import GHC.Generics (Generic)
type BoolFunc = Bool -> Bool -> Bool
printTable :: [(Bool, Bool, Bool)] -> IO ()
printTable :: [(Bool, Bool, Bool)] -> IO ()
printTable [(Bool, Bool, Bool)]
ts = ((Bool, Bool, Bool) -> IO ()) -> [(Bool, Bool, Bool)] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String -> IO ()
putStrLn (String -> IO ())
-> ((Bool, Bool, Bool) -> String) -> (Bool, Bool, Bool) -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool, Bool, Bool) -> String
showRow) ([(Bool, Bool, Bool)] -> IO ()) -> [(Bool, Bool, Bool)] -> IO ()
forall a b. (a -> b) -> a -> b
$ [(Bool, Bool, Bool)] -> [(Bool, Bool, Bool)]
forall a. Ord a => [a] -> [a]
sort [(Bool, Bool, Bool)]
ts
where showRow :: (Bool, Bool, Bool) -> String
showRow (Bool
a, Bool
b, Bool
c) = Bool -> String
showBool Bool
a String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Bool -> String
showBool Bool
b String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Bool -> String
showBool Bool
c
showBool :: Bool -> String
showBool Bool
a = if Bool
a then String
"True " else String
"False"
printTablen :: [[Bool]] -> IO ()
printTablen :: [[Bool]] -> IO ()
printTablen [[Bool]]
t = ([Bool] -> IO ()) -> [[Bool]] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String -> IO ()
putStrLn (String -> IO ()) -> ([Bool] -> String) -> [Bool] -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Bool] -> String
showRow) ([[Bool]] -> IO ()) -> [[Bool]] -> IO ()
forall a b. (a -> b) -> a -> b
$ [[Bool]] -> [[Bool]]
forall a. Ord a => [a] -> [a]
sort [[Bool]]
t
where showRow :: [Bool] -> String
showRow [Bool]
xs = [String] -> String
unwords ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (Bool -> String) -> [Bool] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Bool -> String
showBool [Bool]
xs
showBool :: Bool -> String
showBool Bool
a = if Bool
a then String
"True " else String
"False"
data Functions = Functions { Functions -> (Bool -> Bool -> Bool) -> [(Bool, Bool, Bool)]
getTable :: (Bool -> Bool -> Bool) -> [(Bool, Bool, Bool)]
, Functions -> Bool -> Bool -> Bool
getAnd :: Bool -> Bool -> Bool
, Functions -> Bool -> Bool -> Bool
getOr :: Bool -> Bool -> Bool
, Functions -> Bool -> Bool -> Bool
getNand :: Bool -> Bool -> Bool
, Functions -> Bool -> Bool -> Bool
getNor :: Bool -> Bool -> Bool
, Functions -> Bool -> Bool -> Bool
getXor :: Bool -> Bool -> Bool
, Functions -> Bool -> Bool -> Bool
getImpl :: Bool -> Bool -> Bool
, Functions -> Bool -> Bool -> Bool
getEqu :: Bool -> Bool -> Bool
}
data Formula
= Value Bool
| Variable String
| Complement Formula
| Disjoin [Formula]
| Conjoin [Formula]
deriving (Formula -> Formula -> Bool
(Formula -> Formula -> Bool)
-> (Formula -> Formula -> Bool) -> Eq Formula
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Formula -> Formula -> Bool
== :: Formula -> Formula -> Bool
$c/= :: Formula -> Formula -> Bool
/= :: Formula -> Formula -> Bool
Eq, Eq Formula
Eq Formula =>
(Formula -> Formula -> Ordering)
-> (Formula -> Formula -> Bool)
-> (Formula -> Formula -> Bool)
-> (Formula -> Formula -> Bool)
-> (Formula -> Formula -> Bool)
-> (Formula -> Formula -> Formula)
-> (Formula -> Formula -> Formula)
-> Ord Formula
Formula -> Formula -> Bool
Formula -> Formula -> Ordering
Formula -> Formula -> Formula
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Formula -> Formula -> Ordering
compare :: Formula -> Formula -> Ordering
$c< :: Formula -> Formula -> Bool
< :: Formula -> Formula -> Bool
$c<= :: Formula -> Formula -> Bool
<= :: Formula -> Formula -> Bool
$c> :: Formula -> Formula -> Bool
> :: Formula -> Formula -> Bool
$c>= :: Formula -> Formula -> Bool
>= :: Formula -> Formula -> Bool
$cmax :: Formula -> Formula -> Formula
max :: Formula -> Formula -> Formula
$cmin :: Formula -> Formula -> Formula
min :: Formula -> Formula -> Formula
Ord, Int -> Formula -> String -> String
[Formula] -> String -> String
Formula -> String
(Int -> Formula -> String -> String)
-> (Formula -> String)
-> ([Formula] -> String -> String)
-> Show Formula
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> Formula -> String -> String
showsPrec :: Int -> Formula -> String -> String
$cshow :: Formula -> String
show :: Formula -> String
$cshowList :: [Formula] -> String -> String
showList :: [Formula] -> String -> String
Show, (forall x. Formula -> Rep Formula x)
-> (forall x. Rep Formula x -> Formula) -> Generic Formula
forall x. Rep Formula x -> Formula
forall x. Formula -> Rep Formula x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Formula -> Rep Formula x
from :: forall x. Formula -> Rep Formula x
$cto :: forall x. Rep Formula x -> Formula
to :: forall x. Rep Formula x -> Formula
Generic, Formula -> ()
(Formula -> ()) -> NFData Formula
forall a. (a -> ()) -> NFData a
$crnf :: Formula -> ()
rnf :: Formula -> ()
NFData)
evaluateFormula :: Map String Bool -> Formula -> Bool
evaluateFormula :: Map String Bool -> Formula -> Bool
evaluateFormula Map String Bool
_ (Value Bool
x) = Bool
x
evaluateFormula Map String Bool
m (Variable String
s) = Map String Bool
m Map String Bool -> String -> Bool
forall k a. Ord k => Map k a -> k -> a
! String
s
evaluateFormula Map String Bool
m (Complement Formula
f) = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Map String Bool -> Formula -> Bool
evaluateFormula Map String Bool
m Formula
f
evaluateFormula Map String Bool
m (Disjoin [Formula]
fs) = (Formula -> Bool) -> [Formula] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Map String Bool -> Formula -> Bool
evaluateFormula Map String Bool
m) [Formula]
fs
evaluateFormula Map String Bool
m (Conjoin [Formula]
fs) = (Formula -> Bool) -> [Formula] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Map String Bool -> Formula -> Bool
evaluateFormula Map String Bool
m) [Formula]
fs