如何为寄存器指定一个自然数(寄存器用自然数表示)。
例如,如何加载自然数n来注册k? 如何比较两个自然数并分配给寄存器?
我的想法是定义一个归纳类型,其中n,k为自然数,但我不确定构造函数应该是什么样的....
我正在做类似的事情:
Inductive assign (n, k : nat) Type :=
| load k => k
| load k n =>
答案 0 :(得分:3)
执行此操作的一种方法是将所有寄存器的状态表示为从寄存器编号到存储的自然编号的函数。我们可以定义一个由自然数索引的寄存器类型,如下所示:
Inductive register : Type :=
R : nat -> register.
这不是严格必要的,但是为寄存器设置单独的类型可以防止寄存器与它们存储的自然数之间的混淆。然后状态只是从寄存器到nat的函数,在空状态下,我们可以认为每个寄存器都保持零值。
Definition state := register -> nat.
Definition empty_state : state := fun _ => 0.
现在可以将赋值操作实现为一个函数,该函数接受一个状态并返回一个新状态,其中指定的寄存器采用新值。为了定义这个,我们需要证明一个快速定理,确定寄存器相等是可判定的:
Require Import Coq.Arith.EqNat.
Theorem eq_register_decide : forall r1 r2 : register, {r1 = r2} + {r1 <> r2}.
Proof.
intros r1 r2. destruct r1 as [n1]. destruct r2 as [n2].
destruct (eq_nat_decide n1 n2) as [Heq | Hneq].
(* Case 1: n1 = n2 *)
left. replace n2 with n1. reflexivity. apply eq_nat_eq. apply Heq.
(* Case 2: n1 <> n2 *)
right. intros contra. inversion contra.
apply Hneq. apply eq_eq_nat. apply H0.
Qed.
Definition assign (st : state) (k : register) (n : nat) : state :=
fun k' => if eq_register_decide k k' then n else st k'.
以下是一个显示此功能的示例。我们可以将值5分配给寄存器0并成功读回它:
Example assign_five_to_r0 : (assign empty_state (R 0) 5) (R 0) = 5.
Proof.
unfold assign. destruct (eq_register_decide (R 0) (R 0)).
reflexivity. exfalso. apply n. reflexivity.
Qed.
此代码的灵感来自Pierce等人在Software Foundations的Imp章节中定义的更新函数。在那里,他们解决了类似的问题,但使用&#34;变量&#34;而不是&#34;寄存器。&#34;