(* ============================================
              Finite State Automata
   ============================================ *)

type id = int

type state = id
type initial_state = state
type final_state = state
type fa_transition = state * char * state
type fautomata = initial_state * (fa_transition list) * final_state list

let accepts ((qi, ts, qf) : fautomata) (w : char list) =
  let rec head q (read : char list) =
    match read with
    | [] -> List.mem q qf
    | c::w ->
      let (_, _, qnext) =
        List.hd (List.filter (fun (qs, c', qt) -> qs=q && c=c') ts)
      in head qnext w
  in head qi w

(* _________ Examples _________ *)

let even_ones : fautomata = (
  0,
  [
    (0, '1', 1);
    (1, '1', 0)
  ],
  [0]
)