[英]Doing this proof automatically on Isabelle
幾周前,我與Isabelle一起工作,我很難自動做一些證明。 我只是使用規則“ less_induct”在列表上顯示屬性。
theorem cuenta_ordena_1:
"cuenta (ordena xs) y = cuenta xs y"
proof(induct "length xs" arbitrary: xs rule: less_induct)
case less
show ?case
proof(cases xs)
assume "xs=[]"
then show ?thesis by simp
next
fix a list
assume "xs=a#list"
have "length(menores a list)<Suc(length list)" by simp
also have "... = length (a#list)" by simp
also have "... = length (xs)" using `xs=a#list` by simp
finally have 1:"length (menores a list)< length xs" by simp
have "length(mayores a list)<Suc(length list)" by simp
also have "... = length (a#list)" by simp
also have "... = length (xs)" using `xs=a#list` by simp
finally have 2:"length (mayores a list)< length xs" by simp
have " cuenta (ordena xs) y= cuenta (ordena (a#list)) y" using `xs=a#list` by simp
also have "...= cuenta ((ordena (menores a list)) @ (a # (ordena (mayores a list)))) y " by simp
also have "... = cuenta (ordena (menores a list)) y + cuenta (a # (ordena (mayores a list))) y " by (rule cuenta_append)
also have "... = cuenta (menores a list) y + cuenta (a # (ordena (mayores a list))) y " using less 1 by simp
finally have 3:"cuenta(ordena xs) y = cuenta (menores a list) y + cuenta (a # (ordena (mayores a list))) y" by simp
also have 4:"... = cuenta xs y"
proof(cases "a=y")
case False
then have "cuenta (menores a list) y + cuenta (a # (ordena (mayores a list))) y
= cuenta (menores a list) y + cuenta (ordena (mayores a list)) y " by simp
also have "... = cuenta (menores a list) y + cuenta (mayores a list) y " using less 2 by simp
also have "... = cuenta xs y"
proof (cases "y<a")
case True
hence "cuenta (menores a list) y + cuenta (mayores a list) y
= cuenta list y + cuenta (mayores a list) y" by (simp add: cuenta_menores)
also have "... = cuenta list y" using "True" by (simp add: cuenta_mayores)
also have "... = cuenta (a#list) y" using "False" by simp
finally show ?thesis using `xs=a#list` by simp
next
case False
hence "cuenta (menores a list) y + cuenta (mayores a list) y
= cuenta (mayores a list) y" by (simp add: cuenta_menores)
also have "... = cuenta list y" using "False" by (simp add: cuenta_mayores)
also have "... = cuenta (a#list) y" using `¬(a=y)` by simp
finally show ?thesis using `xs=a#list` by simp
qed
finally show ?thesis by simp
next
case True
hence "¬(y<a)" by simp
have "cuenta (menores a list) y + cuenta (a # (ordena (mayores a list))) y
= cuenta (menores a list) y + Suc(cuenta (ordena (mayores a list)) y) " using "True" by simp
also have "... = cuenta (menores a list) y + Suc(cuenta (mayores a list) y) " using less 2 by simp
also have "... = Suc(cuenta(mayores a list) y)" using `¬(y<a)` by (simp add: cuenta_menores)
also have "... = Suc(cuenta list y)" using `¬(y<a)` by (simp add: cuenta_mayores)
also have "... = cuenta (a#list) y" using "True" by simp
finally show ?thesis using `xs=a#list` by simp
qed
finally show ?thesis using 3 4 by simp
qed
qed
為了做自動證明,我想我必須寫這樣的東西:
theorem cuenta_ordena:
"cuenta (ordena xs) y = cuenta xs y"
apply (induction "length xs" arbitrary: xs rule: less_induct)
apply (cases xs)
apply (auto simp add: cuenta_append cuenta_menores cuenta_mayores)
你能幫助我嗎?
謝謝!
根據您的證明和我對西班牙語的微薄知識,我認為您的理論看起來像這樣:
fun mejores :: "('a :: linorder) ⇒ 'a list ⇒ 'a list" where
"mejores y [] = []"
| "mejores y (x#xs) = (if x ≥ y then [x] else []) @ mejores y xs"
fun menores :: "('a :: linorder) ⇒ 'a list ⇒ 'a list" where
"menores y [] = []"
| "menores y (x#xs) = (if x < y then [x] else []) @ menores y xs"
lemma length_mejores [simp]: "length (mejores y xs) ≤ length xs"
by (induction xs) simp_all
lemma length_menores [simp]: "length (menores y xs) ≤ length xs"
by (induction xs) simp_all
fun ordena where
"ordena [] = []"
| "ordena (x#xs) = ordena (menores x xs) @ [x] @ ordena (mejores x xs)"
fun cuenta :: "_ list ⇒ _ ⇒ nat" where
"cuenta [] y = 0"
| "cuenta (x#xs) y = (if y = x then 1 else 0) + cuenta xs y"
您建議的自動證明在這里無法使用,因為在編寫apply (cases xs)
, xs
是在目標中普遍量化的變量。 如果要對此類變量進行大小寫區分,則應進行Isar證明(如前所述)。
需要較少輔助引理的簡單方法如下:
lemma cuenta_append [simp]: "cuenta (xs @ ys) y = cuenta xs y + cuenta ys y"
by (induction xs) simp_all
lemma cuenta_mejores_menores: "cuenta (menores x xs) y + cuenta (mejores x xs) y = cuenta xs y"
by (induction xs) auto
...並且證明是完全自動的:
lemma "cuenta (ordena xs) y = cuenta xs y"
by (induction xs rule: ordena.induct) (auto simp: cuenta_mejores_menores)
請注意,我將歸納規則用於ordena
函數。 您所做的列表長度歸納法比較籠統,但這使使用自動化變得更加困難。 規則ordena.induct
看起來像這樣:
P [] ⟹
(⋀x xs.
P (menores x xs) ⟹
P (mejores x xs) ⟹
P (x # xs)) ⟹
P a0
這正是您所需要的。 另外,請注意,如果您確實想對列表長度進行歸納,則使用規則length_induct
比對列表長度本身進行自然數歸納要容易得多,這就是您所做的。
另外,不需要輔助功能menores
和mejores
的ordena
的更簡單定義是:
fun ordena :: "('a :: linorder) list ⇒ 'a list" where
"ordena [] = []"
| "ordena (x#xs) = ordena [y ← xs. y < x] @ [x] @ ordena [y ← xs. y ≥ x]"
注意[y ← xs. y < x]
[y ← xs. y < x]
只是filter (λy. y < x) xs
語法糖。 然后,您不再需要cuenta_mejores_menores,並且可以在cuenta
和filter
之間的交互上使用以下非常一般的引理:
lemma cuenta_filter [simp]: "cuenta (filter P xs) y = (if P y then cuenta xs y else 0)"
by (induction xs) simp_all
證明又自動通過:
lemma "cuenta (ordena xs) y = cuenta xs y"
by (induction xs rule: ordena.induct) auto
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.