 ### Added [FixSolver], which solves a system of inequations in a join-semi-lattice.

`Tested it by using to compute the FOLLOW sets.`
parent 4eeb62da
src/FixSolver.ml 0 → 100644
 module Make (M : Fix.IMPERATIVE_MAPS) (P : sig include Fix.PROPERTY val union: property -> property -> property end) = struct type variable = M.key type property = P.property (* A constraint is represented as a mapping of each variable to an expression, which represents its lower bound. We could represent an expression as a list of constants and variables; we can also represent it as a binary tree, as follows. *) type expression = | EBottom | ECon of property | EVar of variable | EJoin of expression * expression type constraint_ = expression M.t (* Looking up a variable's lower bound. *) let consult (m : constraint_) (x : variable) : expression = try M.find x m with Not_found -> EBottom (* Evaluation of an expression in an environment. *) let rec evaluate get e = match e with | EBottom -> P.bottom | ECon p -> p | EVar x -> get x | EJoin (e1, e2) -> P.union (evaluate get e1) (evaluate get e2) (* Solving a constraint. *) let solve (m : constraint_) : variable -> property = let module F = Fix.Make(M)(P) in F.lfp (fun x get -> evaluate get (consult m x) ) (* The imperative interface. *) let create () = let m = M.create() in let record_ConVar p y = M.add y (EJoin (ECon p, consult m y)) m and record_VarVar x y = M.add y (EJoin (EVar x, consult m y)) m in record_ConVar, record_VarVar, fun () -> solve m end
src/FixSolver.mli 0 → 100644
 module Make (M : Fix.IMPERATIVE_MAPS) (P : sig include Fix.PROPERTY val union: property -> property -> property end) : sig (* Variables and constraints. A constraint is an inequality between a constant or a variable, on the left-hand side, and a variable, on the right-hand side. *) type variable = M.key type property = P.property (* An imperative interface, where we create a new constraint system, and are given three functions to add constraints and (once we are done adding) to solve the system. *) val create: unit -> (property -> variable -> unit) * (variable -> variable -> unit) * (unit -> (variable -> property)) end