bv-little-1.0.0: util/Operator/Unary/Logical.hs
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Operator.Unary.Logical
( UnaryLogicalOperator()
, getUnaryLogicalSymbol
, getUnaryLogicalOperator
, fromUnaryLogicalFunction
) where
import Control.DeepSeq
import Data.Data
import Data.Monoid ()
import Data.Semigroup
import GHC.Generics
import Test.QuickCheck hiding (generate)
import Test.SmallCheck.Series
data UnaryLogicalOperator
= AlwaysFalse
| Identity
| Negation
| AlwaysTrue
deriving (Data, Eq, Ord, Generic, NFData, Typeable)
instance Arbitrary UnaryLogicalOperator where
arbitrary = arbitraryBoundedEnum
instance Bounded UnaryLogicalOperator where
minBound = AlwaysFalse
maxBound = AlwaysTrue
instance CoArbitrary UnaryLogicalOperator where
coarbitrary = coarbitraryEnum
instance Enum UnaryLogicalOperator where
toEnum n =
case n `rem` 4 of
0 -> AlwaysFalse
1 -> Identity
2 -> Negation
_ -> AlwaysTrue
fromEnum x =
case x of
AlwaysFalse -> 0
Identity -> 1
Negation -> 2
AlwaysTrue -> 3
succ x =
case x of
AlwaysFalse -> Identity
Identity -> Negation
Negation -> AlwaysTrue
AlwaysTrue -> AlwaysFalse
pred x =
case x of
AlwaysFalse -> AlwaysTrue
Identity -> AlwaysFalse
Negation -> Identity
AlwaysTrue -> Negation
instance Monad m => Serial m UnaryLogicalOperator where
series = generate $ const [minBound .. maxBound]
instance Show UnaryLogicalOperator where
show x = "f p q = " <> s
where
s = case x of
AlwaysFalse -> "False (Contradiction)"
Identity -> "id (Identity)"
Negation -> "not (Negation)"
AlwaysTrue -> "True (Tautology)"
getUnaryLogicalOperator :: UnaryLogicalOperator -> Bool -> Bool
getUnaryLogicalOperator x =
case x of
AlwaysFalse -> const False
Identity -> id
Negation -> not
AlwaysTrue -> const True
getUnaryLogicalSymbol :: UnaryLogicalOperator -> String
getUnaryLogicalSymbol x =
case x of
AlwaysFalse -> "(const False)"
Identity -> "(id)"
Negation -> "(not)"
AlwaysTrue -> "(const True)"
fromUnaryLogicalFunction :: (Bool -> Bool) -> UnaryLogicalOperator
fromUnaryLogicalFunction f =
case (f False, f True) of
(False, False) -> AlwaysFalse
(False, True ) -> Identity
(True , False) -> Negation
(True , True ) -> AlwaysTrue