I satarted to work with Isabelle a few weeks ago and it's hard to me to do some proves automatically. I've just use the rule "less_induct" to show a property on a list.
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
To do the automatic proof I think I have to write something like this:
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)
Can you help me?
Thank you!
Based upon your proof and my meagre knowledge of Spanish, I imagine your theory looks something like this:
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"
The automatic proof you suggested cannot work here, because when you write apply (cases xs)
, xs
is a variable that is universally quantified in the goal. If you want to do case distinction over such a variable, you should do an Isar proof (as you did before).
An easier approach requiring fewer auxiliary lemmas would be the following:
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
...and the proof is completely automatic:
lemma "cuenta (ordena xs) y = cuenta xs y"
by (induction xs rule: ordena.induct) (auto simp: cuenta_mejores_menores)
Note that I used the induction rule for the ordena
function. The induction on the list length that you did is more general, but that makes it more difficult to use automation. The rule ordena.induct
looks like this:
P [] ⟹
(⋀x xs.
P (menores x xs) ⟹
P (mejores x xs) ⟹
P (x # xs)) ⟹
P a0
That is precisely what you need here. Also, note that if you do want to do induction on list length, using the rule length_induct
is much easier than natural-number induction on the list length itself, which is what you did.
Also, a simpler definition of ordena
that does not require the auxiliary functions menores
and mejores
would be:
fun ordena :: "('a :: linorder) list ⇒ 'a list" where
"ordena [] = []"
| "ordena (x#xs) = ordena [y ← xs. y < x] @ [x] @ ordena [y ← xs. y ≥ x]"
Note that [y ← xs. y < x]
[y ← xs. y < x]
is simply syntactic sugar for filter (λy. y < x) xs
. Then you don't need cuenta_mejores_menores anymore and can use the following very general lemma on the interaction between cuenta
and filter
:
lemma cuenta_filter [simp]: "cuenta (filter P xs) y = (if P y then cuenta xs y else 0)"
by (induction xs) simp_all
and the proof goes through automatically again:
lemma "cuenta (ordena xs) y = cuenta xs y"
by (induction xs rule: ordena.induct) auto
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.