List 在Prolog中列出我想要的列表元素
这是我在Prolog中的列表:List 在Prolog中列出我想要的列表元素,list,prolog,List,Prolog,这是我在Prolog中的列表: myList([a,b,c,d,e]). 我试图写一个谓词。该谓词应给出以下结果: ab ac ad ae bc bd be cd ce de 我找到了一个接近我目标的解决方案。但这并不是我想要的 ?- L=[a,b,c], findall(foo(X,Y), (member(X,L),member(Y,L)), R). L = [a, b, c], R = [foo(a, a), foo(a, b), foo(a, c), foo(b, a), foo(
myList([a,b,c,d,e]).
我试图写一个谓词。该谓词应给出以下结果:
ab
ac
ad
ae
bc
bd
be
cd
ce
de
我找到了一个接近我目标的解决方案。但这并不是我想要的
?- L=[a,b,c], findall(foo(X,Y), (member(X,L),member(Y,L)), R).
L = [a, b, c],
R = [foo(a, a), foo(a, b), foo(a, c), foo(b, a), foo(b, b), foo(b, c), foo(c, a), foo(c, b), foo(..., ...)].
例如,我不想aa、bb或cc。而且,已经有了ac结果。所以我不想再去了
对不起我的英语。
谢谢。下面几个谓词怎么样
printCouples(_, []).
printCouples(E1, [E2 | T]) :-
write(E1), write(E2), nl,
printCouples(E1, T).
printList([]).
printList([H | T]) :-
printCouples(H, T),
printList(T).
从
你得到
ab
ac
ad
bc
bd
cd
从你的问题来看,你想要什么并不明显,但你似乎很乐意使用findall/3
。上述解决方案使用了bagof/3
,这是findall/3
的一个更文明的版本bagof/3
考虑了变量,因此您可以使用具体字符[a、b、c、d、e]
或变量列表[a、b、c、d、e]
获得相同的结果
您已经使用了术语
foo(a,b)
,在这种情况下,说a-b
更常见(也更方便),这里有另一个解决方案,它不需要任何高阶谓词
:- set_prolog_flag(double_quotes, chars).
:- use_module(library(double_quotes)).
list_pairwise([], []).
list_pairwise([E|Es], Fs0) :-
phrase(values_key(Es, E), Fs0,Fs),
list_pairwise(Es, Fs).
values_key([], _K) --> [].
values_key([V|Vs], K) -->
[K-V],
values_key(Vs, K).
?- list_pairwise("abcde", KVs).
KVs = [a-b,a-c,a-d,a-e,b-c,b-d,b-e,c-d,c-e,d-e]
; true.
?- list_pairwise(L, [a-b,a-c,a-d,a-e,b-c,b-d,b-e,c-d,c-e,d-e]).
L = "abcde"
; false.
?- list_pairwise(L, [A-B,A-C,A-D,A-E,B-C,B-D,B-E,C-D,C-E,D-E]).
L = [A,B,C,D,E]
; false.
?- KVs = [K1-_,K1-_,K2-_|_], dif(K1,K2), list_pairwise(Ks,KVs).
KVs = [K1-K2,K1-_A,K2-_A],
Ks = [K1,K2,_A],
dif(K1,K2)
; false.
:-set_prolog_标志(双引号,字符)。
:-使用_模块()。
成对列出([],[])。
列表成对([E|Es],Fs0):-
短语(值_键(Es,E),Fs0,Fs),
成对列出(Es、Fs)。
值\u键([],\u K)-->[]。
值u键([V|Vs],K)-->
[K-V],
值\u键(Vs,K)。
?成对列出(“abcde”,KVs)。
KVs=[a-b,a-c,a-d,a-e,b-c,b-d,b-e,c-d,c-e,d-e]
; 对。
?列表(L[a-b,a-c,a-d,a-e,b-c,b-d,b-e,c-d,c-e,d-e])。
L=“abcde”
; 错。
?列表(L[A-B,A-C,A-D,A-E,B-C,B-D,B-E,C-D,C-E,D-E])。
L=[A,B,C,D,E]
; 错。
?-KVs=[K1-uu,K1-u,K2-124; uu],dif(K1,K2),成对列表(Ks,KVs)。
KVs=[K1-K2,K1-_A,K2-_A],
Ks=[K1,K2,_A],
dif(K1,K2)
; 错。
在上一个查询中,我们显示以键开始的序列,
K1、K1、K2
只能产生三个元素的序列。三个答案都很好。我用这个是因为我很容易理解代码。优雅,优雅。为了在SWI Prolog doc的findall页面添加注释,我允许自己偷取此文件。此外,XYs
的打印输出将被截断,除非设置Prolog\u标志(回答写选项,[引用(真)、描绘(真)、最大深度(100)]。
我同意这两个缩进,但不同意最大深度,也没有其他与SWI相关的链接。SWI甚至没有正确地实现bagof/3
或findall/3
。谢谢,但是关于SWI Prolog的bagof/findall错误实现的更多信息吗?或者,它们在哪种实现中是正确的?SICStus很好。而在SWI中,findall(t,(repeat,fail),1)
应该产生type\u错误(list,1)
,但它会循环。
?- set_prolog_flag(double_quotes, chars).
true.
?- List = "abcde",
bagof(X-Y, Pre^Ys^( append(Pre, [X|Ys], List), member(Y,Ys) ), XYs).
List = "abcde",
XYs = [a-b,a-c,a-d,a-e,b-c,b-d,b-e,c-d,c-e,d-e].
?- List = [A,B,C,D,E],
bagof(X-Y, Pre^Ys^( append(Pre, [X|Ys], List), member(Y,Ys) ), XYs).
List = [A,B,C,D,E],
XYs = [A-B,A-C,A-D,A-E,B-C,B-D,B-E,C-D,C-E,D-E].
:- set_prolog_flag(double_quotes, chars).
:- use_module(library(double_quotes)).
list_pairwise([], []).
list_pairwise([E|Es], Fs0) :-
phrase(values_key(Es, E), Fs0,Fs),
list_pairwise(Es, Fs).
values_key([], _K) --> [].
values_key([V|Vs], K) -->
[K-V],
values_key(Vs, K).
?- list_pairwise("abcde", KVs).
KVs = [a-b,a-c,a-d,a-e,b-c,b-d,b-e,c-d,c-e,d-e]
; true.
?- list_pairwise(L, [a-b,a-c,a-d,a-e,b-c,b-d,b-e,c-d,c-e,d-e]).
L = "abcde"
; false.
?- list_pairwise(L, [A-B,A-C,A-D,A-E,B-C,B-D,B-E,C-D,C-E,D-E]).
L = [A,B,C,D,E]
; false.
?- KVs = [K1-_,K1-_,K2-_|_], dif(K1,K2), list_pairwise(Ks,KVs).
KVs = [K1-K2,K1-_A,K2-_A],
Ks = [K1,K2,_A],
dif(K1,K2)
; false.