Estou curioso. Eu tenho trabalhado nesse tipo de dados no OCaml :
type 'a exptree =
| Epsilon
| Delta of 'a exptree * 'a exptree
| Omicron of 'a
| Iota of 'a exptree exptree
Que pode ser manipulado usando funções recursivas de tipo explícito (um recurso que foi adicionado recentemente). Exemplo:
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
Mas nunca fui capaz de defini-lo no 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 está choramingando. Não gosta do último construtor e diz algo que não entendo ou concordo completamente:
Error: Non strictly positive occurrence of "exptree" in "exptree (exptree a) -> exptree a".
O que posso entender é que tipos indutivos que usam uma negação dentro de sua definição como type 'a term = Constructor ('a term -> …)
são rejeitados, porque levariam a bestas feias e não fundamentadas, como termos λ (não tipados). No entanto, esse exptree
tipo de dados em particular parece bastante inócuo: olhando para sua definição de OCaml , seu argumento 'a
nunca é usado em posições negativas.
Parece que Coq é cauteloso aqui. Então, existe realmente um problema com esse tipo de dados indutivo específico? Ou poderia Coq ser um pouco mais permissivo aqui?
Além disso, e os outros assistentes de prova, eles são capazes de lidar com uma definição tão indutiva (de uma maneira natural)?