我是Isabelle/HOL的新手,仍然在研究鍛鍊練習。與此同時,我正在通過將這些證明技巧應用於組合詞的問題來鍛鍊。我觀察到一個非常不同的行爲(效率方面),在'價值'和'引理'之間。Isabelle/HOL:'simp'的證明是緩慢的,'value'是瞬時的
能解釋兩個命令之間的不同評估/搜索策略嗎?
有沒有一種方法可以在「引理」的證明中使用「價值」的速度?
當然,我在問,因爲我還沒有在文檔中找到答案(到目前爲止)。什麼是手冊,這種效率差異將被記錄和解釋?
下面是重現問題的最小源代碼。
theory SlowLemma
imports Main
begin
(* Alphabet for Motzkin words. *)
datatype alphabet = up | lv | dn
(* Keep the [...] notation for lists. *)
no_notation Cons (infixr "#" 65) and append (infixr "@" 65)
primrec count :: "'a ⇒ 'a list ⇒ nat" where
"count _ Nil = 0" |
"count s (Cons h q) = (if h = s then Suc (count s q) else count s q)"
(* prefix n l simply returns undefined if n > length l. *)
fun prefix :: "'a list ⇒ nat ⇒ 'a list" where
"prefix _ 0 = []" |
"prefix (Cons h q) (Suc n) = Cons h (prefix q n)"
definition M_ex_7 :: "alphabet list" where
"M_ex_7 ≡ [lv, lv, up, up, lv, dn, dn]"
definition M_ex_19 :: "alphabet list" where
"M_ex_19 ≡ [lv, lv, up, up, lv, up, lv, dn, lv, dn, lv, up, dn, dn, lv, up, dn, lv, lv]"
fun height :: "alphabet list ⇒ int" where
"height w = (int (count up w + count up w)) - (int (count dn w + count dn w))"
primrec is_pre_M :: "alphabet list ⇒ nat ⇒ bool" where
"is_pre_M _ (0 :: nat) = True"
| "is_pre_M w (Suc n) = (let w' = prefix w (Suc n) in is_pre_M w' n ∧ height w' ≥ 0)"
fun is_M :: "alphabet list ⇒ bool" where
"is_M w = (is_pre_M w (length w) ∧ height w = 0)"
(* These two calls to value are fast. *)
value "is_M M_ex_7"
value "is_M M_ex_19"
(* This first lemma goes fast. *)
lemma is_M_M_ex_7: "is_M M_ex_7"
by (simp add: M_ex_7_def)
(* This second lemma takes five minutes. *)
lemma is_M_M_ex_19: "is_M M_ex_19"
by (simp add: M_ex_19_def)
end
code_simp'和''之間的差異simp'是由於simproc'let_simp',其運行時間在'嵌套深度指數來反映意見let'。如果將'Let_def'添加到簡化器的simpset中,'simp'在很短的時間內也可以證明'is_M_M_ex_19'。 –
我忽略了展開'let'構造的需要。另一個解決方案(更多地解釋了這種現象)是用''is_pre_M w(Suc n)=(is_pre_M(前綴w(Suc n))n∧height(前綴)替換我最初定義'is_pre_M'的第二種情況w(Suc n))≥0)「'。 –
@AndreasLochbihler我根據您的評論更新了我的答案。 – larsrh