I'm trying to find ancestors of the Greek mythological Muses using the following facts and rules (simplified):
/* 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).
The muse
and ancestor rules are defined as:
/* 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).
I want to essentially do the following:
/* Get the set of ancestors A of muses B and store in Z*/
setof(A, ancestor(A, muse(B)), Z).
This doesn't work, and returns false
. Another variant I tried:
findall(B, muse(B), Muses),
setof(A, ancestor(A, Muses), Z).
But given that I have a lot more parent
facts, it just iterates through every possible ancestor
bag.
The last variant I tried:
setof(A, ancestor(A, member(X, muse(X)), Z).
but that errors out with:
ERROR: Syntax error: Operator expected
ERROR: setof(A, ancestor(A, member(X, muse(X)), Z)
ERROR: ** here **
ERROR: .
which makes sense.
I want to be able to write the results, such as:
write('The Muses ancestors are: '), write(MuseAncestors), nl.
What am I doing wrong?