さて、私はこの質問に答えるために最善を尽くします。コメントや編集をして、改善してください。カルマが必要な場合は、この回答をコピーして再投稿することもできます(回答が優れている場合は、回答を削除します)。
このユーザーガイドは私が始めるのを助けました。
さて、私たちの理論がにあると仮定しましょうlocale MyLocale
。
locale MyLocale =
fixes A :: "'a set"
begin
definition isInA :: "'a => bool" where
"isInA a ⟷ a ∈ A"
end
isInA
ロケールをで実装することで関数を実装すると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
タイプにが付いていると仮定しましょう'a
。たとえば、linorder
自然数、文字列、リスト、タプルなどがあります。この仮定は、'a ::linorder
の代わりに書くことで表現し'a
ます。プロパティを活用できるデータ型の1つlinorder
は、赤黒木です。私たちのロケールでは、A
でしたset
。セットでは、要素の順序は重要ではありません。したがって、リストの代わりに、より効率的な赤黒木を使用できます。リストは固定された順序を指示しますが、要素は任意に順序付けることができるため、赤黒木はリストよりも効率的です。赤黒木を使用するには、正式な証明のアーカイブからコレクションフレームワークをインポートします。thy-fileの先頭で、imports
セクションに追加します
"./isabelle_afp/Collections/Collections"
これで、赤黒木(rs
)バージョンを実装し、その正しさを示すことができます。コレクションフレームワークの関数rs_α
(alpha<tab>
アルファ版の場合はjEditと入力)は、赤黒木を対応するセットにマップします。
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
関数には対数実行時間があります。TODO:本当に?どこで調べられますか?
コードをさらに改善しましょう。コードではリストの方が簡単なので、バージョンに固執したいとし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)
赤黒を作成してからルックアップを実行すると、単純なリストバージョンよりもコストがかかると思いますが、これは単なる例です。より多くのルックアップが必要な場合は、赤黒木バージョンの方が間違いなく効率的です。
IsabellejEditのコードをいくつかのタイプでテストしてみましょう。自然数から始めます。
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
、タイプにnoが定義されていることを示してい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'')"