Theory Small_Proof
section "Small Proofs"
theory Small_Proof
imports Common_Proof Small_Aux
begin
lemma step_size [simp]: "invar (small :: 'a small_state) ⟹ size (step small) = size small"
by(induction small rule: step_small_state.induct)(auto split: current.splits)
lemma step_size_new [simp]:
"invar (small :: 'a small_state) ⟹ size_new (step small) = size_new small"
by(induction small rule: step_small_state.induct)(auto split: current.splits)
lemma size_push [simp]: "invar small ⟹ size (push x small) = Suc (size small)"
by(induction x small rule: push.induct) (auto split: current.splits)
lemma size_new_push [simp]: "invar small ⟹ size_new (push x small) = Suc (size_new small)"
by(induction x small rule: push.induct) (auto split: current.splits)
lemma size_pop [simp]: "⟦invar small; 0 < size small; pop small = (x, small')⟧
⟹ Suc (size small') = size small"
proof(induction small rule: pop.induct)
case (1 state)
then show ?case
by(auto split: prod.splits)
next
case (2 current small auxS)
then show ?case
using Current_Proof.size_pop[of current]
by(induction current rule: Current.pop.induct) auto
next
case (3 current auxS big newS count)
then show ?case
using Current_Proof.size_pop[of current]
by(induction current rule: Current.pop.induct) auto
qed
lemma size_new_pop [simp]: "⟦invar small; 0 < size_new small; pop small = (x, small')⟧
⟹ Suc (size_new small') = size_new small"
proof(induction small rule: pop.induct)
case (1 state)
then show ?case
by(auto split: prod.splits)
next
case (2 current small auxS)
then show ?case
by(induction current rule: Current.pop.induct) auto
next
case (3 current auxS big newS count)
then show ?case
by(induction current rule: Current.pop.induct) auto
qed
lemma size_size_new: "⟦invar (small :: 'a small_state); 0 < size small⟧ ⟹ 0 < size_new small"
by(induction small)(auto simp: size_size_new)
lemma step_list_current [simp]: "invar small ⟹ list_current (step small) = list_current small"
by(induction small rule: step_small_state.induct)(auto split: current.splits)
lemma step_list_common [simp]:
"⟦small = Small3 common; invar small⟧ ⟹ list (step small) = list small"
by auto
lemma step_list_Small2 [simp]:
assumes
"small = (Small2 current aux big new count)"
"invar small"
shows
"list (step small) = list small"
proof -
have size_not_empty: "(0 < size big) = (¬ is_empty big)"
by (simp add: Stack_Proof.size_not_empty)
have "¬ is_empty big
⟹ rev (Stack_Aux.list (Stack.pop big)) @ [Stack.first big] = rev (Stack_Aux.list big)"
by(induction big rule: Stack.pop.induct) auto
with assms show ?thesis
using Stack_Proof.size_pop[of big] size_not_empty
by(auto simp: Stack_Proof.list_empty split: current.splits)
qed
lemma invar_step: "invar (small :: 'a small_state) ⟹ invar (step small)"
proof(induction small rule: step_small_state.induct)
case (1 state)
then show ?case
by(auto simp: invar_step)
next
case (2 current small aux)
then show ?case
proof(cases "is_empty small")
case True
with 2 show ?thesis
by auto
next
case False
with 2 have "rev (Stack_Aux.list small) @ aux =
rev (Stack_Aux.list (Stack.pop small)) @ Stack.first small # aux"
by(auto simp: rev_app_single Stack_Proof.list_not_empty)
with 2 show ?thesis
by(auto split: current.splits)
qed
next
case (3 current auxS big newS count)
then show ?case
proof(cases "is_empty big")
case True
then have big_size [simp]: "size big = 0"
by (simp add: Stack_Proof.size_empty)
with True 3 show ?thesis
proof(cases current)
case (Current extra added old remained)
with 3 True show ?thesis
proof(cases "remained ≤ count")
case True
with 3 Current show ?thesis
using Stack_Proof.size_empty[of big]
by auto
next
case False
with True 3 Current show ?thesis
by(auto)
qed
qed
next
case False
with 3 show ?thesis
using Stack_Proof.size_pop[of big]
by(auto simp: Stack_Proof.size_not_empty split: current.splits)
qed
qed
lemma invar_push: "invar small ⟹ invar (push x small)"
by(induction x small rule: push.induct)(auto simp: invar_push split: current.splits)
lemma invar_pop: "⟦
0 < size small;
invar small;
pop small = (x, small')
⟧ ⟹ invar small'"
proof(induction small arbitrary: x rule: pop.induct)
case (1 state)
then show ?case
by(auto simp: invar_pop split: prod.splits)
next
case (2 current small auxS)
then show ?case
proof(induction current rule: Current.pop.induct)
case (1 added old remained)
then show ?case
by(cases "size small < size old")
(auto simp: rev_take Suc_diff_le drop_Suc tl_drop)
next
case 2
then show ?case by auto
qed
next
case (3 current auxS big newS count)
then show ?case
by (induction current rule: Current.pop.induct)
(auto simp: rev_take Suc_diff_le drop_Suc tl_drop)
qed
lemma push_list_common [simp]: "small = Small3 common ⟹ list (push x small) = x # list small"
by auto
lemma push_list_current [simp]: "list_current (push x small) = x # list_current small"
by(induction x small rule: push.induct) auto
lemma pop_list_current [simp]: "⟦invar small; 0 < size small; Small.pop small = (x, small')⟧
⟹ x # list_current small' = list_current small"
proof(induction small arbitrary: x rule: pop.induct)
case (1 state)
then show ?case
by(auto simp: pop_list_current split: prod.splits)
next
case (2 current small auxS)
then have "invar current"
by(auto split: current.splits)
with 2 show ?case
by auto
next
case (3 current auxS big newS count)
then show ?case
proof(induction current rule: Current.pop.induct)
case (1 added old remained)
then have "¬is_empty old"
by(auto simp: Stack_Proof.size_not_empty)
with 1 show ?case
by(auto simp: rev_take drop_Suc drop_tl)
next
case 2
then show ?case
by auto
qed
qed
lemma list_current_size [simp]: "⟦0 < size small; list_current small = []; invar small⟧ ⟹ False"
proof(induction small)
case (Small1 current)
then have "invar current"
by(auto split: current.splits)
with Small1 show ?case
using Current_Proof.list_size
by auto
next
case Small2
then show ?case
by(auto split: current.splits)
next
case Small3
then show ?case
using list_current_size by auto
qed
lemma list_Small2 [simp]: "⟦
0 < size (Small2 current auxS big newS count);
invar (Small2 current auxS big newS count)
⟧ ⟹
fst (Current.pop current) # list (Small2 (drop_first current) auxS big newS count) =
list (Small2 current auxS big newS count)"
by(induction current rule: Current.pop.induct)
(auto simp: first_hd rev_take Suc_diff_le)
end