J'essaie d'écrire le tamis de Eratosthènes dans Coq. J'ai une fonction crossout : forall {n:nat}, vector bool n -> nat -> vector bool n
. Lorsque le tamis trouve un nombre premier, il utilise crossout
pour marquer tous les nombres qui ne sont pas premiers, puis récursifs sur le vecteur résultant. Le tamis ne peut évidemment pas être structurellement récursif sur le vecteur lui-même, mais il est structurellement récursif sur la longueur du vecteur. Ce que je veux faire quelque chose comme ceci:Récursion structurelle sur un paramètre dépendant
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.
Mais si je l'écris comme ça, Coq se plaint que la longueur de v'
n'est pas un sous-terme de n
. Je sais que c'est le cas, mais peu importe comment je structure la fonction, je n'arrive pas à convaincre Coq que c'est le cas. Est-ce que quelqu'un sait comment je peux?
Merci beaucoup pour cela. Je l'ai compris quelque chose comme une heure avant votre publication, mais je ne savais pas si c'était la solution «canonique». – nosewings