Как найти племянника в Кодексе Пролога? - PullRequest
0 голосов
/ 19 февраля 2019

Я пытаюсь заставить Пролог выводить людей в племяннике генеалогических деревьев, как в nephew(X,Y) будет отображаться список

X = the nephew
Y = Aunt/ Uncle

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

1 Ответ

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

Вы были так близко.

Если бы вы выполнили запрос

nephew(X,Y), вы бы получили

?- nephew(X,Y).
X = pam,
Y = liz ;
X = john,
Y = liz ;
X = liz,
Y = joe ;
X = liz,
Y = tim ;
false.

, что, как вы заметили, неверно.

Однако если вы переименуете свои переменные так, чтобы их было легче понять

sibling(Child_a, Child_b) :-
    parent(Parent, Child_a),
    parent(Parent, Child_b),
    Child_a \= Child_b.

son(Child,Parent) :-
    parent(Parent, Child),
    male(Child).

nephew(Parent, Child_a) :-
    sibling(Child_a, Child_b),
    son(Child_b, Parent).

вы увидите, что sibling / 2 и son / 2 верны и должны увидеть вашу проблему с племянником / 2.

Когда переименовываете переменные, начинайте с фактов и работайте в обратном направлении, не начинайте с заголовка предложения и работайте вниз.


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

?- sibling(Parent,Aunt_uncle),son(Nephew,Parent).
Parent = liz,
Aunt_uncle = bob,
Nephew = joe ;
Parent = liz,
Aunt_uncle = bob,
Nephew = tim ;
Parent = pat,
Aunt_uncle = ann,
Nephew = jim ;
false.

Хотя этот запрос дает больше информации, чем необходимо, правильные значения содержатся в результатах.Поместив это в предикат и вернув только нужные значения, это все, что осталось, чтобы этот запрос работал как нужно.


Правильный ответ для племянника / 2:

nephew(Nephew,Aunt_uncle) :-
    sibling(Parent,Aunt_uncle),
    son(Nephew,Parent).

Пример выполнения:

?- nephew(Nephew,Aunt_uncle).
Nephew = jim,
Aunt_uncle = ann ;
Nephew = joe,
Aunt_uncle = bob ;
Nephew = tim,
Aunt_uncle = bob ;
false.

При написании кода рекомендуется также создавать тестовые случаи.

Если вы используете SWI-Prolog, тогда вы можете использовать следующие тестовые случаи.

:- begin_tests(family).

% example of single test case

test(001) :-
    sibling(bob,liz).

test(002) :-
    son(tim,liz).

test(003,[nondet]) :-
    nephew(tim,bob).

% example of test cases that test multiple variations for one predicate

sibling_test_case(bob,liz).
sibling_test_case(liz,bob).
sibling_test_case(ann,pat).
sibling_test_case(pat,ann).
sibling_test_case(joe,tim).
sibling_test_case(tim,joe).

test(004, [forall(sibling_test_case(Child_a,Child_b))]) :-
    sibling(Child_a,Child_b).

son_test_case(bob,pam).
son_test_case(bob,john).
son_test_case(jim,pat).
son_test_case(joe,liz).
son_test_case(tim,liz).

test(005, [forall(son_test_case(Child,Parent)),nondet]) :-
    son(Child,Parent).

nephew_test_case(joe,bob).
nephew_test_case(tim,bob).
nephew_test_case(jim,ann).

test(006, [forall(nephew_test_case(Nephew,Aunt_uncle)),nondet]) :-
    nephew(Nephew,Aunt_uncle).

:- end_tests(family).

Они запускаются с run_tests.

?- run_tests.
% PL-Unit: family ................. done
% All 17 tests passed
true.

См .: Пролог-модульные тесты

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