许多系统提供了纯粹而有效的实现member/2.特别是,没有选择点可供选择:
?- member(b,[a,b]).
true.
Run Code Online (Sandbox Code Playgroud)
然而,member/2生产的天真实施相当:
?- member(b,[a,b]).
true ;
false.
Run Code Online (Sandbox Code Playgroud)
从声明的角度来看肯定是正确的,但效率较低.
另一方面,存在一些技术问题member/2.它允许冗余解决方案,如:
?- member(a,[a,a]).
true ;
true.
Run Code Online (Sandbox Code Playgroud)
memberd/2使用if_/3和解决这个问题(=)/3.
memberd(E, [X|Xs]) :-
if_(E = X, true, memberd(E, Xs)).
?- memberd(a,[a,a]).
true.
Run Code Online (Sandbox Code Playgroud)
不幸的是,这个定义使选择点再次打开 - ; false在成员不这样做的情况下产生("剩余的选择点"):
?- memberd(X,[a,b]).
X = a ;
X = b ;
false. % BAD - to be avoided!
?- member(X,[a,b]).
X = a ;
X = b.
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:是否有一个定义memberd/2,避免选择点如上所述?
我最近一直在刷一些Prolog.我有点喜欢提出随机问题来尝试解决然后解决它们.这一点非常艰难,我不会放弃我已经着手解决的问题.
问题:我想创建一个谓词,它将有2个预定列表,2个数字要交换,然后在交换完成后输出列表.
进一步说明:我希望从列表1中找到一个特定的唯一编号,并使用列表2中的特定唯一编号交换它,以便如果我有2个列表... [7,2,7] ,8,5]和[1,2,3,8,7,9,8],然后给出谓词2个数字(只说8和7),那么数字8和数字7将被交换如果数字8在第一个列表中而数字7在第二个列表中,则在列表IF和ON之间.(它将忽略第二个列表中的8和第一个列表中的7).
具有预期答案的示例查询:
?- bothSwap([7,2,7,8,5],[1,2,3,8,7,9,8],8,7,X,Y).
X = [7,2,7,7,5], Y = [1,2,3,8,8,9,8].
Run Code Online (Sandbox Code Playgroud)
我有点陷入困境:
bothSwap([],L2,N1,N2,[],L2).
bothSwap(L1,[],N1,N2,L1,[]).
bothSwap([H1|T1],[H2|T2],N1,N2,X,Y) :- H1 == N1, H2 == N2, bothSwap(T1,T2,N1,N2,D1,D2), append(D1,[H2],X), append(D2,[H1],Y).
bothSwap([H1|T1],[H2|T2],N1,N2,X,Y) :- H1 == N1, H2 =\= N2, bothSwap([H1|T1],T2,N1,N2,D1,D2).
bothSwap([H1|T1],[H2|T2],N1,N2,X,Y) :- H1 =\= N1, H2 == N2, bothSwap(T1,[H2|T2],N1,N2,D1,D2).
Run Code Online (Sandbox Code Playgroud)
有什么聪明的头脑愿意和我一起解决这个问题吗?:)