Graphics 如何在不使用循环的情况下,从表示转换的int*char*int列表中以图形方式表示自动机

Graphics 如何在不使用循环的情况下,从表示转换的int*char*int列表中以图形方式表示自动机,graphics,functional-programming,ocaml,automata,Graphics,Functional Programming,Ocaml,Automata,我制作了一个名为automaton的记录,其中包含表示自动机所需的5个字段。我应该使用图形来表示转换列表中的每个状态和转换,而不使用for或while循环,只使用递归函数 transitions :(int*char*int) list; 这可能是最容易用来绘制实际图形的方法。它会自动从节点和边列表中绘制图形,这正是您的输入。函数fmt_转换生成一条边,函数fmt_转换将其提升到转换列表中,并将其包装到正确的标题中 let fmt_transition fmt (inedge,by,outed

我制作了一个名为automaton的记录,其中包含表示自动机所需的5个字段。我应该使用图形来表示转换列表中的每个状态和转换,而不使用for或while循环,只使用递归函数

transitions :(int*char*int) list;

这可能是最容易用来绘制实际图形的方法。它会自动从节点和边列表中绘制图形,这正是您的输入。函数
fmt_转换
生成一条边,函数
fmt_转换
将其提升到转换列表中,并将其包装到正确的标题中

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)
结果:

digraph output
{
   1 -> 2 [label="a"];
   2 -> 1 [label="b"];
   1 -> 1 [label="b"];
}
对graphviz的调用是:

dot -T pdf -o output.pdf < input.dot
调用
call_dot test1 |>cleanup
将数据发送到dot并打开ghostview。为防止达到打开文件的限制,一声喊叫将等待进程终止并关闭通道,这在
清理
中完成


如果您想改用图像库,可能需要将cmd的定义替换为“dot-Tpng”,并在调用cleanup之前从stdin读取图像数据。

这可能是最容易用于实际绘图的方法。它会自动从节点和边列表中绘制图形,这正是您的输入。函数
fmt_转换
生成一条边,函数
fmt_转换
将其提升到转换列表中,并将其包装到正确的标题中

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)
结果:

digraph output
{
   1 -> 2 [label="a"];
   2 -> 1 [label="b"];
   1 -> 1 [label="b"];
}
对graphviz的调用是:

dot -T pdf -o output.pdf < input.dot
调用
call_dot test1 |>cleanup
将数据发送到dot并打开ghostview。为防止达到打开文件的限制,一声喊叫将等待进程终止并关闭通道,这在
清理
中完成


如果您想改用图像库,您可能需要将cmd的定义替换为“dot-Tpng”调用cleanup之前,请先从stdin中读取图像数据。

我知道使用graphviz更容易,但是有没有一种方法可以让我只使用ocaml的图形模块,可能带有一个作用于列表元素的递归函数,也可能是多个函数。另外,我想指出的是,我没有找到输出文件的方法由ocaml从ocaml生成您如何继续取决于您的进一步计划——对于静态数据,将点输出管道化到evince/ghostview就足够了。如果需要用户界面,可以创建一个映像,并使用ocaml gtk绑定。也有,但我没有这方面的经验。在最坏的情况下,您可以使用graphviz的注释输出为节点找到一个好的位置,并使用gdk画布中的低级绘图函数完成其余的工作。但是点文件在哪里?您能给我一个如何使用此示例执行程序的示例吗:让a1={etat_initial=[0];ensemble_des_etas=[1;2];字母表=[a';[b'];过渡=[(1,'a',1);(1,'b',2);(2,'a',2)];最终过渡=[1]};;我知道使用graphviz更容易,但是有没有一种方法可以让我只使用ocaml的图形模块,可以使用作用于列表元素的递归函数,也可以使用多个函数。另外,我想指出的是,我没有找到从ocaml输出ocaml生成的文件的方法。如何使用取决于您的未来她的计划——对于静态数据,将点输出管道化到evince/ghostview中就足够了。如果你想要一个用户界面,你可以创建一个图像,然后使用ocaml gtk绑定。也有,但我没有这方面的经验。在最坏的情况下,你可以使用graphviz的注释输出来为节点找到一个好的位置,而不需要你能给我一个如何用这个例子执行程序的例子吗:让a1={etat_initial=[0];employee_des_etats=[1;2];alphabets=['a';'b'];transitions=[(1,'a',1);(1,'b',2);(2,'a',2)];etats_finaux=[1];;