局部映射 Partial Maps
作为在Coq中如何定义数据结构的最后一个例子,这里有一个simple _partial map_data类型,类似于大多数编程语言中的map或dictionary数据结构。
首先,我们定义一个新的归纳数据类型id作为部分映射的“键”。
Inductive id
Inductive id : Type :=
| Id (n : nat).
在内部,id只是一个数字。通过使用标记Id包装每个nat,引入一个单独的类型,使定义更具可读性,并为我们提供了更大的灵活性。
我们还需要对ids进行平等性测试:
Definition eqb_id
Definition eqb_id (x1 x2 : id) :=
match x1, x2 with
| Id n1, Id n2 => n1 =? n2
end.
现在我们定义部分映射的类型:
Inductive partial_map
Module PartialMap.
Export NatList.
Inductive partial_map : Type :=
| empty
| record (i : id) (v : nat) (m : partial_map).
该声明可以理解为:“有两种方法可以构造部分映射:使用构造函数empty来表示空的部分映射,或者将构造函数记录应用于键、值和现有的部分映射来构造具有附加键到值映射的部分映射。”
update函数通过使用新项对局部映射中的给定项进行阴影覆盖来覆盖该项(如果给定项尚未存在,则只需添加一个新项)。
Definition update
Definition update (d : partial_map)
(x : id) (value : nat)
: partial_map :=
record x value d.
最后,find函数在局部映射中搜索给定的键。如果找不到键,则返回None;如果键与val关联,则返回某个val。如果同一键映射到多个值,则find将返回它遇到的第一个值。
Fixpoint find
Fixpoint find (x : id) (d : partial_map) : natoption :=
match d with
| empty => None
| record y v d' => if eqb_id x y
then Some v
else find x d'
end.
41: 1 star, standard (eqb_id_refl)
Theorem eqb_id_refl
Theorem eqb_id_refl : forall x, eqb_id x x = true.
Proof.
(* FILL IN HERE *) Admitted.
Coq代码
Search (?n =? ?n).
Theorem eqb_id_refl : forall x, eqb_id x x = true.
Proof.
intros []. induction n as [| n' IHn'].
- simpl. reflexivity.
- simpl. rewrite -> eqb_refl. reflexivity.
Qed.
42: 1 star, standard (update_eq)
Theorem update_eq
Theorem update_eq :
forall (d : partial_map) (x : id) (v: nat),
find x (update d x v) = Some v.
Proof.
(* FILL IN HERE *) Admitted.
Coq代码
Theorem update_eq :
forall (d : partial_map) (x : id) (v: nat),
find x (update d x v) = Some v.
Proof.
intros d x v.
simpl. rewrite -> eqb_id_refl.
reflexivity.
Qed.
43: 1 star, standard (update_neq)
Theorem update_neq
Theorem update_neq :
forall (d : partial_map) (x y : id) (o: nat),
eqb_id x y = false -> find x (update d y o) = find x d.
Proof.
(* FILL IN HERE *) Admitted.
End PartialMap.
Coq代码
Theorem update_neq :
forall (d : partial_map) (x y : id) (o: nat),
eqb_id x y = false -> find x (update d y o) = find x d.
Proof.
intros d x v o.
intros H.
simpl. rewrite -> H.
reflexivity.
Qed.
44: 2 stars, standard, optional (baz_num_elts)
考虑下面的归纳定义:
Inductive baz : Type :=
| Baz1 (x : baz)
| Baz2 (y : baz) (b : bool).
baz类型有多少个元素?(用文字或评论进行解释。)
(* FILL IN HERE *)
(* Do not modify the following line: *)
Definition manual_grade_for_baz_num_elts : option (nat*string) := None.