好的,我会尽力回答这个问题。请随时评论和编辑以改进它。如果您想要因果报应,您也可以复制此答案并重新发布(如果您的答案更好,我将删除我的答案)。
这个用户指南帮助我开始。
好的,让我们假设我们的理论在locale MyLocale
.
locale MyLocale =
fixes A :: "'a set"
begin
definition isInA :: "'a => bool" where
"isInA a ⟷ a ∈ A"
end
假设我们通过 aisInA
实现语言环境来实现该功能。然后,我们可以生成代码并显示其正确性set
A
list
definition code_isInA_list :: "'a list => 'a => bool"
where "code_isInA_list Al a ⟷ a ∈ set Al"
lemma code_isInA_list_correct:
"code_isInA_list Al a = MyLocale.isInA (set Al) a"
by(simp add: MyLocale.isInA_def code_isInA_list_def)
export_code code_isInA_list in Scala file -
这基本上会产生以下 Scala 代码
def code_isInA_list[A : HOL.equal](al: List[A], a: A): Boolean =
Lista.member[A](al, a)
这些Lista.member
函数是线性时间算法。我们能做得更好吗?
假设我们linorder
的 type 上有一个'a
。例如,我们有linorder
自然数、字符串、列表、元组……我们通过写作'a ::linorder
而不是 来表达这个假设'a
。可以利用该linorder
属性的一种数据类型是红黑树。在我们的语言环境中,A
是一个set
. 在集合中,元素的顺序无关紧要。所以我们可以使用更高效的红黑树来代替列表。红黑树比列表更有效,因为元素可以任意排序,而列表规定了固定的顺序。为了使用红黑树,我们从形式证明档案中导入 Collections 框架。在 thy 文件的开头,我们添加到该imports
部分
"./isabelle_afp/Collections/Collections"
现在我们可以实现一个红黑树(rs
)版本并显示它的正确性。Collections 框架中的函数rs_α
(alpha<tab>
在 jEdit 中键入 alpha)将红黑树映射到其对应的集合。
definition code_isInA_rs :: "('a ::linorder) rs => 'a => bool"
where "code_isInA_rs Al a ⟷ rs_memb a Al"
lemma code_isInA_rs_correct:
"code_isInA_rs Ars a = MyLocale.isInA (rs_α Ars) a"
by(simp add: MyLocale.isInA_def code_isInA_rs_def rs_correct)
export_code code_isInA_rs in Scala file -
我们产生以下代码
def code_isInA_rs[A : Orderings.linorder](al: RBT.rbt[A, Unit], a: A): Boolean =
RBTSetImpl.rs_memb[A].apply(a).apply(al)
该rs_memb
函数具有对数运行时间。托多:真的吗?我在哪里可以查到?
让我们进一步改进我们的代码。假设我们要坚持使用该code_isInA_list
版本,因为在我们的代码中列表对我们来说更容易。我们可以code_isInA_list
根据code_isInA_rs
. 因此,我们使用list_to_rs
它将列表转换为红黑树。通过该[code]
属性,我们告诉代码生成器使用新版本。
lemma [code]: "code_isInA_list Al a ⟷ code_isInA_rs (list_to_rs Al) a"
by(simp add: code_isInA_list_def code_isInA_rs_def rs_correct)
export_code code_isInA_list in Scala file -
我们产生以下代码。
def code_isInA_list[A : Orderings.linorder](al: List[A], a: A): Boolean =
code_isInA_rs[A](RBTSetImpl.list_to_rs[A].apply(al), a)
我想创建一个红黑然后在其中进行查找比简单的列表版本更昂贵,但这只是一个例子。如果我们需要更多的查找,红黑树版本肯定会更高效。
让我们用一些类型来测试 Isabelle jEdit 中的代码。我们从自然数开始。
value[code] "code_isInA_list [(1::nat), 3, 7, 4] 4"
这导致True
接下来,我们尝试字符串。
value[code] "code_isInA_list [''a'', ''b'', ''xyz''] ''b''"
这导致
Wellsortedness error:
Type char list not of sort linorder
No type arity list :: linorder
错误消息告诉我们没有linorder
在string
类型上定义。所以我们引入以下理论。
"~~/src/HOL/Library/List_lexord"
"~~/src/HOL/Library/Code_Char"
"~~/src/HOL/Library/Code_Char_chr"
"~~/src/HOL/Library/Code_Char_ord"
现在我们得到了想要的结果True
。该代码甚至适用于元组。
value[code] "code_isInA_list [(''a'', ''a''), (''b'', ''c''), (''xyz'', '''')] (''b'', ''c'')"