Reputation: 445
Let's say that we have a function truthtable ::BoolExpr -> [([Variable], Bool)]
that returns the value in List of ordered pairs of the variable and it's Bool evaluation.
functions are defined as following
module BoolExpr (Variable, BoolExpr(..), evaluate) where
import Data.List
import System.IO
type Variable = Char
data BoolExpr = T
|F
|Var Variable
|Not BoolExpr
|And BoolExpr BoolExpr
|Or BoolExpr BoolExpr
deriving(Show)
-- evaluates an expression
evaluate :: BoolExpr -> [Variable] -> Bool
evaluate T _ = True
evaluate F _ = False
evaluate (Var v) vs = v `elem` vs
evaluate (Not e) vs = not (evaluate e vs)
evaluate (And e1 e2) vs = evaluate e1 vs && evaluate e2 vs
evaluate (Or e1 e2) vs = evaluate e1 vs || evaluate e2 vs
--remove duplicates
rmdups :: (Ord a) => [a] -> [a]
rmdups = map head . group . sort
variables :: BoolExpr -> [Variable]
variables T = []
variables F = []
variables (Var e1) = [e1]
variables (And e1 e2) =rmdups$ sort $ variables e1 ++ variables e2
variables (Or e1 e2) =rmdups$ sort $ variables e1 ++ variables e2
variables (Not e) = variables e
--function to get the subsets of a list
subsets :: [Variable] -> [[Variable]]
subsets [] = [[]]
subsets (x:xs) = [zs | ys <- subsets xs, zs <- [ys, (x:ys)]]
Now the function subsets return all possible subsets in a string eg.
> subsets "abc"
["","c","b","bc","a","ac","ab","abc"]
Now how to take each element in this list and put it here
evaluate (And (Var 'a') (Or (Var 'c') (Var 'b'))) "HERE"
I know how to do something like this in C using iteration over the list and doing the calculation.
My approach : number of subsets of string= 2^n, where n is the number of elements
now I would use a scenario like this:
let x=0
iterate form x to (n-1) (subsets $ variables (And e1 e2)) !! x
i know that !!
operator allow to pick element from the list according to the index written.
Finally the result of the chunk above is applied to the evaluate
function at the end part HERE. that what the function truthtable
evaluate as a whole
> truthtable (And (Var 'a') (Or (Var 'c') (Var 'b')))
[("",False),("c",False),("b",False),("bc",False),("a",False),("ac",True),("ab",True),("abc",True)]
any ideas how to apply this in Haskell
Upvotes: 1
Views: 710
Reputation: 71065
> truthtable (And (Var 'a') (Or (Var 'c') (Var 'b'))) [("",False),("c",False),("b",False), ...
You mean,
truthtable expr =
[ evaluate expr s | s <- subsets (variables expr) ]
{-
expr :: BoolExpr
variables :: BoolExpr -> [Variable]
variables expr :: [Variable]
subsets :: [Variable] -> [[Variable]]
subsets (variables expr) :: [[Variable]]
s :: [Variable]
evaluate :: BoolExpr -> [Variable] -> Bool
evaluate expr s :: Bool
[evaluate expr s ] :: [Bool]
-----------------------------------------------------------------------
truthtable :: BoolExpr -> [Bool]
-}
The [ foo | x <- xs ]
syntax is known as "list comprehension".
It is analogous to a loop in imperative paradigm, and can be read as "the list of foo
s, for x
in xs
". It is also equivalent to map (\ x -> foo ) xs
; also
[ foo | x <- [a, b, c] ]
=
[ foo | x <- [a] ++ [b] ++ [c] ]
=
[ foo | x <- [a] ] ++ [ foo | x <- [b] ] ++ [ foo | x <- [c] ]
=
[ foo | let x=a ] ++ [ foo | let x=b ] ++ [ foo | let x=c ]
::
means "has type".
Upvotes: 1
Reputation: 152707
Now how to take each element in this list and put it here
evaluate (And (Var 'a') (Or (Var 'c') (Var 'b'))) "HERE"
Like this:
map (evaluate (And ...)) (subsets "abc")
Upvotes: 4