为什么不接受此FStar功能?

时间:2020-07-06 16:10:23

标签: fstar

我想了解为什么不将此功能作为终止功能:

<div jstcache="243" class="ugiz4pqJLAG__primary-text gm2-body-2" jsan="7.ugiz4pqJLAG__primary-text,7.gm2-body-2">Example, 431 St Michale Rd, New York 3004, United States</div>

FStar拒绝它并发送以下消息:

(错误)无法证明此递归调用已终止:求解程序找到了(部分)反例...

这里的约束问题可能与我在FStar function strange behavior下的相关问题中的约束问题不同

FStar可以显示反例吗?

2 个答案:

答案 0 :(得分:2)

此功能并非在所有输入上都终止。考虑ni < ni_maxnw=0。不幸的是,F *找不到这样的具体反例。

您可以证明函数终止的变体,但是您必须明确告诉F *正在减少什么。在这里,我们在nat上使用了有根据的排序。

let as_nat (x:int) : nat = if x < 0 then 0 else x
val while_items: ni: nat -> ni_max: nat -> nw: nat{ni < ni_max ==> nw > 0} -> Tot bool
                 (decreases (as_nat (ni_max - ni)))
let rec while_items ni ni_max nw =
  (if   ni < ni_max
   then while_items (ni + nw) ni_max nw
   else true)

答案 1 :(得分:2)

the tutorial中所述,默认情况下F *使用减少量度将所有参数按字典顺序排列

val while_items: ni: nat -> ni_max: nat -> nw: nat -> Tot bool (decreases %[ni,ni_max;nw])

这不适用于证明此功能终止,因为显然ni + nw不小于ni

使用正确的减少量度并假设nw为正的前提是:

val while_items: ni: nat -> ni_max: nat -> nw: pos ->
  Tot bool (decreases (if ni < ni_max then ni_max-ni else 0))

与原始示例不完全相同,但是肯定会nw=0永远循环下去!而且无论如何,即使在此修复程序之后,此代码仍然没有什么意义,并且对于函数式编程而言,使用这样的循环也不是习惯。

最后,F *无法产生反例,并且此错误消息最近已修复:https://github.com/FStarLang/FStar/pull/2075