aboutsummaryrefslogtreecommitdiff
path: root/regex.ml
blob: e0b7b354c578aa27b97404f82de430ab49c76afb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
include List

type letter = string
type alphabet = letter list
type state = int
type transition = state * letter * state
type trans_func = transition list

type regex =
  | Empty
  | Epsilon
  | Letter of letter
  | Plus of regex * regex
  | Concat of regex * regex
  | Star of regex

(* <E, Q, q0, d, F> *)
type automaton = Automaton of alphabet * (state list) * state * trans_func * (state list)

let rec big_plus letters = 
  match letters with
  | [] -> Empty
  | "" :: [] -> Epsilon
  | l :: [] -> Letter l
  | "" :: tl -> Plus (Epsilon,  big_plus tl)
  | l :: tl -> Plus ((Letter l), (big_plus tl))

let basic_regexes states delta =
  let get_letters_aux s1 s2 = 
    List.map 
      (fun (w,l,v) -> l) 
      (List.filter (fun (w,l,v) -> w = s1 && v = s2) delta)
  in let get_letters s1 s2 =
    let res = (get_letters_aux s1 s2) in
    if s1 = s2 then "" :: res else res
  in let gen_basic state =  
    List.map big_plus (List.map (get_letters state) states)
  in List.map gen_basic states
 
let s = [0;1;2;3;4];;
let delta = [ (0, "a", 0); (0, "b", 1); 
              (1, "a", 2); (1, "b", 1); 
              (2, "a", 0); (2, "b", 3);
              (3, "a", 4); (3, "b", 1);
              (4, "a", 4); (4, "b", 4)]

let rec iter_list = function
  | 0 -> [0]
  | n -> n :: iter_list (n - 1)

let rec iter n = List.rev (iter_list (n-1))

let increment_phis states_num regexes k = 
  let ijth i j = (List.nth (List.nth regexes i) j) in 
  let increment_regex i j =
    let rij = (ijth i j) in
    let rik = (ijth i k) in
    let rkk = (ijth k k) in
    let rkj = (ijth k j) in
    Plus (rij, Concat (rik, Concat (Star rkk, rkj))) in
  let incr_for_i i = List.map (fun j -> increment_regex i j) (iter states_num) in
  List.map incr_for_i (iter states_num)

let get_results states_num delta = 
  let states = iter states_num in
  let regexes = basic_regexes states delta in
  let rec update_regexes regexes k =
    if k = states_num then regexes else
      update_regexes (increment_phis states_num regexes k) (k+1) in
  update_regexes regexes 1

let rec string_of_regex regex = 
  match regex with
    | Empty -> "∅"
    | Epsilon -> "ε"
    | Letter l -> l
    | Plus (phi1, phi2) -> "(" ^ (string_of_regex phi1) ^ ") + (" ^ (string_of_regex phi2) ^ ")"
    | Concat (phi1, phi2) ->  (string_of_regex phi1) ^ (string_of_regex phi2)
    | Star phi -> "(" ^ (string_of_regex phi) ^ ")*"

let pp_print_regex fmtr f =
  Format.pp_print_string fmtr (string_of_regex f)