Clingo:断言部分约束

时间:2014-05-05 21:28:41

标签: zebra-puzzle answer-set-programming clingo

我正在尝试在clingo中实现一个解决其中一个经典谜语的程序,在这个谜语中你有一系列事实和约束断言,你必须推断其他事实。这就是问题所在:

  

五个不同国籍的男人住在五个并排的房子里,每个房子都有不同的颜色;他们都有不同的工作,不同的动物和最喜欢的饮料。我们知道:

     
      
  1. 英国人住在红房子里。
  2.   
  3. 西班牙男人最喜欢的动物是狗。
  4.   
  5. 日本人是画家。
  6.   
  7. 意大利男人喝茶。
  8.   
  9. 这名挪威男子住在左起第一间房子里。 (number_norw = 1)
  10.   
  11. 住在温室里的人喝咖啡。
  12.   
  13. 温室就在白宫右边。 (number_green = number_white + 1)
  14.   
  15. 店员喜欢猫。
  16.   
  17. 推销员住在黄屋里。
  18.   
  19. 牛奶是中心屋内最受欢迎的饮品。 (number_milk = 3)
  20.   
  21. 挪威人的房子与蓝色房子相邻。 (number_norw = number_blue±1)
  22.   
  23. 厨师喜欢果汁。
  24.   
  25. 住在医院旁边的那个男人喜欢狐狸。
  26.   
  27. 爱马的男人住在推销员的隔壁。
  28.   

任务是找出谁喜欢斑马。 所以我提出断言:

% Number (the number of the house, 1 being the leftmost of the block, 5 the rightmost)
number(1..5).

% Color
color(red;green;white;yellow;blue).

% Nationality
nationality(english;spanish;japanese;italian;norwegian).

% Animal
animal(dog;cat;fox;horse;zebra).

% Job
job(painter;clerk;salesman;cook;doctor).

% Beverage
beverage(tea;coffee;milk;juice;coke).

% House
house(X, C, N, A, J, B) :-
    number(X),
    color(C),
    nationality(N),
    animal(A),
    job(J),
    beverage(B).

现在我坚持主张限制;我如何编写断言1.到14?我只需要理解正确的语法,所以如果有人能够通过一两个例子让我走上正轨,我可以弄清楚其余部分。 感谢。

N.B。请注意,我可以从5和11推断,第二个房子是蓝色房子,因为11. number_blue = number_norw ± 15. number_norw = 1和0不在可能的数字范围内,但我不知道想要手动将其添加到约束中,因为我希望clingo能够自行解决它。

1 个答案:

答案 0 :(得分:1)

为第一个断言添加约束的一种方法:

% 1. The English man lives in the red house.
%     S: english --> red house <==> red house OR not english
% not S: not (red house OR not english) <==> not red house AND english
% ie. it is not so, that the english man doesn't live in the red house
:- not 1 { house(X, red, english, A, J, B) :
           number(X) : animal(A) : job(J) : beverage(B) }.

另一个例子是第七个断言:

% 7. The green house is immediately right of the white one.
% (number_green = number_white + 1)
:- house(NG, green, _, _, _, _), house(NW, white, _, _, _, _), NG!=NW+1.
然而,这将导致长的解决时间和大的内存需求(千兆字节),因为接地程序(gringo的输出)是巨大的。您可以使用gringo -t yourcode.asp查看此信息。这是因为上面第一个断言的约束中的“不关心”变量_(和X, A, J, B)。每条规则将以至少5 * 5 * 5 * 5的方式编写。

微米。 Gebser告诉我,谓词(关系)应该保持简短。这种实例编码的问题是house/6太长了。解决这个问题的一种方法是使用以下样式对其进行编码:

house(1..5).
elem(color, red;green;white;yellow;blue).
elem(nationality, english;spanish;japanese;italian;norwegian).
...

从那里开始。现在,elem的arity只有2.当以这种方式定义实例时,程序变得更简单,例如。断言的约束不需要聚合(1{ ... }N语法)。

:- not chosen(H, nationality, english), chosen(H, color, red).

微米。 Gebser还建议求解器(clasp)也可以从另一种方式编写规则中受益:

:- not chosen(H, nationality, english), chosen(H, color, red).
:- chosen(H, nationality, english), not chosen(H, color, red).

您还需要一些额外的限制,例如,不应将同一类型的两个不同元素映射到一个房屋。

为了获得更好的输出,您可以创建一个给出house/6输出的关系。

请注意,我使用的是gringo3和clasp2,它们不是最新版本。如果您有新的clingo,可能需要进行修改。