我不知道 Isabelle2013 的库中是否有任何更快的实现,但您可以自己轻松完成,如下所示:
- 实现一个
distinct_sorted确定排序列表的独特性的函数。
- 证明
distinct_sorted确实distinct在排序列表上实现
- 证明实现
distinct通过distinct_list和排序的引理,并将其声明为distinct.
总之,这看起来如下:
context linorder begin
fun distinct_sorted :: "'a list => bool" where
"distinct_sorted [] = True"
| "distinct_sorted [x] = True"
| "distinct_sorted (x#y#xs) = (x ~= y & distinct_sorted (y#xs))"
lemma distinct_sorted: "sorted xs ==> distinct_sorted xs = distinct xs"
by(induct xs rule: distinct_sorted.induct)(auto simp add: sorted_Cons)
end
lemma distinct_sort [code]: "distinct xs = distinct_sorted (sort xs)"
by(simp add: distinct_sorted)
接下来,您需要一个高效的排序算法。默认情况下,sort使用插入排序。如果从 HOL/Library 导入 Multiset,sort将通过快速排序实现。如果您从形式证明档案中导入高效合并排序,您将获得合并排序。
While this can improve efficiency, there's also a snag: After the above declarations, you can execute distinct only on lists whose elements are instances of the type class linorder. As this refinement happens only inside the code generator, your definitions and theorems in Isabelle are not affected.
For example, to apply distinct to a list of lists in any code equation, you first have to define a linear order on lists: List_lexord in HOL/Library does so by picking the lexicographic order, but this requires a linear order on the elements. If you want to use string, which abbreviates char list, Char_ord defines the usual order on char. If you map characters to the character type of the target language with Code_Char, you also need the adaptation theory Code_Char_ord for the combination with Char_ord.