diff --git a/thys/Real_Time_Deque/Big_Aux.thy b/thys/Real_Time_Deque/Big_Aux.thy --- a/thys/Real_Time_Deque/Big_Aux.thy +++ b/thys/Real_Time_Deque/Big_Aux.thy @@ -1,73 +1,72 @@ theory Big_Aux imports Big Common_Aux begin text \\<^noindent> Functions: \<^descr> \size_new\: Returns the size that the deque end will have after the rebalancing is finished. \<^descr> \size\: Minimum of \size_new\ and the number of elements contained in the current state. \<^descr> \remaining_steps\: Returns how many steps are left until the rebalancing is finished. \<^descr> \list\: List abstraction of the elements which this end will contain after the rebalancing is finished \<^descr> \list_current\: List abstraction of the elements currently in this deque end.\ fun list :: "'a big_state \ 'a list" where "list (Big2 common) = Common_Aux.list common" | "list (Big1 (Current extra _ _ remained) big aux count) = ( let reversed = take_rev count (Stack_Aux.list big) @ aux in extra @ (take_rev remained reversed) )" fun list_current :: "'a big_state \ 'a list" where "list_current (Big2 common) = Common_Aux.list_current common" | "list_current (Big1 current _ _ _) = Current_Aux.list current" instantiation big_state ::(type) invar begin fun invar_big_state :: "'a big_state \ bool" where "invar (Big2 state) \ invar state" | "invar (Big1 current big aux count) \ ( case current of Current extra added old remained \ invar current - \ List.length aux \ remained - count - + \ remained \ length aux + count \ count \ size big \ Stack_Aux.list old = rev (take (size old) ((rev (Stack_Aux.list big)) @ aux)) \ take remained (Stack_Aux.list old) = rev (take remained (take_rev count (Stack_Aux.list big) @ aux)) )" instance.. end instantiation big_state ::(type) size begin fun size_big_state :: "'a big_state \ nat" where "size (Big2 state) = size state" | "size (Big1 current _ _ _) = min (size current) (size_new current)" instance.. end instantiation big_state ::(type) size_new begin fun size_new_big_state :: "'a big_state \ nat" where "size_new (Big2 state) = size_new state" | "size_new (Big1 current _ _ _) = size_new current" instance.. end instantiation big_state ::(type) remaining_steps begin fun remaining_steps_big_state :: "'a big_state \ nat" where "remaining_steps (Big2 state) = remaining_steps state" | "remaining_steps (Big1 (Current _ _ _ remaining) _ _ count) = count + remaining + 1" instance.. end end diff --git a/thys/Real_Time_Deque/Big_Proof.thy b/thys/Real_Time_Deque/Big_Proof.thy --- a/thys/Real_Time_Deque/Big_Proof.thy +++ b/thys/Real_Time_Deque/Big_Proof.thy @@ -1,324 +1,324 @@ section "Big Proofs" theory Big_Proof imports Big_Aux Common_Proof begin lemma step_list [simp]: "invar big \ list (step big) = list big" proof(induction big rule: step_big_state.induct) case 1 then show ?case by auto next case 2 then show ?case by(auto split: current.splits) next case 3 then show ?case by(auto simp: rev_take take_drop drop_Suc tl_take rev_drop split: current.splits) qed lemma step_list_current [simp]: "invar big \ list_current (step big) = list_current big" by(induction big rule: step_big_state.induct)(auto split: current.splits) lemma push_list [simp]: "list (push x big) = x # list big" proof(induction x big rule: push.induct) case (1 x state) then show ?case by auto next case (2 x current big aux count) then show ?case by(induction x current rule: Current.push.induct) auto qed lemma list_Big1: "\ 0 < size (Big1 current big aux count); invar (Big1 current big aux count) \ \ first current # list (Big1 (drop_first current) big aux count) = list (Big1 current big aux count)" proof(induction current rule: Current.pop.induct) case (1 added old remained) then have [simp]: "remained - Suc 0 < length (take_rev count (Stack_Aux.list big) @ aux)" by(auto simp: le_diff_conv) (* TODO: *) then have " \0 < size old; 0 < remained; added = 0; remained - count \ length aux; count \ size big; Stack_Aux.list old = rev (take (size old - size big) aux) @ rev (take (size old) (rev (Stack_Aux.list big))); take remained (rev (take (size old - size big) aux)) @ take (remained - min (length aux) (size old - size big)) (rev (take (size old) (rev (Stack_Aux.list big)))) = rev (take (remained - count) aux) @ rev (take remained (rev (take count (Stack_Aux.list big))))\ \ hd (rev (take (size old - size big) aux) @ rev (take (size old) (rev (Stack_Aux.list big)))) = (rev (take count (Stack_Aux.list big)) @ aux) ! (remained - Suc 0)" by (smt (verit) Suc_pred hd_drop_conv_nth hd_rev hd_take last_snoc length_rev length_take min.absorb2 rev_append take_rev_def size_list_length take_append take_hd_drop) with 1 have [simp]: "Stack.first old = (take_rev count (Stack_Aux.list big) @ aux) ! (remained - Suc 0)" by(auto simp: take_hd_drop first_hd) from 1 show ?case using take_rev_nth[of "remained - Suc 0" "take_rev count (Stack_Aux.list big) @ aux" "Stack.first old" "[]" ] by auto next case 2 then show ?case by auto qed lemma size_list [simp]: "\0 < size big; invar big; list big = []\ \ False" proof(induction big rule: list.induct) case 1 then show ?case using list_size by auto next case 2 then show ?case by (metis list.distinct(1) list_Big1) qed lemma pop_list [simp]: "\0 < size big; invar big; Big.pop big = (x, big')\ \ x # list big' = list big" proof(induction big arbitrary: x rule: list.induct) case 1 then show ?case by(auto split: prod.splits) next case 2 then show ?case by (metis Big.pop.simps(2) list_Big1 prod.inject) qed lemma pop_list_tl: "\0 < size big; invar big; pop big = (x, big')\ \ list big' = tl (list big)" using pop_list cons_tl[of x "list big'" "list big"] by force (* TODO: *) lemma invar_step: "invar (big :: 'a big_state) \ invar (step big)" proof(induction big rule: step_big_state.induct) case 1 then show ?case by(auto simp: invar_step) next case (2 current big aux) then obtain extra old remained where current: "current = Current extra (length extra) old remained" by(auto split: current.splits) (* TODO: *) with 2 have "\ current = Current extra (length extra) old remained; remained \ length aux; Stack_Aux.list old = rev (take (size old - size big) aux) @ rev (take (size old) (rev (Stack_Aux.list big))); take remained (rev (take (size old - size big) aux)) @ take (remained - min (length aux) (size old - size big)) (rev (take (size old) (rev (Stack_Aux.list big)))) = rev (take remained aux)\ \ remained \ size old" by(metis length_rev length_take min.absorb_iff2 size_list_length take_append) with 2 current have "remained - size old = 0" by auto with current 2 show ?case by(auto simp: take_rev_drop drop_rev) next case (3 current big aux count) then have "0 < size big" by(auto split: current.splits) then have big_not_empty: "Stack_Aux.list big \ []" by(auto simp: Stack_Proof.size_not_empty Stack_Proof.list_not_empty) with 3 have a: " rev (Stack_Aux.list big) @ aux = rev (Stack_Aux.list (Stack.pop big)) @ Stack.first big # aux" by(auto simp: rev_tl_hd first_hd split: current.splits) from 3 have "0 < size big" by(auto split: current.splits) from 3 big_not_empty have " take_rev (Suc count) (Stack_Aux.list big) @ aux = take_rev count (Stack_Aux.list (Stack.pop big)) @ (Stack.first big # aux)" using take_rev_tl_hd[of "Suc count" "Stack_Aux.list big" aux] by(auto simp: Stack_Proof.list_not_empty split: current.splits) with 3 a show ?case by(auto split: current.splits) qed lemma invar_push: "invar big \ invar (push x big)" by(induction x big rule: push.induct)(auto simp: invar_push split: current.splits) (* TODO: *) lemma invar_pop: "\ 0 < size big; invar big; pop big = (x, big') \ \ invar big'" proof(induction big arbitrary: x rule: pop.induct) case (1 state) then show ?case by(auto simp: invar_pop split: prod.splits) next case (2 current big aux count) then show ?case proof(induction current rule: Current.pop.induct) case (1 added old remained) have linarith: "\x y z. x - y \ z \ x - (Suc y) \ z" by linarith have a: " \remained \ count + length aux; 0 < remained; added = 0; x = Stack.first old; big' = Big1 (Current [] 0 (Stack.pop old) (remained - Suc 0)) big aux count; count \ size big; Stack_Aux.list old = rev aux @ Stack_Aux.list big; take remained (rev aux) @ take (remained - length aux) (Stack_Aux.list big) = drop (count + length aux - remained) (rev aux) @ drop (count - remained) (take count (Stack_Aux.list big)); \ size old \ length aux + size big\ \ tl (rev aux @ Stack_Aux.list big) = rev aux @ Stack_Aux.list big" by (metis le_refl length_append length_rev size_list_length) have b: "\remained \ length (take_rev count (Stack_Aux.list big) @ aux); 0 < size old; 0 < remained; added = 0; x = Stack.first old; big' = Big1 (Current [] 0 (Stack.pop old) (remained - Suc 0)) big aux count; remained - count \ length aux; count \ size big; Stack_Aux.list old = drop (length aux - (size old - size big)) (rev aux) @ drop (size big - size old) (Stack_Aux.list big); take remained (drop (length aux - (size old - size big)) (rev aux)) @ take (remained + (length aux - (size old - size big)) - length aux) (drop (size big - size old) (Stack_Aux.list big)) = drop (length (take_rev count (Stack_Aux.list big) @ aux) - remained) (rev (take_rev count (Stack_Aux.list big) @ aux))\ \ tl (drop (length aux - (size old - size big)) (rev aux) @ drop (size big - size old) (Stack_Aux.list big)) = drop (length aux - (size old - Suc (size big))) (rev aux) @ drop (Suc (size big) - size old) (Stack_Aux.list big)" apply(cases "size old - size big \ length aux"; cases "size old \ size big") by(auto simp: tl_drop_2 Suc_diff_le le_diff_conv le_refl a) from 1 have "remained \ length (take_rev count (Stack_Aux.list big) @ aux)" by(auto) with 1 show ?case apply(auto simp: rev_take take_tl drop_Suc Suc_diff_le tl_drop linarith simp del: take_rev_def) using b - apply (metis \remained \ length (take_rev count (Stack_Aux.list big) @ aux)\ rev_append rev_take take_append) + apply (metis \remained \ length (take_rev count (Stack_Aux.list big) @ aux)\ le_diff_conv rev_append rev_take take_append) by (smt (verit, del_insts) Nat.diff_cancel tl_append_if Suc_diff_le append_self_conv2 diff_add_inverse diff_diff_cancel diff_is_0_eq diff_le_mono drop_eq_Nil2 length_rev nle_le not_less_eq_eq plus_1_eq_Suc tl_drop_2) next case (2 x xs added old remained) then show ?case by auto qed qed lemma push_list_current [simp]: "list_current (push x big) = x # list_current big" by(induction x big rule: push.induct) auto lemma pop_list_current [simp]: "\invar big; 0 < size big; Big.pop big = (x, big')\ \ x # list_current big' = list_current big" proof(induction big arbitrary: x rule: pop.induct) case (1 state) then show ?case by(auto simp: pop_list_current split: prod.splits) next case (2 current big aux count) then show ?case proof(induction current rule: Current.pop.induct) case (1 added old remained) then have "rev (take (size old - size big) aux) @ rev (take (size old) (rev (Stack_Aux.list big))) \ []" using order_less_le_trans[of 0 "size old" "size big"] order_less_le_trans[of 0 count "size big"] by(auto simp: Stack_Proof.size_not_empty Stack_Proof.list_not_empty) with 1 show ?case by(auto simp: first_hd) next case (2 x xs added old remained) then show ?case by auto qed qed lemma list_current_size: "\0 < size big; list_current big = []; invar big\ \ False" proof(induction big rule: list_current.induct) case 1 then show ?case using list_current_size by simp next case (2 current uu uv uw) then show ?case apply(cases current) by(auto simp: Stack_Proof.size_not_empty Stack_Proof.list_empty) qed lemma step_size: "invar (big :: 'a big_state) \ size big = size (step big)" by(induction big rule: step_big_state.induct)(auto split: current.splits) lemma remaining_steps_step [simp]: "\invar (big :: 'a big_state); remaining_steps big > 0\ \ Suc (remaining_steps (step big)) = remaining_steps big" by(induction big rule: step_big_state.induct)(auto split: current.splits) lemma remaining_steps_step_0 [simp]: "\invar (big :: 'a big_state); remaining_steps big = 0\ \ remaining_steps (step big) = 0" by(induction big)(auto split: current.splits) lemma remaining_steps_push: "invar big \ remaining_steps (push x big) = remaining_steps big" by(induction x big rule: push.induct)(auto split: current.splits) lemma remaining_steps_pop: "\invar big; pop big = (x, big')\ \ remaining_steps big' \ remaining_steps big" proof(induction big rule: pop.induct) case (1 state) then show ?case by(auto simp: remaining_steps_pop split: prod.splits) next case (2 current big aux count) then show ?case by(induction current rule: Current.pop.induct) auto qed lemma size_push [simp]: "invar big \ size (push x big) = Suc (size big)" by(induction x big rule: push.induct)(auto split: current.splits) lemma size_new_push [simp]: "invar big \ size_new (push x big) = Suc (size_new big)" by(induction x big rule: Big.push.induct)(auto split: current.splits) lemma size_pop [simp]: "\invar big; 0 < size big; pop big = (x, big')\ \ Suc (size big') = size big" proof(induction big rule: pop.induct) case 1 then show ?case by(auto split: prod.splits) next case (2 current big aux count) then show ?case by(induction current rule: Current.pop.induct) auto qed lemma size_new_pop [simp]: "\invar big; 0 < size_new big; pop big = (x, big')\ \ Suc (size_new big') = size_new big" proof(induction big rule: pop.induct) case 1 then show ?case by(auto split: prod.splits) next case (2 current big aux count) then show ?case by(induction current rule: Current.pop.induct) auto qed lemma size_size_new: "\invar (big :: 'a big_state); 0 < size big\ \ 0 < size_new big" by(induction big)(auto simp: size_size_new) end diff --git a/thys/Real_Time_Deque/States_Aux.thy b/thys/Real_Time_Deque/States_Aux.thy --- a/thys/Real_Time_Deque/States_Aux.thy +++ b/thys/Real_Time_Deque/States_Aux.thy @@ -1,89 +1,87 @@ theory States_Aux imports States Big_Aux Small_Aux begin instantiation states::(type) remaining_steps begin fun remaining_steps_states :: "'a states \ nat" where "remaining_steps (States _ big small) = max (remaining_steps big) (case small of Small3 common \ remaining_steps common - | Small2 (Current _ _ _ remaining) _ big _ count \ - (remaining - (count + size big)) + size big + 1 + | Small2 (Current _ _ _ remaining) _ big _ count \ remaining - count + 1 | Small1 (Current _ _ _ remaining) _ _ \ - case big of - Big1 currentB big auxB count \ size big + (remaining + count - size big) + 2 + case big of Big1 currentB big auxB count \ remaining + count + 2 )" instance.. end fun lists :: "'a states \ 'a list * 'a list" where "lists (States _ (Big1 currentB big auxB count) (Small1 currentS small auxS)) = ( Big_Aux.list (Big1 currentB big auxB count), Small_Aux.list (Small2 currentS (take_rev count (Stack_Aux.list small) @ auxS) ((Stack.pop ^^ count) big) [] 0) )" | "lists (States _ big small) = (Big_Aux.list big, Small_Aux.list small)" fun list_small_first :: "'a states \ 'a list" where "list_small_first states = (let (big, small) = lists states in small @ (rev big))" fun list_big_first :: "'a states \ 'a list" where "list_big_first states = (let (big, small) = lists states in big @ (rev small))" fun lists_current :: "'a states \ 'a list * 'a list" where "lists_current (States _ big small) = (Big_Aux.list_current big, Small_Aux.list_current small)" fun list_current_small_first :: "'a states \ 'a list" where "list_current_small_first states = (let (big, small) = lists_current states in small @ (rev big))" fun list_current_big_first :: "'a states \ 'a list" where "list_current_big_first states = (let (big, small) = lists_current states in big @ (rev small))" fun listL :: "'a states \ 'a list" where "listL (States Left big small) = list_small_first (States Left big small)" | "listL (States Right big small) = list_big_first (States Right big small)" instantiation states::(type) invar begin fun invar_states :: "'a states \ bool" where "invar (States dir big small) \ ( invar big \ invar small \ list_small_first (States dir big small) = list_current_small_first (States dir big small) \ (case (big, small) of (Big1 _ big _ count, Small1 (Current _ _ old remained) small _) \ size big - count = remained - size old \ count \ size small | (_, Small1 _ _ _) \ False | (Big1 _ _ _ _, _) \ False | _ \ True ))" instance.. end fun size_ok' :: "'a states \ nat \ bool" where "size_ok' (States _ big small) steps \ size_new small + steps + 2 \ 3 * size_new big \ size_new big + steps + 2 \ 3 * size_new small \ steps + 1 \ 4 * size small \ steps + 1 \ 4 * size big " abbreviation size_ok :: "'a states \ bool" where "size_ok states \ size_ok' states (remaining_steps states)" abbreviation size_small where "size_small states \ case states of States _ _ small \ size small" abbreviation size_new_small where "size_new_small states \ case states of States _ _ small \ size_new small" abbreviation size_big where "size_big states \ case states of States _ big _ \ size big" abbreviation size_new_big where "size_new_big states \ case states of States _ big _ \ size_new big" end