我正在尝试使用Prolog解决一个简单的游戏,其中有3个玩家:Alice,Bob和Charlie。每个玩家都会秘密选择一张牌来玩,其中牌可以是红色或蓝色。然后洗牌并翻转。

假设爱丽丝的观点,我们知道她打了哪张牌。因此,如果显示的牌是蓝色,蓝色和红色,而爱丽丝扮演红色,那么她可以推断鲍勃和查理都扮演蓝色。我正在努力为此确定适当的原因。这是我的基本事实:

player(alice).
player(bob).
player(charlie).

color(blue).
color(red).

% The overturned cards -- all players can see these. Order is unimportant.
cards([blue, red, red]).

played(alice, blue).

由此,我们应该可以推断出鲍勃和查理各自扮演红色。我不确定如何告诉Prolog,这三位玩家中的每位都完全打了cards([blue, red, red])事实中的一张牌。还是像num_cards(blue, 1), num_cards(red, 2)这样的东西会更好?

作为一个稍微困难一点的例子,应该使用以下事实来推论查理打了红牌(例如,如果爱丽丝能够窥视鲍勃打的牌):
player(alice).
player(bob).
player(charlie).

color(blue).
color(red).

% The overturned cards -- all players can see these. Order is unimportant.
cards([blue, red, red]).

played(alice, red).
played(bob, blue).

我能够找到的最相似的SO问题是this one,但是我无法将其应用于我的问题。 CLPFD库似乎很相关。

最佳答案

已经进行了非常完善的背景搜索:+1!您链接到Boris's solution的问题确实与此任务密切相关。

首先,我想指出的是,您的任务从表面上看很容易,而且看起来很适合Prolog初学者解决。我认为,这样的任务根本不容易,而且当还必须表示其他知识(例如:谁知道整个不同层次的知识)时,难度很快就变得不可收拾。我完全可以想象,完成任务等任务的初学者会很快摆脱“我本可以用Java轻松解决这个问题,但在Prolog中不可能解决”的感觉。他们也无法用Java解决它的事实通常不会丝毫困扰他们。

在这种具体情况下, clpfd 约束确实很合适。实际上,例如在SICStus Prolog中可用的global_cardinality/2约束可以轻松解决这两个示例。

使用CLP(FD)约束时,技巧是将您感兴趣的域映射到整数。在这种情况下,我将(任意)使用:

  • 1个表示蓝色
  • 2个表示红色

  • 另外,我将简单地使用变量,每个人一个,代表该人玩的具体“牌”(即整数)。想法是指定我们所知道的,然后让约束求解器找出其余部分。

    因此,在第一种情况下,我们有:

    ?-global_cardinality([Alice,Bob,Charlie],[1-1,2-2]),
    爱丽丝= 1。
    爱丽丝= 1
    鲍勃=查理,查理= 2。

    在第二种情况下:

    ?-global_cardinality([Alice,Bob,Charlie],[1-1,2-2]),
    爱丽丝= 2
    鲍勃= 1。
    爱丽丝=查理,查理= 2,
    鲍勃= 1。

    因此,在两种情况下,只需说明给定的约束就足以推断出相应的单个解决方案,就像您期望的那样。

    关于prolog - 序言:游戏中的每个玩家都玩一张牌。在部分了解谁打了哪些牌的情况下,推断出谁打了其他的牌,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36875221/

    10-13 00:01