{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE PatternSynonyms        #-}
{-# LANGUAGE TemplateHaskell        #-}
module Satyros.CNF.Positivity
  ( Positivity(Positive, Negative)
  , isPositive
  , negatePositivity
  ) where

import           Control.Lens           (Iso', _Wrapped, makeWrapped)
import           Data.Coerce            (coerce)
import           GHC.Generics           (Generic)
import           System.Random.Stateful (Random)

newtype Positivity = Positivity Bool
  deriving stock ((forall x. Positivity -> Rep Positivity x)
-> (forall x. Rep Positivity x -> Positivity) -> Generic Positivity
forall x. Rep Positivity x -> Positivity
forall x. Positivity -> Rep Positivity x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Positivity x -> Positivity
$cfrom :: forall x. Positivity -> Rep Positivity x
Generic, Positivity -> Positivity -> Bool
(Positivity -> Positivity -> Bool)
-> (Positivity -> Positivity -> Bool) -> Eq Positivity
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Positivity -> Positivity -> Bool
$c/= :: Positivity -> Positivity -> Bool
== :: Positivity -> Positivity -> Bool
$c== :: Positivity -> Positivity -> Bool
Eq, Eq Positivity
Eq Positivity
-> (Positivity -> Positivity -> Ordering)
-> (Positivity -> Positivity -> Bool)
-> (Positivity -> Positivity -> Bool)
-> (Positivity -> Positivity -> Bool)
-> (Positivity -> Positivity -> Bool)
-> (Positivity -> Positivity -> Positivity)
-> (Positivity -> Positivity -> Positivity)
-> Ord Positivity
Positivity -> Positivity -> Bool
Positivity -> Positivity -> Ordering
Positivity -> Positivity -> Positivity
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
min :: Positivity -> Positivity -> Positivity
$cmin :: Positivity -> Positivity -> Positivity
max :: Positivity -> Positivity -> Positivity
$cmax :: Positivity -> Positivity -> Positivity
>= :: Positivity -> Positivity -> Bool
$c>= :: Positivity -> Positivity -> Bool
> :: Positivity -> Positivity -> Bool
$c> :: Positivity -> Positivity -> Bool
<= :: Positivity -> Positivity -> Bool
$c<= :: Positivity -> Positivity -> Bool
< :: Positivity -> Positivity -> Bool
$c< :: Positivity -> Positivity -> Bool
compare :: Positivity -> Positivity -> Ordering
$ccompare :: Positivity -> Positivity -> Ordering
$cp1Ord :: Eq Positivity
Ord)
  deriving newtype (Int -> Positivity -> ShowS
[Positivity] -> ShowS
Positivity -> String
(Int -> Positivity -> ShowS)
-> (Positivity -> String)
-> ([Positivity] -> ShowS)
-> Show Positivity
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Positivity] -> ShowS
$cshowList :: [Positivity] -> ShowS
show :: Positivity -> String
$cshow :: Positivity -> String
showsPrec :: Int -> Positivity -> ShowS
$cshowsPrec :: Int -> Positivity -> ShowS
Show, g -> (Positivity, g)
g -> [Positivity]
(Positivity, Positivity) -> g -> (Positivity, g)
(Positivity, Positivity) -> g -> [Positivity]
(forall g.
 RandomGen g =>
 (Positivity, Positivity) -> g -> (Positivity, g))
-> (forall g. RandomGen g => g -> (Positivity, g))
-> (forall g.
    RandomGen g =>
    (Positivity, Positivity) -> g -> [Positivity])
-> (forall g. RandomGen g => g -> [Positivity])
-> Random Positivity
forall g. RandomGen g => g -> [Positivity]
forall g. RandomGen g => g -> (Positivity, g)
forall g.
RandomGen g =>
(Positivity, Positivity) -> g -> [Positivity]
forall g.
RandomGen g =>
(Positivity, Positivity) -> g -> (Positivity, g)
forall a.
(forall g. RandomGen g => (a, a) -> g -> (a, g))
-> (forall g. RandomGen g => g -> (a, g))
-> (forall g. RandomGen g => (a, a) -> g -> [a])
-> (forall g. RandomGen g => g -> [a])
-> Random a
randoms :: g -> [Positivity]
$crandoms :: forall g. RandomGen g => g -> [Positivity]
randomRs :: (Positivity, Positivity) -> g -> [Positivity]
$crandomRs :: forall g.
RandomGen g =>
(Positivity, Positivity) -> g -> [Positivity]
random :: g -> (Positivity, g)
$crandom :: forall g. RandomGen g => g -> (Positivity, g)
randomR :: (Positivity, Positivity) -> g -> (Positivity, g)
$crandomR :: forall g.
RandomGen g =>
(Positivity, Positivity) -> g -> (Positivity, g)
Random)

makeWrapped ''Positivity

isPositive :: Iso' Positivity Bool
isPositive :: p Bool (f Bool) -> p Positivity (f Positivity)
isPositive = p Bool (f Bool) -> p Positivity (f Positivity)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
_Wrapped
{-# INLINE isPositive #-}

pattern Positive :: Positivity
pattern $bPositive :: Positivity
$mPositive :: forall r. Positivity -> (Void# -> r) -> (Void# -> r) -> r
Positive = Positivity True
pattern Negative :: Positivity
pattern $bNegative :: Positivity
$mNegative :: forall r. Positivity -> (Void# -> r) -> (Void# -> r) -> r
Negative = Positivity False
{-# COMPLETE Positive, Negative #-}

negatePositivity :: Positivity -> Positivity
negatePositivity :: Positivity -> Positivity
negatePositivity = (Bool -> Bool) -> Positivity -> Positivity
coerce Bool -> Bool
not
{-# INLINE negatePositivity #-}