使用约束逻辑编程排序列表

alb*_*laz 9 list prolog constraint-programming

我想知道是否有人可以帮我解决这个问题:我必须使用Prolog与Constraing Logic Programming订购一个列表,我必须以更有效的方式来做.

所以我定义的主要谓词是下一个:

order(Xs,Ys) :-
    same_length(Xs,Ys),      /* To determine the list Ys with the Xs' length */
    perm(Xs,Ys),             /* Permutation */
    ordered(Ys),             /* Is Ys ordered? */
    ! .
Run Code Online (Sandbox Code Playgroud)

每个先前辅助谓词的实现如下:

same_length(Xs,Ys) :-
    length(Xs,L),
    length(Ys,L).

perm([],[]).
perm([X|Xs],Ys) :- elem(X,Ys,Ws), perm(Xs,Ws).

ordered([]).
ordered([_]).
ordered([X,Y|Xs]) :- X =< Y, ordered([Y|Xs]).

elem(X,[X|Ys],Ys).
elem(X,[Y|Ws],[Y|Zs]) :- elem(X,Ws,Zs).
Run Code Online (Sandbox Code Playgroud)

我已经证明了我制作的节目并且有效!但我不知道是否有可能提高效率,如果是,我怎么能这样做(我在这里阅读这个旧线程).我应该添加或修改任何约束吗?

谢谢!

fal*_*lse 9

您的定义same_length/2不会经常终止.相反,考虑一下

same_length([],[]).
same_length([_|Xs], [_|Ys]) :-
   same_length(Xs, Ys).
Run Code Online (Sandbox Code Playgroud)

同样,library(lambda)使用

... maplist(\_^_^true,Xs, Ys), ...
Run Code Online (Sandbox Code Playgroud)

代替

... same_length(Xs, Ys), ...
Run Code Online (Sandbox Code Playgroud)

看起来你想通过先说明,列表是有序的,然后只搜索排列来重新排序.以下适用于SICStus,SWI,YAP.

ordered2([]).
ordered2([_]).
ordered2([X,Y|Xs]) :-
   when((nonvar(X),nonvar(Y)),
        ( X =< Y, ordered2([Y|Xs]) )).

list_sorted2(Xs,Ys) :-
    maplist(\_^_^true,Xs,Ys),
    ordered2(Ys),
    perm(Ys,Xs).
Run Code Online (Sandbox Code Playgroud)

请注意,perm/2中的参数现在已经交换了!使用SWI:

?- time(order([10,9,8,7,6,5,4,3,2,1],Xs)).
% 38,434,099 inferences, 10.655 CPU in 11.474 seconds (93% CPU, 3607101 Lips)

?- time(list_sorted2([10,9,8,7,6,5,4,3,2,1],Xs)).
% 50,139 inferences, 0.023 CPU in 0.032 seconds (72% CPU, 2205620 Lips)
Run Code Online (Sandbox Code Playgroud)

  • 它更好,因为它更短.`maplist/2,3 ...`是非常强大的谓词,它们包含了函数语言中的map,zip,zipWith. (4认同)
  • 目标`当(Cond,Goal)`意味着'目标',但它将等待执行'目标`直到'Cond`满意为止.我不确定如果你指的是,有`(;)/ 2` if-then-else,`( - >)/ 2`和`if/3`或`(* - >)/ 2` .在任何情况下,所有这些都不会延迟执行,就像/ 2一样. (2认同)