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