Javascript 芬德尔复制品

Javascript 芬德尔复制品,javascript,Javascript,我输入了我的事实: likesdrinking(tom). likesdrinking(sally). likesdrinking(holly). likespainting(tom). likespainting(sally). likespainting(chad). likespainting(margo). likesskating(tom). likesskating(holly). likesskating(margo). likesskating(matt). likesska

我输入了我的事实:

likesdrinking(tom).
likesdrinking(sally).
likesdrinking(holly).

likespainting(tom).
likespainting(sally).
likespainting(chad).
likespainting(margo).

likesskating(tom).
likesskating(holly).
likesskating(margo).
likesskating(matt).
likesskating(cass).
如果我想找到那些喜欢喝酒、画画或滑冰的人,我会使用findall方法,即:

findall(X,(likesdrinking(X),likesskating(X),likespainting(X)),X). 
它将为那些喜欢不止一次的人提供结果。 X=汤姆、莎莉、霍莉、汤姆、莎莉、查德。。。。等

但是我如何使它只返回一个答案而不是重复的答案呢? 是的

X = tom, sally, holly, chad, margo, matt , cass 

您需要标准的
setof/3
谓词:

?- setof(X, (likesdrinking(X),likesskating(X),likespainting(X)), L).
L = [tom].

?- setof(X, (likesdrinking(X),likesskating(X)), L).
L = [holly, tom].

?- setof(X, (likesdrinking(X),likespainting(X)), L).
L = [sally, tom].
正如David在评论中所指出的,如果您想构建一个至少喜欢其中一项活动的人员列表(无重复项):

对于像“谁喜欢滑冰而不喜欢喝酒”这样的问题,你必须注意目标的顺序。以下查询错误:

?- setof(X, (\+ likesdrinking(X), likesskating(X)), L).
false.
为什么??调用
\+likesdrinking(X)
时,变量
X
没有绑定,这将失败,因为有几个人喜欢喝酒。您需要改为编写:

?- setof(X, (likesskating(X), \+ likesdrinking(X)), L).
L = [cass, margo, matt].

likeskating(X)
目标将绑定
X
,然后
\+likeskating(X)
将检查特定的人是否不喜欢喝酒。一般来说,在非地面目标中使用否定(
\+/1
)时要小心。

实际上,在你的指导下,你会得到那些喜欢喝酒、滑冰和绘画的目标。要获取与一个或多个条件匹配的值,请使用或分隔符
而不是AND分隔符
。请注意,如果setof/3没有找到任何内容(逻辑上是正确的),它将失败,而findall/3将其第三个参数与空列表统一起来(通俗地说,“返回空列表”),如果它没有找到任何内容,这将打破Prolog的“fail-then-redo”策略,更适合于非逻辑工作的代码扩展。
?- setof(X, (likesskating(X), \+ likesdrinking(X)), L).
L = [cass, margo, matt].