{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -Wall -Werror #-}
module Documentation.SBV.Examples.Puzzles.Rabbits where
import Data.SBV
data Rabbit
mkUninterpretedSort ''Rabbit
greedy :: SRabbit -> SBool
greedy :: SRabbit -> SBool
greedy = String -> SRabbit -> SBool
forall a. SMTDefinable a => String -> a
uninterpret String
"greedy"
black :: SRabbit -> SBool
black :: SRabbit -> SBool
black = String -> SRabbit -> SBool
forall a. SMTDefinable a => String -> a
uninterpret String
"black"
old :: SRabbit -> SBool
old :: SRabbit -> SBool
old = String -> SRabbit -> SBool
forall a. SMTDefinable a => String -> a
uninterpret String
"old"
rabbits :: Predicate
rabbits :: Predicate
rabbits = do
(Forall Any Rabbit -> SBool) -> SymbolicT IO ()
forall a. QuantifiedBool a => a -> SymbolicT IO ()
forall (m :: * -> *) a.
(SolverContext m, QuantifiedBool a) =>
a -> m ()
constrain ((Forall Any Rabbit -> SBool) -> SymbolicT IO ())
-> (Forall Any Rabbit -> SBool) -> SymbolicT IO ()
forall a b. (a -> b) -> a -> b
$ \(Forall SRabbit
x) -> SBool -> SBool
sNot (SRabbit -> SBool
greedy SRabbit
x) SBool -> SBool -> SBool
.=> SRabbit -> SBool
black SRabbit
x
(Forall Any Rabbit -> SBool) -> SymbolicT IO ()
forall a. QuantifiedBool a => a -> SymbolicT IO ()
forall (m :: * -> *) a.
(SolverContext m, QuantifiedBool a) =>
a -> m ()
constrain ((Forall Any Rabbit -> SBool) -> SymbolicT IO ())
-> (Forall Any Rabbit -> SBool) -> SymbolicT IO ()
forall a b. (a -> b) -> a -> b
$ \(Forall SRabbit
x) -> SRabbit -> SBool
old SRabbit
x SBool -> SBool -> SBool
.=> SRabbit -> SBool
greedy SRabbit
x
(Exists Any Rabbit -> SBool) -> SymbolicT IO ()
forall a. QuantifiedBool a => a -> SymbolicT IO ()
forall (m :: * -> *) a.
(SolverContext m, QuantifiedBool a) =>
a -> m ()
constrain ((Exists Any Rabbit -> SBool) -> SymbolicT IO ())
-> (Exists Any Rabbit -> SBool) -> SymbolicT IO ()
forall a b. (a -> b) -> a -> b
$ \(Exists SRabbit
x) -> SBool -> SBool
sNot (SRabbit -> SBool
greedy SRabbit
x)
SBool -> Predicate
forall a. a -> SymbolicT IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SBool -> Predicate) -> SBool -> Predicate
forall a b. (a -> b) -> a -> b
$ (Exists Any Rabbit -> SBool) -> SBool
forall a. QuantifiedBool a => a -> SBool
quantifiedBool ((Exists Any Rabbit -> SBool) -> SBool)
-> (Exists Any Rabbit -> SBool) -> SBool
forall a b. (a -> b) -> a -> b
$ \(Exists SRabbit
x) -> SRabbit -> SBool
black SRabbit
x SBool -> SBool -> SBool
.&& SBool -> SBool
sNot (SRabbit -> SBool
old SRabbit
x)
rabbitsAreOK :: IO ThmResult
rabbitsAreOK :: IO ThmResult
rabbitsAreOK = Predicate -> IO ThmResult
forall a. Provable a => a -> IO ThmResult
prove Predicate
rabbits