Как выразить общее отношение заказа в прологе? - PullRequest
2 голосов
/ 17 октября 2011

Как лучше всего выразить отношение общего порядка в Прологе?

Например, скажем, у меня есть набор фактов

person(tim)
person(ana)
person(jack)
...

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

Так что моя проблема заключается в том, что более богатое предложение должнобыть способным создавать экземпляры своих переменных, а также гарантировать, что никогда не бывает, чтобы богаче (X, Y) и богаче (Y, X) одновременно.

Вот лучший пример, чтобы увидеть, что яmean:

person(tim).
person(john).
happier(tim, john).

hates(X, Y) :- person(X), person(Y), richer(Y, X).
hates(X, Y) :- person(X), person(Y), richer(X, Y), happier(Y, X).

Теперь ответ на запрос hates (john, tim) должен возвращать true, потому что, если richer удовлетворяет указанному свойству, одно из этих двух предложений hates должно быть истинным.В механизме логического вывода на основе разрешения я мог бы утверждать, что факт (богаче (X, Y) V богаче (Y, X)) и предикатные ненависти (Джон, Тим) могут быть подтверждены.Я не ожидаю, что смогу выразить это таким же образом в Прологе с тем же эффектом.Однако как я могу реализовать это условие, чтобы данный пример работал?

Обратите внимание, что я не знаю, кто богаче: Тим или Джон.Я только сейчас, что один богаче другого.

Спасибо.

Ответы [ 2 ]

1 голос
/ 17 октября 2011

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

is_richer(tim, anna).
is_richer(anna, jack).

, а затем предикат, чтобы найти всех людей, которые Х богаче -

richer(X, Z) :-
   is_richer(X, Z).
richer(X, Z) :-
   is_richer(X, Y),
   richer(Y, Z).

Если ваш предикат is_richer содержит циклы (в этом примере, если вы добавили is_richer (jack, tim)), это может взорваться.Вам нужно отследить, где вы побывали в этом дереве.

Пример прогона богаче будет:

?- richer(X, Y).
X=tim
Y=anna ;
X=anna
Y=jack ;
X=tim
y=jack ;
no
1 голос
/ 17 октября 2011

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

это предикат, который проверяет, является ли отношение общим порядком на конечном множестве:

is_total_order(Foo,Set):-
    forall(
           (member(X,Set),
        member(Y,Set)),
           (
        XY =.. [Foo,X,Y],
        YX =.. [Foo,Y,X],
        (call(XY);call(YX)),                %checking if the relationship is total
        \+ (call(XY),call(YX), X\=Y)        %checking if it's an order
           )
          ).

operator = .. / 2 (оператор univ) создает предикат из списка (то есть: X = .. [foo, 4,2]. -> X = foo (4,2)) и вызов предиката / 1 вызывает другой предикат. Как видите, мы используем мета-предикаты, которые оперируют другими предикатами.

Для полного порядка на бесконечных множествах все усложняется, так как мы не можем проверить каждую пару, как делали раньше. Я даже не думаю, что это можно написать, поскольку доказательство того, что отношения - это общий порядок, не является чем-то тривиальным.

Тем не менее, это не объявляет, что предикат является полным порядком; он просто проверяет, если это так.

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