# HG changeset patch # User nipkow # Date 1602084864 -7200 # Node ID 3d255ebe9733763de3eafa857e66ea547237929b # Parent 633d14bd1e59eefaa76f502055dd8d773555b83b Aded Queues diff -r 633d14bd1e59 -r 3d255ebe9733 src/HOL/Data_Structures/Queue_2Lists.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Data_Structures/Queue_2Lists.thy Wed Oct 07 17:34:24 2020 +0200 @@ -0,0 +1,86 @@ +(* Author: Tobias Nipkow *) + +section \Queue Implementation via 2 Lists\ + +theory Queue_2Lists +imports Queue_Spec +begin + +text \Definitions:\ + +type_synonym 'a queue = "'a list \ 'a list" + +fun norm :: "'a queue \ 'a queue" where +"norm (os,is) = (if os = [] then (rev is, []) else (os,is))" + +fun enq :: "'a \ 'a queue \ 'a queue" where +"enq a (os,is) = norm(os, a # is)" + +fun deq :: "'a queue \ 'a queue" where +"deq (os,is) = (if os = [] then (os,is) else norm(tl os,is))" + +fun front :: "'a queue \ 'a" where +"front (a # os,is) = a" + +fun is_empty :: "'a queue \ bool" where +"is_empty (os,is) = (os = [])" + +fun list :: "'a queue \ 'a list" where +"list (os,is) = os @ rev is" + +fun invar :: "'a queue \ bool" where +"invar (os,is) = (os = [] \ is = [])" + + +text \Implementation correctness:\ + +interpretation Queue +where empty = "([],[])" and enq = enq and deq = deq and front = front +and is_empty = is_empty and list = list and invar = invar +proof (standard, goal_cases) + case 1 show ?case by (simp) +next + case (2 q) thus ?case by(cases q) (simp) +next + case (3 q) thus ?case by(cases q) (simp) +next + case (4 q) thus ?case by(cases q) (auto simp: neq_Nil_conv) +next + case (5 q) thus ?case by(cases q) (auto) +next + case 6 show ?case by(simp) +next + case (7 q) thus ?case by(cases q) (simp) +next + case (8 q) thus ?case by(cases q) (simp) +qed + +text \Running times:\ + +fun t_norm :: "'a queue \ nat" where +"t_norm (os,is) = (if os = [] then length is else 0) + 1" + +fun t_enq :: "'a \ 'a queue \ nat" where +"t_enq a (os,is) = t_norm(os, a # is)" + +fun t_deq :: "'a queue \ nat" where +"t_deq (os,is) = (if os = [] then 0 else t_norm(tl os,is)) + 1" + +fun t_front :: "'a queue \ nat" where +"t_front (a # os,is) = 1" + +fun t_is_empty :: "'a queue \ nat" where +"t_is_empty (os,is) = 1" + +text \Amortized running times:\ + +fun \ :: "'a queue \ nat" where +"\(os,is) = length is" + +lemma a_enq: "t_enq a (os,is) + \(enq a (os,is)) - \(os,is) \ 2" +by(auto) + +lemma a_deq: "t_deq (os,is) + \(deq (os,is)) - \(os,is) \ 2" +by(auto) + +end diff -r 633d14bd1e59 -r 3d255ebe9733 src/HOL/Data_Structures/Queue_Spec.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Data_Structures/Queue_Spec.thy Wed Oct 07 17:34:24 2020 +0200 @@ -0,0 +1,28 @@ +(* Author: Tobias Nipkow *) + +section \Queue Specification\ + +theory Queue_Spec +imports Main +begin + +text \The basic queue interface with \list\-based specification:\ + +locale Queue = +fixes empty :: "'q" +fixes enq :: "'a \ 'q \ 'q" +fixes front :: "'q \ 'a" +fixes deq :: "'q \ 'q" +fixes is_empty :: "'q \ bool" +fixes list :: "'q \ 'a list" +fixes invar :: "'q \ bool" +assumes list_empty: "list empty = []" +assumes list_enq: "invar q \ list(enq x q) = list q @ [x]" +assumes list_deq: "invar q \ list(deq q) = tl(list q)" +assumes list_front: "invar q \ \ list q = [] \ front q = hd(list q)" +assumes list_is_empty: "invar q \ is_empty q = (list q = [])" +assumes invar_empty: "invar empty" +assumes invar_enq: "invar q \ invar(enq x q)" +assumes invar_deq: "invar q \ invar(deq q)" + +end diff -r 633d14bd1e59 -r 3d255ebe9733 src/HOL/ROOT --- a/src/HOL/ROOT Wed Oct 07 10:39:14 2020 +0200 +++ b/src/HOL/ROOT Wed Oct 07 17:34:24 2020 +0200 @@ -282,6 +282,7 @@ Trie_Fun Trie_Map Tries_Binary + Queue_2Lists Leftist_Heap Binomial_Heap document_files "root.tex" "root.bib"