我想知道是否可以从prolog中的嵌套谓词中获取数字列表。
我会举一个例子,来自:
?- elements(p(f(0,5,1), k(8, f(7,3), h(6)), 5), X).
我想要X:
X = [0,5,1,8,7,3,6,5].
谢谢你,如果你可以帮助我=)
答案 0 :(得分:2)
每当你编写涉及一般术语遍历的谓词时,请记住这些谓词在使用它们的方式上会受到限制。让我们调用你的关系term_subtermnumbers/2
,它将一个术语与其中出现的数字列表相关联,作为从左到右外观顺序的子项,包括多次出现。首先,您可以考虑一下您提供的示例,例如
?- term_subtermnumbers(p(f(0,5,1), k(8, f(7,3), h(6)), 5), Numbers).
Numbers = [0, 5, 1, 8, 7, 3, 6, 5].
但是,如果你转动查询,请改为:
?- term_subtermnumbers(Term, [0, 5, 1, 8, 7, 3, 6, 5]).
解决方案有很多种可能性。实际上,无限多。或者采取更简单的查询:
?- term_subtermnumbers(Term, []).
即所有不包含数字的Term
。
由于这里的解决方案集是无限的,并且没有办法将该集合有意义地缩写为答案,因此在这种情况下产生一个称为实例化错误的特殊错误确实很有意义。
部分 - 不是全部 - Prolog内置插件可确保此属性。 (=..)/2
和functor/3
忠实地保证了该财产。赫拉斯,number/1
不是。因此,请始终在(=..)/2
,functor/3
,number/1
和其他一些人之前使用atom/1
或atomic/1
。
term_subtermnumbers(Term, Numbers) :-
phrase(subtermnumbers(Term), Numbers).
subtermnumbers(Term) -->
{ Term =.. [_| Args] },
( {number(Term)} -> [Term]
; args_subtermnumbers(Args)
).
args_subtermnumbers([]) --> [].
args_subtermnumbers([Arg|Args]) -->
subtermnumbers(Arg),
args_subtermnumbers(Args).
答案 1 :(得分:1)
如果你的Prolog附加了/ 2和maplist / 3:
elements(N, [N]) :- number(N), !.
elements(S, Ss) :- S=..[_|Es], maplist(elements, Es, Ts), append(Ts, Ss).
答案 2 :(得分:-1)
这对我有用:
?- elements(p(f(0,5,1), k(8, f(7,3), h(6)), 5), X), writenl(X), fail. elements(X,X) :- integer(X). elements([],[]). elements([X|Y],Z) :- integer(X), elements(Y,V), Z=[X|V]. elements([X|Y],Z) :- elements(X,W), elements(Y,V), append(W,V,Z). elements(_(|Y),Z) :- elements(Y,Z). writenl(X) :- write(X), nl.
它给了我[0, 5, 1, 8, 7, 3, 6, 5]
。
请改为尝试:
?- elements(p(f(0,5,1), k(8, f(7,3), h(6)), 5), X), writenl(X), fail. elements(X,X) :- integer(X). elements([],[]). elements([X|Y],Z) :- integer(X), elements(Y,V), Z=[X|V]. elements([X|Y],Z) :- elements(X,W), elements(Y,V), append(W,V,Z). elements(X,Z) :- X=..[_|Y], elements(Y,Z). writenl(X) :- write(X), nl.