В coq я могу определить отношения равенства для коиндуктивных типов, компоненты которых являются парами:
Section Pairs.
Variable (A:Type).
CoInductive Stream :=
cons : (A * Stream) -> Stream.
CoInductive Stream_eq : Stream -> Stream -> Prop :=
stream_eq : forall t1 t2 b1 b2, Stream_eq (t1) (t2)
-> (b1 = b2)
-> Stream_eq (cons (b1,t1)) (cons (b2,t2)).
End Pairs.
Я также могу сделать это для типов, компоненты которых являются функциями:
Section Functions.
Variable (A:Type).
CoInductive Useless :=
cons_useless : (A -> Useless) -> Useless.
CoInductive Useless_eq : Useless -> Useless -> Prop :=
useless_eq : forall t1 t2, (forall b, Useless_eq (t1 b) (t2 b))
-> Useless_eq (cons_useless t1) (cons_useless t2).
End Functions.
Но яне могу определить аналогичное отношение для типов, чьи компоненты являются функциями для пар:
Section FunctionsToPairs.
Variable (A:Type).
Variable (B:Type).
CoInductive InfiniteTree :=
cons_tree : (A -> B * InfiniteTree) -> InfiniteTree.
CoInductive Tree_eq : InfiniteTree -> InfiniteTree -> Prop :=
tree_eq : forall (t1:A -> B*InfiniteTree) (t2:A -> B*InfiniteTree),
(forall b, let (a1, c1) := (t1 b) in
let (a2, c2) := (t2 b) in Tree_eq c1 c2 /\ a1 = a2)
-> Tree_eq (cons_tree t1) (cons_tree t2).
End FunctionsToPairs.
Я получаю ошибку:
Non strictly positive occurrence of "Tree_eq" in
"forall t1 t2 : A -> B * InfiniteTree,
(forall b : A, let (a1, c1) := t1 b in let (a2, c2) := t2 b in Tree_eq c1 c2 /\ a1 = a2) ->
Tree_eq (cons_tree t1) (cons_tree t2)".
Есть ли какой-либо способ иметь четко определенное равенствоотношение для типа InfiniteTree?