这是对有关对术语的特定自变量进行排序的问题的答案的后续操作,而无需为该术语创建新列表keysort
(如果我正确理解了原始问题)。
假设我们想predsort/3
完全按照sort/2
以下行为进行操作:如果我理解正确,则意味着将其称为:
?- predsort(compare, List, Sorted).
现在说我们想使用predsort/3
按实现的排序msort/2
(另请参见此问题)。这样做将是定义一个比较谓词的一种方式Pred(-Delta, +A, +B)
不统一Delta
与=
当元素实际上是平等的:
mcompare(Delta, A, B) :-
compare(Delta0, A, B),
( Delta0 == (=)
-> Delta = (<)
; Delta = Delta0
).
?- predsort(mcompare, List, Sorted).
问题:这真的可以简单地排序而不删除重复项msort/2
吗?似乎应该。
继续:假设我们要对arity> n的术语按术语中第n个参数的标准顺序进行排序。干净的方法是:
sort_argn(N, List, Sorted) :-
map_list_to_pairs(arg(N), List, Pairs),
keysort(Pairs, Sorted_pairs),
pairs_values(Sorted_pairs, Sorted).
如果我们想使用predsort/3
来达到相同的效果,我们可以尝试使用比较谓词,如下所示:
compare_argn(N, Delta, A, B) :-
arg(N, A, AN),
arg(N, B, BN),
compare(Delta, AN-A, BN-B).
并排序第二个参数:
?- predsort(compare_argn(2), List, Sorted).
然而,这是不一样的sort_argn/3
使用上面keysort/2
。如果两个词的第二个参数碰巧相等,它将删除重复项,并将按照原始完整词的标准顺序对复合词进行排序:
?- predsort(compare_argn(2), [f(b,2), f(a,1), f(a,1), f(a,2)], Sorted).
Sorted = [f(a, 1), f(a, 2), f(b, 2)].
?- sort_argn(2, [f(b,2), f(a,1), f(a,1), f(a,2)], Sorted).
Sorted = [f(a, 1), f(a, 1), f(b, 2), f(a, 2)].
对于每对和传递给比较谓词的假设,都位于原始列表的前面。我们可以定义一个比较:A
B
Pred(Delta, A, B)
A
B
compare_argn_stable(N, Delta, A, B) :-
arg(N, A, AN),
arg(N, B, BN),
compare(Delta0, AN, BN),
( Delta0 == (=)
-> Delta = (<)
; Delta = Delta0
).
在这一点上,当且仅当任何两个元素A
和B
始终以与原始列表中相同的顺序传递给比较谓词时,其行为应与sort_argn/3
以上相同:
?- predsort(compare_argn_stable(N), List, Sorted).
现在,当然重要的是,compare_argn_stable/4
相结合Delta
使用<
时,两个“键”是相等的。此外,该行为取决于实现,并且仅与keysort
示例相同,仅当predsort/3
将元素传递给比较谓词时才保留元素的原始顺序。
问题那是正确的吗?
问题是否有涵盖此方面的标准predsort/3
?
既然没有人回答,并且因为我现在已经相当确定:
是的,您可以predsort/3
用来模拟其他任何种类。该问题详细描述了如何进行。
但是:这是一个坏主意,原因有几个。
predsort/3
(请参阅问题)predsort/3
本身不是任何标准的一部分(据我可以告诉)msort/2
或keysort/2
效率比predsort/3
在极少数情况下,列表元素的大小会比我们要排序的列表的长度大得多,这是一种小舞步:
list_to_keyval_pairs(List, Pairs), % defined by the user as necessary
keysort(Pairs, Sorted_pairs),
pairs_values(Sorted_pairs, Sorted)
(请参见此处)实际上比使用更昂贵(更慢)predsort(keycmp, List, Sorted)
,与keycmp/3
由用户定义的。即使这样,具有等效键的结果顺序也不仅取决于的(用户)定义keycmp/3
,而且还取决于的实现predsort/3
。
换句话说,“稳定”排序predsort/3
是一个坏主意。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句