我正在尝试在 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.
但如果我这样写,Coq 会抱怨长度v'
不是n
. 我知道它是,但无论我如何构造函数,我似乎都无法说服 Coq 它是。有谁知道我该怎么做?