 ### Progress up to derivation.

parent 1332b24b
 ... ... @@ -239,3 +239,48 @@ let nullable : regexp -> bool = not (nullable e) ) ``` ## Derivation We now reach a key operation: computing the Brzozowski derivative of an expression. If `a` is a character and `e` is an expression, then `delta a e` is the derivative of `e` with respect to `a`. Implementing `delta` is a textbook exercise. A key remark, though, is that this function **must** be memoized in order to ensure good complexity. A naive, non-memoizing version of it would have exponential cost, due to the duplication that takes place in the cases of concatenation and iteration. In order to memoize a function of two arguments, one possible approach would be to rewrite it as a function that takes a pair as an argument. Here, instead, I rely on currying. For every character `a`, `delta a` is a function of type `regexp -> regexp`. I memoize each such function independently using `fix`, and I memoize the function `delta` itself using `memoize`, a nonrecursive memoization combinator. ``` let delta : Char.t -> regexp -> regexp = let module C = Memoize.ForHashedType(Char) in let module M = Memoize.ForHashedType(R) in C.memoize (fun a -> M.fix (fun delta e -> match skeleton e with | EEpsilon -> zero | EChar b -> if Char.equal a b then epsilon else zero | ECat (e1, e2) -> delta e1 @@ e2 ||| if nullable e1 then delta e2 else zero | EStar e -> delta e @@ star e | EDisj es -> disjunction (map delta es) | EConj es -> conjunction (map delta es) | ENeg e -> neg (delta e) ) ) ```
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!