0

I have written a program that writes an automaton's diagram from a list of nodes and edges in a dot file and opens it via the unix module in ocaml using imagemagick. It worked fine and it has opened the generated image when compiled and executed on linux but on cygwin, it doesn't work for some reason. I already installed graphviz and imagemagick on cygwin but no luck. Here is the code of the program:

(*d'abord definissons le type automate*)

type automate = {
    etat_initial : int;
    ensemble_des_etats : int list;
    alphabets : char list;
    transitions :(int*char*int) list;
    etats_finaux : int list
};;

(*prenons une variable a1 du type automate qu'on a definit precedemment comme exemple*)

let a1={
    etat_initial=1;
    ensemble_des_etats=[1;2];
    alphabets=['a';'b'];
    transitions=[(1,'a',1);(1,'b',2);(2,'a',2);(2,'b',1)];
    etats_finaux=[2]
};;

(*pour tester si un automate est complet ou non on a besoin de trois fonctions*)
(*la premiere donne l'image d'un couple (etat,caractere) par une transition*)

let rec image e a t= 
match t with 
[]->[]
|x::l-> let (i,j,k)=x in if (i=e && j=a) then k::(image e a l) 
else image e a l ;;

(*la deuxieme donne une liste qui contient tout les couples d'un etat (etat,caractere)
 qui n'ont pas d'image donc si image e la lt=[] cela veut dire que l'automate est n'est pas complet dans cet etat*)

let rec nodef e la lt=
match la with
| [] -> []
| a::la'-> if image e a lt = [] then (e,a)::nodef e la' lt else nodef e la' lt;;

(*la troisieme applique nodef sur tout les element d'une liste*)

let rec est_complet le la lt =
match le with
| [] -> []
| e::le'-> nodef e la lt :: est_complet le' la lt;;

  (*ici c'est l'application directe de toutes les fonctions precedentes sur un automate*)

let complet auto=
if est_complet auto.ensemble_des_etats auto.alphabets auto.transitions = []
then true else false ;;

(*la partie qui teste est ce qu'un automate est complet termine ici*)
(*on s'interesse maintenant a faire une fonction qui teste si un automate est deterministe*)
(*d'abord on realie la fonction membre qui retourne true si un element donné en parametre est membre d'une liste false sinon*)

let rec membre a l =
    match l with
    | [] -> false
    | x::rl -> x=a || membre a rl;;

(*ensuite on definie deux fonctions dans une*) 

let est_det a=

(*la premiere pour voir si une liste contient des doublons*)

let rec appartient l = match l with 
[] -> false
| x::r -> (membre x r) || (appartient r);

in

(*la deuxieme pour rendre une liste de paires a partir d'une qui contenait des triplets*)

let rec mettre_en_couple l =
match l with
|[]->[]
|(a,b,c)::l1->(a,b)::mettre_en_couple l1;

in

(*et enfin on applique la premiere fonction sur la liste rendu par la deuxieme*)

let l = mettre_en_couple a
in
appartient l;;

let deterministe auto=
if est_det auto.transitions=false then true else false;;

(*ici c'est l'application directe de toutes les fonctions precedentes sur un automate*)

(*pour representer un automate graphiquement en utilisant graphviz on necessite 4 fonctions*)

(*la premiere pour ecrire dans un fichier qui sera passé par la sortie standard stdout vers la fonction dessiner_automate,le fichier fmt
 contiendra la description suivant la condition appliqué a une transition de l'automate du graph en langage dot*)
let fmt_transition auto fmt (inedge,by,outedge)=
    if membre outedge auto.etats_finaux=true then
 Format.fprintf fmt "@[node [shape = doublecircle]%d;@]" outedge;
 if inedge=auto.etat_initial then
 Format.fprintf fmt "@[node [shape = point]start;node [shape = circle];start -> %d ;@]"inedge ;
 Format.fprintf fmt "@[%d -> %d [label=\"%c\"];@]" inedge outedge by;;
(*la deuxieme fonction levera la premiere sur toute les transitions de l'automate *)
let fmt_transitions fmt auto=
 Format.fprintf fmt "@[<v 2>digraph output {@,%a@,@]}@,@."
  (Format.pp_print_list (fmt_transition auto)) auto.transitions
;;
(*la troisieme va lancer la commande d'affichage de l'image genere par le fichier dot passe en parametre dans 
un environement linux depuis ocaml *)
let dessiner_automate auto =
  let cmd = "dot -Tpng | display -" in
  let (sout, sin, serr) as channels =
    Unix.open_process_full cmd (Unix.environment ()) in
  let fmt = Format.formatter_of_out_channel sin in
  Format.fprintf fmt "%a@." fmt_transitions auto;
  channels 

let cleanup channels =
  (* missing: flush channels, empty buffers *)
  Unix.close_process_full channels;;

  dessiner_automate a1 ;;

print_newline()
Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
  • cygwin terminal is text mode not graphic. May be you should run in a Xterm under X ? – matzeri Feb 11 '17 at 10:34
  • i installed the xinit and xorg packages tried executing the program nothing appears when i run display it says unable to open xserver –  Feb 11 '17 at 10:52
  • This is more a cygwin problem. Did you try to display an image with 'display' program ? – Pierre G. Feb 11 '17 at 11:25
  • Read `https://x.cygwin.com/docs/ug/using.html` to understand how to start the X Server and the Xterm – matzeri Feb 11 '17 at 11:46
  • when i try to use display it says unable to start xserver –  Feb 11 '17 at 16:19
  • You are NOT running display from inside Xterm. You are likely using the Cygwin Terminal – matzeri Feb 11 '17 at 19:41

0 Answers0