【问题标题】:Haskell Beginner without a Clue没有线索的 Haskell 初学者
【发布时间】:2013-11-18 02:07:56
【问题描述】:

我花了一段时间才弄清楚这个问题在寻找什么。我只需要返回那些对 True 进行整体评估的命题。我们的例子是 And p (Or 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

我现在必须编写一个模型函数,并且我发现 typeline 必须是

models :: Prop -> [Valuations]

作为我的示例,必须返回评估为 True 的评估列表,即: 模型示例 == [[("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)

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

我相信,一旦我可以使用 evals 函数评估列表中的所有元素,我就可以使用某种形式的等式分配将评估为 True 的元素添加,例如:

where finalList == True = 

唉,这甚至看起来都不正确。

对我的逻辑的任何帮助都会有所帮助。哦,如果我能解释一下我如何递归评估列表的其余部分,我们将不胜感激。

【问题讨论】:

  • 'Haskell Beginner without a Clue' - 别担心,这很正常。有了更多的经验,事情会变得更糟:)
  • 是否提供了所有功能,或者您想出了一些功能?
  • 是的,我尝试将作业添加到描述行,但它不允许我将作业更改为“没有线索”。主块中的所有代码都是我们被赋予使用的,所有其余的(不起作用的东西)都是由我编写的。我真的对逻辑更感兴趣,即如何制定解决方案,而不是直接回答,因为我认为这对我有更多帮助。在尝试递归调用列表时,我似乎总是遇到同样的错误,即第一个元素求值,但其余元素通常是列表类型,即给定 [Char] 时预期的 Char。

标签: list haskell


【解决方案1】:

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

models form = valuations (vars form)

让我们走到了一半;它具有正确的类型,Prop -> [Valuation]。这只是列出了form 中变量的每个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)]]

现在,我们可能还需要一个函数来检查是否存在满足命题的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

【讨论】:

  • 由于这显然是家庭作业,并且您正在努力处理filter 列表,我建议您尝试编写函数alwaysTrue :: Prop -> Bool。如果所有可能的Valuation 计算结果为True,它应该返回True,否则返回Falsesatisfiable :: Prop -> Bool 也可以写成与alwaysTrue 类似的方式。
  • 感谢 Cirdec,我从未想过以这种方式使用过滤器。好吧,至少不是直接的,因为一旦我递归地调用每个元素,我就想将我的评估用作列表理解的谓词。第一次在 Hoogle 上检查了 filter 的源代码后,我注意到它本身就是一个列表理解。我仍然需要仔细考虑 where 语句才能完全理解它是如何工作的,但我想我现在对它有了一个清晰的认识。再次感谢!我确实尝试在描述中输入作业,但它不允许我,因为它是在凌晨 2 点之后。我就离开了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-06
  • 2011-07-12
  • 1970-01-01
  • 1970-01-01
  • 2015-05-23
  • 1970-01-01
相关资源
最近更新 更多