How can I represent an automaton graphically from a list of int*char*int representing the transitions without using loops

穿精又带淫゛_ 提交于 2019-12-25 07:47:14

问题


I made a record called automaton containing the 5 fields required to represent an automaton I'm supposed to use graphics to represent every state and transition from the transitions list without using for or while loops only recursive functions

transitions :(int*char*int) list;

回答1:


It might be easiest to use graphviz to do the actual drawing. It automatically draws a graph from a list of nodes and edges, which is exactly what your input is. The function fmt_transition generates one edge, the function fmt_transitions lifts it via pp_print_list to lists of transitions and wraps it into the correct header.

let fmt_transition fmt (inedge,by,outedge) =
  Format.fprintf fmt "@[%d -> %d [label=\"%c\"];@]" inedge outedge by

let fmt_transitions fmt =
  Format.fprintf fmt "@[<v 2>digraph output {@,%a@,@]}@,@."
    (Format.pp_print_list fmt_transition)

If we try it on some test data, we get the test file we wanted:

let test1 = [ (1,'a',2); (2,'b',1); (1,'b',1)] in
fmt_transitions Format.std_formatter test1;;

results in:

digraph output
{
   1 -> 2 [label="a"];
   2 -> 1 [label="b"];
   1 -> 1 [label="b"];
}

The call to graphviz is:

dot -T pdf -o output.pdf < input.dot

If you call it directly from ocaml, you can also pipe the data directly into dot without writing it to disk first.

Alternatively, you can also use an external viewer like gv:

let call_dot data =
  let cmd = "dot -Tps | gv -" 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 data;
  channels

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

The call call_dot test1 |> cleanup will send the data to dot and open ghostview. To prevent hitting the limit of open files, one shout await the termination of the process and close the channels, which is done in cleanup.

If you want to use an image library instead, you might want to replace the definition of cmd by "dot -Tpng" and read the image data from stdin before you call cleanup.



来源:https://stackoverflow.com/questions/41780982/how-can-i-represent-an-automaton-graphically-from-a-list-of-intcharint-represe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!