package pomap

  1. Overview
  2. Docs

Source file store_impl.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
(* POMAP - Library for manipulating partially ordered maps

   Copyright (C) 2001-2002 Markus Mottl (OEFAI) email: markus.mottl@gmail.com
   WWW: http://www.ocaml.info

   This library is free software; you can redistribute it and/or modify it under
   the terms of the GNU Lesser General Public License as published by the Free
   Software Foundation; either version 2.1 of the License, or (at your option)
   any later version.

   This library is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
   details.

   You should have received a copy of the GNU Lesser General Public License
   along with this library; if not, write to the Free Software Foundation, Inc.,
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *)

open Store_intf

module IntIx = struct
  type t = int
  type gen = int

  module Set = Ptset

  module Map = Map.Make (struct
    type t = int

    let compare x y = x - y
  end)

  let start = 0
  let next_ix gen = gen
  let next n = (n, n + 1)
  let remove_ix gen n = max gen (n + 1)
  let int_of_ix n = n
end

module Make (Ix : INDEX) = struct
  module Ix = Ix

  type 'a t = Ix.gen * 'a Ix.Map.t

  let empty = (Ix.start, Ix.Map.empty)
  let is_empty (_, m) = Ix.Map.is_empty m
  let count _ _ n = n + 1
  let cardinal (_, m) = Ix.Map.fold count m 0
  let next_ix (gen, _) = Ix.next_ix gen

  let singleton el =
    let ix, gen = Ix.next Ix.start in
    (ix, (gen, Ix.Map.add ix el Ix.Map.empty))

  let add el (gen, m) =
    let ix, new_gen = Ix.next gen in
    (ix, (new_gen, Ix.Map.add ix el m))

  let find el (_, m) = Ix.Map.find el m
  let update ix el (gen, m) = (Ix.remove_ix gen ix, Ix.Map.add ix el m)
  let remove ix (gen, m) = (gen, Ix.Map.remove ix m)
  let iter f (_, m) = Ix.Map.iter (fun _ el -> f el) m
  let iteri f (_, m) = Ix.Map.iter f m
  let map f (gen, m) = (gen, Ix.Map.map f m)
  let mapi f (gen, m) = (gen, Ix.Map.mapi f m)
  let fold f (_, m) acc = Ix.Map.fold (fun _ el acc -> f el acc) m acc
  let foldi f (_, m) acc = Ix.Map.fold f m acc
  let cons_tpl ix el acc = (ix, el) :: acc
  let to_list s = foldi cons_tpl s []

  let choose (_, m) =
    let x_ref = ref (Obj.magic 0) in
    let act ix el =
      x_ref := (ix, el);
      raise Exit
    in
    try
      Ix.Map.iter act m;
      raise Not_found
    with Exit -> !x_ref

  let filter p (gen, m) =
    let coll ix el acc = if p ix el then acc else Ix.Map.remove ix acc in
    (gen, Ix.Map.fold coll m m)

  let partition p (gen, m) =
    let coll ix el (yes, no) =
      if p ix el then (yes, Ix.Map.remove ix no) else (Ix.Map.remove ix yes, no)
    in
    let yes, no = Ix.Map.fold coll m (m, m) in
    ((gen, yes), (gen, no))

  let eq_classes eq (gen, m) =
    let rec coll acc ix el = function
      | [] -> (el, Ix.Map.add ix el Ix.Map.empty) :: acc
      | ((eq_el, eq_m) as ec) :: ecs ->
          if eq el eq_el then
            (eq_el, Ix.Map.add ix el eq_m) :: List.rev_append acc ecs
          else coll (ec :: acc) ix el ecs
    in
    let ecs = Ix.Map.fold (coll []) m [] in
    List.rev_map (fun (eq_el, eq_m) -> (eq_el, (gen, eq_m))) ecs

  let get_ix_map (_, m) = m
end

module IntStore = Make (IntIx)
OCaml

Innovation. Community. Security.