ISO-Prolog提供sort/2
和keysort/2
,它依赖于通常称为"标准术语顺序"的术语顺序(7.2)。
对具有不同顺序的列表进行排序的常用方法是将该列表的每个元素El
以某种方式映射到对XKey-El
对列表,然后对该列表进行排序,最后将密钥投射出去。例如,考虑keysort/2
(See the note for an implementation)如何表达sort/2
。
在许多情况下,这种方法比使用通用实现特定排序谓词快得多,后者依赖于用户定义的顺序作为SWI predsort(C_3, List, SortedList)
或SICStus' samsort(O_2, List, SortedList)
我的问题归结为:
是否存在使用
predsort/3
进行排序的情况。samsort/3
不能被某些映射取代sort/2
- 并且正在投射? 1
为了清楚起见,更好地坚持有限的基础术语。因为,无限的地面术语不具有完整的词典顺序,因为它需要作为有限情况的扩展;而且,目前尚不清楚变量与两个不同变量的实例相关的比较将如何得出ISO / IEC 13211-1:1995中的7.2.1:
7.2.1变量
如果
X
和Y
是不相同的变量,则为X
term_precedesY
应依赖于实现 除了在创建排序列表期间(7.1.6.5,
8.10.3.1 j)排序应保持不变。
因此不清楚predsort/3
是否仍然符合条件
创建排序列表。很清楚的是,在 sort/2
和keysort/2
期间,排序保持不变。
1感谢@WillNess,此预测至少应包括reverse/2
- 或任何线性转换。这也意味着可以实现具有重复和独特结果的结果(类似于keysort/2
的实现方式)。
答案 0 :(得分:5)
首先,你可以"否定" Prolog原子。我们称之为atom_neg/2
(这是一个愚蠢的名字,但无论如何它确实有些愚蠢):
atom_neg(A, NK) :-
atom_codes(A, Cs),
maplist(negate, Cs, NCs),
append(NCs, [0], NK).
negate(X, N) :- N is -X.
我并不是说这样做很实际,但显然,这是可能的。
总排序是一个弱排序,一个关键函数 f 在集合 T 上,同时在密码域上有一个总排序 r f ,定义弱排序 wr(x,y)< ==> r(f(x),f(y))。
(该上下文中函数的Codomain是函数返回的值的域。)
我可能完全错了,但是关系的存在需要一个密钥的存在:你可以用另一个关系来定义一个关系,但最终你必须比较一些可以孤立存在的东西:密钥。
这里的要点是键不需要与我们想要排序的东西在同一个域中,并且为<的对象定义弱排序(关系) strong>相同域名。 Prolog在这里做了一些奇怪的事情:它为所有可能的术语定义了一个标准的术语 。 Prolog也没有&#34;类型&#34;或&#34;域&#34;的正确概念。我的直觉告诉我,排序不属于同一个域的东西根本不是很有用,但Prolog显然不同意。
您无法为两种情况定义关键功能:
无论哪种方式,predsort
都很有用:没有人比Will Ness更喜欢atom_neg/2
解决方案。然而,它目前有一个严重的效率:它不允许稳定的排序。 SWI-Prolog已经can be used in this way,只需要将当前行为添加到predsort/3
的规范和文档中。
答案 1 :(得分:4)
编辑:the answer显示了如何“否定”原子以进行比较,因此在这种情况下它会使我的控制论无效。而问题中的新规定完全无效。
在复杂排序标准的情况下,必须安排多个子键。如果需要保留重复项,则在为sort/2
构造的术语中,在排序子项之后,应将增量索引作为原始术语的前缀。
虽然构造的子键的复杂性和数量可能会失控。成像排序首先按X,然后按Y,在某些区域按升序或降序排列,首先按和按Y,在其他区域按X秒排序。
然后,在标准的术语顺序中,仅用线性数量的键构造和对数线性(可能是轻的)比较来替换对数线性(可能是计算上很重)的比较的优势可以消失。琐事,predsort/3
例如反向的原子列表,带有自定义比较谓词
comp(<,A,B):- B @< A.
等,sort/2
无法在"standard order of terms"中起作用(引用SWI文档)。有了数字,我们可以翻转标志,但不能用名字。
也许您想要将reverse
添加到允许的操作中。
允许sort/4
,我看不到任何不起作用的内容。由于它是稳定的,因此可以通过二次通过(首先是次要通道,然后通过主要标准)来适应次要标准。
答案 2 :(得分:2)
我想我可能会对你的问题有一个正确的答案。
如果您有部分订购,您仍然可以尝试使用predsort/3
进行排序,并且您可能会得到比仅仅说&#34更好的结果;总排序不存在。&#34;
这是一个例子:说你有一支由两支队伍组成的比赛。每场比赛都只给出一支球队,并且在一支球队达到一定数量的分数之前进行比赛。
现在,你组织一个锦标赛,它有一个小组赛阶段,由4个小组组成,这是一个循环赛。只有两支顶级球队才能脱颖而出。
对于每场比赛,球队得分为own_points - other_teams_points
。换句话说,如果你玩到7,最终得分是:
A队 - 5:7 - B队
他们A队得分-2,B队得2分。
在小组赛阶段结束时,您可以通过以下方式订购球队:
最值得注意的是,使用这种得分方案,如果A队击败B队,B队击败C队,C队击败A队和#34队,则无法解决三方平局 ;稳定&#34;在这种情况下,排序毫无意义。
但是,使用predsort/3
,您可以尝试找到两个顶级团队,在大多数情况下,您将获得明确的答案。如上所述解决三向抽签通常使用抛硬币来解决。