Пролог: считайте только прямые дочерние узлы родителя, используя чистую рекурсию - PullRequest
1 голос
/ 22 сентября 2019

Возможно ли в Пролог подсчитать количество прямых дочерних узлов родителя с помощью рекурсии без retract / aggregate и т. Д.

Например, скажем, у нас есть следующее:

parent(p1, child_node1).
parent(p1, child_node2).
parent(p1, child_node3).
parent(p1, child_node4).

parent(child_node1, another_node1).
parent(child_node1, another_node2).
parent(child_node2, another_node3).
parent(child_node2, another_node4).
parent(child_node3, another_node5).
parent(child_node3, another_node6).
parent(child_node4, another_node7).
parent(child_node4, another_node8).

Как с помощью рекурсии считать, что p1 имеет 4 прямых дочерних узлов?

1 Ответ

0 голосов
/ 22 сентября 2019

Простое решение - вести список детей, которых мы уже видели, и каждый раз запрашивать ребенка, который еще не является членом этого списка.Каждый раз, когда мы находим ребенка, мы производим рекурсию и добавляем ребенка в список.В случае, если мы больше не можем найти такого потомка, мы можем просто объединить результат с полученными до сих пор потомками.

count_children(Parent, N) :-
    count_children(Parent, [], 0, N).

count_children(Parent, L, N0, N) :-
    (parent(Parent, C), \+member(C, L))
    -> (N1 is N0+1, count_children(Parent, [C|L], N1, N))
    ; N = N0.

Например:

?- count_children(p1, N).
N = 4.

?- count_children(child_node1, N).
N = 2.

?- count_children(child_node2, N).
N = 2.

?- count_children(child_node3, N).
N = 2.

?- count_children(child_node4, N).
N = 2.

?- count_children(another_node1, N).
N = 0.

Если родитель не объединеноднако он объединится с первым родителем и остановится после того, как получит первый результат:

?- count_children(P, N).
P = p1,
N = 4.

Я оставляю это как упражнение, чтобы позволить этому объединиться со всеми возможными родителями.

...