Пролог нескольких предикатов в 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].