如何证明与使用Coq中的对更新变量相关的定理?

时间:2018-03-28 11:06:58

标签: coq

我定义变量和表达式的值如下:

Inductive id : Set := 
| Id : nat -> id.    

Theorem eq_id_dec :
  forall id1 id2 : id, {id1 = id2} + {id1 <> id2}.
Proof.
 intros id1 id2.
 destruct id1 as [n1]. destruct id2 as [n2].
 destruct (eq_nat_dec n1 n2) as [Heq | Hneq].
 - (* n1 = n2 *)
   left. rewrite Heq. reflexivity.
 - (* n1 <> n2 *)
   right. intros contra. inversion contra. apply Hneq. apply H0.
Defined.

Definition fvalue := id * nat.

Inductive aexp : Type := 
| ANum : nat -> aexp
| AId : id -> aexp
| APlus : aexp -> aexp -> aexp
| AMinus : aexp -> aexp -> aexp
| AMult : aexp -> aexp -> aexp.

然后我定义一个函数来更新变量的值:

Fixpoint fvalue_up (st : list fvalue) (e : id) (v : nat) :=
match st with
| nil => nil
| h :: st' =>
  if eq_id_dec (fst h) e then (e, v) :: st'
  else fvalue_up st' e v
end.

Definition fvalue_ids (st : list fvalue) :=
  map fst st.

Definition fvalue_update (st : list fvalue) (e : id) (v : nat) :=
  if beq_nat (count_occ eq_id_dec (fvalue_ids st) e) 0
  then (e, v) :: st
  else fvalue_up st e v.



Fixpoint get_fvalue (st : list fvalue) (e : id) (default : nat) :=
match st with
| nil => default
| h :: st' =>
  if eq_id_dec (fst h) e then snd h
  else get_fvalue st' e default
end.

Fixpoint daeval (st : list fvalue) (e : aexp) {struct e} : nat :=
match e with
| ANum n => n
| AId x => get_fvalue st x 0
| APlus a1 a2 => plus (daeval st a1) (daeval st a2)
| AMinus a1 a2  => minus (daeval st a1) (daeval st a2)
| AMult a1 a2 => mult (daeval st a1) (daeval st a2)
end.

现在我想证明以下定理,我认为这是正确的。

Theorem fvalue_update_same :
  forall (st : list fvalue) (x : id) (e : aexp) (f : aexp -> aexp),
  fvalue_update (fvalue_update st x (daeval st e)) x (daeval (fvalue_update st x (daeval st e)) (f (AId x))) =
  fvalue_update st x (daeval st (f e)).

例如,如果初始变量x = 1,我们首先分配x:= x + 1,然后我们分配x:= 2 * x,最终变量x = 4.它等于我们分配x:直接= 2 *(x + 1)。任何人都可以为这个定理提出一些建议吗?

1 个答案:

答案 0 :(得分:0)

你的定理几乎肯定是假的,有daeval的定义(我假设它用上下文来计算表达式)。原因是函数f可以区分原始表达式和AId x。我想你只想在语句中删除该函数(即使其成为身份函数)。

Fixpoint fvalue_lookup (st: list fvalue) (e:id) : nat :=
  match st with
  | nil => 0
  | (e', v) :: st' => if eq_id_dec e e' then v else fvalue_lookup st' e
  end.

Fixpoint daeval (st:list fvalue) (e:aexp) : nat :=
  match e with
  | ANum n => n
  | AId i => fvalue_lookup st i
  | APlus e1 e2 => daeval st e1 + daeval st e2
  | AMinus e1 e2 => daeval st e1 - daeval st e2
  | AMult e1 e2 => daeval st e1 - daeval st e2
  end.

Definition fvalue_update_same_statement st x e f :=
  fvalue_update (fvalue_update st x (daeval st e)) x (daeval (fvalue_update st x (daeval st e)) (f (AId x))) =
  fvalue_update st x (daeval st (f e)).

Example fvalue_update_same_contradiction :
  ~fvalue_update_same_statement
   [(Id 0, 0)]
   (Id 0)
   (ANum 0)
   (fun e => match e with
          | AId _ => ANum 0
          | ANum _ => ANum 1
          | _ => ANum 4
          end).
Proof.
  compute.
  (* [(Id 0, 0)] = [(Id 0, 1)] -> False *)
  congruence.
Qed.