Мне любопытно. Я работал над этим типом данных в OCaml :
type 'a exptree =
| Epsilon
| Delta of 'a exptree * 'a exptree
| Omicron of 'a
| Iota of 'a exptree exptree
Которым можно манипулировать, используя явно типизированные рекурсивные функции (функция, которая была добавлена совсем недавно). Пример:
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
Но я никогда не мог определить это в 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 скулит. Ему не нравится последний конструктор, и он говорит что-то, с чем я не совсем понимаю или с чем не согласен:
Error: Non strictly positive occurrence of "exptree" in "exptree (exptree a) -> exptree a".
Что я могу понять, так это то, что индуктивные типы, использующие отрицание внутри своего определения, как type 'a term = Constructor ('a term -> …)
, отвергнуты, потому что они приведут к уродливым необоснованным животным, таким как (нетипизированные) λ-члены. Однако этот конкретный exptree
тип данных выглядит достаточно безобидным: если смотреть на его определение OCaml , его аргумент 'a
никогда не используется в отрицательных позициях.
Кажется, что Coq здесь слишком осторожен. Так есть ли действительно проблема с этим конкретным индуктивным типом данных? Или Coq может быть немного более разрешающим здесь?
Кроме того, как насчет других помощников по доказательству, способны ли они справиться с таким индуктивным определением (естественным образом)?