2015-12-11 2 views
2

Я работаю над созданием генеалогического древа в прологе. Где я нахожусь в беде, когда я звоню сестре или брату. Результаты, которые я получаю, верны, где Джули - сестра майка, Джули - сестра аманды, аманда - сестра Майка, а Аманда - сестра юли. Но что происходит, а не заканчивается там, если я продолжаю ударять по ключу «n», он снова проведет повторную проверку результатов. Почему это происходит?Пролог - генеалогическое дерево

parent(pete,mike). 
parent(pete,julie). 
parent(pete,amanda). 
parent(mary,mike). 
parent(mary,julie). 
parent(mary,amanda). 
female(mary). 
female(julie). 
female(amanda). 
male(mike). 
male(pete). 



mother(X,Y):- 
    parent(X,Y), 
    female(X). 

father(X,Y):- 
    parent(X,Y), 
    male(X). 

sibling(X,Y):- 
    parent(Z,X), 
    parent(Z,Y), 
    X\=Y. 

sister(X,Y):- 
    sibling(X,Y), 
    female(X). 

brother(X,Y):- 
    sibling(X,Y), 
    male(X). 

ответ

1

Каждая пара братьев и сестер будет иметь и тот же отец и ту же мать (в более консервативных обществах, по крайней мере, и в вашей программе на данный момент). Здесь вы получаете двойные ответы. Вы могли бы сказать, что братья и сестры всегда разделяют и родителей?

+0

Как бы я так сказал? – OmonoiatisUSa

+0

@OmonoiatisUSa Как вы это сделали, просто добавьте еще два «родительских» подзаголовка в определение 'sibling' (и не забудьте сказать, что« Parent1 »и« Parent2 »не совпадают). –

+0

Да, я знаю, это звучит глупо, но я все еще не уверен, как:/ты не возражаешь, показывая мне? – OmonoiatisUSa

1

Как указано, вы получаете двойные ответы, потому что вы проверяете, есть ли у них один и тот же родитель, и у них есть два из них. Более того, вы получаете еще больше решений, например, Майк является братом аманды, но также аманда является братом майка, и вы ничего не делаете, чтобы предотвратить появление обоих решений. Таким образом, вместо:

sibling(X, Y):- 
    parent(Z, X), 
    parent(Z, Y), 
    X\=Y. 

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

sibling(X, Y):- 
    mother(Z, X), 
    mother(Z, Y), 
    father(W, X), 
    father(W, Y), 
    X\=Y. 

Вы могли бы остановить вторую задачу (X = микрофон, Y = AMANDA; X = Amanda, Y = МАЙК) путем введения @ <:

sibling(X, Y):- 
    mother(Z, X), 
    mother(Z, Y), 
    father(W, X), 
    father(W, Y), 
    [email protected]<Y. 

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

В зависимости от необходимости, возможно, более элегантное и общее решение (не требующее, чтобы оба родителя были одинаковыми), было бы использовать setof (http://www.swi-prolog.org/pldoc/doc_for?object=setof/3) с вашим оригинальным предложением для сестер, но вы переработаете свои статьи брата/сестры, например:

sibling(X, Y):- 
    parent(Z, X), 
    parent(Z, Y), 
    X\=Y. 

sister(X,Y,L):- 
    female(X), 
    setof([X, Y], (sibling(X, Y)), L). 

brother(X,Y,L):- 
    male(X), 
    setof([X, Y], (sibling(X, Y)), L). 

Это даст вам список уникальных пар в списке L, например для сестры (X, Y, L) вы получаете:

X = julie 
L = [[julie, amanda], [julie, mike]] 

X = amanda 
L = [[amanda, julie], [amanda, mike]] 

Поиграйте с ним, чтобы получить именно то, что вам нужно.

+0

Хорошо и тщательно (+1), только небольшая деталь: 'X @

+2

Да, хороший ответ. Но еще один маленький совет: используйте dif/2 вместо X \ = Y, потому что это чистый предикат;) –

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