-
Notifications
You must be signed in to change notification settings - Fork 0
/
tfile.ml
96 lines (82 loc) · 3.58 KB
/
tfile.ml
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
open Graph
open Printf
type path = string
(* Input text file's format :
*
* S id cap -> Source (Provider) 's id with its supply's capacity
* D id cap -> Destination (Consumer) 's id with its demand's capacity
*
* C id1 id2 cap -> Transport road between two points with its capacity
*)
(*-------------------------------------------------------------*)
(*This auxiliary function read source nodes from a line and write in output file an arc between an "imaginary" main source and these sources*)
let read_source line outfile =
try Scanf.sscanf line "S %s \"%s@\"" (fun id label ->
fprintf outfile "v %s\n" id;
fprintf outfile "e \"%s\" S %s\n" label id)
with e ->
Printf.printf "Cannot read source line - %s:\n%s\n" (Printexc.to_string e) line ;
failwith "read_source"
(*-------------------------------------------------------------*)
(*This auxiliary function read destination nodes from a line and write in output file an arc between these destinations and an "imaginary" main destination*)
let read_destination line outfile =
try Scanf.sscanf line "D %s \"%s@\"" (fun id label ->
fprintf outfile "v %s\n" id;
fprintf outfile "e \"%s\" %s D\n" label id;)
with e ->
Printf.printf "Cannot read destination line - %s:\n%s\n" (Printexc.to_string e) line ;
failwith "read_destination"
(*-------------------------------------------------------------*)
(*This auxiliary function read transport roads between 2 points from a line and write in output file an arc between them*)
let read_transport line outfile =
try Scanf.sscanf line "C %s %s \"%s@\"" (fun id1 id2 label ->
fprintf outfile "e \"%s\" %s %s\n" label id1 id2;)
with e ->
Printf.printf "Cannot read line - %s:\n%s\n" (Printexc.to_string e) line ;
failwith "read_transport"
(*-------------------------------------------------------------*)
(*This function uses all auxiliary above to translate a transport problem into a text-fomatted graph file*)
let create_file infile outfile =
let fx = open_in infile in
let ff = open_out outfile in
(* Create 2 points : Source and Destination*)
fprintf ff "v S\n";
fprintf ff "v D\n";
(* Read all lines until end of file. *)
let rec loop () =
try
let line = input_line fx in
let () =
(* Ignore empty lines *)
if line = "" then ()
(* The first character of a line determines its content : S, D or C.
* Else it will be ignored *)
else match line.[0] with
| 'S' -> read_source line ff
| 'D' -> read_destination line ff
| 'C' -> read_transport line ff
| _ -> ()
in
loop ()
with End_of_file -> ()
in
loop ();
close_out ff;
close_in fx;
()
(*-------------------------------------------------------------*)
(*This function export a formatted graph file so it can be converted into an image*)
let export path graph =
(* Open a write-file. *)
let ff = open_out path in
(* Write in this file. *)
fprintf ff "digraph finite_state_machine {\n" ;
fprintf ff " rankdir=LR;\n" ;
fprintf ff " size=\"8,5\"\n" ;
fprintf ff " node [shape = circle];\n";
(* Write all arcs *)
(*The output graph must not contain 2 "imaginary" points : the "main" source and the "main" destination*)
v_iter graph (fun id out -> if (id <> "S" && id <> "D") then List.iter (fun (id2, lbl) -> if (id2 <> "D" && id2 <> "S") then fprintf ff " %s -> %s [ label = \"%s\" ]; \n" id id2 lbl) out) ;
fprintf ff "}" ;
close_out ff ;
()