有没有一种方法可以使用 write/1 来编写 length/1 谓词来打印结果?
Is there a way to write a length/1 predicate using write/1 to print result?
我有一个学校作业,最近开始学习Prolog。
这是练习(非常简单):
Write a program in Prolog to find a length of a given list. For example, length([a, b, c, d, e]).
should print 5
我真的不知道如何创建一个 length/1
谓词来为我做这件事。这是我的代码:
length([],0).
length([_|T],N) :- length(T,X), N is X+1.
现在,我问我的老师如何将其转换为 length/1
谓词,他告诉我使用 write/1
谓词。
我查找了 write/1
谓词,但看不出这将如何帮助我编写 length/1
谓词。
有人 tips/tricks 可以这样做吗?
要清楚,这是作业。
解决方法很简单:impure(Ls) :- length(Ls, L), write(L).
。
但是,出于几个原因,这是一个非常糟糕的主意。
一个非常重要的一点是,只出现在屏幕上的东西无法在 Prolog 中被推理!
因此,如果您只是用 write/1
写一些结果,您就无法真正 运行 自动测试用例来查看您的谓词是否确实按预期运行。这样至少编写测试变得更难。
相比之下,使用您原始的 更纯净 版本的代码(未使用副作用),您可以轻松测试,例如:
?- length([a,b,c], 3).
true.
还有运行几个这样的自动测试用例,用Prolog看是否成功。例如,一批 10,000 个测试用例可能看起来像(搜索反例):
?- between(1, 10_000, L), length(Ls, L), length([_|Ls], L1), L1 =\= L+1.
false.
相比之下,如何测试不纯谓词?
?- between(1, 10_000, L), length(Ls, L), impure([_|Ls]) what now??
如您所见,对谓词的输出进行推理真的很难!
此外,这使您的谓词 比当前版本更不通用 !您不能再在其他方向使用不纯版本。例如,您现在如何生成给定长度的列表?无法提供长度!
保持纯真,使用 Prolog 顶层获取答案,而不是在屏幕上自己写!
TL;DR: 不要!
您绝对想要的是在Prolog中可以实现的,但是问问自己“我应该那样做吗?”。
我给你的建议是:
不要使用 Prolog 的低级 I/O API (write/1
, nl/0
, ...) 因为它是基于side-effects.
在定子句语法上使用 dcg! Start by reading this fine Prolog primer。
熟悉(并使用!)prolog-toplevel。
我有一个学校作业,最近开始学习Prolog。
这是练习(非常简单):
Write a program in Prolog to find a length of a given list. For example,
length([a, b, c, d, e]).
should print 5
我真的不知道如何创建一个 length/1
谓词来为我做这件事。这是我的代码:
length([],0).
length([_|T],N) :- length(T,X), N is X+1.
现在,我问我的老师如何将其转换为 length/1
谓词,他告诉我使用 write/1
谓词。
我查找了 write/1
谓词,但看不出这将如何帮助我编写 length/1
谓词。
有人 tips/tricks 可以这样做吗?
要清楚,这是作业。
解决方法很简单:impure(Ls) :- length(Ls, L), write(L).
。
但是,出于几个原因,这是一个非常糟糕的主意。
一个非常重要的一点是,只出现在屏幕上的东西无法在 Prolog 中被推理!
因此,如果您只是用 write/1
写一些结果,您就无法真正 运行 自动测试用例来查看您的谓词是否确实按预期运行。这样至少编写测试变得更难。
相比之下,使用您原始的 更纯净 版本的代码(未使用副作用),您可以轻松测试,例如:
?- length([a,b,c], 3). true.
还有运行几个这样的自动测试用例,用Prolog看是否成功。例如,一批 10,000 个测试用例可能看起来像(搜索反例):
?- between(1, 10_000, L), length(Ls, L), length([_|Ls], L1), L1 =\= L+1. false.
相比之下,如何测试不纯谓词?
?- between(1, 10_000, L), length(Ls, L), impure([_|Ls]) what now??
如您所见,对谓词的输出进行推理真的很难!
此外,这使您的谓词 比当前版本更不通用 !您不能再在其他方向使用不纯版本。例如,您现在如何生成给定长度的列表?无法提供长度!
保持纯真,使用 Prolog 顶层获取答案,而不是在屏幕上自己写!
TL;DR: 不要!
您绝对想要的是在Prolog中可以实现的,但是问问自己“我应该那样做吗?”。
我给你的建议是:
不要使用 Prolog 的低级 I/O API (
write/1
,nl/0
, ...) 因为它是基于side-effects.在定子句语法上使用 dcg! Start by reading this fine Prolog primer。
熟悉(并使用!)prolog-toplevel。