【问题标题】:Using the Prolog select predicate?使用 Prolog 选择谓词?
【发布时间】:2013-03-20 14:30:52
【问题描述】:

我正在尝试制作一个程序,如果可以将列表中的人员重新安排到座位列表中,则 seat(Guests, Seating) 将保持不变,以便每个人都与两边的人兼容。

我有每个人的事实:

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

等等……

我还有一个共同的谓词,这是一个测试两个人是否有共同话题的规则。

common(Person1, Person2, Topic)

我将不得不使用内置的选择谓词和我的用户定义的公共谓词,但我不确定如何。

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

【问题讨论】:

    标签: select recursion prolog logic predicate


    【解决方案1】:

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

    • 从客人中选择一位客人,这也将获得没有该所选客人的座位列表
    • 调用一个递归过程,接受该客人并选择另一个客人(再次返回剩余客人的列表),并测试兼容性。如果它们兼容,则递归调用该过程与新来宾。
    • 此过程的基本情况是客人列表中没有客人。

    看起来像:

    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).
    

    【讨论】:

    • 澄清一下:它的工作方式是select/3将从列表中选择一个元素(从第一个开始),如果解决方案树中的这条路径失败,则回溯select将从列表中选择下一个元素,并从那里继续搜索解决方案。
    • @Boris,正确!。 select/3,在这里使用(第一个和第三个参数未实例化,第二个参数已实例化)将从第二个参数的列表中获取一个元素(将其统一在第一个参数上)并将第三个参数与其余元素统一名单。回溯后,它将测试列表中的所有其他元素(select/3 的第二个参数)。当然,您也可以调用座位,实例化第二个列表,以测试座位列表是否与某些客人列表兼容
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多