定义无限树的等式关系
Defining equality relation for infinite trees
在 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 类型定义明确的等式关系吗?
当在析构函数下递归出现某个类型时,Coq 会感到困惑。您可以通过稍微更改树类型的定义来解决此问题:
Section FunctionsToPairs.
Variable (A:Type).
Variable (B:Type).
CoInductive InfiniteTree :=
cons_tree : (A -> B) -> (A -> InfiniteTree) -> InfiniteTree.
CoInductive Tree_eq : InfiniteTree -> InfiniteTree -> Prop :=
tree_eq : forall (f1 f2 : A -> B) (t1 t2 : A -> InfiniteTree),
(forall x, f1 x = f2 x) ->
(forall x, Tree_eq (t1 x) (t2 x)) ->
Tree_eq (cons_tree f1 t1) (cons_tree f2 t2).
End FunctionsToPairs.
我想我可能已经想出了如何在不使用互感应修改 InfiniteTree 类型的情况下执行此操作。
CoInductive Tree_eq : InfiniteTree -> InfiniteTree -> Prop :=
tree_eq : forall (t1:A -> B*InfiniteTree) (t2:A -> B*InfiniteTree),
(forall b, Pair_eq (t1 b) (t1 b))
-> Tree_eq (cons_tree t1) (cons_tree t2)
with Pair_eq : B*InfiniteTree -> B*InfiniteTree -> Prop :=
pair_eq : forall b1 b2 t1 t2, b1 = b2 -> Tree_eq t1 t2 -> Pair_eq (b1, t1) (b2, t2).
一个缺点是,用这种方式构造 Tree_eq 的证明可能比使用 Arthur 的 .
中描述的方法更难
您的定义大多被拒绝,因为使用了让检查器无法确定构造函数 tree_eq
中 Tree_eq c1 c2
的出现是有效的构造。如果您删除它们,或者以不同的方式编写它们,则 Coq 接受该定义。
例如以下作品:
CoInductive Tree_eq : InfiniteTree -> InfiniteTree -> Prop :=
tree_eq : forall (t1:A -> B*InfiniteTree) (t2:A -> B*InfiniteTree),
(forall b, let x1 := (t1 b) in
let x2 := (t2 b) in Tree_eq (snd x1) (snd x2) /\ fst x1 = fst x2)
-> Tree_eq (cons_tree t1) (cons_tree t2).
请注意,启用原始投影后,您的原始定义有效(这个想法来自@JasonGross 的)。
Set Primitive Projections.
Record prod {A B} := pair { fst : A ; snd : B }.
Arguments prod : clear implicits.
Arguments pair {A B}.
Add Printing Let prod.
Notation "x * y" := (prod x y) : type_scope.
Notation "( x , y , .. , z )" := (pair .. (pair x y) .. z) : core_scope.
Hint Resolve pair : core.
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.
在 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 类型定义明确的等式关系吗?
当在析构函数下递归出现某个类型时,Coq 会感到困惑。您可以通过稍微更改树类型的定义来解决此问题:
Section FunctionsToPairs.
Variable (A:Type).
Variable (B:Type).
CoInductive InfiniteTree :=
cons_tree : (A -> B) -> (A -> InfiniteTree) -> InfiniteTree.
CoInductive Tree_eq : InfiniteTree -> InfiniteTree -> Prop :=
tree_eq : forall (f1 f2 : A -> B) (t1 t2 : A -> InfiniteTree),
(forall x, f1 x = f2 x) ->
(forall x, Tree_eq (t1 x) (t2 x)) ->
Tree_eq (cons_tree f1 t1) (cons_tree f2 t2).
End FunctionsToPairs.
我想我可能已经想出了如何在不使用互感应修改 InfiniteTree 类型的情况下执行此操作。
CoInductive Tree_eq : InfiniteTree -> InfiniteTree -> Prop :=
tree_eq : forall (t1:A -> B*InfiniteTree) (t2:A -> B*InfiniteTree),
(forall b, Pair_eq (t1 b) (t1 b))
-> Tree_eq (cons_tree t1) (cons_tree t2)
with Pair_eq : B*InfiniteTree -> B*InfiniteTree -> Prop :=
pair_eq : forall b1 b2 t1 t2, b1 = b2 -> Tree_eq t1 t2 -> Pair_eq (b1, t1) (b2, t2).
一个缺点是,用这种方式构造 Tree_eq 的证明可能比使用 Arthur 的
您的定义大多被拒绝,因为使用了让检查器无法确定构造函数 tree_eq
中 Tree_eq c1 c2
的出现是有效的构造。如果您删除它们,或者以不同的方式编写它们,则 Coq 接受该定义。
例如以下作品:
CoInductive Tree_eq : InfiniteTree -> InfiniteTree -> Prop :=
tree_eq : forall (t1:A -> B*InfiniteTree) (t2:A -> B*InfiniteTree),
(forall b, let x1 := (t1 b) in
let x2 := (t2 b) in Tree_eq (snd x1) (snd x2) /\ fst x1 = fst x2)
-> Tree_eq (cons_tree t1) (cons_tree t2).
请注意,启用原始投影后,您的原始定义有效(这个想法来自@JasonGross 的
Set Primitive Projections.
Record prod {A B} := pair { fst : A ; snd : B }.
Arguments prod : clear implicits.
Arguments pair {A B}.
Add Printing Let prod.
Notation "x * y" := (prod x y) : type_scope.
Notation "( x , y , .. , z )" := (pair .. (pair x y) .. z) : core_scope.
Hint Resolve pair : core.
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.