rewriting-0.2: examples/logic/LogicStrategies.hs
{-# LANGUAGE FlexibleContexts #-}
-----------------------------------------------------------------------------
-- Copyright 2008, Open Universiteit Nederland. This file is distributed
-- under the terms of the GNU General Public License. For more information,
-- see the file "LICENSE.txt", which is included in the distribution.
-----------------------------------------------------------------------------
-- |
-- Maintainer : bastiaan.heeren@ou.nl
-- Stability : provisional
-- Portability : portable (depends on ghc)
--
-----------------------------------------------------------------------------
module LogicStrategies where
import Prelude hiding (repeat)
import Logic
import LogicRules hiding (main)
import System.Random
import Test.QuickCheck hiding (label)
import Generics.Regular.Rewriting
type Strategy a = a -> [a]
label _ = id
(s <*> t) a = [c | b <- s a, c <- t b]
(s <|> t) a = s a ++ t a
many s = return <|> (s <*> many s)
repeat s = many s <*> notS s
alternatives = foldr (<|>) (const [])
notS s a = if null (s a) then [a] else []
rewriteMl :: Rewrite a => [Rule a] -> Strategy a
rewriteMl = alternatives . map rewriteM
eliminateConstants :: Strategy (Logic)
eliminateConstants = repeat $ once $
alternatives $
[ rewriteMl ruleFalseZeroOr
, rewriteMl ruleTrueZeroOr
, rewriteMl ruleTrueZeroAnd
, rewriteMl ruleFalseZeroAnd
, rewriteMl ruleNotBoolConst
, rewriteMl ruleFalseInEquiv
, rewriteMl ruleTrueInEquiv
, rewriteMl ruleFalseInImpl
, rewriteMl ruleTrueInImpl
]
eliminateImplEquiv :: Strategy (Logic)
eliminateImplEquiv = repeat $ once $
rewriteM ruleDefImpl
<|> rewriteM ruleDefEquiv
eliminateNots :: Strategy (Logic)
eliminateNots = repeat $ once $
rewriteM ruleDeMorganAnd
<|> rewriteM ruleDeMorganOr
<|> rewriteM ruleNotNot
orToTop :: Strategy (Logic)
orToTop = repeat $ once $ rewriteMl ruleAndOverOr
toDNF :: Strategy (Logic)
toDNF = label "Bring to dnf"
$ label "Eliminate constants" eliminateConstants
<*> label "Eliminate implications/equivalences" eliminateImplEquiv
<*> label "Eliminate nots" eliminateNots
<*> label "Move ors to top" orToTop
propSound :: Logic -> Bool
propSound p =
case toDNF p of
x:_ -> isDNF x
_ -> False
propView :: Logic -> Bool
propView p = p == to (from p)
checks :: IO ()
checks = do
quickCheck propView
quickCheck propSound
main :: IO ()
main = print $ all checkOne [0..250]
where
checkOne n =
propSound (generate n (mkStdGen n) arbitrary)