【问题标题】:Is there a way to write a length/1 predicate using write/1 to print result?有没有办法使用 write/1 来编写 length/1 谓词来打印结果?
【发布时间】:2015-11-25 15:39:27
【问题描述】:

我有一个学校作业,最近开始学习 Prolog。
这是练习(非常简单):

在 Prolog 中编写一个程序来查找给定列表的长度。例如,length([a, b, c, d, e]). 应该打印 5

我真的不知道如何为我创建一个 length/1 谓词。这是我的代码:

length([],0).
length([_|T],N) :- length(T,X), N is X+1. 

现在,我问我的老师如何将其转换为 length/1 谓词,他告诉我使用 write/1 谓词。 我查找了write/1 谓词,但我不明白这将如何帮助我编写length/1 谓词。 任何提示/技巧可以做到这一点?
需要明确的是,这是家庭作业。

【问题讨论】:

  • 没有诀窍。 length/1 谓词远不如length/2 谓词有用。通常,您会这样做,length([1,2,3], N), write(N), nl. 如果您愿意,您可以轻松地将其转换为 length/1 谓词。他们似乎在 Prolog 课程中教授的原则有点令人不安。他们似乎将 Prolog 作为一种迟钝且有限的命令式语言来教授,而不是简单而强大的关系语言。
  • 好评论,+1!我以前也是这么看的,直到@repeat 向我指出了一件有趣的事情:如果你看看那些教和使用 Prolog 的人,你会发现他们很开心,即使他们只使用了一小部分语言的实际能力。从那以后,我对这件事采取了稍微不同的解释:即使他们失去了这么多,但他们已经为自己所拥有的很少而感到非常高兴!将来,他们可能会更喜欢越来越广为人知的更普遍的特征(约束等)!

标签: list prolog prolog-toplevel


【解决方案1】:

解决方法很简单:impure(Ls) :- length(Ls, L), write(L).

但是,出于多种原因,这是一个非常糟糕的主意

非常重要的一点是,仅出现在屏幕上的事物无法在 Prolog 中推理

因此,如果您只是使用write/1 编写一些结果,您将无法真正运行自动测试用例来查看您的谓词是否真的按预期运行。这样至少编写测试会变得困难得多

相比之下,使用您的原始代码,更纯版本(没有使用副作用),您可以轻松地进行测试,例如:

?- 长度([a,b,c], 3)。 是的。

并自动运行几个这样的测试用例,并使用 Prolog 来查看它们是否成功。例如,一批 10,000 个测试用例可能看起来像(搜索反例):

?- 在(1, 10_000, L), 长度(Ls, L), 长度([_|Ls], L1), L1 =\= L+1。 错误

相比之下,你如何测试一个不纯的谓词?

?- between(1, 10_000, L), length(Ls, L), impure([_|Ls]) 现在怎么办??

如您所见,很难推断谓词的输出!

此外,这使您的谓词比您当前的版本更不通用!您不能再在其他方向使用不纯版本。例如,您现在如何生成给定长度的列表?没有办法提供长度!

保持纯洁,使用 Prolog 顶层来获得答案,而不是自己在屏幕上写出来!

【讨论】:

    【解决方案2】:

    TL;DR:不要!

    你想要的绝对在 Prolog 中可以做到的,但问问自己“我应该那样做吗?”。

    我对您的建议是:

    1. 不要使用 Prolog 的低级 I/O API(write/1nl/0、...),因为它基于

    2. 使用!首先阅读this fine Prolog primer 的定句语法。

    3. 熟悉(并使用!)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-05
      • 1970-01-01
      • 2020-04-08
      • 1970-01-01
      • 1970-01-01
      • 2019-09-06
      相关资源
      最近更新 更多