私は、ドメインが自然数の有限の「インデックスセット」であり、そのイメージが最大値を定義できる何らかのタイプの関数として、ベクトルのカスタム実装を使用していますreal
。たとえば、とを使用して 2 次元ベクトルを作成できv
ます。v 1 = 2.7
v 3 = 4.2
3
そのようなベクトルでは、上記の例で、最大コンポーネントのインデックスを教えてくれる「arg max」のような演算子を定義したいと思いますv
。「arg max」のような演算子は、値を持つコンポーネントに適用されるタイブレーク関数をさらに受け入れるため、「the」インデックスと言っています。(背景はオークションでの入札です。)
私はMax
、有限集合が次を使用して定義されていることを知ってfold1
います(それがどのように機能するかはまだわかりません)。私はこれを試しましたが、それ自体は受け入れられましたが、私がやりたかった他のことにはうまくいきませんでした:
fun arg_max_tb :: "index_set ⇒ tie_breaker ⇒ (real vector) ⇒ nat"
where "arg_max_tb N t v = fold1
(λ x y . if (v x > v y) then x (* component values differ *)
else if (v x = v y ∧ t x y) then x (* tie-breaking needed *)
else y) N"
さらに、「arg max」のような演算子の特定のプロパティを証明したいことに注意してください。これには、誘導が必要になる可能性があります。finite_ne_induct
有限集合上の帰納法の法則があることは知っています。わかりましたが、評価できるように演算子を定義できるようにしたいと思います(たとえば、具体的な有限集合を試す場合)が、評価します
value "arg_max_tb {1::nat} (op >) (nth [27::real, 42])"
期待される戻り値1
を使用すると、次のエラーが発生します。
Wellsortedness error
(in code equation arg_max_tb ?n ?t ?v \equiv
fold1 (\lambda x y. if ord_real_inst.less_real (?v y) (?v x) then ...) ?n):
Type nat not of sort enum
No type arity nat :: enum
したがって、有限集合をリストに変換することにしました。リストでは、演算子を定義し、そのプロパティの一部を証明することができました (興味がある場合はコードを共有できます) list_nonempty_induct
。
作業リストベースの定義は次のようになります。
fun arg_max_l_tb :: "(nat list) ⇒ tie_breaker ⇒ (real vector) ⇒ nat"
where "arg_max_l_tb [] t v = 0"
(* in practice we will only call the function
with lists of at least one element *)
| "arg_max_l_tb [x] t v = x"
| "arg_max_l_tb (x # xs) t v =
(let y = arg_max_l_tb xs t v in
if (v x > v y) then x (* component values differ *)
else if (v x = v y ∧ t x y) then x (* tie-breaking needed *)
else y)"
fun arg_max_tb :: "index_set ⇒ tie_breaker ⇒ (real vector) ⇒ nat"
where "arg_max_tb N t v = arg_max_l_tb (sorted_list_of_set N) t v"
有限集合のコンストラクターに対して関数を直接定義することに成功しませんでした。以下は機能しません。
fun arg_max_tb :: "index_set ⇒ tie_breaker ⇒ (real vector) ⇒ participant"
where "arg_max_tb {} t b = 0"
| "arg_max_tb {x} t b = x"
| "arg_max_tb (insert x S) t b =
(let y = arg_max_tb S t b in
if (b x > b y) then x
else if (b x = b y ∧ t x y) then x
else y)"
エラーメッセージが表示されます
Malformed definition:
Non-constructor pattern not allowed in sequential mode.
⋀t b. arg_max_tb {} t b = 0
これは、リスト コンストラクターが として定義されているdatatype
のに対し、有限集合は単にinductive
スキームとして定義されているためでしょうか?
何であれ、この関数を有限集合上で定義する方法を知っていますか? 直接書き留めるか、折り畳み式のユーティリティ関数を使用しますか?