显示此人家谱的所有后代数量的程序

A program that displays the number of all descendants of this person's family tree

示例数据库:

descendant("son","father")
descendant("son","father")
descendant("son","father")

等..

对于“J”个后代数 = 0。
对于“A”的后代数量 = 8.

我做了一个程序,但是不知为什么不能正确计数,如果分支太多,就输出“False”。

descendant('B', 'A').
descendant('F', 'A').
descendant('D', 'B').
descendant('E', 'B').
descendant('G', 'F').
descendant('H', 'G').
descendant('I', 'G').
descendant('J', 'G').

 

num_of_descendant('G', 0).
num_of_descendant(N,Nb) :-
    descendant(P,N), 
    num_of_descendant(P,Nb1), 
    Nb is Nb1+1.

更新:

descendant('Игорь', 'Рюрик').
descendant('Ольга', 'Игорь').
descendant('Святослав Игоревич', 'Ольга').
descendant('Ярополк', 'Святослав Игоревич').
descendant('Святополк Окаянный', 'Ярополк').
descendant('Владимир Святой', 'Святослав Игоревич').
descendant('Ярослав I Мудрый', 'Владимир Святой').
descendant('Святослав', 'Ярослав I Мудрый').
descendant('Олег', 'Святослав').
descendant('Всеволод II', 'Олег').
descendant('Изяслав I', 'Ярослав I Мудрый').
descendant('Святополк', 'Изяслав I').
descendant('Всеволод I', 'Ярослав I Мудрый').
descendant('Владимир Мономах', 'Всеволод I').
descendant('Мстислав Великий', 'Владимир Мономах').
descendant('Изяслав II', 'Мстислав Великий').
descendant('Ярополк', 'Владимир Мономах').
descendant('Юрий Долгорукий', 'Владимир Мономах').
descendant('Владимир Мономах', 'Всеволод I').
descendant('Михаил I', 'Юрий Долгорукий').
descendant('Всеволод III Большое Гнездо', 'Юрий Долгорукий').
descendant('Юрий II', 'Всеволод III Большое Гнездо').
descendant('Ярослав II', 'Всеволод III Большое Гнездо').
descendant('Андрей', 'Ярослав II').
descendant('Василий', 'Андрей').
descendant('Константин', 'Василий').
descendant('Дмитрий Суздальский', 'Константин').
descendant('Василий Костромской', 'Ярослав II').
descendant('Ярослав III Тверской', 'Ярослав II').
descendant('Михаил II Святой', 'Ярослав III Тверской').
descendant('Александр II', 'Михаил II Святой').
descendant('Александр Невский', 'Ярослав II').
descendant('Андрей Городецкий', 'Александр Невский').
descendant('Дмитрий Переяславский', 'Александр Невский').
descendant('Даниил Московский', 'Александр Невский').
descendant('Юрий III Московский', 'Даниил Московский').
descendant('Иоанн I Калита', 'Даниил Московский' ).
descendant('Симеон Гордый', 'Иоанн I Калита').
descendant('Иоанн II Кроткий', 'Иоанн I Калита').
descendant('Дмитрий Донской', 'Иоанн II Kроткий').
descendant('Василий I', 'Дмитрий Донской').
descendant('Василий II Темный', 'Василий I').
descendant('Иоанн III', 'Василий II Темный').
descendant('Василий III', 'Иоанн III').
descendant('Иоанн IV', 'Василий III').
descendant('Федор', 'Иоанн IV').
descendant('Константин', 'Всеволод III Большое Гнездо').


descendant_path(Lower, Upper) :-
    descendant(Down1, Upper),
    (Down1 = Lower ; descendant_path(Lower, Down1)).

descendants_count(TopLevel, Count) :-
    aggregate_all(count, Desc, descendant_path(Desc, TopLevel), Count).

树的图片: Click

对于“Александр Невский”,后代数 = 14,但您的代码 return 计数 = 7。我认为您的代码停止在“Иоанн II Кротый”并且不计算其余后代。

使用aggregate_all/4

descendant('B', 'A').
descendant('F', 'A').
descendant('D', 'B').
descendant('E', 'B').
descendant('G', 'F').
descendant('H', 'G').
descendant('I', 'G').
descendant('J', 'G').


descendant_path(Lower, Upper) :-
    descendant(Down1, Upper),
    (Down1 = Lower ; descendant_path(Lower, Down1)).

descendants_count(TopLevel, Count) :-
    aggregate_all(count, Desc, descendant_path(Desc, TopLevel), Count).

swi-prolog 中的结果:

?- time(descendants_count('A', Count)).
% 67 inferences, 0.000 CPU in 0.000 seconds (96% CPU, 627294 Lips)
Count = 8.

?- time(descendants_count('J', Count)).
% 27 inferences, 0.000 CPU in 0.000 seconds (93% CPU, 358585 Lips)
Count = 0.

?- time(descendants_count('F', Count)).
% 47 inferences, 0.000 CPU in 0.000 seconds (95% CPU, 496110 Lips)
Count = 4.

注意拼写错误和字符不匹配:

?- "Иоанн II Kроткий" = "Иоанн II Кроткий".
false.

?- "K" = "К".
false.