我正在使用向量的自定义实现作为函数,其域是自然数的有限“索引集”,并且其图像是某种可以定义最大值的类型,通常是real
. v
例如,我可以有一个带有v 1 = 2.7
和的二维向量v 3 = 4.2
。
在这样的向量上,我想定义一个类似“arg max”的运算符,它告诉我最大分量的索引,3
在上面的例子中v
。我说的是“the”索引,因为“arg max”like 运算符将另外接受一个打破平局的函数,以应用于具有值的组件。(背景是拍卖中的出价。)
我知道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
这可能是因为列表构造函数被定义为 a datatype
,而有限集仅被定义为一个inductive
方案?
不管怎样——你知道在有限集上定义这个函数的方法吗?要么直接写下来,要么通过一些类似折叠的效用函数?