我在下面有一个证明,还有三个子目标要做。证明是关于用这里演示的简单算术语言优化 away plus 0
( ) 的正确性。是“算术表达式”并且是“算术评估”。optimize_0plus
aexp
aeval
3 subgoal
a1 : aexp
a2 : aexp
IHa1 : aeval (optimize_0plus a1) = aeval a1
IHa2 : aeval (optimize_0plus a2) = aeval a2
______________________________________(1/3)
aeval (optimize_0plus (APlus a1 a2)) = aeval (APlus a1 a2)
,其中optimize_0plus
是:
Fixpoint optimize_0plus (a:aexp) : aexp :=
match a with
| ANum n =>
ANum n
| APlus (ANum 0) e2 =>
optimize_0plus e2
| APlus e1 e2 =>
APlus (optimize_0plus e1) (optimize_0plus e2)
| AMinus e1 e2 =>
AMinus (optimize_0plus e1) (optimize_0plus e2)
| AMult e1 e2 =>
AMult (optimize_0plus e1) (optimize_0plus e2)
end.
我的作战计划是应用optimize_0plus
在当前子目标的 LHS 中,并获得:
aeval (APlus (optimize_0plus a1) (optimize_0plus a2)) = aeval (APlus a1 a2)
(但我不知道如何在 Coq 中做到这一点)。
然后,通过 some simpl
,得到:
(aeval (optimize_0plus a1)) + (aeval (optimize_0plus a2)) = (aeval a1) + (aeval a2)
并应用归纳假设IHa1
并IHa2
完成证明。
我的问题是:
我如何告诉 Coq 只应用optimize_0plus
一次的定义,并且不做多也不做少?
我试过simpl optimize_0plus
了,但它给出了一个很长的match
陈述,这似乎做得太多了。而且我不喜欢rewrite
每次都使用这种策略来建立引理,因为这种计算恰好是纸笔的一步。
笔记:
1.这与我之前的问题有关,但那里关于使用的答案simpl XXX
似乎在这里不起作用。这似乎是一个更复杂的案例。
2.原始网站提供了有效的证明。但是那里的证明似乎比必要的复杂,因为它开始对条款a1
等进行案例分析。
Case "APlus". destruct a1.
SCase "a1 = ANum n". destruct n.
SSCase "n = 0". simpl. apply IHa2.
SSCase "n ≠ 0". simpl. rewrite IHa2. reflexivity.
SCase "a1 = APlus a1_1 a1_2".
simpl. simpl in IHa1. rewrite IHa1.
rewrite IHa2. reflexivity.
SCase "a1 = AMinus a1_1 a1_2".
simpl. simpl in IHa1. rewrite IHa1.
rewrite IHa2. reflexivity.
SCase "a1 = AMult a1_1 a1_2".
simpl. simpl in IHa1. rewrite IHa1.
rewrite IHa2. reflexivity.
所以,我关心的不是真正证明这个简单的定理,而是如何像在纸上一样直观地证明这一点。
- 更新 -
感谢@gallais,我原来的计划是不正确的,因为可以改变
aeval (optimize_0plus (APlus a1 a2))
至
aeval (APlus (optimize_0plus a1) (optimize_0plus a2))
仅适用于a1
is not的情况ANum 0
。案件须按注 2 所引之课程网站0
另行处理。destruct a1.
但是,对于下面列出的其他情况,我仍然有同样的问题,我认为我的原始计划应该可行:
5 subgoal
SCase := "a1 = APlus a1_1 a1_2" : String.string
Case := "APlus" : String.string
a1_1 : aexp
a1_2 : aexp
a2 : aexp
IHa1 : aeval (optimize_0plus (APlus a1_1 a1_2)) = aeval (APlus a1_1 a1_2)
IHa2 : aeval (optimize_0plus a2) = aeval a2
______________________________________(1/5)
aeval (optimize_0plus (APlus (APlus a1_1 a1_2) a2)) =
aeval (APlus (APlus a1_1 a1_2) a2)
...
______________________________________(5/5)
aeval (optimize_0plus (AMult a1 a2)) = aeval (AMult a1 a2)
对于这 5 种情况中的每一种,似乎一个应用程序(beta
减少??)optimize_0plus
应该允许我们改变例如(for AMinus
)
aeval (optimize_0plus (AMinus a1 a2))
至
aeval (AMinus (optimize_0plus a1) (optimize_0plus a2))
, 正确的?
如果是这样,我该如何做这个一步减少?
注意:我试过
Eval cbv beta in (aeval (optimize_0plus (AMinus a1 a2))).
而且我什至无法得到aeval (AMinus (optimize_0plus a1) (optimize_0plus a2))
我想Eval
在证明中使用的。