Могу ли я использовать целые числа в качестве параметров? - PullRequest
0 голосов
/ 13 февраля 2019

Как я могу узнать, является ли человек X потомком человека Y, получившего степень потомства?

Я пробовал это:

descendant(X, Y, 1) :- son(X, Y).
descendant(X, Y, Degree) :- son(X, Z) , descendant(Z, Y, Degree-1).

Где son(X, Y) возвращает yes, если X сын Y. Если Degree == 1, он возвращает правильный ответ, но для descendant(X, Y, 2)например, должен возвращать yes, если X является внуком Y, но возвращает no.

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

1) Именование: Означает ли son(X,Y) "X сын Y" - или наоборот?son_of(X,Y) лучше.

2) Эксплойт : Здесь нам не нужна общая арифметика ... нам нужно только считать.


Итак, давайте начнем в начале ...

child_of(abel, <b>adam</b>).           % <a href="https://en.wikipedia.org/wiki/Genealogies_in_the_Bible" rel="nofollow noreferrer">from source</a>
child_of(abel, <b>eve</b>).
child_of(cain, adam).
child_of(cain, eve).
child_of(enoch, cain).
child_of(irad, enoch).
child_of(mehujael, irad).
child_of(methushael, mehujael).
child_of(lamech, methushael).
child_of(jabal, lamech).
child_of(jabal, adah).
child_of(jubal, lamech).
child_of(jubal, adah).
child_of(tubal_cain, lamech).
child_of(tubal_cain, zillah).
child_of(naamah, lamech).
child_of(naamah, zillah).
child_of(seth, adam).
child_of(seth, eve).
child_of(enos, seth).
child_of(kenan, enos).
child_of(mahalalel, kenan).
child_of(jared, mahalalel).
child_of(enoch, jared).
child_of(methuselah, enoch).
child_of(lamech, methuselah).
child_of(noah, lamech).
child_of(shem, noah).
child_of(ham, noah).
child_of(japheth, noah).

На основании child_of/2 мы сначала определим ancestor_of/2- это не должно быть для вас чем-то новым!

ancestor_of(Y, Z) :-
   child_of(Z, Y).              %   <i>If</i> Z is  a    child of Y ...
                                % <i>then</i> Y is an ancestor of Z.
ancestor_of(X, Z) :-
   child_of(Z, Y),              %   <i>If</i> Z is  a    child of Y ...
   ancestor_of(X, Y).           %  <i>and</i> X is an ancestor of Y ...
                                % <i>then</i> X is an ancestor of Z.

Далее мы добавляем дополнительный параметр, указывающий расстояние.

Мы используем s/1 слагаемые для представления натуральных чисел и добавления нового аргументак ancestor_of/2:

ancestor_of_dist(Y, Z, s(0)) :-      
   child_of(Z, Y).              %   <i>If</i> Z is  a    child of Y ... 
                                % <i>then</i> Y is an ancestor of Z <b>with distance = 1</b>."
ancestor_of_dist(X, Z, s(N)) :-      
   child_of(Z, Y),              %   <i>If</i> Z is  a    child of Y ... 
   ancestor_of_dist(X, Y, N).   %  <i>and</i> X is an ancestor of Y <b>with distance N</b> ...
                                % <i>then</i> X is an ancestor of Z <b>with distance N+1</b>.

Итак ... кто из них дедушка?

?- ancestor_of_dist(X, Z, s(s(0))).
   X = adam, Z = enoch
;  X = eve, Z = enoch
;  X = cain, Z = irad
;  X = jared, Z = irad
;  X = enoch, Z = mehujael
;  ... 
;  X = lamech, Z = japheth
;  false.
0 голосов
/ 13 февраля 2019

Пролог не является функциональным языком.Таким образом, термин Degree-1 не интерпретируется и не оценивается как выражение.Для Пролога Degree-1 это просто составной термин с двумя аргументами.Это можно выяснить, используя стандартный предикат write_canonical/1, который записывает термин без использования операторной нотации:

?- write_canonical(Degree-1).
-(_,1)
true.

Вместо этого пишите:

descendant(X, Y, 1) :-
    son(X, Y).
descendant(X, Y, Degree) :-
    son(X, Z) ,
    descendant(Z, Y, Degree0),
    Degree is Degree0 + 1.

Встроенный стандарт is/2in предикат объединяет левый аргумент со значением арифметического выражения в правом аргументе.

PS Обратите внимание, что альтернативное определение предиката descendant/3, которое я предлагаю, решит описанную вами проблему, но оно не является эффективным определением, посколькуэто не хвостово-рекурсивное определение.Т.е. рекурсивный вызов во втором предложении не является последним вызовом в теле предложения.Однако эту проблему легко решить, используя аккумулятор .

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