下面是一個簡單的理論寫在普通HOL:如何HOLCF證明清單的雙重逆轉並沒有改變它
theory ToyList
imports Main
begin
no_notation Nil ("[]") and Cons (infixr "#" 65) and append (infixr "@" 65)
hide_type list
hide_const rev
datatype 'a list = Nil ("[]") | Cons 'a "'a list" (infixr "#" 65)
primrec snoc :: "'a list => 'a => 'a list" (infixr "#>" 65)
where
"[] #> y = y # []" |
"(x # xs) #> y = x # (xs #> y)"
primrec rev :: "'a list => 'a list"
where
"rev [] = []" |
"rev (x # xs) = (rev xs) #> x"
lemma rev_snoc [simp]: "rev(xs #> y) = y # (rev xs)"
apply(induct_tac xs)
apply(auto)
done
theorem rev_rev [simp]: "rev(rev xs) = xs"
apply(induct_tac xs)
apply(auto)
done
end
snoc
是cons
相反。它將一個項目添加到列表的末尾。
我想通過HOLCF證明類似的引理。在第一階段,我只考慮嚴格的名單。我在HOLCF中聲明瞭嚴格的列表域。此外,我聲明瞭兩個遞歸函數:
ssnoc
- 追加到一個列表srev
結束的項目 - 反轉列表
前綴s
的意思是 「嚴格」。
theory Test
imports HOLCF
begin
domain 'a SList = SNil | SCons "'a" "'a SList"
fixrec ssnoc :: "'a SList → 'a → 'a SList"
where
"ssnoc ⋅ SNil ⋅ x = SCons ⋅ x ⋅ SNil" |
"ssnoc ⋅ ⊥ ⋅ x = ⊥" |
"x ≠ ⊥ ∧ xs ≠ ⊥ ⟹ ssnoc ⋅ (SCons ⋅ x ⋅ xs) ⋅ y = SCons ⋅ x ⋅ (ssnoc ⋅ xs ⋅ y)"
fixrec srev :: "'a SList → 'a SList"
where
"srev ⋅ ⊥ = ⊥" |
"srev ⋅ SNil = SNil" |
"x ≠ ⊥ ∧ xs ≠ ⊥ ⟹ srev ⋅ (SCons ⋅ x ⋅ xs) = ssnoc ⋅ (srev ⋅ xs) ⋅ x"
lemma srev_singleton [simp]:
"srev ⋅ (SCons ⋅ a ⋅ SNil) = SCons ⋅ a ⋅ SNil"
apply(induct)
apply(simp_all)
done
lemma srev_ssnoc [simp]:
"srev ⋅ (ssnoc ⋅ xs ⋅ a) = SCons ⋅ a ⋅ (srev ⋅ xs)"
apply(induct xs)
apply(simp_all)
done
lemma srev_srev [simp]:
"srev ⋅ (srev ⋅ xs) = xs"
apply(induct xs)
apply(simp_all)
done
end
我想證明列表的那個雙逆轉等於原始列表(srev_srev
引理)。我宣佈兩個輔助引理:
srev_singleton
- 單身名單的反向是原單列表srev_ssnoc
- 列表的逆轉等於從原來的名單追加逆轉的最後一個項目啓動列表原列表的其餘項目
但我不能證明任何引理。你能指出錯誤嗎?
爲什麼在函數定義中必須使用前提"x ≠ ⊥ ∧ xs ≠ ⊥"
?我爲什麼要明確聲明"srev ⋅ ⊥ = ⊥"
和"ssnoc ⋅ ⊥ ⋅ x = ⊥"
。我想在HOLCF默認情況下,如果任何參數未定義,函數都是未定義的。
感謝您的答案和文章的鏈接!但即使是嚴格的名單,我仍然無法證明這些引理。我認爲我誤解了一些微不足道的東西。我在這個問題中添加了用簡單HOL寫的引理句。他們很容易被證實。但似乎我需要一些額外的東西來證明他們在HOLCF中。 – Denis
@Denis:的確如此。看到我的更新;) – chris
這就是我需要的!所有這些與不同論點和案例分析中功能的嚴格性相關的東西現在對我來說都更加清晰。非常感謝! – Denis