Theory RealTimeDeque_Enqueue_Proof
section "Enqueue Proofs"
theory RealTimeDeque_Enqueue_Proof
imports Deque RealTimeDeque_Aux States_Proof
begin
lemma list_enqL: "invar deque ⟹ listL (enqL x deque) = x # listL deque"
proof(induction x deque rule: enqL.induct)
case (5 x left right length_right)
obtain left' length_left' where pushed [simp]:
"Idle.push x left = idle.Idle left' length_left'"
using is_empty_idle.cases by blast
then have invar_left': "invar (idle.Idle left' length_left')"
using Idle_Proof.invar_push[of left x] 5 by auto
show ?case
proof(cases "length_left' ≤ 3 * length_right")
case True
then show ?thesis
using Idle_Proof.push_list[of x left]
by(auto simp: Let_def)
next
case False
let ?length_left = "length_left' - length_right - 1"
let ?length_right = "2 * length_right + 1"
let ?big = "Big1 (Current [] 0 left' ?length_left) left' [] ?length_left"
let ?small = "Small1 (Current [] 0 right ?length_right) right []"
let ?states = "States Right ?big ?small"
let ?states_stepped = "(step^^6) ?states"
from False 5 invar_left' have invar: "invar ?states"
by(auto simp: rev_drop rev_take)
then have "States_Aux.listL ?states = x # Idle_Aux.list left @ rev (Stack_Aux.list right)"
using Idle_Proof.push_list[of x left]
by(auto)
then have "States_Aux.listL ?states_stepped = x # Idle_Aux.list left @ rev (Stack_Aux.list right)"
by (metis invar step_n_listL)
with False show ?thesis
by(auto simp: Let_def)
qed
next
case (6 x big small)
let ?small = "Small.push x small"
let ?states = "States Left big ?small"
let ?states_stepped = "(step^^4) ?states"
obtain big_stepped small_stepped where stepped:
"?states_stepped = States Left big_stepped small_stepped"
by (metis remaining_steps_states.cases step_n_same)
from 6 have "invar ?states"
using invar_push_small[of Left big small x]
by auto
then have
"States_Aux.listL ?states_stepped =
x # Small_Aux.list_current small @ rev (Big_Aux.list_current big)"
using step_n_listL by fastforce
with 6 show ?case
by(cases big_stepped; cases small_stepped)
(auto simp: Let_def stepped split!: common_state.split)
next
case (7 x big small)
let ?big = "Big.push x big"
let ?states = "States Right ?big small"
let ?states_stepped = "(step^^4) ?states"
obtain big_stepped small_stepped where stepped:
"?states_stepped = States Right big_stepped small_stepped"
by (metis remaining_steps_states.cases step_n_same)
from 7 have list_invar:
"list_current_small_first (States Right big small) = list_small_first (States Right big small)"
by auto
from 7 have invar: "invar ?states"
using invar_push_big[of Right big small x]
by auto
then have
"States_Aux.listL ?states = x # Big_Aux.list_current big @ rev (Small_Aux.list_current small)"
using app_rev[of _ _ _ "x # Big_Aux.list_current big"]
by(auto split: prod.split)
then have
"States_Aux.listL ?states_stepped =
x # Big_Aux.list_current big @ rev (Small_Aux.list_current small)"
by (metis invar step_n_listL)
with list_invar show ?case
using app_rev[of "Small_Aux.list_current small" "Big_Aux.list_current big"]
by(cases big_stepped; cases small_stepped)
(auto simp: Let_def stepped split!: prod.split common_state.split)
qed auto
lemma invar_enqL: "invar deque ⟹ invar (enqL x deque)"
proof(induction x deque rule: enqL.induct)
case (5 x left right length_right)
obtain left' length_left' where pushed [simp]:
"Idle.push x left = idle.Idle left' length_left'"
using is_empty_idle.cases by blast
then have invar_left': "invar (idle.Idle left' length_left')"
using Idle_Proof.invar_push[of left x] 5 by auto
have [simp]: "size left' = Suc (size left)"
using Idle_Proof.size_push[of x left]
by auto
show ?case
proof(cases "length_left' ≤ 3 * length_right")
case True
with 5 show ?thesis
using invar_left' Idle_Proof.size_push[of x left] Stack_Proof.size_not_empty[of left']
by auto
next
case False
let ?length_left = "length_left' - length_right - 1"
let ?length_right = "Suc (2 * length_right)"
let ?states = "States Right
(Big1 (Current [] 0 left' ?length_left) left' [] ?length_left)
(Small1 (Current [] 0 right ?length_right) right [])"
let ?states_stepped = "(step^^6) ?states"
from invar_left' 5 False have invar: "invar ?states"
by(auto simp: rev_drop rev_take)
then have invar_stepped: "invar ?states_stepped"
using invar_step_n by blast
from False invar_left' 5 have remaining_steps: "6 < remaining_steps ?states"
using Stack_Proof.size_not_empty[of right]
by auto
then have remaining_steps_stepped: "0 < remaining_steps ?states_stepped"
using invar remaining_steps_n_steps_sub
by (metis zero_less_diff)
from False invar_left' 5 have "size_ok' ?states (remaining_steps ?states - 6)"
using Stack_Proof.size_not_empty[of right]
size_not_empty
by auto
then have size_ok_stepped: "size_ok ?states_stepped"
using size_ok_steps[of ?states 6] remaining_steps invar
by blast
from False show ?thesis
using invar_stepped remaining_steps_stepped size_ok_stepped
by(auto simp: Let_def)
qed
next
case (6 x big small)
let ?small = "Small.push x small"
let ?states = "States Left big ?small"
let ?states_stepped = "(step^^4) ?states"
from 6 have invar: "invar ?states"
using invar_push_small[of Left big small x]
by auto
then have invar_stepped: "invar ?states_stepped"
using invar_step_n by blast
show ?case
proof(cases "4 < remaining_steps ?states")
case True
obtain big_stepped small_stepped where stepped [simp]:
"?states_stepped = States Left big_stepped small_stepped"
by (metis remaining_steps_states.cases step_n_same)
from True have remaining_steps: "0 < remaining_steps ?states_stepped"
using invar remaining_steps_n_steps_sub[of ?states 4]
by simp
from True 6(1) have size_ok: "size_ok ?states_stepped"
using
step_4_push_small_size_ok[of Left big small x]
remaining_steps_push_small[of Left big small x]
by auto
from remaining_steps size_ok invar_stepped show ?thesis
by(cases big_stepped; cases small_stepped)
(auto simp: Let_def split!: common_state.split)
next
case False
then have remaining_steps_stepped: "remaining_steps ?states_stepped = 0"
using invar by auto
then obtain small_current small_idle big_current big_idle where idle [simp]: "
?states_stepped =
States Left
(Big2 (common_state.Idle big_current big_idle))
(Small3 (common_state.Idle small_current small_idle))
"
using remaining_steps_idle' invar_stepped remaining_steps_stepped step_n_same
by (smt (verit) invar_states.elims(2))
from 6 have [simp]: "size_new (Small.push x small) = Suc (size_new small)"
using Small_Proof.size_new_push by auto
have [simp]: "size small_idle = size_new (Small.push x small)"
using invar invar_stepped step_n_size_new_small[of Left big "Small.push x small" 4]
by auto
then have [simp]: "¬is_empty small_idle"
using Idle_Proof.size_not_empty[of small_idle]
by auto
have size_new_big [simp]: "0 < size_new big"
using 6
by auto
then have [simp]: "size big_idle = size_new big"
using invar invar_stepped step_n_size_new_big[of Left big "Small.push x small" 4]
by auto
then have [simp]: "¬is_empty big_idle"
using Idle_Proof.size_not_empty size_new_big
by metis
have size_ok_1: "size small_idle ≤ 3 * size big_idle"
using 6 by auto
have size_ok_2: "size big_idle ≤ 3 * size small_idle"
using 6 by auto
from False show ?thesis
using invar_stepped size_ok_1 size_ok_2
by auto
qed
next
case (7 x big small)
let ?big = "Big.push x big"
let ?states = "States Right ?big small"
let ?states_stepped = "(step^^4) ?states"
from 7 have invar: "invar ?states"
using invar_push_big[of Right big small x]
by auto
then have invar_stepped: "invar ?states_stepped"
using invar_step_n by blast
show ?case
proof(cases "4 < remaining_steps ?states")
case True
obtain big_stepped small_stepped where stepped [simp]:
"?states_stepped = States Right big_stepped small_stepped"
by (metis remaining_steps_states.cases step_n_same)
from True have remaining_steps: "0 < remaining_steps ?states_stepped"
using invar remaining_steps_n_steps_sub[of ?states 4]
by simp
from True 7(1) have size_ok: "size_ok ?states_stepped"
using
step_4_push_big_size_ok[of Right big small x]
remaining_steps_push_big[of Right big small x]
by auto
from remaining_steps size_ok invar_stepped show ?thesis
by(cases big_stepped; cases small_stepped)
(auto simp: Let_def split!: common_state.split)
next
case False
then have remaining_steps_stepped: "remaining_steps ?states_stepped = 0"
using invar by auto
then obtain small_current small_idle big_current big_idle where idle [simp]: "
?states_stepped =
States Right
(Big2 (common_state.Idle big_current big_idle))
(Small3 (common_state.Idle small_current small_idle))
"
using remaining_steps_idle' invar_stepped remaining_steps_stepped step_n_same
by (smt (verit) invar_states.elims(2))
from 7 have [simp]: "size_new (Big.push x big) = Suc (size_new big)"
using Big_Proof.size_new_push by auto
have [simp]: "size big_idle = size_new (Big.push x big)"
using invar invar_stepped step_n_size_new_big[of Right "Big.push x big" small 4]
by auto
then have [simp]: "¬is_empty big_idle"
using Idle_Proof.size_not_empty[of big_idle]
by auto
have size_new_small [simp]: "0 < size_new small"
using 7
by auto
then have [simp]: "size small_idle = size_new small"
using invar invar_stepped step_n_size_new_small[of Right "Big.push x big" small 4]
by auto
then have [simp]: "¬is_empty small_idle"
using Idle_Proof.size_not_empty size_new_small
by metis
have size_ok_1: "size small_idle ≤ 3 * size big_idle"
using 7 by auto
have size_ok_2: "size big_idle ≤ 3 * size small_idle"
using 7 by auto
from False show ?thesis
using invar_stepped size_ok_1 size_ok_2
by auto
qed
qed auto
end