我是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]].
但是我不确定如何删除数字,而只是获取字母。
任何帮助将不胜感激。
答案 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).
很显然,您会为事实,谓词和变量选择明智的名称。我认为我的名字(foo
,List
,OrderedList
,S
,N
,X
)不足以申请但是我不熟悉您的实际问题域,因此这仅是出于说明目的。
顺便说一句,请注意,事实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 ;
...
因此,您可以避免构建完整列表。