Theory Stack_Proof
section "Stack Proofs"
theory Stack_Proof
imports Stack_Aux RTD_Util
begin
lemma push_list [simp]: "list (push x stack) = x # list stack"
by(cases stack) auto
lemma pop_list [simp]: "list (pop stack) = tl (list stack)"
by(induction stack rule: pop.induct) auto
lemma first_list [simp]: "¬ is_empty stack ⟹ first stack = hd (list stack)"
by(induction stack rule: first.induct) auto
lemma list_empty: "list stack = [] ⟷ is_empty stack"
by(induction stack rule: is_empty_stack.induct) auto
lemma list_not_empty: "list stack ≠ [] ⟷ ¬ is_empty stack"
by(induction stack rule: is_empty_stack.induct) auto
lemma list_empty_2 [simp]: "⟦list stack ≠ []; is_empty stack⟧ ⟹ False"
by (simp add: list_empty)
lemma list_not_empty_2 [simp]:"⟦list stack = []; ¬ is_empty stack⟧ ⟹ False"
by (simp add: list_empty)
lemma list_empty_size: "list stack = [] ⟷ size stack = 0"
by(induction stack) auto
lemma list_not_empty_size:"list stack ≠ [] ⟷ 0 < size stack"
by(induction stack) auto
lemma list_empty_size_2 [simp]: "⟦list stack ≠ []; size stack = 0⟧ ⟹ False"
by (simp add: list_empty_size)
lemma list_not_empty_size_2 [simp]:"⟦list stack = []; 0 < size stack⟧ ⟹ False"
by (simp add: list_empty_size)
lemma size_push [simp]: "size (push x stack) = Suc (size stack)"
by(cases stack) auto
lemma size_pop [simp]: "size (pop stack) = size stack - Suc 0"
by(induction stack rule: pop.induct) auto
lemma size_empty: "size (stack :: 'a stack) = 0 ⟷ is_empty stack"
by(induction stack rule: is_empty_stack.induct) auto
lemma size_not_empty: "size (stack :: 'a stack) > 0 ⟷ ¬ is_empty stack"
by(induction stack rule: is_empty_stack.induct) auto
lemma size_empty_2[simp]: "⟦size (stack :: 'a stack) = 0; ¬is_empty stack⟧ ⟹ False"
by (simp add: size_empty)
lemma size_not_empty_2[simp]: "⟦0 < size (stack :: 'a stack); is_empty stack⟧ ⟹ False"
by (simp add: size_not_empty)
lemma size_list_length [simp]: "length (list stack) = size stack"
by(cases stack) auto
lemma first_pop [simp]: "¬ is_empty stack ⟹ first stack # list (pop stack) = list stack"
by(induction stack rule: pop.induct) auto
lemma push_not_empty [simp]: "⟦¬ is_empty stack; is_empty (push x stack)⟧ ⟹ False"
by(induction x stack rule: push.induct) auto
lemma pop_list_length [simp]: "¬ is_empty stack
⟹ Suc (length (list (pop stack))) = length (list stack)"
by(induction stack rule: pop.induct) auto
lemma first_take: "¬is_empty stack ⟹ [first stack] = take 1 (list stack)"
by (simp add: list_empty)
lemma first_take_tl [simp]: "0 < size big
⟹ (first big # take count (tl (list big))) = take (Suc count) (list big)"
by(induction big rule: Stack.first.induct) auto
lemma first_take_pop [simp]: "⟦¬is_empty stack; 0 < x⟧
⟹ first stack # take (x - Suc 0) (list (pop stack)) = take x (list stack)"
by(induction stack rule: pop.induct) (auto simp: take_Cons')
lemma [simp]: "first (Stack [] []) = undefined"
by (meson first.elims list.distinct(1) stack.inject)
lemma first_hd: "first stack = hd (list stack)"
by(induction stack rule: first.induct)(auto simp: hd_def)
lemma pop_tl [simp]: "list (pop stack) = tl (list stack)"
by(induction stack rule: pop.induct) auto
lemma pop_drop: "list (pop stack) = drop 1 (list stack)"
by (simp add: drop_Suc)
lemma popN_drop [simp]: "list ((pop ^^ n) stack) = drop n (list stack)"
by(induction n)(auto simp: drop_Suc tl_drop)
lemma popN_size [simp]: "size ((pop ^^ n) stack) = (size stack) - n"
by(induction n) auto
lemma take_first: "⟦0 < size s1; 0 < size s2; take (size s1) (list s2) = take (size s2) (list s1)⟧
⟹ first s1 = first s2"
by(induction s1 rule: first.induct; induction s2 rule: first.induct) auto
end