Список элементов в списке, как я хочу, в Прологе - PullRequest
0 голосов
/ 12 января 2020

Это мой список в Прологе:

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. Кроме того, уже есть c результат. Так что я не хочу снова ок.

Извините за мой английский sh. Спасибо.

Ответы [ 3 ]

3 голосов
/ 12 января 2020
?- 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].

Из вашего вопроса не так очевидно, что вы хотите, но кажется, что вы с удовольствием используете findall/3. Вышеупомянутые решения используют bagof/3, который является несколько более цивилизованной версией findall/3. bagof/3 учитывает переменные, и, таким образом, вы получаете тот же результат с конкретными символами [a,b,c,d,e] или со списком переменных [A,B,C,D,E].

Вы использовали термины foo(a,b), в таких ситуациях это более распространенным (и удобным) сказать a-b.

3 голосов
/ 12 января 2020

Вот еще одно решение, которое не требует никаких предикатов высшего порядка.

:- set_prolog_flag(double_quotes, chars).
:- use_module(<a href="https://stackoverflow.com/a/8269897/772868">library(double_quotes)</a>).

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.

В последнем запросе мы показываем, что последовательность, начинающаяся с ключей, K1, K1, K2 может привести только к последовательности из трех элементов.

1 голос
/ 12 января 2020

Как насчет пары предикатов следующим образом?

printCouples(_, []).
printCouples(E1, [E2 | T]) :-
  write(E1), write(E2), nl,
  printCouples(E1, T).

printList([]).
printList([H | T]) :-
  printCouples(H, T),
  printList(T).

Из

printList([a, b, c, d])

вы получите

ab
ac
ad
bc
bd
cd
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...