как распечатать все узлы с определенного узла

#prolog

Вопрос:

У меня есть следующая база знаний:

 connects(1,11,10,8).
connects(1,12,2,6).
connects(1,13,-3,-2).
connects(1,14,1,-5).
 

У меня есть эти предикаты:

 friends(Node, L):-
findall(X,(connects(Node,X,_,_);connects(X,Node,_,_)),L).
 

когда я задам вопрос ?- друзья(1,Л) у меня есть это:

 L = [11, 12, 13, 14].
 

Но моя цель-напечатать такой список:

 L = [11,10,8,12,2,6,13,-3,-2,14,-5]
 

Как я могу этого достичь?

Ответ №1:

Мне не ясно, какое отношение на самом деле представляет предикат. В любом случае, вы можете поступить следующим образом:

  • Во-первых, используйте findall для сбора необходимых данных в виде списка списков:
 ?- findall([X,Y,Z], connects(1,X,Y,Z), L).
L = [[11, 10, 8], [12, 2, 6], [13, -3, -2], [14, 1, -5]].
 
  • После этого вы можете использовать приложение, чтобы получить сглаженный список:
 ?- findall([X,Y,Z], connects(1,X,Y,Z), L0), append(L0, L1).
L0 = [[11, 10, 8], [12, 2, 6], [13, -3, -2], [14, 1, -5]],
L1 = [11, 10, 8, 12, 2, 6, 13, -3, -2, 14, 1, -5].
 

Собрав все это вместе, вы можете определить friends/2 как:

 friends(Node, L1):-
   findall([X,Y,Z],
           ( connects(Node, X,Y,Z)
           ; connects(X, Node, Y,Z) ), L0),
   append(L0, L1).
 

Ответ №2:

Предположим, что вы можете изменить предикат. Замена _ s переменными даст вам необходимые значения. А затем используйте flatten/2 , чтобы превратить матрицу (2D-список) в простой 1D-список.

Это должно решить вашу проблему.

 friends(Node, L):-
    findall([X, Y, Z], (connects(Node, X, Y, Z)), A),
    flatten(A, L).
 

Пример вывода:

 ?- friends(1, L)
L = [11, 10, 8, 12, 2, 6, 13, -3, -2, 14, 1, -5]