I have the following isabelle code below
theory sec24
imports Main
begin
datatype bdd = Leaf bool | Branch bdd bdd
primrec eval :: "(nat ⇒ bool) ⇒ nat ⇒ bdd ⇒ bool" where
"eval f n (Leaf x) = x" |
"eval f n (Branch left right) = (if f n then eval f (Suc n) right else eval f (Suc n) left)"
primrec bdd_unop :: "(bool ⇒ bool) ⇒ bdd ⇒ bdd" where
"bdd_unop f (Leaf x) = Leaf (f x)" |
"bdd_unop f (Branch left right) = Branch (bdd_unop f left) (bdd_unop f right)"
primrec bdd_binop :: "(bool ⇒ bool ⇒ bool) ⇒ bdd ⇒ bdd ⇒ bdd" where
"bdd_binop f (Leaf x) t2 = bdd_unop (f x) t2" |
"bdd_binop f (Branch left right) t2 = (case t2 of
Leaf x ⇒ Branch (bdd_binop f left t2) (bdd_binop f right t2)
| Branch left2 right2 ⇒ Branch (bdd_binop f left left2) (bdd_binop f right right2))"
theorem t1: "g (eval f n t) = eval f n (bdd_unop g t)"
apply (induct t arbitrary: n)
apply auto
done
lemma l1: "eval f n (bdd_unop ((=) (eval f n t)) t)"
apply (induct t arbitrary: n)
apply auto
done
lemma l2: "bdd_binop g t (Leaf y) = bdd_unop (λ x. g x y) t"
apply (induct t)
apply auto
done
lemma l3: "If True (eval e (Suc i) b12) = (λ _. (eval e (Suc i) b12))"
apply auto
done
theorem t2: "∀ i b2. eval e i (bdd_binop f b1 b2) = f (eval e i b1) (eval e i b2)"
apply (induct b1)
apply (auto simp: t1 l1)
apply (case_tac b2)
apply (auto simp: If_def l2)
apply (case_tac "e i")
apply (auto simp: l3)
using t1 apply auto
apply (case_tac "e i")
by (auto simp: the_equality)
end
Context: I'm working through some exercises on binary decision trees and I saw that the solution for theorem t2
was much simpler than mine, but it doesn't work, possibly due to changes in isabelle since 2012.
I would like to know if I can optimise the proof of theorem t2
such that less lines are used, and less time is taken to process each application.
As for my thought process, I mainly observed each subgoal in order to define each lemma above, then used sledgehammer in places where I believed the goal could be intuitively achieved without introducing additional lemmas. I then simplified the sledgehammer lines. Could I please also have some advice on this too?
theorem t2: "eval e i (bdd_binop f b1 b2) = f (eval e i b1) (eval e i b2)"
apply (induct b1 arbitrary: i b2)
using t1 apply (auto simp: l1 split: bdd.splits if_splits)
done
Thanks Mathias. Since I haven't seen the split argument in the auto tactic yet, could you lmk how it works?
lmao it's in prog-prove, please disregard. Sorry. Will ask further if necessary.
theorem t2: "eval e i (bdd_binop f b1 b2) = f (eval e i b1) (eval e i b2)"
by (induct b1 arbitrary: i b2)
(use t1 in ‹auto simp: l1 split: bdd.splits if_splits›
but it is a bit of magic
Turns out you don't need if_splits
theorem t2'': "eval e i (bdd_binop f b1 b2) = f (eval e i b1) (eval e i b2)"
apply (induct b1 arbitrary: i b2)
using t1 apply (auto simp: l1 split: bdd.splits)
done
very interesting.
Last updated: Dec 21 2024 at 16:20 UTC