Определите правило been_before (X, Y), которое определяет отношение, в котором произошло событие X до события Y, используя системные предикаты - PullRequest
1 голос
/ 25 февраля 2020

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

Определите правило произошло_перед (X, Y), которое определяет отношение, в котором событие X произошло до события Y, и используйте это получить все такие пары событий. Вам нужно будет использовать системный предикат <, меньше чем. Например? - (5 <7). преуспевает. Соответствующим образом созданные переменные могут использоваться с любой стороны от <вместо чисел. Начните правило с случаями_перед (X, Y): -. </p>

моя попытка выглядит следующим образом:

event(battle_of_hastings, 1066).
event(plague_of_london, 1665).
event(fire_of_london, 1666).
event(man_on_the_moon, 1969). 

happened_before(X,Y) :-
    (Event1, Y1),
    (Event2, Y2).
    Y1 < Y2.

1 Ответ

1 голос
/ 25 февраля 2020

Вы близки.

То, что вам нужно, это

happened_before(Event1,Event2) :-
    event(Event1, Y1),
    event(Event2, Y2),
    Y1 < Y2.

Пролог - это синтактика c объединение , которое часто можно считать простым совпадением условия .

В этом случае строка типа event(Event1, Y1), которая сама по себе известна как цель , должна соответствовать чему-либо для работы ( success ). У вас есть факты , которые вы пытаетесь сопоставить.

Итак,

event ( функтор ) в event(Event1, Y1) должен совпадать с event на самом деле, как event(battle_of_hastings, 1066)..

Тогда количество аргументов должно совпадать, и в этом случае они оба имеют 2 аргумента.

Теперь, так как цель имеет две переменные ( начинаются с заглавной буквы) они будут совпадать ( unify ) с соответствующими частями фактов. Таким образом,

Event1 объединяется с battle_of_hastings и
Y1 объединяется с 1066.


Причина, по которой вам нужно сопоставить функтор, заключается в том, что если вы есть такой факт, как

time(battle_of_hastings, 1066).

, и такой запрос, как у вас (Event1,Y1) с тем, как вы хотели, чтобы он работал без функтора, совпадение будет успешно объединено, если вы тоже этого не хотите.


Еще один способ думать об объединении терминов, который усиливает необходимость проверки функтора при объединении, - это изменение терминов Prolog по сравнению с прошедшими днями

event(battle_of_hastings, 1066)

в прошлом было бы

(event, battle_of_hastings, 1066)

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


Здесь это весь код с тестовыми примерами.

event(battle_of_hastings, 1066).
event(plague_of_london, 1665).
event(fire_of_london, 1666).
event(man_on_the_moon, 1969).

happened_before(Event1,Event2) :-
    event(Event1, Y1),
    event(Event2, Y2),
    Y1 < Y2.


:- begin_tests(happened_before).

happened_before_test_case_generator(success,plague_of_london,fire_of_london).
happened_before_test_case_generator(success,plague_of_london,man_on_the_moon).
happened_before_test_case_generator(fail,plague_of_london,plague_of_london).
happened_before_test_case_generator(fail,fire_of_london,plague_of_london).
happened_before_test_case_generator(fail,man_on_the_moon,plague_of_london).

test(01,[forall(happened_before_test_case_generator(success,Event1,Event2))]) :-
    happened_before(Event1,Event2).

test(02,[fail,forall(happened_before_test_case_generator(fail,Event1,Event2))]) :-
    happened_before(Event1,Event2).

:- end_tests(happened_before).

Пример запуска тестов.

?- run_tests.
% PL-Unit: happened_before ..... done
% All 5 tests passed
true.
...