prolog - 如何检查序言中的顺序?

标签 prolog

我正在尝试在序言中解决这个难题

Five people were eating apples, A finished before B, but behind C. D finished before E, but behind B. What was the finishing order?

我当前的解决方案有单例变量,我不知道如何解决这个问题。

finishbefore(A, B, Ls) :- append(_, [A,B|_], Ls).

order(Al):-
   length(Al,5),
   finishbefore(A,B,Al),
   finishbefore(C,A,Al),
   finishbefore(D,E,Al),
   finishbefore(B,D,Al).
%%query
%%?- order(Al).

最佳答案

这是使用library(clpz)library(clpfd)约束的纯版本。这个想法是提出一个稍微不同的问题。

How can an endpoint in time be associated to each person respecting the constraints given?

由于我们有五个人,所以五个不同的时间点就足够了,但不是绝对必要的,例如 1..5。

:- use_module(library(clpz)).  % or clpfd
:- set_prolog_flag(double_quotes, chars).  % for "abcde" below.

appleeating_(Ends, Zs) :-
    Ends = [A,B,C,D,E],
    Zs = Ends,
    Ends ins 1..5,
    % alldifferent(Ends),
    A #< B,
    C #< A,
    D #< E,
    B #< D.

?- appleeating_(Ends, Zs).
   Ends = [2, 3, 1, 4, 5], Zs = [2, 3, 1, 4, 5].

只有一个解决方案!请注意,all different/1 并不是直接需要的,因为没有任何地方指出不允许两个人同时结束。事实上,上面证明了没有更短的解决方案。 @CapelliC 的解决方案强加了一个命令,即使两个人按照平等原则完成。但为了兼容性,现在让我们将解决方案映射回您的表示。

list_nth1(Es, N, E) :-
    nth1(N, Es, E).

appleeatingorder(OrderedPeople) :-
    appleeating_(Ends, Zs),
    same_length(OrderedPeople, Ends),
    labeling([], Zs), % not strictly needed
    maplist(list_nth1(OrderedPeople), Ends,"abcde").  % effectively enforces alldifferent/1

?- appleeatingorder(OrderedPeople).
   OrderedPeople = [c,a,b,d,e].
?- appleeatingorder(OrderedPeople).
   OrderedPeople = "cabde".

最后一个使用双引号的解决方案直接生成 Scryer。在 SWI 中使用 library(double_quotes) .

(在这种情况下,appleeating_/2 的额外参数 Zs 并不是严格需要的,但它对于一般 CLP 谓词来说是一个非常有用的约定。它将从搜索部分 (labeling([], Zs)) 中提取建模部分 (appleeating_/2),以便您可以轻松地同时尝试各种版本的搜索/标签.为了真正解决问题,Zs 中的所有变量都必须具有实际值。)

关于prolog - 如何检查序言中的顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67278346/

相关文章:

functional-programming - Curry 中的 N 元函数和 Prolog 中的 N+1 元关系有什么区别吗?

prolog - SICStus Prolog JIT 编译器

recursion - 无法理解为什么序言会无限循环

tree - 如何在序言中实现树算法的尾递归

prolog - 如何在prolog中模拟嵌套循环?

prolog - 如何在 Prolog 中创建算术和不等式约束

list - 如何将递归函数的值存储在序言的列表中?

prolog - swi-prolog forall 功能不起作用

file - 从 Prolog 中的大文件中提取文本

algorithm - SWI Prolog 中的 Hangman 游戏