2

我有一个学校的分配,最近开始学习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谓词。任何提示/技巧来做到这一点?
需要明确的是,这是家庭作业。

4

2 回答 2

4

解决方法很简单: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 顶层来获得答案,而不是自己在屏幕上写出来!

于 2015-11-25T15:55:18.440 回答
2

TL;DR:不要!

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

我对您如何进行的建议是:

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

  2. 使用!首先阅读这篇关于定句语法的优秀 Prolog 入门。

  3. 熟悉(并使用!)

于 2015-11-25T22:49:59.490 回答