Je suis curieux. J'ai travaillé sur ce type de données dans OCaml :
type 'a exptree =
| Epsilon
| Delta of 'a exptree * 'a exptree
| Omicron of 'a
| Iota of 'a exptree exptree
Qui peut être manipulé en utilisant des fonctions récursives explicitement typées (une fonctionnalité qui a été ajoutée assez récemment). Exemple:
let rec map : 'a 'b. ('a -> 'b) -> 'a exptree -> 'b exptree =
fun f ->
begin function
| Epsilon -> Epsilon
| Delta (t1, t2) -> Delta (map f t1, map f t2)
| Omicron t -> Omicron (f t)
| Iota tt -> Iota (map (map f) tt)
end
Mais je n'ai jamais pu le définir dans Coq :
Inductive exptree a :=
| epsilon : exptree a
| delta : exptree a -> exptree a -> exptree a
| omicron : a -> exptree a
| iota : exptree (exptree a) -> exptree a
.
Coq gémit. Il n'aime pas le dernier constructeur et dit quelque chose que je ne comprends pas complètement ou avec lequel je ne suis pas d'accord:
Error: Non strictly positive occurrence of "exptree" in "exptree (exptree a) -> exptree a".
Ce que je peux comprendre, c'est que les types inductifs utilisant une négation à l'intérieur de leur définition comme type 'a term = Constructor ('a term -> …)
sont rejetés, car ils conduiraient à des bêtes laides non fondées comme des termes λ (non typés). Cependant, ce exptree
type de données particulier semble assez anodin: en regardant sa définition OCaml , son argument 'a
n'est jamais utilisé dans des positions négatives.
Il semble que Coq soit trop prudent ici. Existe-t-il vraiment un problème avec ce type de données inductif particulier? Ou Coq pourrait-il être un peu plus permissif ici?
Et qu'en est-il des autres assistants de preuve, sont-ils capables de faire face à une telle définition inductive (de manière naturelle)?