2012-04-20 2 views
1

Я пытаюсь написать правило в моей программе пролога, которая определяет, является ли кто-то другом брата.Exception Exception in Prolog Program

Например, если я нахожу brother_of (chris, X), он вернется к Рождеству, потому что Крис - брат крещения. Однако, когда я набираю это, я получаю исключение существования. Я включил факты, чтобы охватить все, но, может быть, это проблема в определении моего правила? Код ниже.

/* Facts */ 
female(ella). 
female(jodi). 
female(sonya). 
female(jane). 
female(christy). 
female(mary). 
male(arnold). 
male(chris). 
male(louis). 
male(mark). 
father(arnold). 
father(louis). 
father(mark). 
mother(ella). 
mother(jodi). 
mother(jane). 
mother(mary). 
father_of(arnold, chris). /* arnold is the father of chris */ 
father_of(arnold, christy). 
father_of(louis, mark). 
father_of(mark, arnold). 
mother_of(mary, chris). 
mother_of(mary, christy).   
mother_of(jane, arnold).  
mother_of(ella, sonya). 
mother_of(jodi, ella). 
mother_of(jodi, mark). 

/* Rules */ 

brother_of(X, Y) :- 
    male(X), 
    ((father_of(Z, X), father_of(Z, Y)); 
    (mother_of(W, X), mother_of(W, Y))), 
    X =\= Y. 

ответ

1

Оператор =\= используется в арифметике только (AFAIK), чтобы увидеть, если два термина отличаются (не unifiable) использовать оператор \=:

X \= Y. 

Обновление: краткое введение к цели cut (!): когда разрез используется в предикате, это означает, что больше не нужно искать ответы, кроме уже найденных (т.е. вы «разрезаете оставшиеся ветви» в дереве поиска). Пример:

first_child(X,Y) :- 
    father_of(X,Y), !. 

?- first_child(arnold,Y). 

Y = chris ; 

no 

После достижения крой, все указывает выбор перед разрез отбрасываются (а новые могут быть созданы после него). В вашем примере вы знаете, что если у X и Y есть один и тот же отец, это не имеет значения, если у них также есть та же мать. Таким образом, вы можете вырезать сразу после «общий отец» часть преуспевает:

brother_of(X, Y) :- 
    male(X), 
    ((father_of(Z, X), father_of(Z, Y), X \= Y, !); # If cut is reached, will not run the next line 
    (mother_of(W, X), mother_of(W, Y), X \= Y)). 

Заметим, однако, что использование разреза имеет много подводных камней (см «зеленый вырезать» против «красной разрезом» в связанном статье Википедии), но это слишком сложно описать здесь. (Обратите внимание, как я повторил X \= Y - если бы я не делал, что программа потерпит неудачу иногда)

Наконец, я хотел бы также отметить, что использование ; часто рекомендуется при написании Пролога коды (вы можете использовать при необходимости хоть). Вместо этого, написать его в двух пунктах:

brother_of(X, Y) :- 
    male(X), 
    father_of(Z, X), 
    father_of(Z, Y), 
    X \= Y, 
    !. 
brother_of(X, Y) :- 
    male(X), 
    mother_of(W, X), 
    mother_of(W, Y), 
    X \= Y. 

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

+0

Это сработало, спасибо! Но теперь, когда я спрашиваю брата (chris, X), он дважды возвращается к Рождеству. После того, как я вернусь в первый раз, я напечатаю «;» чтобы убедиться, что нет больше, чего не должно быть, поэтому он должен возвращать «нет», но снова возвращается к Рождеству. Есть идеи о том, почему? – aclark

+0

Вам нужна цель [cut] (http://en.wikipedia.org/wiki/Cut_%28logic_programming%29): '!'. Спросите меня, нужна ли вам помощь по ее использованию (не знаю, если вы уже видели это в своих исследованиях или нет) – mgibsonbr

+0

Я этого не видел. Как его использовать? – aclark