Prolog按规则位置排序列表

时间:2018-11-30 05:51:11

标签: prolog

我是Prolog和以下程序的新手:

place(Store,2,a).
place(Store,1,b).
place(Store,3,d).
place(Store,4,c).
placeSort(S,List):- findall(L,place(S,N,L),List).

输出:List = [a, b, d, c].

通过使用placeSort(S,List),我可以找到包含S(存储)的所有元素(a,b,c,d)。

但是我想在这里实现的是使用N对a,b,c,d的位置进行排序,但是我不知道该怎么做,因为使用sort只会按字母顺序对其进行排序

placeSort(S,NewList):- findall(L,place(S,N,L),List),sort(List,NewList).

输出:List = [a, b, c, d]. 我要实现的目标:List = [b,a,d,c]

**我知道使用placeSort(S,NewList):- findall([N,L],place(S,N,L),List),sort(List,NewList).

它将返回按数字排序的列表列表。 输出:List = [[1, b], [2, a], [3, d], [4, c]].

但是我不确定如何删除数字,而只是获取字母。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

最简单的方法是使用setof/3(按术语排序),然后选择一个适合您的术语表。在这种情况下,您可以收集N-X形式的place(_, N, X)形式的术语:{p>

setof(N-X, place(S,N,X), OrderedList).  % Assuming `S` is bound

这将导致:

OrderedList = [1-b, 2-a, 3-d, 4-c]

然后,您可以使用maplist/3通过定义一个简单的映射来获取列表:

foo(_-X, X).
maplist(foo, OrderedList, List).

这将为您提供所需的元素。

您的完整谓词如下:

foo(_-X, X).

placeSort(S, List) :-
    setof(N-X, place(S,N,X), OrderedList),
    maplist(foo, OrderedList, List).

很显然,您会为事实,谓词和变量选择明智的名称。我认为我的名字(fooListOrderedListSNX)不足以申请但是我不熟悉您的实际问题域,因此这仅是出于说明目的。

顺便说一句,请注意,事实Store是一个变量,因此在事实中并不是特别有意义。我在您的谓词中保留了您对S的使用,但是我不清楚您真正打算如何使用它。

答案 1 :(得分:0)

SWI-Prolog提供了有趣的内置order_by / 2,通过库(solutionsequences)弥补了传统Prolog与SQL相比所遭受的空白:

?- order_by([asc(X)],place(P,X,W)).
X = 1,
W = b ;
X = 2,
W = a ;
...

因此,您可以避免构建完整列表。