packages feed

Hs2lib-0.4.8: Tests/Src/Test_Bewijzen.hs

{-# LANGUAGE DeriveDataTypeable #-}
module Tests.Src.Test_Bewijzen where

import Data.Data
import Data.Generics
import Data.List
import Data.Char
import Data.Maybe
import Control.Monad
import Debug.Trace

data Prop = Var Var
          | F
          | T
          | Not Prop
          | And Prop Prop
          | Or Prop Prop
          | Impl Prop Prop
            deriving (Show,Data,Typeable)
            
type PropAlgebra a = (Var -> a
                      , a
                      , a
                      , a -> a
                      , a -> a -> a
                      , a -> a -> a
                      , a -> a -> a)
            
type Var = String

demo = Var "p" `And` (Not (Var "q") `Or` (Var "r"))

foldProp :: PropAlgebra a -> Prop -> a
foldProp (var_,f_,t_,not_,and_,or_,impl_) prop = foldalgebra prop
 where foldalgebra prop = 
         case prop of
           (Var v)      -> var_ v
           F            -> f_
           T            -> t_
           (Not p)      -> not_ (foldalgebra p)
           (And p1 p2)  -> (foldalgebra p1) `and_`  (foldalgebra p2)
           (Or p1 p2)   -> (foldalgebra p1) `or_`   (foldalgebra p2)
           (Impl p1 p2) -> (foldalgebra p1) `impl_` (foldalgebra p2)

-- @@ Export
ppProp :: Prop -> String
-- ppProp (Var p)      = p
-- ppProp (Not p)      = "Not "  ++ ppProp p
-- ppProp (And p1 p2)  = "And "  ++ ppProp p1 ++ " " ++ ppProp p2
-- ppProp (Or p1 p2)   = "Or "   ++ ppProp p1 ++ " " ++ ppProp p2
-- ppProp (Impl p1 p2) = "Impl " ++ ppProp p1 ++ " " ++ ppProp p2
-- ppProp T            = "T"
-- ppProp F            = "F"
--------------------------------------
-- -- OR using folds
--------------------------------------
-- ppProp = foldProp (id,
                   -- "F",
                   -- "T",
                   -- ("Not "++),
                   -- (\a b->"And "++a++" "++b),
                   -- (\a b->"Or "++a++" "++b),
                   -- (\a b->"Impl "++a++" "++b)
                   -- )
--------------------------------------
-- -- OR using Scrap Your Boilerplate
--------------------------------------
ppProp = init.everything (++) ([] `mkQ` inner)
     where inner (Var p) = p ++ " "
           inner x = (showConstr.toConstr) x ++ " "
       
-- @@ Export=ppPropPrime
ppProp' :: Prop -> String
ppProp' = foldProp (id,
                    "F",
                    "T",
                    (++" Not"),
                    (\a b->a++" "++b++" And"),
                    (\a b->a++" "++b++" Or"),
                    (\a b->a++" "++b++" Impl")
                )
 
-- @@ Export 
parseVar :: String -> Maybe (Var,String)
parseVar input = 
 do let (a,v) = head $ lex input
    case (all isLower a) of
       False -> Nothing
       True -> Just (a,v)
       
-- @@ Export
parseProp :: String -> Maybe Prop
parseProp input = let result = parseProp' input 
                  in if null result 
                    then Nothing 
                    else case head result of
                            (val,[]) -> val
                            _        -> Nothing
    where         
        parseProp' :: ReadS (Maybe Prop)
        parseProp' x = 
         do let (hd,r1) = head $ lex x
            when (null hd) (error "Parse error")
            case hd of
              "And"  -> pp And r1
              "Or"   -> pp Or r1
              "Not"  -> do let (Just f1,r2) = head $ parseProp' r1
                           return (Just $ Not f1,r2)
              "Impl" -> pp Impl r1
              "F"    -> return (Just F,r1)
              "T"    -> return (Just T,r1)
              y      -> return $ maybe (Nothing,x) (\(a,v)->(Just $ Var a,v++r1)) (parseVar y)
          where f = fromJust.fst.head
                pp cons r1 = do let (Just f1,r2) = head $ parseProp' r1
                                let (Just f2,r3) = head $ parseProp' r2
                                return (Just $ cons f1 f2,r3)

-- @@ Export = parsePropPrime                                
parseProp' :: String -> Maybe Prop
parseProp' input = let result = parseProp'' [] input 
                  in if null result 
                    then Nothing 
                    else case head result of
                            (val,[]) -> val
                            _        -> Nothing
    where          
        parseProp'' :: [Prop] -> ReadS (Maybe Prop)
        parseProp'' p x = let (hd,r1) = head $ lex x 
                          in if (null hd) 
                               then if length p == 1 then return (Just $ head p,"") else []
                               else 
         do case hd of
              "And"  -> pp And r1
              "Or"   -> pp Or r1
              "Not"  -> do let (f1:[]) = take 1 p
                               rest = drop 1 p
                           parseProp'' (Not f1:rest) r1
              "Impl" -> pp Impl r1
              "F"    -> parseProp'' (F:p) r1
              "T"    -> parseProp'' (T:p) r1
              y      -> maybe [(Nothing,x)] (\(a,v)->parseProp'' (Var a:p) (v++r1)) (parseVar y)
          where f = fromJust.fst.head
                pp cons r1 = do if length p < 2 
                                    then []
                                    else let (f1:f2:[]) = take 2 p
                                             rest       = drop 2 p
                                         in parseProp'' (cons f2 f1:rest) r1

-- @@ Export = getVars                                         
vars :: Prop -> [Var]
vars = nub.foldProp ((:[]),[],[],id,(++),(++),(++))

type Env = Var -> Bool

--truthTable :: [Var] -> [Env]
--truthTable input = [   , a <- input, b <- input, c <- input , d <- [True,False]]
--    where m b = case a

f "p" = True
f "q" = False
f "r" = True