findall/setof 中的 Prolog 多个谓词
Prolog multiple predicates in 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).
这不行,returns 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.
我做错了什么?
要将复合目标传递给以目标为参数的谓词,只需将其放在括号中即可:
setof(X, ( G1, G2 ), Xs).
关于您的复合目标:也许最好问:
Who are the ancestors of muses?
?- muse(M), ancestor(A, M).
您需要 目标的结合 。任何介绍性的 Prolog 文本都应该解释连词的含义以及为什么 ancestor(A, muse(M))
不是您的意思。
请记住,如果您写:
?- setof(A, ( muse(M), ancestor(A, M) ), As).
您留下 M
一个自由变量,您将获得一组针对 该变量的每个可能绑定 的解决方案。为避免这种情况,您可以明确告诉 Prolog 不要尝试绑定它:
?- setof(A, M^( muse(M), ancestor(A, M) ), As).
As = [gaia, kronos, mnemosyne, oranos, rheia, zeus].
我正在尝试使用以下事实和规则(已简化)寻找希腊神话中缪斯女神的祖先:
/* 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).
这不行,returns 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.
我做错了什么?
要将复合目标传递给以目标为参数的谓词,只需将其放在括号中即可:
setof(X, ( G1, G2 ), Xs).
关于您的复合目标:也许最好问:
Who are the ancestors of muses?
?- muse(M), ancestor(A, M).
您需要 目标的结合 。任何介绍性的 Prolog 文本都应该解释连词的含义以及为什么 ancestor(A, muse(M))
不是您的意思。
请记住,如果您写:
?- setof(A, ( muse(M), ancestor(A, M) ), As).
您留下 M
一个自由变量,您将获得一组针对 该变量的每个可能绑定 的解决方案。为避免这种情况,您可以明确告诉 Prolog 不要尝试绑定它:
?- setof(A, M^( muse(M), ancestor(A, M) ), As).
As = [gaia, kronos, mnemosyne, oranos, rheia, zeus].