package regenerate
Regenerate is a tool to generate test-cases for regular expression engines
Install
Dune Dependency
Authors
Maintainers
Sources
regenerate-0.2.tbz
sha256=12495bc3692524dd62e7231e956df4afd7e6b69970deb865e8feafb232e734b2
sha512=b5886b07a9db6f0be8c1b6245aa856538eabf6327cf35b82cecee3dfb9e9fc6e6f3a710753c90919e161b975be2e49df47d5e4c211e6e68dabf677021cbd0df2
doc/src/regenerate.segments/Trie.ml.html
Source file Trie.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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
(* This file is free software, part of containers. See file "license" for more details. *) (** {1 Prefix Tree} *) (** {2 Signatures} *) (** {6 A Composite Word} Words are made of characters, who belong to a total order *) module type WORD = sig type t type char val compare_char : char -> char -> int val append : t -> t -> t val to_iter : t -> char Iter.t val of_list : char list -> t end module Make(W : WORD) (* : Sigs.S with type elt = W.t *) = struct type char = W.char type elt = W.t module M = Map.Make(struct type t = char let compare = W.compare_char end) type +'a trie = | Empty | Leaf of 'a | Node of 'a trie M.t type t = unit trie let empty = Empty let rec _check_invariants = function | Empty | Leaf (_ , _) -> true | Node map -> not (M.is_empty map) && M.for_all (fun _ v -> _check_invariants v) map let is_empty = function | Empty -> true | _ -> false let _id x = x (** Smart constructors *) (* sub-tree t prefixed with c *) let _cons c t = if is_empty t then Empty else Node (M.singleton c t) let _leaf x = Leaf x (* build a Node value *) let _node map = if M.is_empty map then Empty else if M.cardinal map = 1 then let c, sub = M.min_binding map in _cons c sub else Node map let _node2 c1 t1 c2 t2 = match is_empty t1, is_empty t2 with | true, true -> Empty | true, false -> _cons c2 t2 | false, true -> _cons c1 t1 | false, false -> let map = M.add c1 t1 M.empty in let map = M.add c2 t2 map in _node map (** Inserting/Removing *) (* fold [f] on [iter] with accumulator [acc], and call [finish] on the accumulator once [iter] is exhausted *) let _fold_iter_and_then f ~finish acc iter = let acc = ref acc in iter (fun x -> acc := f !acc x); finish !acc let update key f t = (* first arg: current subtree and rebuild function; [c]: current char *) let goto (t, rebuild) c = match t with | Empty | Leaf _ -> t, fun t -> rebuild (_cons c t) | Node map -> try let t' = M.find c map in (* rebuild: we modify [t], so we put the new version in [map] if it's not empty, and make the node again *) let rebuild' new_child = rebuild ( if is_empty new_child then _node (M.remove c map) else _node (M.add c new_child map) ) in t', rebuild' with Not_found -> let rebuild' new_child = if is_empty new_child then rebuild t (* ignore *) else let map' = M.add c new_child map in rebuild (_node map') in empty, rebuild' in let leaf_or_empty rebuild o = match f o with | None -> rebuild (_node M.empty) | Some x' -> rebuild (_leaf x') in let finish (t,rebuild) = match t with | Leaf x -> leaf_or_empty rebuild @@ Some x | Empty -> leaf_or_empty rebuild @@ None | Node map -> rebuild (_node map) in let word = W.to_iter key in _fold_iter_and_then goto ~finish (t, _id) word let add k v t = update k (fun _ -> Some v) t (* let remove k t = update k (fun _ -> None) t *) let singleton k v = add k v Empty (** Iter/Fold *) type 'a difflist = 'a list -> 'a list let _difflist_add : 'a difflist -> 'a -> 'a difflist = fun f x -> fun l' -> f (x :: l') (* fold that also keeps the path from the root, so as to provide the list of chars that lead to a value. The path is a difference list, ie a function that prepends a list to some suffix *) let rec _fold f path t acc = match t with | Empty -> acc | Leaf v -> f acc path v (* | Cons (c, t') -> _fold f (_difflist_add path c) t' acc *) | Node map -> M.fold (fun c t' acc -> _fold f (_difflist_add path c) t' acc) map acc (* let fold f acc t = * _fold * (fun acc path v -> * let key = W.of_list (path []) in * f acc key v) * _id t acc *) (*$T T.fold (fun acc k v -> (k,v) :: acc) [] t1 \ |> List.sort Pervasives.compare = List.sort Pervasives.compare l1 *) let iter f t = _fold (fun () path y -> f (W.of_list (path [])) y) _id t () (* let rec fold_values f acc t = match t with * | Empty -> acc * | Leaf v -> f acc v * (\* | Cons (_, t') -> fold_values f acc t' *\) * | Node map -> * M.fold * (fun _c t' acc -> fold_values f acc t') * map acc * * let iter_values f t = fold_values (fun () x -> f x) () t *) (** Merging operations *) let _mk = function Some x -> _leaf x | None -> empty let[@specialize] rec merge_with ~f ~left ~right t1 t2 = match t1, t2 with | Empty, Empty -> f None None | Empty, Node _ -> right t2 | Node _, Empty -> left t1 | Leaf v, Empty -> f (Some v) None | Empty, Leaf v -> f None (Some v) | Leaf v, Leaf v' -> f (Some v) (Some v') | Leaf _, Node _ | Node _, Leaf _ -> assert false (* | Cons (c1,t1'), Cons (c2,t2') -> * if W.compare_char c1 c2 = 0 * then _cons c1 (merge_with ~f ~left ~right t1' t2') * else _node2 c1 (left t1') c2 (right t2') * * | Cons (c1, t1'), Node (value, map) -> * begin try * (\* collision *\) * let t2' = M.find c1 map in * let new_t = merge_with ~f ~left ~right t1' t2' in * let map' = if is_empty new_t * then M.remove c1 map * else M.add c1 new_t map * in * _node value map' * with Not_found -> * (\* no collision *\) * assert (not(is_empty t1')); * let t1' = left t1' in * let map' = if is_empty t1' then map else M.add c1 t1' map in * Node (value, map') * end * | Node (value, map), Cons (c2, t2') -> * begin try * (\* collision *\) * let t1' = M.find c2 map in * let new_t = merge_with ~f ~left ~right t1' t2' in * let map' = if is_empty new_t * then M.remove c2 map * else M.add c2 new_t map * in * _node value map' * with Not_found -> * (\* no collision *\) * assert (not(is_empty t2')); * let t2' = left t2' in * let map' = if is_empty t2' then map else M.add c2 t2' map in * Node (value, map') * end *) | Node map1, Node map2 -> (* let v = f v1 v2 in *) let as_option t = if is_empty t then None else Some t in let map' = M.merge (fun _c t1 t2 -> match t1, t2 with | None, None -> assert false | Some t, None -> as_option @@ left t | None, Some t -> as_option @@ right t | Some t1, Some t2 -> let new_t = merge_with ~f ~left ~right t1 t2 in as_option new_t ) map1 map2 in _node map' let keep x = x let drop _ = Empty let union l l' = let left = keep and right = keep and f a b = match a,b with | Some _, _ -> _mk a | None, _ -> _mk b in merge_with ~f ~left ~right l l' let inter l l' = let left = drop and right = drop and f a b = match a,b with | Some _, Some _ -> _mk a | _ -> empty in merge_with ~f ~left ~right l l' let diff l l' = let left = keep and right = drop and f a b = match a,b with | Some _, None -> _mk a | _ -> empty in merge_with ~f ~left ~right l l' let merge l = List.fold_left union Empty l (** Grafting/flatmap *) (* let map f t = * let rec map_ = function * | Empty -> Empty * (\* | Cons (c, t') -> Cons (c, map_ t') *\) * | Leaf x -> Leaf (f x) * | Node map -> * let map' = M.map map_ map * in Node map' * in map_ t *) let rec append t t0 = match t with | Empty -> Empty | Leaf _v -> t0 (* | Cons (c, t') -> Cons (c, append t' t0) *) | Node map -> let map = M.map (fun t' -> append t' t0) map in Node map (** Misc *) (* let rec size t = match t with * | Empty -> 0 * | Cons (_, t') -> size t' * | Node (v, map) -> * let s = if v=None then 0 else 1 in * M.fold * (fun _ t' acc -> size t' + acc) * map s *) let of_list l = List.fold_left (fun acc v -> add v () acc) empty l let to_iter t k = iter (fun x () -> k x) t (** External API *) let return x = singleton x () let memoize x = x end module type ORDERED = sig type t val compare : t -> t -> int end module MakeArray(X : ORDERED) = Make(struct type t = X.t array type char = X.t let append = Array.append let compare_char = X.compare let to_iter a k = Array.iter k a let of_list = Array.of_list end) module MakeList(X : ORDERED) = Make(struct type t = X.t list type char = X.t let append = List.append let compare_char = X.compare let to_iter a k = List.iter k a let of_list l = l end) module String = Make(struct type t = string type nonrec char = char let append = (^) let compare_char = Char.compare let to_iter s k = String.iter k s let of_list l = let buf = Buffer.create (List.length l) in List.iter (fun c -> Buffer.add_char buf c) l; Buffer.contents buf end)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>