再次成为Prolog的初学者: - }
我使用
按元素构建列表元素(1)
member(NewElement,ListToBeFilled).
在重复的电话中,
(2)
ListToBeFilled = [NewElement|TmpListToBeFilled].
在递归调用中,如
something(...,TmpListToBeFilled).
(2)的具体例子
catch_all_nth1(List, AllNth, Counter, Result) :-
[H|T] = List,
NewCounter is Counter + 1,
(
0 is Counter mod AllNth
->
Result = [H|Result1]
;
Result = Result1
),
catch_all_nth1(T,AllNth,NewCounter,Result1),
!.
catch_all_nth1([], _, _, _).
结果我得到了一个类似
的列表[E1, E2, E3, ..., Elast | _G12321].
当然,Tail是一个变量。 [顺便说一下:有没有更好的方法来填补 列表,直接避免"未分配的尾巴"?]
我现在正在寻找一种简单的方法来消除"未分配的尾巴"。
我发现: Delete an unassigned member in list 建议使用:
exclude(var, ListWithVar, ListWithoutVar),!,
[发现这一点,但没有帮助,因为我最后不想要一个虚拟元素 Prolog list has uninstantiated tail, need to get rid of it]
我注意到使用长度\ 2消除了"未分配的尾部",以及附加功能 同样的名单仍然存在。
我的问题是:它是如何运作的?我想使用这种机制来消除未分配的尾部,而不使用新的变量... [在SWI Prolog'到现在为止我没有得到调试器 输入长度()?!]
示例:
Z=['a','b','c' | Y],
X = Z,
write(' X '),write(X),nl,
length(X,Tmp),
write(' X '),write(X),nl.
13 ?- test(X).
X [a,b,c|_G3453]
X [a,b,c]
X = [a, b, c] .
我认为X,一旦初始化就不能再改变了,你需要 一个新的变量,如exclude(var,ListWithVar,ListWithoutVar)。
如果有人向我解释这个伎俩会很高兴......
谢谢: - )
答案 0 :(得分:0)
我认为应该这样做:
% case 1: end of list reached, replace final var with empty list
close_open_list(Uninstantiated_Var) :-
var(Uninstantiated_Var), !,
Uninstantiated_Var = '[]'.
% case 2: not the end, recurse
close_open_list([_|Tail]) :-
close_open_list(Tail).
?- X=[1,2,3|_], close_open_list(X).
X = [1, 2, 3].
请注意,只使用变量X ..它只是通过列表进行递归,直到它到达最后的var,用一个空列表替换它,然后关闭它。然后X可以作为常规'关闭'列表。
编辑:一旦将列表元素分配给特定的内容,就无法更改。但是当列表构建为开放列表时,列表本身可以附加到。最后用_ _打开列表是构建列表元素而不需要新变量的好方法。例如
X=[1,2,3|_], memberchk(4, X), memberchk(5,X).
X = [1, 2, 3, 4, 5|_G378304]
在上面的示例中,memberchk尝试尝试制作' 4'然后' 5'列表的成员,它通过在每种情况下将它们插入到自由变量中而成功完成。
然后当你完成时,关闭它。
答案 1 :(得分:0)
你对这种奇怪的行为是正确的:这是由于length / 2在使用未绑定参数调用时的能力
谓词是非确定性的,如果List是部分列表且Int未绑定,则生成长度增加的列表。
示例:
?- length([a,b,c|X],N).
X = [],
N = 3 ;
X = [_G16],
N = 4 ;
X = [_G16, _G19],
N = 5 ;
...
对于您的“应用”代码,这种微小的修正应该足够了。将基本递归子句更改为
catch_all_nth1([], _, _, []).
这是
之前的结果4 ?- catch_all_nth1([a,b,c,d],2,1,R).
R = [b, d|_G75].
并且在更正之后:
5 ?- catch_all_nth1([a,b,c,d],2,1,R).
R = [b, d].
但我建议改为使用Prolog为我们提供的一些更好的知识方法:例如findall / 3:
?- findall(E, (nth1(I,[a,b,c,d],E), I mod 2 =:= 0), L).
L = [b, d].