Получение правды; ложный набор двух ответов для набора правил

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

Я обращаюсь со свекровью так, что мой шурин также является моим братом, поэтому мне нужно несколько проверок, чтобы узнать, что из этого правда. Я хочу, чтобы пролог возвращал истину и только истину, если какой-либо из вариантов верен. Однако он возвращает true и false как возможные варианты, поскольку, конечно, один из вариантов всегда будет ложным, а другой всегда будет истинным. Либо они мой шурин, либо мой родной брат. Я не могу заставить пролог возвращать только истину и не могу указать ложь в качестве другого ответа. Если у кого-то есть совет, было бы здорово. Соответствующий код приведен ниже. Итак, если я наберу «брат (ребенок, папа)». Я получаю истинный и ложный как возможные ответы, когда все, что мне нужно, - это ложь. Однако «брат (папа, малыш)». возвращает только истину. Но сейчас я болтаю. Извините, если какой-либо код не соответствует детскому папе. Спасибо!

/*facts for relationships*/

female(widow).
female(redhair).

spouse(i,widow).
spouse(widow,i).
spouse(dad,redhair).
spouse(redhair,dad).

child(i,dad).
child(redhair,widow).
child(baby,i).
child(onrun,dad).

male(onrun).
male(baby).
male(dad).
male(i).

/*rules*/
daughter(D,P):-
    female(D), (child(D,P);(spouse(P,S),child(D,S))).
son(D,P):-
    male(D), (child(D,P);(spouse(P,S),child(D,S))).
mother(X,Y):-
    female(X),
    child(Y,X).
father(X,Y):-
    male(X),
    child(Y,X).
son_in_law(C,P):-
    male(C),spouse(C,S),
    (child(S,P);(spouse(P,W),child(S,W))).
daughter_in_law(C,P):-
    female(C),spouse(C,S),
    (child(S,P);(spouse(P,W),child(S,W))).
brother(S1,S2) :- male(S1), 
    (child(S1,P) = child(S2,P2));
    (child(S1,P),child(S2,P2),spouse(P,P2));
    ((child(S1,P),son_in_law(S2,P));(child(S2,P),son_in_law(S1,P))).

person cliff259    schedule 15.10.2010    source источник
comment
Что child(S1,P) = child(S2,P2) должен делать? (А почему внебрачные дети не допускаются, разве вы еще не узнали об отрицании?;)   -  person Fred Foo    schedule 16.10.2010
comment
проект, над которым я работаю, немного более конкретен. Логика этого странная и конкретная, я знаю. Я не уверен, как здесь мне поможет отрицание, хотя я не очень хорошо с ним знаком?   -  person cliff259    schedule 16.10.2010


Ответы (2)


Эти множественные ответы можно предотвратить с помощью мета-предиката once/1:

?- once(brother(baby,dad)).
true.

?-
person Fred Foo    schedule 15.10.2010
comment
Спасибо, larsmans, просто хотел сказать всем, кто смотрел, что это помогло. Думаю, я слишком усложнял. Краткое резюме для всех, кого это интересует. Я подумал, что моя программа вернула истину в качестве первого ответа, а затем, когда я спросил о любых других возможных ответах, она вернула ложь в качестве возможного ответа. На самом деле теперь я думаю, что он говорил мне, что ответ был истинным, и когда я попросил больше возможных ответов, он не смог найти больше ответов и поэтому вернул ложь. Насколько я понимаю, этот мета-предикат устраняет эту проблему, выполняя поиск только один раз. Спасибо! - person cliff259; 16.10.2010

Спасибо за прочтение. Я знаю, что это не так-то просто понять. ребенок находится выше во множестве фактов, которые вы видите. Ребенок дублируется для теста, чтобы получить родителей. Итак, когда я передаю брату (ребенку, папе), программа затем вызывает child (baby, X) = child (dad, X), дочерняя функция передается дочернему элементу, поэтому он возвращает родителя. Затем я проверяю, совпадают ли родители, поскольку это будет означать, что они братья.

person cliff259    schedule 15.10.2010
comment
Я понимаю, что вы пытаетесь сделать, но Пролог работает не так. child(S1,P) = child(S2,P2) пытается объединить две структуры, а это значит, что S1 и S2 должны быть равны. - person Fred Foo; 16.10.2010
comment
аааа да. Итак, чтобы достичь своей цели в этом случае, я действительно хочу протестировать P = P2 после использования каждой функции. Это проверит, совпадают ли родители. - person cliff259; 16.10.2010
comment
Но поскольку я больше смотрю на отрицание из вашего предыдущего указателя, я понимаю, что это означает, что я мог бы использовать отрицание для создания функции Brother (), чтобы она возвращала истину, если цель доказана в любой момент? В принципе, результата хочу. - person cliff259; 16.10.2010