我想证明在有限数量的情况下参数化的属性。我想将问题划分为每个案例一个实例,并分别解决每个实例。这是一个清理事情的例子:
module Minimal
open FStar.List
open FStar.Tactics
open FStar.Reflection.Data
unfold let lst = [0;1]
unfold let prop i =
match i with
| 0 -> i == 0
| 1 -> i == 1
| _ -> False
val propHolds (i:int) : Lemma (requires (List.mem i lst)) (ensures (prop i))
在这种情况下,案例由列表 lst 定义。我可以很容易地证明 propHolds:
let propHolds i =
assert_by_tactic (prop 0) (fun () -> norm[delta;primops;iota;zeta]; dump "normalized"; trivial ());
assert_by_tactic (prop 1) (fun () -> norm[delta;primops;iota;zeta]; dump "normalized"; trivial ())
但我显然不想为每种情况写一个单独的 assert_by_tactic (不是当可能有数千个......)。我想以某种方式为 lst 中的所有元素自动生成上述证明。
我尝试了各种各样的东西,这里是其中之一:
assert_by_tactic (let rec props i =
if i = 0 then prop 0
else (prop i) /\ (props (i-1))
in
props 1) (fun () -> norm[delta;primops;iota;zeta]; dump "normalized")
不幸的是,这并没有完全达到我想要的效果,assert_by_tactic 失败了(并且没有以我期望的方式减少)。我想我遗漏了一些关于标准化的明显内容,但是在 F* 中执行此操作的规范方法是什么?如果解决方案指向失败的“案例”/断言(如果存在),则加分。