Пролог нескольких предикатов в findall/setof

Я пытаюсь найти предков греческих мифологических муз, используя следующие факты и правила (упрощенно):

/* parent(A, B) - A is the parent of B */
parent(zeus, calliope).
parent(zeus, clio).
parent(zeus, melpomene).
parent(zeus, euterpe).
parent(zeus, erato).
parent(zeus, terpsichore).
parent(zeus, urania).
parent(zeus, thalia).
parent(zeus, polymnia).
parent(mnemosyne, calliope).
parent(mnemosyne, clio).
parent(mnemosyne, melpomene).
parent(mnemosyne, euterpe).
parent(mnemosyne, erato).
parent(mnemosyne, terpsichore).
parent(mnemosyne, urania).
parent(mnemosyne, thalia).
parent(mnemosyne, polymnia).

parent(kronos, zeus).
parent(rheia, zeus).
parent(oranos, kronos).
parent(gaia, oranos).

muse и правила предка определены как:

/* A is a Muse if A's parents are Zeus and Mnemosyne */
muse(A):- parent(zeus, A), parent(mnemosyne, A).
/* A is the ancestor of B if A is the parent of B */
ancestor(A, B):- parent(A, B).
/* A is an ancestor of C if A is the parent of B and B is the ancestor of C */
ancestor(A, C):- parent(A, B), ancestor(B, C).

Я хочу по существу сделать следующее:

/* Get the set of ancestors A of muses B and store in Z*/
setof(A, ancestor(A, muse(B)), Z).

Это не работает, и возвращает false, Другой вариант, который я попробовал:

findall(B, muse(B), Muses),
setof(A, ancestor(A, Muses), Z).

Но учитывая, что у меня есть намного больше parent факты, это просто перебирает все возможные ancestor мешок.

Последний вариант, который я попробовал:

setof(A, ancestor(A, member(X, muse(X)), Z).

но это ошибки с:

ERROR: Syntax error: Operator expected
ERROR: setof(A, ancestor(A, member(X, muse(X)), Z)
ERROR: ** here **
ERROR: .

что имеет смысл.

Я хочу иметь возможность писать результаты, такие как:

write('The Muses ancestors are: '), write(MuseAncestors), nl.

Что я делаю неправильно?

1 ответ

Решение

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

setof(X, ( G1, G2 ), Xs).

Что касается вашей составной цели: может быть, лучше спросить:

Кто такие предки муз?

?- muse(M), ancestor(A, M).

Вам нужно сочетание целей. Любой вводный текст Пролога должен объяснить, что означает соединение и почему ancestor(A, muse(M)) это не то, что вы имеете в виду.

Имейте в виду, что если вы напишите:

?- setof(A, ( muse(M), ancestor(A, M) ), As).

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

?- setof(A, M^( muse(M), ancestor(A, M) ), As).
As = [gaia, kronos, mnemosyne, oranos, rheia, zeus].
Другие вопросы по тегам