Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
(* TD 2 : Compilation d'automates *) (* 2.1.1 Type d'un automate *) type 'a automate = { n:int; i:int list; a:'a list; t:((int*'a)*(int list)) list; f:int list };; (* 2.1.2 Exemple d'automate reconnaissant (a+b)*ab *) let a1 = { n=3; i=[1]; a=['a';'b']; t=[((1,'a'),[1;2]);((1,'b'),[1]);((2,'b'),[3])]; f=[3] };; (* 2.1.3 Conversion d'un fichier en automate *) let lire_nombre_etats c = int_of_string (input_line c);; let rec lire_alphabet c = let s = (input_line c).[0] in if s='.' then [] else s::(lire_alphabet c);; let rec lire_etats c = let s = input_line c in if s.[0]='.' then [] else (int_of_string s)::(lire_etats c);; let rec add_in_transition_list (a,b) = function [] -> [(a,[b])] | ((c,dl)::l) when c=a -> (c,b::dl)::l | (cd::l) -> cd::(add_in_transition_list (a,b) l);; let rec lire_transitions c = let s = input_line c in if s.[0]='.' then [] else let b1 = (String.index s ' ')+1 in let i = int_of_string (String.sub s 0 (b1-1)) and j = int_of_string (String.sub s (b1+2) (String.length s -b1-2) ) in add_in_transition_list ((i,s.[b1]),j) (lire_transitions c);; let lire_automate fichier = let canal = open_in fichier in let n=lire_nombre_etats canal and a=lire_alphabet canal and i=lire_etats canal and t=lire_transitions canal and f=lire_etats canal in close_in canal; {n=n;a=a;i=i;t=t;f=f};; let a2 = lire_automate "aut_deterministe";; (* l'automate de la section 1.3 *) (* 2.1.4 Ecriture d'un automate en fichier *) let rec ecrire_alphabet c = function [] -> output_string c ".\n" | (a::l) -> output_char c a; output_char c '\n'; ecrire_alphabet c l;; let rec ecrire_etats c = function [] -> output_string c ".\n" | (a::l) -> output_string c ((string_of_int a)^"\n"); ecrire_etats c l;; let rec ecrire_transitions c = function [] -> output_string c ".\n" | (((i,a),tl)::l) -> List.iter (fun j -> output_string c ((string_of_int i) ^" "^(String.make 1 a)^" "^(string_of_int j)^"\n") ) tl; ecrire_transitions c l;; let ecrire_automate aut fichier = let canal = open_out fichier in output_string canal ((string_of_int aut.n)^"\n"); ecrire_alphabet canal aut.a; ecrire_etats canal aut.i; ecrire_transitions canal aut.t; ecrire_etats canal aut.f; close_out canal;; ecrire_automate a1 "automate1";; (* 2.1.5 Algo impératif de reconnaissance pour automate déterministe *) let fin_de_chaine = '\004';; (* ctrl+D *) let carSuiv alphabet = let c = input_char stdin in if List.mem c alphabet then c else fin_de_chaine;; let purger_reste_ligne () = ignore (input_line stdin);; let reconnaitre aut = let q = ref (List.hd aut.i) and c = ref (carSuiv aut.a) and fin = ref false in while (!c<>fin_de_chaine && not !fin) do try q:=List.hd (List.assoc (!q,!c) aut.t); c:=carSuiv aut.a with Not_found -> fin:=true done; purger_reste_ligne(); (not !fin) && (List.mem !q aut.f);; print_string "Entrez une ligne à reconnaitre (impératif) avec a2\n";; reconnaitre a2;; (* 2.1.6 Algo récursif de reconnaissance pour automate déterministe *) let rec cheminer aut = let c = carSuiv aut.a in if c = fin_de_chaine then List.hd aut.i else try cheminer {aut with i=List.assoc (List.hd(aut.i), c) aut.t} with Not_found -> 0;; let reconnaitre_rec aut = let q = cheminer aut in purger_reste_ligne(); List.mem q aut.f;; print_string "Entrez une ligne à reconnaitre (récursif) avec a2\n";; reconnaitre_rec a2;; (* 2.1.8 Compilateur d'automate en programme CAML *) let rec compil_par_etat aut n = if n>0 then (compil_par_etat aut (n-1))^ "\t| "^(string_of_int n)^" -> ( match carSuiv !alphabet with \n"^ (String.concat "" (List.map (function ((q,c),l) when q=n -> "\t\t| '"^(String.make 1 c)^"' -> automate "^ (string_of_int (List.hd l))^"\n" | _ -> "" ) aut.t))^ (if List.mem n aut.f then "\t\t| c -> c=fin_de_chaine )\n" else "\t\t| _ -> false )\n") else "";; let alphabet = ref [];; let compilateur aut = alphabet := aut.a; print_string ("let autom () = let rec automate = function \n"^ (compil_par_etat aut aut.n)^ "\t| _ -> raise (Failure \"Erreur dans l'automate\") in \n"^ "let r = automate "^(string_of_int (List.hd aut.i))^ " in \n purger_reste_ligne (); r;;\n");; compilateur a2;;