我正试图在Coq上写Eratosthenes的筛子。我有一个功能crossout : forall {n:nat}, vector bool n -> nat -> vector bool n
。当筛子找到一个数字是质数时,它使用crossout
来标记所有不是质数的数字,然后在结果矢量上递归。对于矢量本身来说,筛子显然不能在结构上递归,但它在矢量的长度上是结构递归的。我要的是做这样的事情:依赖参数的结构递归
Fixpoint sieve {n:nat} (v:vector bool n) (acc:nat) {struct n} : list nat :=
match v with
| [] => Datatypes.nil
| false :: v' => sieve v' (S acc)
| true :: v' => Datatypes.cons acc (sieve (crossout v' acc) (S acc))
end.
但如果我把它写这样的,勒柯克抱怨的v'
的长度不是n
一个subterm。我知道这是事实,但不管我如何构造这个功能,我似乎都无法说服Coq。有谁知道我可以怎么做?
非常感谢。我在你发布之前的一个小时内发现了这个问题,但我不确定它是否是“规范”解决方案。 – nosewings