我正在尝试编写一个简单的过程来检查列表是否有任何重复.这是我到目前为止所尝试的:
% returns true if the list has no duplicate items.
no_duplicates([X|XS]) :- member(X,XS) -> false ; no_duplicates(XS).
no_duplicates([]) :- true.
Run Code Online (Sandbox Code Playgroud)
如果我试试no_duplicates([1,2,3,3]).它说的是真的.为什么是这样?我可能在这里误解了Prolog,但任何帮助都表示赞赏.
回答你的问题:你的解决方案实际上失败了no_duplicates([1,2,3,3]).所以没有问题.
现在进行查询:
?- A = 1, no_duplicates([A, 2]).
A = 1.
?- no_duplicates([A, 2]), A = 1.
Run Code Online (Sandbox Code Playgroud)
它们都意味着相同,所以我们应该期待Prolog会产生相同的答案.(更确切地说,我们期望相同的忽略错误和非终止).
但是,提出的四种解决方案不同 而那个没有的,不同的是:
?- A = 2, no_duplicates([A, 2]).
false.
?- no_duplicates([A, 2]), A = 2.
Run Code Online (Sandbox Code Playgroud)
请注意,它总是第二个产生麻烦的查询.要解决这个问题,我们需要一个很好的答案no_duplicates([A, 2]).它不可能false,因为有一些值A可以使它成为现实.喜欢A = 1.也不是真的,因为有些价值观不合适,比如A = 2.
另一种可能性是instantiation_error在这种情况下发布.含义:我没有足够的信息,所以我最好停下来,而不是弄乱可能不正确的信息.
理想情况下,我们得到一个涵盖所有可能解决方案的答案.这个答案dif(A, 2)意味着所有A与2不同的是解决方案.
dif/2是最古老的内置谓词之一,Prolog 0确实拥有它.不幸的是,后来的发展在Prolog I和Edinburgh Prolog以及ISO Prolog中丢弃了它.
但是,包括SICStus,YAP,SWI在内的现有系统都提供它.还有就是一种安全的方式接近dif/2安全的ISO-序言
no_duplicates(Xs) :-
all_different(Xs). % the common name
all_different([]).
all_different([X|Xs]) :-
maplist(dif(X),Xs).
all_different(Xs).
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
324 次 |
| 最近记录: |