Skip to content

Instantly share code, notes, and snippets.

@chichunchen
Created October 9, 2017 19:34
Show Gist options
  • Save chichunchen/f9152150eb9f4baddf8d4484a6a56174 to your computer and use it in GitHub Desktop.
Save chichunchen/f9152150eb9f4baddf8d4484a6a56174 to your computer and use it in GitHub Desktop.
dfa in ocaml
type state = int;;
type 'a dfa = {
current_state : state;
transition_function : (state * 'a * state) list;
final_states : state list;
};;
type decision = Accept | Reject;;
let a_b_even_dfa : char dfa = (* input symbols are characters *)
{ current_state = 0;
transition_function =
[ (0, 'a', 2); (0, 'b', 1); (1, 'a', 3); (1, 'b', 0);
(2, 'a', 0); (2, 'b', 3); (3, 'a', 1); (3, 'b', 2) ];
final_states = [0];
};;
open List;; (* includes rev, find, and mem functions *)
let move (d:'a dfa) (x:'a) : 'a dfa =
{ current_state = (
let (_, _, q) =
find (fun (s, c, _) -> s = d.current_state && c = x)
d.transition_function in
q);
transition_function = d.transition_function;
final_states = d.final_states;
};;
let simulate (d:'a dfa) (input:'a list) : (state list * decision) =
let rec helper moves d2 remaining_input : (state option * state list) =
match remaining_input with
| [] -> (Some d2.current_state, moves)
| hd :: tl ->
let new_moves = d2.current_state :: moves in
try helper new_moves (move d2 hd) tl
with Not_found -> (None, new_moves) in
match helper [] d input with
| (None, moves) -> (rev moves, Reject)
| (Some last_state, moves) ->
( rev (last_state :: moves),
if mem last_state d.final_states then Accept else Reject);;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment