diff --git a/thys/Amortized_Complexity/Amortized_Framework0.thy b/thys/Amortized_Complexity/Amortized_Framework0.thy --- a/thys/Amortized_Complexity/Amortized_Framework0.thy +++ b/thys/Amortized_Complexity/Amortized_Framework0.thy @@ -1,356 +1,356 @@ section "Amortized Complexity (Unary Operations)" theory Amortized_Framework0 imports Complex_Main begin text\ This theory provides a simple amortized analysis framework where all operations act on a single data type, i.e. no union-like operations. This is the basis of the ITP 2015 paper by Nipkow. Although it is superseded by the model in \Amortized_Framework\ that allows arbitrarily many parameters, it is still of interest because of its simplicity.\ locale Amortized = fixes init :: "'s" fixes nxt :: "'o \ 's \ 's" fixes inv :: "'s \ bool" fixes t :: "'o \ 's \ real" fixes \ :: "'s \ real" fixes U :: "'o \ 's \ real" assumes inv_init: "inv init" assumes inv_nxt: "inv s \ inv(nxt f s)" assumes ppos: "inv s \ \ s \ 0" assumes p0: "\ init = 0" assumes U: "inv s \ t f s + \(nxt f s) - \ s \ U f s" begin fun state :: "(nat \ 'o) \ nat \ 's" where "state f 0 = init" | "state f (Suc n) = nxt (f n) (state f n)" lemma inv_state: "inv(state f n)" by(induction n)(simp_all add: inv_init inv_nxt) definition a :: "(nat \ 'o) \ nat \ real" where "a f i = t (f i) (state f i) + \(state f (i+1)) - \(state f i)" lemma aeq: "(\ii(state f n)" apply(induction n) apply (simp add: p0) apply (simp add: a_def) done corollary ta: "(\i (\i U (f i) (state f i)" by(simp add: a_def U inv_state) lemma ub: "(\i (\ii\<^sub>n\<^sub>c\<^sub>r :: "bool list \ real" where -"t\<^sub>i\<^sub>n\<^sub>c\<^sub>r [] = 1" | -"t\<^sub>i\<^sub>n\<^sub>c\<^sub>r (False#bs) = 1" | -"t\<^sub>i\<^sub>n\<^sub>c\<^sub>r (True#bs) = t\<^sub>i\<^sub>n\<^sub>c\<^sub>r bs + 1" +fun t_incr :: "bool list \ real" where +"t_incr [] = 1" | +"t_incr (False#bs) = 1" | +"t_incr (True#bs) = t_incr bs + 1" -definition p_incr :: "bool list \ real" ("\\<^sub>i\<^sub>n\<^sub>c\<^sub>r") where -"\\<^sub>i\<^sub>n\<^sub>c\<^sub>r bs = length(filter id bs)" +definition p_incr :: "bool list \ real" ("\") where +"\ bs = length(filter id bs)" -lemma a_incr: "t\<^sub>i\<^sub>n\<^sub>c\<^sub>r bs + \\<^sub>i\<^sub>n\<^sub>c\<^sub>r(incr bs) - \\<^sub>i\<^sub>n\<^sub>c\<^sub>r bs = 2" +lemma a_incr: "t_incr bs + \(incr bs) - \ bs = 2" apply(induction bs rule: incr.induct) apply (simp_all add: p_incr_def) done interpretation incr: Amortized where init = "[]" and nxt = "%_. incr" and inv = "\_. True" -and t = "\_. t\<^sub>i\<^sub>n\<^sub>c\<^sub>r" and \ = \\<^sub>i\<^sub>n\<^sub>c\<^sub>r and U = "\_ _. 2" +and t = "\_. t_incr" and \ = \ and U = "\_ _. 2" proof (standard, goal_cases) case 1 show ?case by simp next case 2 show ?case by simp next case 3 show ?case by(simp add: p_incr_def) next case 4 show ?case by(simp add: p_incr_def) next case 5 show ?case by(simp add: a_incr) qed thm incr.ub subsection "Dynamic tables: insert only" fun t\<^sub>i\<^sub>n\<^sub>s :: "nat \ nat \ real" where "t\<^sub>i\<^sub>n\<^sub>s (n,l) = (if n = "\(n,l). 2*n - l" and U = "\_ _. 3" proof (standard, goal_cases) case 1 show ?case by auto next case (2 s) thus ?case by(cases s) auto next case (3 s) thus ?case by(cases s)(simp split: if_splits) next case 4 show ?case by(simp) next case (5 s) thus ?case by(cases s) auto qed locale table_insert = fixes a :: real fixes c :: real assumes c1[arith]: "c > 1" assumes ac2: "a \ c/(c - 1)" begin lemma ac: "a \ 1/(c - 1)" using ac2 by(simp add: field_simps) lemma a0[arith]: "a>0" proof- have "1/(c - 1) > 0" using ac by simp thus ?thesis by (metis ac dual_order.strict_trans1) qed definition "b = 1/(c - 1)" lemma b0[arith]: "b > 0" using ac by (simp add: b_def) fun "ins" :: "nat * nat \ nat * nat" where "ins(n,l) = (n+1, if n real" where "pins(n,l) = a*n - b*l" interpretation ins: Amortized where init = "(0,0)" and nxt = "%_. ins" and inv = "\(n,l). if l=0 then n=0 else n \ l \ (b/a)*l \ n" and t = "\_. t\<^sub>i\<^sub>n\<^sub>s" and \ = pins and U = "\_ _. a + 1" proof (standard, goal_cases) case 1 show ?case by auto next case (2 s) show ?case proof (cases s) case [simp]: (Pair n l) show ?thesis proof cases assume "l=0" thus ?thesis using 2 ac by (simp add: b_def field_simps) next assume "l\0" show ?thesis proof cases assume "n nl\0\ by simp have 1: "(b/a) * ceiling(c * l) \ real l + 1" proof- have "(b/a) * ceiling(c * l) = ceiling(c * l)/(a*(c - 1))" by(simp add: b_def) also have "ceiling(c * l) \ c*l + 1" by simp also have "\ \ c*(real l+1)" by (simp add: algebra_simps) also have "\ / (a*(c - 1)) = (c/(a*(c - 1))) * (real l + 1)" by simp also have "c/(a*(c - 1)) \ 1" using ac2 by (simp add: field_simps) finally show ?thesis by (simp add: divide_right_mono) qed have 2: "real l + 1 \ ceiling(c * real l)" proof- have "real l + 1 = of_int(int(l)) + 1" by simp also have "... \ ceiling(c * real l)" using \l \ 0\ by(simp only: int_less_real_le[symmetric] less_ceiling_iff) (simp add: mult_less_cancel_right1) finally show ?thesis . qed from \l\0\ 1 2 show ?thesis by simp (simp add: not_le zero_less_mult_iff) qed qed qed next case (3 s) thus ?case by(cases s)(simp add: field_simps split: if_splits) next case 4 show ?case by(simp) next case (5 s) show ?case proof (cases s) case [simp]: (Pair n l) show ?thesis proof cases assume "l=0" thus ?thesis using 5 by (simp) next assume [arith]: "l\0" show ?thesis proof cases assume "n ni\<^sub>n\<^sub>s s + pins (ins s) - pins s = l + a + 1 + (- b*ceiling(c*l)) + b*l" using \l\0\ by(simp add: algebra_simps less_trans[of "-1::real" 0]) also have "- b * ceiling(c*l) \ - b * (c*l)" by (simp add: ceiling_correct) also have "l + a + 1 + - b*(c*l) + b*l = a + 1 + l*(1 - b*(c - 1))" by (simp add: algebra_simps) also have "b*(c - 1) = 1" by(simp add: b_def) also have "a + 1 + (real l)*(1 - 1) = a+1" by simp finally show ?thesis by simp qed qed qed qed thm ins.ub end subsection "Stack with multipop" datatype 'a op\<^sub>s\<^sub>t\<^sub>k = Push 'a | Pop nat fun nxt\<^sub>s\<^sub>t\<^sub>k :: "'a op\<^sub>s\<^sub>t\<^sub>k \ 'a list \ 'a list" where "nxt\<^sub>s\<^sub>t\<^sub>k (Push x) xs = x # xs" | "nxt\<^sub>s\<^sub>t\<^sub>k (Pop n) xs = drop n xs" fun t\<^sub>s\<^sub>t\<^sub>k:: "'a op\<^sub>s\<^sub>t\<^sub>k \ 'a list \ real" where "t\<^sub>s\<^sub>t\<^sub>k (Push x) xs = 1" | "t\<^sub>s\<^sub>t\<^sub>k (Pop n) xs = min n (length xs)" interpretation stack: Amortized where init = "[]" and nxt = nxt\<^sub>s\<^sub>t\<^sub>k and inv = "\_. True" and t = t\<^sub>s\<^sub>t\<^sub>k and \ = "length" and U = "\f _. case f of Push _ \ 2 | Pop _ \ 0" proof (standard, goal_cases) case 1 show ?case by auto next case (2 s) thus ?case by(cases s) auto next case 3 thus ?case by simp next case 4 show ?case by(simp) next case (5 _ f) thus ?case by (cases f) auto qed subsection "Queue" text\See, for example, the book by Okasaki~\cite{Okasaki}.\ datatype 'a op\<^sub>q = Enq 'a | Deq type_synonym 'a queue = "'a list * 'a list" fun nxt\<^sub>q :: "'a op\<^sub>q \ 'a queue \ 'a queue" where "nxt\<^sub>q (Enq x) (xs,ys) = (x#xs,ys)" | "nxt\<^sub>q Deq (xs,ys) = (if ys = [] then ([], tl(rev xs)) else (xs,tl ys))" fun t\<^sub>q :: "'a op\<^sub>q \ 'a queue \ real" where "t\<^sub>q (Enq x) (xs,ys) = 1" | "t\<^sub>q Deq (xs,ys) = (if ys = [] then length xs else 0)" interpretation queue: Amortized where init = "([],[])" and nxt = nxt\<^sub>q and inv = "\_. True" and t = t\<^sub>q and \ = "\(xs,ys). length xs" and U = "\f _. case f of Enq _ \ 2 | Deq \ 0" proof (standard, goal_cases) case 1 show ?case by auto next case (2 s) thus ?case by(cases s) auto next case (3 s) thus ?case by(cases s) auto next case 4 show ?case by(simp) next case (5 s f) thus ?case apply(cases s) apply(cases f) by auto qed fun balance :: "'a queue \ 'a queue" where "balance(xs,ys) = (if size xs \ size ys then (xs,ys) else ([], ys @ rev xs))" fun nxt_q2 :: "'a op\<^sub>q \ 'a queue \ 'a queue" where "nxt_q2 (Enq a) (xs,ys) = balance (a#xs,ys)" | "nxt_q2 Deq (xs,ys) = balance (xs, tl ys)" fun t_q2 :: "'a op\<^sub>q \ 'a queue \ real" where "t_q2 (Enq _) (xs,ys) = 1 + (if size xs + 1 \ size ys then 0 else size xs + 1 + size ys)" | "t_q2 Deq (xs,ys) = (if size xs \ size ys - 1 then 0 else size xs + (size ys - 1))" interpretation queue2: Amortized where init = "([],[])" and nxt = nxt_q2 and inv = "\(xs,ys). size xs \ size ys" and t = t_q2 and \ = "\(xs,ys). 2 * size xs" and U = "\f _. case f of Enq _ \ 3 | Deq \ 0" proof (standard, goal_cases) case 1 show ?case by auto next case (2 s f) thus ?case by(cases s) (cases f, auto) next case (3 s) thus ?case by(cases s) auto next case 4 show ?case by(simp) next case (5 s f) thus ?case apply(cases s) apply(cases f) by (auto simp: split: prod.splits) qed subsection "Dynamic tables: insert and delete" datatype op\<^sub>t\<^sub>b = Ins | Del fun nxt\<^sub>t\<^sub>b :: "op\<^sub>t\<^sub>b \ nat*nat \ nat*nat" where "nxt\<^sub>t\<^sub>b Ins (n,l) = (n+1, if nt\<^sub>b Del (n,l) = (n - 1, if n=1 then 0 else if 4*(n - 1)t\<^sub>b :: "op\<^sub>t\<^sub>b \ nat*nat \ real" where "t\<^sub>t\<^sub>b Ins (n,l) = (if nt\<^sub>b Del (n,l) = (if n=1 then 1 else if 4*(n - 1)t\<^sub>b and inv = "\(n,l). if l=0 then n=0 else n \ l \ l \ 4*n" and t = t\<^sub>t\<^sub>b and \ = "(\(n,l). if 2*n < l then l/2 - n else 2*n - l)" and U = "\f _. case f of Ins \ 3 | Del \ 2" proof (standard, goal_cases) case 1 show ?case by auto next case (2 s f) thus ?case by(cases s, cases f) (auto split: if_splits) next case (3 s) thus ?case by(cases s)(simp split: if_splits) next case 4 show ?case by(simp) next case (5 s f) thus ?case apply(cases s) apply(cases f) by (auto simp: field_simps) qed end