Использование And в HEAD оператора пролога - PullRequest
1 голос
/ 30 ноября 2009

Каждый член этого клуба либо образован, либо богат, либо оба.

Я хотел написать утверждение, очень похожее на приведенное выше, в моем коде PROLOG. Я написал все остальное.

edu(X);rich(X) :- member(X). 

Это то, что я написал. Но тогда PROLOG разрешает любые операторы в предложении head. Я потратил 5 часов до сих пор, пытаясь сделать разные вещи с этим утверждением, но не смог найти решение, которое работает. :(

Ответы [ 4 ]

2 голосов
/ 30 ноября 2009

См. http://en.wikipedia.org/wiki/Horn_clause для объяснения формы логики, на которой основан Пролог.

Учитывая ваше заявление («Каждый член этого клуба либо образован, либо богат, либо и тот, и другой»), единственное, что вы можете объявить правдой, это:

  • Человек образован, если он член, а не богат.
  • Человек богат, если он член и не образован.

Следующее, например, не обязательно верно:

  • Человек, который богат и образован, является членом.
  • Богатый член образован.
  • Богатый член не образован.
1 голос
/ 29 апреля 2012

В качестве дополнительного примечания: идея использования дизъюнкций в главах предложений привела к дизъюнктивному логическому программированию , см., Например, "Основы программирования дизъюнктивной логики" Хорхе Лобо, Джек Минкер, Аркот Раджасека , edu(X);rich(X) :- member(X). будет действительным дизъюнктивным предложением. Связанная тема, дизъюнктивный Datalog, была исследована Николой Леоне, Джеральдом Пфейфером и Вольфгангом Фабером в проекте DLV: http://www.dbai.tuwien.ac.at/proj/dlv/

1 голос
/ 30 ноября 2009

Вы не можете объединить несколько голов. Если вы хотите, чтобы edu(X) и rich(X) были истинными, когда member(X) истинно, вы должны определить их отдельно («каждый член этого клуба образован» и «каждый член этого клуба богат»):

edu(X) :-
   member(X).
rich(X) :-
   member(X).

Сложность в том, что ваше первоначальное утверждение не правильно оформлено. Это говорит о том, что некоторые члены могут быть богатыми, но не образованными или наоборот. Это проблематично. Например, давайте возьмем наивный случай, когда член не богат, он образован, и наоборот:

edu(X) :-
    member(X), \+ rich(X).
rich(X) :-
    member(X), \+ edu(X).

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

member(alice).
member(bob).
member(charlie).
member(dave).

rich(alice).
edu(bob).
rich(charlie).
edu(charlie).

В этом случае rich(alice) работает нормально, потому что это факт. edu(alice) приведет к no. Обратное верно для Боба. С Чарли мы определили оба факта, так что оба верны. Но как насчет Дэйва? И edu(dave), и rich(dave) относятся к другому, создавая бесконечную рекурсию. Без каких-либо дополнительных знаний о том, что вы делаете, лучшее, что мы можем сделать, чтобы решить эту проблему, это установить по умолчанию либо edu(X), либо rich(X) в true:

edu(X) :-
    member(X).
rich(X) :-
    member(X), \+ edu(X).

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

0 голосов
/ 01 декабря 2009

Может быть, вы хотите написать:

member(X) :- edu(X) ; rich(X)

Если кто-то образованный, богатый или оба, является членом клуба.

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