2014-01-04 2 views
1

У меня есть пример типичных отношений.Оператор «или» возвращает только первое заявление

m(thomas). 
m(leon). 
w(nina). 
born(thomas, nina, leon). 

born(Father, Mother, Child) :- born(Mother, Father, Child). 
father(Father, Child) :- born(Father, Mother, Child), m(Father). 
mother(Mother, Child) :- born(Father, Mother, Child), w(Mother). 
parent(Parent, Child) :- (father(Parent, Child); mother(Parent, Child)). 

Когда я спрашиваю после родителей, отец будут перечислены только:

?- parent(X, leon). 
X = thomas ; 
X = thomas ; 
..... 

Я хочу обоих родителей:

?- parent(X, leon). 
X = thomas ; 
X = nina ; 

Что я могу сделать?

Edit: проблема:

Моя проблема была не or, потому что normally возвращает оба утверждения.

Проблема заключалась в том, что born/3, в коде выше, представляет собой цикл. Я пытался заставить друг друга обменяться матерью и отцом.

Edit: исправление:

Я получил два ответа на это от ChristianF и CapelliC. Они оба помогли мне понять, что было не так с моим заявлением.

Мое решение:

m(thomas). 
m(leon). 
w(nina). 
b(thomas, nina, leon). 

born(Father, Mother, Child) 
    :- (m(Father), w(Mother), b(Father, Mother, Child)); b(Mother, Father, Child). 
father(Father, Child) :- born(Father,_, Child), m(Father). 
mother(Mother, Child) :- born(_, Mother, Child), w(Mother). 
parent(Parent, Child) :- (father(Parent, Child); mother(Parent, Child)). 
+1

'родился (отец, Мать, Ребенок): - Рожденный (Мать, Отец, Ребенок). «Много проблем. Одна вещь, которая поможет, - создать конвенцию для фактов 'born/3', в которых всегда указывается отец или мать. – lurker

+1

вы действительно должны всегда включать в свои вопросы вывод, который вы получаете, и объяснять, почему это не то, что вы хотели. Я уверен, что это где-то в «Справочном центре» (т. Е. FAQ). Вы включили объяснение, но не сам вывод. –

+0

@mbratch: Это решение, но что-то я не могу сделать. Мне нужно, чтобы отец и мать менялись друг против друга. – Spen

ответ

1

Проблема заключается в том, что существует множество способов показать born для отца, так как существует бесконечный recursi на.

m(thomas).                 
m(leon).                  
w(nina).                  

born(thomas, nina, leon).             

born_sym(Father, Mother, Child) :- born(Father, Mother, Child).    
born_sym(Father, Mother, Child) :- born(Mother, Father, Child).    

father(Father, Child) :- born_sym(Father, Mother, Child), m(Father).   
mother(Mother, Child) :- born_sym(Father, Mother, Child), w(Mother).   
parent(Parent, Child) :- (father(Parent, Child); mother(Parent, Child)).  
+0

Правильно. Но как я могу это решить. Рожденный_sym не делает или не шумит? – Spen

+0

да, мой фрагмент кода решает это. –

+0

Извините. Я не видел, что в теле нет _sym. Спасибо allot :) Я решил свою проблему. – Spen

2

У вас есть 'петля' в правилах. Удалить правило Борна/3, и вы получите

?- parent(P,leon). 
P = thomas ; 
P = nina. 

редактировать так как вам нужно, что родитель мог бы остаться в первой или второй позиции «» независимо от пола, я хотел бы предложить

father(Father, Child) :- 
    m(Father), (born(Father, _, Child) ; born(_, Father, Child)). 

Я переместил гендерный тест перед запросом born/3, кажется более эффективным избежать повторения запроса ...

+0

Это правильно. Я понял, что есть петля, но не смогла ее найти. Благодарю. Но я нуждаюсь в маме и отце, отшатывающихся друг против друга. Поэтому мне нужно это правило. – Spen

+0

Спасибо. Я только что выбрал решение от ChristianF, но я думаю, что ваш поможет мне в другой проблеме. :) – Spen

0

другое исправление с помощью cut в том, чтобы избежать бесконечной рекурсии:

m(thomas). 
m(leon). 
w(nina). 

born(thomas, nina, leon) :- !. 
born(Father, Mother, Child) :- born(Mother, Father, Child). 

father(Father, Child) :- born(Father, Mother, Child), m(Father). 
mother(Mother, Child) :- born(Father, Mother, Child), w(Mother). 
parent(Parent, Child) :- father(Parent, Child); mother(Parent, Child). 

Просто Другой способ исправить зацикливание, может быть, не очень хороший стиль :)

Смежные вопросы