package grenier
A collection of various algorithms in OCaml
Install
Dune Dependency
Authors
Maintainers
Sources
grenier-0.15.tbz
sha256=dec7f84b9e93d5825f10c7dea84d5a74d7365ede45664ae63c26b5e8045c1c44
sha512=b8aa1569c2e24b89674d1b34de34cd1798896bb6a53aa5a1287f68cee880125e6b687f66ad73da9069a01cc3ece1f0684f48328b099d43529bff736b772c8fd8
doc/src/grenier.state_elimination/state_elimination.ml.html
Source file state_elimination.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
open Strong.Finite module type Regex = sig type t val epsilon : t (* Concatenation *) val (^.) : t -> t -> t (* Disjunction *) val (|.) : t -> t -> t (* Kleene star *) val star : t -> t end module type NFA = sig module States : Strong.Natural.T module Transitions : Strong.Natural.T type label val label : Transitions.n elt -> label val source : Transitions.n elt -> States.n elt val target : Transitions.n elt -> States.n elt module Initials : Array.T with type a = States.n elt module Finals : Array.T with type a = States.n elt end module Convert (Regex : Regex) (NFA: NFA with type label := Regex.t) : sig val result : (NFA.Initials.n, (NFA.Finals.n elt * Regex.t list) list) Array.t end = struct type temp = | Unused | Label of Regex.t | Final of { index: NFA.Finals.n elt; mutable regexes : Regex.t list } type state = { mutable preds: (state * Regex.t) list; mutable succs: (state * Regex.t) list; mutable temp: temp; } let is_alive = function {preds = []; succs = []; _} -> false | _ -> true let state_counter = ref 0 let make_state () = incr state_counter; { preds = []; succs = []; temp = Unused } let states : (NFA.States.n, state) Array.t = Array.init NFA.States.n (fun _ -> make_state ()) let update_list state label = function | (state', label') :: rest when state == state' -> (state', Regex.(|.) label label') :: rest | otherwise -> (state, label) :: otherwise let link source target label = ( source.succs <- update_list target label source.succs; target.preds <- update_list source label target.preds; ) let () = Set.iter NFA.Transitions.n (fun transition -> link states.(NFA.source transition) states.(NFA.target transition) (NFA.label transition) ) let initials = let prepare_initial nfa_state = let state = make_state () in link state states.(nfa_state) Regex.epsilon; state in Array.map prepare_initial NFA.Initials.table let finals = let prepare_final nfa_state = let state = make_state () in link states.(nfa_state) state Regex.epsilon; state in Array.map prepare_final NFA.Finals.table let normalize_transitions transitions = let to_temp transitions = assert (List.for_all (fun (state, _) -> state.temp = Unused) transitions); List.iter (fun (state, label) -> if is_alive state then ( match state.temp with | Unused -> state.temp <- Label label | Label label' -> state.temp <- Label (Regex.(|.) label label') | Final _ -> assert false ) ) transitions in let extract_temp (state, _) = match state.temp with | Unused -> None | Label label -> state.temp <- Unused; Some (state, label) | Final _ -> assert false in to_temp transitions; List.filter_map extract_temp transitions let eliminate state = decr state_counter; let preds = state.preds and succs = state.succs in state.succs <- []; state.preds <- []; let stars = List.fold_left (fun acc (succ, label) -> if succ == state then Regex.(|.) label acc else acc) Regex.epsilon succs in let preds = normalize_transitions preds in let succs = normalize_transitions succs in (*Printf.eprintf "state %d, %d predecessors, %d successors\n%!" !state_counter (List.length preds) (List.length succs);*) let stars = if stars == Regex.epsilon then Regex.epsilon else Regex.star stars in List.iter (fun (succ, label_succ) -> List.iter (fun (pred, label_pred) -> let label = Regex.( if stars == epsilon then label_pred ^. stars ^. label_succ else label_pred ^. label_succ ) in link pred succ label; ) preds ) succs let () = Array.iter eliminate states let result = let normalize_initial initial = normalize_transitions initial.succs in let normalized = Array.map normalize_initial initials in let tag_final index state = state.temp <- Final {index; regexes = []} in Array.iteri tag_final finals; let non_null = ref [] in let prepare_transition (state, regex) = match state.temp with | Final t -> if t.regexes = [] then non_null := state.temp :: !non_null; t.regexes <- regex :: t.regexes | _ -> assert false in let flush_final = function | Final t -> let result = t.index, t.regexes in t.regexes <- []; result | _ -> assert false in let prepare_initial transitions = List.iter prepare_transition transitions; let result = List.map flush_final !non_null in non_null := []; result in Array.map prepare_initial normalized end let convert (type regex initials finals) (module Regex : Regex with type t = regex) (module NFA : NFA with type label = regex and type Initials.n = initials and type Finals.n = finals) : (initials, (finals elt * regex list) list) Array.t = let module Result = Convert(Regex)(NFA) in Result.result
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>