【问题标题】:How to code this on Prolog?如何在 Prolog 上编写代码?
【发布时间】:2013-03-14 06:07:49
【问题描述】:

请您解释一下我将如何在 Prolog 上编写此代码?

梅森、亚历克斯、史蒂夫、 西蒙站在警察队伍中。其中一位金发碧眼、英俊且没有疤痕。二 其中不是金发的人站在梅森的两边。亚历克斯是唯一一个站立的人 旁边正好是一个英俊的男人。史蒂夫是唯一一个没有站在一个伤痕累累的人旁边 人。谁又金发又帅又不怕?

这里有,

p --> 站立(x,y)

twoOfThem(不是金发,站在梅森的两边)

standing(mason,[x,y]):-
         blond([x,y]) == false.

亚历克斯只有一个站在旁边正好一个帅哥

standing(alex,x):-
         handsome(x).

Steve 只是没有站在没有疤痕的旁边。

standing(steve,x):- 
         unscared(x).

【问题讨论】:

  • 你试过什么?请向我们展示您的努力(我们应该在 meta 上发布请求,以根据上下文在标记的序言答案中添加此评论...)
  • 你有一个事实清单。您的第一步应该是尝试将这些事实放入 Prolog 语法中(以建立一个“数据库”)。然后开始考虑这些事实之间的关系(表示为谓词)。

标签: prolog zebra-puzzle


【解决方案1】:

在不使用 CLP(FD) 的情况下,您应该使用 Prolog 的组合能力以适当的方式表达问题和约束。比如

puzzle(Name) :-

    L = [[mason, Pos1, Blond1, Handsome1, UnScared1],
         [alex,  Pos2, Blond2, Handsome2, UnScared2],
         [steve, Pos3, Blond3, Handsome3, UnScared3],
         [simon, Pos4, Blond4, Handsome4, UnScared4]
        ],

   permutation([1,2,3,4], [Pos1,Pos2,Pos3,Pos4]),
   maplist(yn,
       [Blond1, Handsome1, UnScared1,
        Blond2, Handsome2, UnScared2,
        Blond3, Handsome3, UnScared3,
        Blond4, Handsome4, UnScared4
       ]),
...

每个变量(那些以大写字母开头的符号!)都是一个人的属性,并且可以假定来自域的值。 yn/1 这是一个服务事实,允许这些二进制值假设是或否:

yn(y).
yn(n).

然后可以用这种方式表达约束(这里只是第一个)

...
   % Two of them who are not blond are standing on either side of Mason.
   member([mason, I1, _,_,_], L),
   member([_,     I2, n,_,_], L),
   member([_,     I3, n,_,_], L),

   (I2>I1, I3>I1 ; I2<I1, I3<I1),
...

解决办法是

   % One of them is blond, handsome, and unscarred.
   member([Name,  _, y, y, y], L).

我不确定我是否理解每个约束(英文),确实我的程序没有找到解决方案。

程序相当慢,需要 CLP(FD)。如果您对 CLP(FD) 解决方案感兴趣,请编辑您的问题(例如添加适当的标签)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多