我在Coq中有一个数据类型快照=(nat,state,bool)。我想编写一个函数 beq_snap 来比较两个快照并返回 bool 类型。
Inductive id : Set :=
| Id : nat -> id.
Definition state := id -> nat.
Definition snapshot := nat * state * bool.
答案 0 :(得分:2)
您的state
类型与nat -> nat
同构,您无法编写比较Coq中此类函数的函数。这背后的直觉是考虑这样的比较是如何工作的:如果它终止并且结束两个状态是相等的,那么它只检查了两个函数的一些有限部分,并且状态的剩余值可能会或可能不会有所不同。因此,在有限时间内不可能得出两个状态相等的结论(尽管如果它们不同,检查每个指数最终会找到一个不同的状态)。
答案 1 :(得分:1)
我建议以稍微不同的方式实现状态:
Require Import Bool.
Inductive id : Set :=
| Id : nat -> id.
Definition state : Set := list (id * nat).
Definition snapshot : Set := nat * state * bool.
Definition id_eqb (a b : id) : bool :=
match a, b with
| Id n1, Id n2 => Nat.eqb n1 n2
end.
Fixpoint list_eqb (A : Set) (f : A -> A -> bool) (a b : list A) {struct a} : bool :=
match a, b with
| cons e1 t1, cons e2 t2 => andb (f e1 e2) (list_eqb A f t1 t2)
| _ , _ => false
end.
Arguments list_eqb [A].
Definition tuple_eqb (A B : Set) (fa : A -> A -> bool) (fb : B -> B -> bool) (a b : (A * B)) : bool :=
match a, b with
| (a1, a2), (b1, b2) => andb (fa a1 b1) (fb a2 b2)
end.
Arguments tuple_eqb [A B].
Definition state_eqb : state -> state -> bool := list_eqb (tuple_eqb id_eqb Nat.eqb).
Notation "x /b\ y" := (andb x y) (at level 50).
Definition beq_snap (a b : snapshot) : bool :=
match a, b with
| (n1, s1, b1), (n2, s2, b2) => Nat.eqb n1 n2 /b\ state_eqb s1 s2 /b\ Bool.eqb b1 b2
end.
请注意,state
定义为list (id * nat)
(也许它只是我,但我没有找到比较元组和列表的预定义函数,所以我手工定义它们。任何人都知道更好的方法吗?)