Haskell初学者没有线索

时间:2013-11-18 02:07:56

标签: list haskell

我花了一些时间才弄清楚这个问题正在寻找什么。我必须只返回那些给出整体评价True的命题。我们的例子是And p(或q(Not q)),我知道p必须是True,q可以是True或False。为了实现我们的目标,我们已经开始提供一些功能。

type Variable = String
type Valuation = [(Variable, Bool)]

data Prop = Falsum         -- a contradiction, or
          | Var Variable   -- a variable, or
          | Not Prop       -- a negation of a formula, or
          | Or  Prop Prop  -- a disjunction of two formulae, or
          | And Prop Prop  -- a conjunction of two formulae, or
          | Imp Prop Prop  -- a conditional of two formulae.
            deriving (Eq, Show)

example = And p (Or q (Not q))

vars :: Prop -> [Variable]
vars = nub . vars'
    where
      vars' Falsum    = []
      vars' (Var v)   = [v]
      vars' (Not f)   = vars' f
      vars' (Or  f g) = vars' f ++ vars' g
      vars' (And f g) = vars' f ++ vars' g 
      vars' (Imp f g) = vars' f ++ vars' g 

eval :: Valuation -> Prop -> Bool
eval val Falsum    = False
eval val (Var v)   = case (lookup v val) of
                       Nothing -> error ("Unbound variable: " ++ v)
                       Just t  -> t 
eval val (Not f)   = not (eval val f)
eval val (Or  f g) = (eval val f) || (eval val g)
eval val (And f g) = (eval val f) && (eval val g)
eval val (Imp f g) = eval val (Or (Not f) g)

valuations :: [Variable] -> [Valuation]
valuations []     = [[]]
valuations (v:vs) = map ((v,True):) ds ++ map ((v,False):) ds 
    where ds = valuations vs

我现在必须写一个模型函数,我发现类型行必须是

models :: Prop -> [Valuations]

因为我的示例必须返回评估为True的评估列表,即: models example == [[(“p”,True)(“q”,True)],[(“p”,True)(“q”,False)]]

我知道vars返回没有重复的变量列表,在本例中为[“p”,“q”],并且将结果从vars传递到估值中会生成应用True和False的所有可能结果的列表“p”和“q”。到目前为止,我只能使用evals函数获取此列表的第一个输出。这是我的代码:

models :: Prop -> Bool
models form = eval v form where (v:vs) = valuations (vars form)

我试图更改代码以评估vs的其余部分,但我不断收到错误消息:

Couldn't match expected type '[Bool]' with actual type 'Bool'

这是我改变的代码:

models :: Prop -> [Bool]
models form = eval v form : eval vs form where (v:vs) = valuations (vars form)

理想情况下,我相信我会放弃eval结果而不是将它们保存在列表中,只返回那些评估为True的估值。我只是坚持如何递归评估其余的vs.

我相信一旦我可以使用evals函数评估列表中的所有元素,那么我可以使用某种形式的相等赋值来添加评估为True的元素,例如:

where finalList == True = 
唉,这甚至看起来都不正确。

对我的逻辑的任何帮助都会有所帮助。哦,以及关于我如何递归评估列表其余部分的解释将不胜感激。

1 个答案:

答案 0 :(得分:1)

我会假设你想要models :: Prop -> [Valuation]就像你开始写作一样。模型将返回满足命题的每个Valuation。从接近你所拥有的东西开始

models form = valuations (vars form)

让我们到达那里;它具有正确的类型Prop -> [Valuation]。这只列出Valuation中变量的每个form。我们想要的只是那些满足命题的结果。这些可以通过eval函数确定。

models :: Prop -> [Valuation]
models form = filter satisfies (valuations (vars form))
    where satisfies val = eval val form 

要运行此操作,我们需要修复您的示例以便编译,并且可能添加一些我自己的示例:

example = And (Var "p") (Or (Var "q") (Not (Var "q")))

main = do
    print $ models Falsum
    print $ models example
    print $ models $ And (Var "p") (Not (Var "p"))
    print $ models $ Or (Var "p") (Not (Var "p"))

此输出

[]
[[("p",True),("q",True)],[("p",True),("q",False)]]
[]
[[("p",True)],[("p",False)]]

现在,我们可能还需要一个函数来检查是否存在满足命题的任何Valuation。这将采用一个命题并返回一个布尔值。

satisfiable :: Prop -> Bool

我们可以根据models

轻松写出来
satisfiable :: Prop -> Bool
satisfiable = not . null . models

对于相同的四个例子

main = do
    print $ satisfiable Falsum
    print $ satisfiable example
    print $ satisfiable $ And (Var "p") (Not (Var "p"))
    print $ satisfiable $ Or (Var "p") (Not (Var "p"))

此输出

False
True
False
True