Commit 5ad4cf02 authored by POTTIER Francois's avatar POTTIER Francois

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!
Please register or to comment