使用系统谓词定义一个规则 happened_before(X,Y) 定义事件 X 发生在事件 Y 之前的关系

Define a rule happened_before(X,Y) which defines the relation that event X happened before event Y using system predicates

我不知道怎么写问题的答案。任何帮助表示赞赏。我理解其背后的逻辑,但找不到正确的语法。

Define a rule happened_before(X,Y) which defines the relation that event X happened before event Y, and use it to obtain all such pairs of events. You will need to use the system predicate <, less than. For example ?- (5 < 7). succeeds. Suitably instantiated variables can be used either side of < instead of numbers. Start the rule with happened_before(X,Y) :-.

我的尝试如下:

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.

你很接近。

你想要的是

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

Prolog 大约 syntactic unification which can often be thought simply as matching terms

在这种情况下,像 event(Event1, Y1) 这样的行本身就是您要匹配的 goal needs to match against something to work (succeed). You have facts

所以

event(Event1, Y1)中的

eventfunctor)需要与event(battle_of_hastings, 1066).中的event相匹配。

然后 arguments 的数量需要匹配,在这种情况下它们都有 2 个参数。

现在由于目标有两个 variables (begin with upper case letter) they will match (unify) 与事实相应的部分。于是

Event1battle_of_hastings
统一 Y11066 统一。


你需要在函子上匹配的原因是因为如果你有一个像

这样的事实
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.