List 没有线索的哈斯克尔初学者

List 没有线索的哈斯克尔初学者,list,haskell,List,Haskell,我花了一段时间才弄明白这个问题在寻找什么。我只需要返回那些对真值进行总体评估的命题。我们的例子是和p(或q(不是q)),我知道p必须是真的,q可以是真的或假的。为了实现我们的目标,我们从几个功能开始 type Variable = String type Valuation = [(Variable, Bool)] data Prop = Falsum -- a contradiction, or | Var Variable -- a variable

我花了一段时间才弄明白这个问题在寻找什么。我只需要返回那些对真值进行总体评估的命题。我们的例子是和p(或q(不是q)),我知道p必须是真的,q可以是真的或假的。为了实现我们的目标,我们从几个功能开始

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函数,并且我计算出,打印行必须是

models :: Prop -> [Valuations]
作为我的示例,必须返回评估为True的评估列表,即: 模型示例==[((“p”,True)(“q”,True)],[((“p,True)(“q”,False)]]

我知道vars返回的变量列表没有重复项,在本例中为[“p”,“q”],并且将vars的结果传递到估值中会产生对“p”和“q”应用True和False的所有可能结果的列表。到目前为止,我只能使用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)
理想情况下,我相信我会放弃评估结果,而不是将其保留在列表中,只返回那些评估为真的评估值。我只是被困在如何递归地计算vs的其余部分

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

where finalList == True = 
唉,这看起来根本不正确


对我的逻辑有任何帮助都会有帮助。哦,如果能解释一下如何递归计算列表中的其他部分,我将不胜感激。

我假设您想要您开始编写的
模型::Prop->[Valuation]
。模型将返回满足命题的每个
估值。从接近你所拥有的东西开始

models form = valuations (vars form)
让我们走到一半;它的类型正确,
Prop->[Valuation]
。这只是列出了
表单中变量的每个
估值
。我们想要的是只有那些满足命题的结果。这些可由
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)]]
False
True
False
True
现在,我们可能还需要一个函数来检查是否存在满足该命题的
估值
。这将接受一个命题并返回一个布尔值

satisfiable :: Prop -> Bool
我们可以很容易地根据
模型编写这篇文章

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"))
这个输出

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

“没有线索的哈斯克尔初学者”-别担心,这很正常。有了更多的经验,事情会变得更糟:)是所有的功能都提供了还是你想出了一些?是的,我试图在描述行中添加家庭作业,但它不允许,所以我把家庭作业改为“毫无线索”。主块中的所有代码都是我们要处理的,其余的(不工作的东西)都是我写的。我真的更感兴趣的是逻辑,即如何解决问题,而不是一个直接的答案,因为我认为这会帮助我更多。在尝试递归调用列表时,我似乎总是遇到相同的错误,即第一个元素求值,但其余元素通常为list类型,即给定[Char]时的预期Char。因为这显然是一个家庭作业,而且您正在努力筛选列表,我建议您尝试编写函数
alwaysTrue::Prop->Bool
。如果所有可能的
Valuation
计算结果均为
True
,则应返回
True
,否则返回
False
satisfable::Prop->Bool
也可以用与
alwaysTrue
类似的方式编写。感谢Cirdec,我从来没有想过用这种方式使用过滤器。好吧,至少不是直接的,当我递归调用每个元素时,我想使用我的求值作为列表理解的谓词。在第一次检查了Hoogle上过滤器的源代码之后,我注意到它本身就是一个列表。我仍然需要仔细考虑where声明,以充分理解它是如何工作的,但我想我现在已经有了一个清晰的概念。再次感谢!我确实试着在描述中输入家庭作业,但它不让我这样做,因为是凌晨2点以后,我才离开。