List 列表搜索在prolog中无限实现
我试图编写一个Prolog程序,该程序接受2个值并计算该对是否有效。如果对在不同的列表中,那么对将是有效的,它们可以进行匹配。如果两个队在同一个名单(组),那么他们不能使比赛,这意味着假 当我启动程序时,它没有显示任何内容。我以为会有无限的搜索或循环。然后尝试了那个简单的代码List 列表搜索在prolog中无限实现,list,search,prolog,List,Search,Prolog,我试图编写一个Prolog程序,该程序接受2个值并计算该对是否有效。如果对在不同的列表中,那么对将是有效的,它们可以进行匹配。如果两个队在同一个名单(组),那么他们不能使比赛,这意味着假 当我启动程序时,它没有显示任何内容。我以为会有无限的搜索或循环。然后尝试了那个简单的代码 GroupB=[china,usa,chile,italy]. member(X,[X|_]). member(X,[_|T]):- member(X,T). match(X):- member(X,Gro
GroupB=[china,usa,chile,italy].
member(X,[X|_]).
member(X,[_|T]):-
member(X,T).
match(X):-
member(X,GroupB).
在那段代码中,我看到程序总是给我正确的答案。我打字;为了给SWI序言,我输入了另一个true;又是一个事实,然后我意识到问题应该在搜索部分。谢谢你从现在开始对我感兴趣。欢迎所有建议
编辑:
我这样编辑代码是为了尝试不同的风格
GroupA([germany,brazil,turkey,korea]).
GroupB([china,usa,chile,italy]).
member(X,[X|_]).
member(X,[_|T]):-
member(X,T).
memberence(X):-
GroupA(L).
GroupB(M).
member(X,L).
member(X,M).
collision(X,Y):-
GroupA(L),
member(X,L),
member(Y,L).
GroupB(L),
member(X,L),
member(Y,L).
match(X,Y) :-
GroupA(L),
memberence(X),
memberence(Y),
\+collision(X,Y).
现在我得到了:
错误:未定义的过程:匹配/2
错误:但是,有以下定义:
错误:catch/3
虽然有一个匹配(X,Y)过程,为什么它会给我未定义的匹配/2错误
GroupA=[germany,brazil,turkey,korea].
GroupB=[china,usa,chile,italy].
member(X,[X|_]).
member(X,[_|T]):-
member(X,T).
memberence(X):-
member(X,GroupA).
member(X,GroupB).
collision(X,Y):-
member(X,GroupA),
member(Y,GroupA).
member(X,GroupB),
member(Y,GroupB).
match(X,Y) :-
memberence(X),
memberence(Y),
\+collision(X,Y).
(a)
您有一个点必须是逗号:
collision(X,Y):-
member(X,GroupA),member(Y,GroupA).
member(X,GroupB),member(Y,GroupB).
collision(X,Y):-
GroupA(L),member(X,L),member(Y,L),
GroupB(L),member(X,L),member(Y,L).
(b)
最好不要重新定义“成员”,它是标准的
(c)
如果我在中以逗号替换点:
collision(X,Y):-
member(X,GroupA),member(Y,GroupA).
member(X,GroupB),member(Y,GroupB).
collision(X,Y):-
GroupA(L),member(X,L),member(Y,L),
GroupB(L),member(X,L),member(Y,L).
此语句将始终失败,因为没有组A和组B共用的列表“L”
(d)
如果我们采用看似原始的请求,则“采用2值并计算配对是否有效。如果配对在不同的列表中,则配对将有效,并且它们可以进行匹配。如果两个团队在同一列表(组)中,则它们无法进行匹配,这意味着false。”
解决方案似乎显而易见:
match(X,Y) :- groupA(A), member(X,A), groupB(B), member(Y,B).
match(Y,X) :- groupA(A), member(X,A), groupB(B), member(Y,B).
你有两个大问题
- 首先,您似乎可以互换地使用
和,
- 其次,您无法理解Prolog的范围规则。任何未在prolog数据库中断言的内容都将作用于immediate语句或谓词的子句,该语句或子句是该语句的一部分。如果您想让别人知道它,它必须是prolog数据库的一部分,或者作为参数传递。因此,当你说 B组=[中国、美国、智利、意大利]
GroupB
与列表[中国、美国、智利、意大利]
统一。此时,断言成功,新绑定的变量和与之统一的列表**超出范围**,不再存在。然后,当您稍后尝试引用它时:
GroupB=[china,usa,chile,italy].
.
.
.
match(X) :- member(X,GroupB).
变量GroupB
未绑定。您对成员/2
的实现
GroupB=[china,usa,chile,
member(X,[X|_]) .
member(X,[_|T]) :- member(X,T) .
当给定一个未绑定的变量作为其第二个参数时,更愿意以生成的方式行事,在回溯时生成连续(无限)长的变量列表。编写groupA(
等代替groupA(
还有许多
其中,
应该是!a)如果我把第一个点变成逗号,比如成员(X,GroupA),成员(Y,GroupA),
成员(X,GroupB),成员(Y,GroupB).
那么只有A组和B组中的X才是真的,Y组和B组中的Y是不可能的。如果它们都在A组中,我会遇到两个冲突,或者如果它们都在B组中,如果其中一个发生,则表示存在冲突,因此必须是点而不是逗号。c)我不明白c)中的要点,如果你用逗号替换点,结果失败了,那就不要修改它。我将更改GropB()检查的atom名称,然后重试。但它将是点而不是逗号。