List 在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(

这是我在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(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.