我试图在Isabelle / HOL中证明交换性是一种自定义的add
函数。我设法证明了相关性,但我坚持这个。
add
的定义:
fun add :: "nat ⇒ nat ⇒ nat" where
"add 0 n = n" |
"add (Suc m) n = Suc(add m n)"
结社证明:
lemma add_Associative: "add(add k m) z = add k (add m z)"
apply(induction k)
apply(auto)
done
交换性证明:
theorem add_commutativity: "add k m = add m k"
apply(induction k)
apply(induction m)
apply(auto)
我有以下目标:
goal (3 subgoals):
1. add 0 0 = add 0 0
2. ⋀m. add 0 m = add m 0 ⟹
add 0 (Suc m) = add (Suc m) 0
3. ⋀k. add k m = add m k ⟹
add (Suc k) m = add m (Suc k)
应用自动后,我只剩下subgoal 3:
3. ⋀k. add k m = add m k ⟹
add (Suc k) m = add m (Suc k)
编辑:我不是在寻找答案,而是朝着正确的方向努力。这些是一本名为Concrete Sementics的书的练习。
答案 0 :(得分:8)
我建议尽可能将证明模块化(即证明中间的引理,以后将有助于解决交换性证明)。为此,在应用完全自动化之前(如induct
),冥想apply (auto)
引入的子目标往往更具信息性。
lemma add_comm:
"add k m = add m k"
apply (induct k)
此时子目标是:
goal (2 subgoals):
1. add 0 m = add m 0
2. ⋀k. add k m = add m k ⟹ add (Suc k) m = add m (Suc k)
让我们分别看一下。
使用add
的定义,我们只能简化左侧,
即add 0 m = m
。那么问题仍然是如何证明add m 0 = m
。
你这样做是主要证据的一部分。我认为它会增加
可读性证明以下单独的引理
lemma add_0 [simp]:
"add m 0 = m"
by (induct m) simp_all
并使用simp
将其添加到自动工具(例如auto
和[simp]
)。在此刻
第一个子目标可以通过simp
解决,只剩下第二个子目标。
应用add
的定义以及归纳假设(add k m = add m k
)后,我们必须证明Suc (add m k) = add m (Suc k)
。这看起来非常类似于add
的原始定义的第二个等式,只有交换的参数。 (从这个角度来看,我们必须证明第一个子目标与add
定义中的第一个等式有交换的论证。)现在,我建议尝试证明一般的引理add m (Suc n) = Suc (add m n)
为了继续。
答案 1 :(得分:2)
我在克里斯答案的评论中回答了RainyCats的问题:
" Isabelle如何证明"。我在Isar中手动和逐步地详细证明了add
的相关性。
通过k上的归纳手动获得相关性:
k
= 0
我们必须证明add (add 0 m) z = add 0 (add m z)
。
我们用add
:
add (add 0 m) z
⇢add m z
add 0 (add m z)
⇢add m z
然后通过=
的反身性来证明目标。
k
= Suc k'
add (add k' m) z = add k' (add m z)
。add (add (Suc k') m) z = add (Suc k') (add m z)
。我们用add
:
add (add (Suc k') m) z
⇢add (Suc (add k' m)) z
⇢Suc (add (add k' m) z)
add (Suc k') (add m z)
⇢Suc (add k' (add m z))
通过归纳假设:Suc (add (add k' m) z)
⇢Suc (add k' (add m z))
然后通过=
的反身性来证明目标。
在伊萨尔这个详细程度,这将给出:
lemma add_Associative: "add(add k m) z = add k (add m z)"
proof (induction k)
case 0
have "add (add 0 m) z = add m z" by (subst add.simps, intro refl)
moreover have "add 0 (add m z) = add m z" by (subst add.simps, intro refl)
ultimately show ?case by (elim ssubst, intro refl)
next
case (Suc k')
have "add (add (Suc k') m) z = add (Suc (add k' m)) z" by (subst add.simps, intro refl)
also have "… = Suc (add (add k' m) z)" by (subst add.simps, intro refl)
also have "… = Suc (add k' (add m z))" by (subst Suc, intro refl)
moreover have "add (Suc k') (add m z) = Suc (add k' (add m z))" by (subst add.simps, intro refl)
ultimately show ?case by (elim ssubst, intro refl)
qed
我已尽可能采取最小步骤,by ...
可以替换所有by simp
。