我的知识库中有以下格式的原子:
car_details(bmw, [1, 3, 5], 40000).
car_details(audi, [1, 3, 4, 5, 6, 8], 60000).
car_details(volvo, [40, 60, 80, 90], 50000).
car_details(mercedes, [a, b, c, e, s], 80000).
我正在尝试根据成本(第三位置值)对这些原子进行排序。是否有内置的谓词可以让我这样做?我尝试将sort/2
与findall
谓词一起使用。但是,这只会产生所有成本的排序列表。我也想要它的相关信息。
上述预期结果应采用以下格式:
[[bmw, [1, 3, 5], 40000], [volvo, [40, 60, 80, 90], 50000], [audi, [1, 3, 4, 5, 6, 8], 60000], [mercedes, [a, b, c, e, s], 80000]].
答案 0 :(得分:1)
我认为没有一个谓词可以做到,但一个简单的解决方案可能是:
reorder([], []).
reorder([[P,M,I]|W], [[M,I,P]|W1]) :- reorder(W, W1).
cars_by_price(Result) :-
setof([Price, Make, Items], car_details(Make, Items, Price), L),
reorder(L, Result).
setof
谓词将删除重复项,因此我假设您的数据集是唯一的。如果没有,您可能需要执行findall
并在sort
之前执行reorder
。
答案 1 :(得分:1)
predsort / 3可以工作:
comp_prices(R,[_,_,P1],[_,_,P2]) :- compare(R,P1,P2).
?- findall([M,D,P],car_details(M,D,P),L), predsort(comp_prices,L,S).
L = [[bmw, [1, 3, 5], 40000], [audi, [1, 3, 4, 5, 6|...], 60000], [volvo, [40, 60, 80, 90], 50000], [mercedes, [a, b, c|...], 80000]],
S = [[bmw, [1, 3, 5], 40000], [volvo, [40, 60, 80, 90], 50000], [audi, [1, 3, 4, 5|...], 60000], [mercedes, [a, b, c|...], 80000]].
keysort / 2效率更高,使用库(pairs)它也很方便使用:
4 ?- findall(P-[M,D,P],car_details(M,D,P), L), keysort(L, S), pairs_values(S, T).
L = [40000-[bmw, [1, 3, 5], 40000], 60000-[audi, [1, 3, 4, 5|...], 60000], 50000-[volvo, [40, 60, 80|...], 50000], 80000-[mercedes, [a, b|...], 80000]],
S = [40000-[bmw, [1, 3, 5], 40000], 50000-[volvo, [40, 60, 80, 90], 50000], 60000-[audi, [1, 3, 4|...], 60000], 80000-[mercedes, [a, b|...], 80000]],
T = [[bmw, [1, 3, 5], 40000], [volvo, [40, 60, 80, 90], 50000], [audi, [1, 3, 4, 5|...], 60000], [mercedes, [a, b, c|...], 80000]].