我需要编写一个谓词next(X, List1, List2)
,它返回List2
,这是一个直接跟在X
之后的元素数组。
例如,
next(v1,[v1,v2,v3,v1,v2,v1,v5],L) returns L=[v2,v2,v5]
next(b,[b,k,m,b,j],L) returns L=[k,j]
next(s,[s,b,c,d,e,f,s,c,s,g],L) returns L=[b,c,g]
....
我知道必须使用递归和尾部。
我想我知道逻辑以及谓词应该如何工作,但我无法让它工作。以下是如果用户输入next(a,[a,b,c,a,b,c],L).
[a,b,c,a,b,c]
%if first letter is a, put the letter after it in array L, if not - remove first letter.
%first letter is a, put b in array L, remove a from initial array.
[b,c,a,b,c]
%if first letter is a, put the letter after it in array L, if not - remove first letter.
% first letter is b, it is not a, so remove it from initial array
[c,a,b,c]
%if first letter is a, put the letter after it in array L, if not - remove first letter.
% first letter is c, it is not a, so remove it from initial array
[a,b,c]
%if first letter is a, put the letter after it in array L, if not - remove first letter.
% first letter is a, put b in array L, remove a from initial array.
[b,c]
%if first letter is a, put the letter after it in array L, if not - remove first letter.
% first letter is b, it is not a, so remove it from initial array
[c]
%if first letter is a, put the letter after it in array L, if not - remove first letter.
% first letter is c, it is not a, so remove it from initial array
这就是我所拥有的:
next(X, List1, List2):-
next(X,[X,X2|List1],X2).
我知道方括号中的部分是错误的。
更新#1:
/* X is the head of the list */
next(X, [X,Y|T1], [Y|T2]) :-
next(X, [Y|T1], T2).
/* X is not the head of the list*/
next(X, [_|T1], [T2]) :-
next(X, T1, T2).
/* T1 contains only one element */
next(X, _, [T2]):-
true.
/* T1 is empty */
next(X,[T2]):-
true.
更新#1的跟踪日志:
1? - 追踪。 真。
[trace] 1 ?- next(a,[a,c,d,e,f,a,g],S).
Call: (6) next(a, [a, c, d, e, f, a, g], _G4792) ? creep
Call: (7) next(a, [c, d, e, f, a, g], _G4880) ? creep
Call: (8) next(a, [d, e, f, a, g], _G4885) ? creep
Call: (9) next(a, [e, f, a, g], _G4888) ? creep
Call: (10) next(a, [f, a, g], _G4891) ? creep
Call: (11) next(a, [a, g], _G4894) ? creep
Call: (12) next(a, [g], _G4898) ? creep
Call: (13) next(a, [], _G4903) ? creep
Exit: (13) next(a, [], [_G4906]) ? creep
Exit: (12) next(a, [g], [[_G4906]]) ? creep
Exit: (11) next(a, [a, g], [g, [_G4906]]) ? creep
Exit: (10) next(a, [f, a, g], [[g, [_G4906]]]) ? creep
Exit: (9) next(a, [e, f, a, g], [[[g, [_G4906]]]]) ? creep
Exit: (8) next(a, [d, e, f, a, g], [[[[g, [_G4906]]]]]) ? creep
Exit: (7) next(a, [c, d, e, f, a, g], [[[[[g, [_G4906]]]]]]) ? creep
Exit: (6) next(a, [a, c, d, e, f, a, g], [c, [[[[g, [_G4906]]]]]]) ? creep
S = [c, [[[[g, [_G4906]]]]]]
我已经从这些资源中查看了基本级别的prolog练习列表: http://www.ic.unicamp.br/~meidanis/courses/problemas-prolog/ http://www.anselm.edu/homepage/mmalita/culpro/index.html
答案 0 :(得分:0)
我认为您已经定义了解决问题所需的规则,但定义这些规则的谓词子句并不完全正确。让我们来看看你定义的规则:
/* X is the head of the list */
next(X, [X,Y|T1], [Y|T2]) :-
next(X, [Y|T1], T2).
这是我在评论中给出的一个,其中列表的头部与元素匹配,并且它是正确的。
/* X is not the head of the list*/
next(X, [_|T1], [T2]) :-
next(X, T1, T2).
此条款有问题。它说, X不是列表的头部,但查询next(a, [a,b,c], T)
将匹配它,因为X = _
是可能的。此外,这里有所有额外括号,T2
已经是一个列表,所以你不想把它放在像[T2]
这样的括号中。更正的条款是:
next(X, [Y|T1], T2) :-
dif(X, Y), % Or X \== Y if you don't have dif/2
next(X, T1, T2).
第三条规则和条款:
/* T1 contains only one element */
next(X, _, [T2]):-
true.
这有一个问题,因为_
匹配任何,而不仅仅是单个元素列表。规则说, T1
只包含一个元素。但T1
甚至没有出现在该条款中。更正后的版本为:
/* A list with one element has no elements "next" */
next(_, [_], []).
所以在上面,第一个参数不再重要,第二个参数是一个元素的任何列表,无论它是什么。结果必须为空。
你的最后一条规则&子句:
/* T1 is empty */
next(X,[T2]):-
true.
一个明显的问题是你现在只有2个参数。你的谓词必须有3.如果T1
为空,我希望中间参数为[]
:
/* An empty list has no "next" values */
next(_, [], []).
您还可以将最后两个子句合并为:
next(_, T, []) :- T = [] ; T = [_].