2013-03-20 96 views
1

我试图制作一个程序,其中seat(Guests, Seating)如果列表中的人员可以重新安排到列表中座位,以便每个人都可以与任一方的人兼容。使用Prolog选择谓词?

我对每个人的事实:

topics(neil, [diving, football, computers, hockey]). 

等等

我也有一个共同的断言它是测试如果两个人有共同话题的规则。我将不得不使用内置的select谓词和我的用户定义的通用谓词,但我不知道如何。

有人可以提供一个合适的解决方案或解释吗?

回答

4

假设你不必有座位列表的第一个和最后一个人之间的共同话题,您可以:

  • 选择一个从客人客人,这也将获得没有了座位名单选定的访客
  • 调用采用该访客并选择另一个访客(再次返回剩余访客列表)的递归过程并测试兼容性。如果它们与新访客一起递归地调用该过程。
  • 此过程的基本情况是客人列表中没有更多客人。

这看起来是这样的:

seats(Guests, [Person1|Seating]):- 
    select(Person1, Guests, NGuests), 
    seats1(Person1, NGuests, Seating). 

seats1(_, [], []). 
seats1(LPerson, Guests, [RPerson|Seating]):- 
    select(RPerson, Guests, NGuests), 
    common(LPerson, RPerson, _), % There is a common topic between them 
    seats1(RPerson, NGuests, Seating). 
+0

澄清:这个工作的方式是'选择/ 3'会从列表中选择一个元素(从第一个开始),如果这解决方案树中的路径失败,在回溯时,'select'将从列表中选择下一个元素,并且搜索解决方案将从那里继续。 – 2013-03-20 15:05:52

+0

@Boris,正确!这里使用的“select/3”(第一个和第三个参数未被实例化并且第二个参数被实例化)将从第二个参数列表中取出一个元素(在第一个参数上统一它)并且将第三个参数与剩余的列表中的元素。回溯时,它将用列表中的其他元素('select/3'的第二个参数)进行测试。当然你也可以通过实例化第二个列表来调用座位,以测试座位列表是否与某些宾客列表兼容 – gusbro 2013-03-20 15:09:52

+0

非常感谢!伟大的工作,现在明白了:) – Ciphor 2013-03-20 15:28:50