1
(************************************************************************)
2
(* This file is part of SKS. SKS is free software; you can
3
redistribute it and/or modify it under the terms of the GNU General
4
Public License as published by the Free Software Foundation; either
5
version 2 of the License, or (at your option) any later version.
7
This program is distributed in the hope that it will be useful, but
8
WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
16
(***********************************************************************)
18
(** Simple implementation of a polymorphic functional queue *)
1
(***********************************************************************)
2
(* fqueue.ml - Simple implementation of a polymorphic functional queue *)
4
(* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, *)
5
(* 2011, 2012 Yaron Minsky and Contributors *)
7
(* This file is part of SKS. SKS is free software; you can *)
8
(* redistribute it and/or modify it under the terms of the GNU General *)
9
(* Public License as published by the Free Software Foundation; either *)
10
(* version 2 of the License, or (at your option) any later version. *)
12
(* This program is distributed in the hope that it will be useful, but *)
13
(* WITHOUT ANY WARRANTY; without even the implied warranty of *)
14
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *)
15
(* General Public License for more details. *)
17
(* You should have received a copy of the GNU General Public License *)
18
(* along with this program; if not, write to the Free Software *)
19
(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *)
20
(* USA or see <http://www.gnu.org/licenses/>. *)
21
(***********************************************************************)
21
25
module Unix=UnixLabels
24
(** push and top are O(1).
28
(** push and top are O(1).
25
29
pop and take are O(1) amortized.
26
30
to_list and length are O(n).
30
if queue is not empty, outlist is not empty
34
if queue is not empty, outlist is not empty
31
35
queue.length = List.length(queue.outlist) + List.length(queue.inlist)*)
35
39
type 'a t = { inlist: 'a list;
40
44
(*****************************************)
43
let test_invariants queue =
47
let test_invariants queue =
46
50
queue.length = (List.length queue.outlist) + (List.length queue.inlist)
50
54
(queue.length = 0) || List.length queue.outlist > 0
54
58
let empty = { inlist = [];
59
63
(*****************************************)
61
65
let push el queue =
62
66
if queue.outlist = [] then
63
let outlist = List.rev (el::queue.inlist)
66
length = queue.length + 1;
67
let outlist = List.rev (el::queue.inlist)
70
length = queue.length + 1;
69
73
{ inlist = el::queue.inlist;
75
79
(*****************************************)
78
82
match queue.outlist with
79
[] -> (if queue.inlist != []
80
then failwith "FQueue.top: BUG. inlist should be empty but isn't"
83
[] -> (if queue.inlist != []
84
then failwith "FQueue.top: BUG. inlist should be empty but isn't"
84
88
(*****************************************)
86
90
let pop queue = match queue.outlist with
87
hd::[] -> (hd, { inlist = [];
88
outlist = (List.rev queue.inlist);
89
length = queue.length - 1})
91
hd::[] -> (hd, { inlist = [];
92
outlist = (List.rev queue.inlist);
93
length = queue.length - 1})
90
94
| hd::tl -> (hd, { inlist = queue.inlist;
92
length = queue.length - 1;})
96
length = queue.length - 1;})
96
100
else (match List.rev queue.inlist with
97
[] -> failwith "FQueue.top: BUG. inlist should not be empty here"
98
| hd::tl -> (hd, { inlist=[];
100
length = queue.length - 1;
101
[] -> failwith "FQueue.top: BUG. inlist should not be empty here"
102
| hd::tl -> (hd, { inlist=[];
104
length = queue.length - 1;
103
107
(*****************************************)
106
110
let (el,new_q) = pop queue in
111
115
(*****************************************)
114
118
queue.inlist @ (List.rev (queue.outlist))
116
(*****************************************)
120
(*****************************************)
118
122
let length queue = queue.length
120
124
let is_empty queue = queue.length = 0