我定义变量和表达式的值如下:
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)。任何人都可以为这个定理提出一些建议吗?
答案 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.