twice(X,[X|Y]):-
member(X,[Y]).
twice(X,[Y|Z]):-
twice(X,[Z]),
X\=Y.
我找不到任何语法错误,但每次都执行失败。
答案 0 :(得分:3)
您对列表结构存在误解。列表[H|T]
包含元素 H
和尾部列表 T
。所以T
本身就是一个列表。如果您放置[T]
,那么该列表只包含一个元素,该元素就是列表T
。
此外,在您的第二个谓词条款中,您不需要X
参数或检查X \= Y
,因为如果您正在检查它并不是真的相关至少两次。
因此,您的解决方案稍有改变:
twice(X, [X|T]) :-
member(X, T).
twice(X, [_|T]) :-
twice(X, T).
如果X
是[X|T]
或 X
的成员,那么 T
在X
中出现两次如果[_|T]
在X
中出现两次T
,则localStorage.removeItem('favorties');
会发生两次。
答案 1 :(得分:3)
我喜欢你的意图,但不能重现你所说的:这个谓词一直都在失败。事实上,它循环!以下是failure-slice:
的片段twice(X,[X|Y]):- false,member(X,[Y]). twice(X,[Y|Z]):- twice(X,[Z]), false,X\=Y?- twice(a,[a,a]).
因为这个片段循环,你的原始程序也循环。 Lurker已经告诉你什么是错的。以下是一些替代配方:
twice(X, Xs) :-
phrase( ( ..., [X], ..., [X], ... ), Xs).
... --> [] | [_], ... .
然而,这个程序有一个很大的缺陷:
?- twice(a,[a,a,a]).
true
; true
; true
; false.
我们的答案完全相同。有一次绰绰有余!
模糊性来自...
- 非终端,这意味着任何序列。有三种方式与列表[a,a,a]
匹配:
[ a, a, a ]
...,[X],...,[X], ...
...,[X], ..., [X],...
..., [X],...,[X],...
要消除歧义,我们需要用更具体的内容替换...
。除了X
之外,序列应该匹配任何内容。这样只剩下第一场比赛。
twice(X, Xs) :-
phrase( ( all(dif(X)), [X], all(dif(X)), [X], ... ), Xs).
all(_) --> [].
all(P_1) -->
[E],
{call(P_1,E)},
all(P_1).
?- twice(a,[a,a,a]).
true
; false.
那要好得多。但这是最好的吗?对SICStus | SWI使用library(reif)
进行了进一步改进。
:- use_module(library(reif)).
twice(C, [X|Xs]) :-
if_(C = X, memberd(X, Xs), twice(C, Xs) ).
memberd(C, [X|Xs]) :-
if_(C = X, true, memberd(C, Xs) ).
?- twice(a,[a,a,a]).
true.
答案 2 :(得分:0)
twicee(X,[X|Y]):- member(X,Y).
twicee(X,[_|Y]):-twicee(X,Y), X\=Y.
为我工作的代码,请检查列表中是否有两个元素。例如:
twicee(X,[a,a,b,b,c,d]).
X = a.
X= b.
twicee(c,[a,a,b,b,d]).
FALSE.