diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..639900d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..9f81b59 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/ocaml-maxflow-project.iml b/.idea/ocaml-maxflow-project.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/ocaml-maxflow-project.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/_build/_digests b/_build/_digests new file mode 100644 index 0000000..76f0837 --- /dev/null +++ b/_build/_digests @@ -0,0 +1,17 @@ +"Rule: ocaml dependencies mli (%=src/gfile )": "7\182\192g\020\238\188\b\211\164{\014\157\135\011\003" +"Rule: ocaml dependencies ml (%=src/ftest )": "'P\029\247\232H;\197;\234_.z\180e9" +"Rule: ocaml: ml & cmi -> cmx & o (%=src/gfile )": "\185\022\131\212\239\224%\026)\232P\180\192Y\211\025" +"Resource: /home/chepycou/Documents/cours/4-IR/functionalProgramming/Projet/repoGit/ocaml-maxflow-project/src/ftest.ml": "\007\196\023\203\192\230\143\1569\199\162\136\173\005;S" +"Rule: ocaml: mli -> cmi (%=src/graph )": "ZJ:\176\2527A6\005k\191 native (%=src/ftest )": "\135\153\250\007\138U\234`\236\163^\171A\192\165\191" +"Rule: ocaml: ml & cmi -> cmx & o (%=src/ftest )": "\245\229K\\\218\250\197(,\245;\1710]\011\128" +"Resource: /home/chepycou/Documents/cours/4-IR/functionalProgramming/Projet/repoGit/ocaml-maxflow-project/src/graph.ml": "\005\175.\2458\176E\202]\255\235=9\015\000\237" +"Rule: ocaml: mli -> cmi (%=src/gfile )": "\2028\135\152o,Y9\219\178\241C\150A*\209" +"Rule: ocaml: ml -> cmo & cmi (%=src/ftest )": "\207\216\168\169\164\213\209`\157N=/\002\tQ\157" +"Resource: /home/chepycou/Documents/cours/4-IR/functionalProgramming/Projet/repoGit/ocaml-maxflow-project/src/gfile.ml": "\1966\177\141\185,fpl\1987gT\128b\028" +"Rule: ocaml: ml & cmi -> cmx & o (%=src/graph )": "\202s\156\178Lm\165*\224l\179\219N\006\193\000" +"Rule: ocaml dependencies ml (%=src/graph )": "\137kk#\140\236\011\255?\132T\225M\018\169\224" +"Rule: ocaml dependencies mli (%=src/graph )": "\b\217\022sE\156(F\165M\014)D\182\178e" +"Resource: /home/chepycou/Documents/cours/4-IR/functionalProgramming/Projet/repoGit/ocaml-maxflow-project/src/gfile.mli": "\203\249\163Ct\234\0067d}\142\011m8T`" +"Rule: ocaml dependencies ml (%=src/gfile )": "U4(<\t=rQ\240c\0278\231N\1949" diff --git a/_build/_log b/_build/_log new file mode 100644 index 0000000..55d0bff --- /dev/null +++ b/_build/_log @@ -0,0 +1,26 @@ +### Starting build. +# Target: src/ftest.ml.depends, tags: { extension:ml, file:src/ftest.ml, include, ocaml, ocamldep, quiet, traverse } +/home/chepycou/.opam/4.14.0/bin/ocamldep.opt -modules src/ftest.ml > src/ftest.ml.depends # cached +# Target: src/gfile.mli.depends, tags: { extension:mli, file:src/gfile.mli, include, ocaml, ocamldep, quiet, traverse } +/home/chepycou/.opam/4.14.0/bin/ocamldep.opt -modules src/gfile.mli > src/gfile.mli.depends # cached +# Target: src/graph.mli.depends, tags: { extension:mli, file:src/graph.mli, include, ocaml, ocamldep, quiet, traverse } +/home/chepycou/.opam/4.14.0/bin/ocamldep.opt -modules src/graph.mli > src/graph.mli.depends # cached +# Target: src/graph.cmi, tags: { byte, compile, extension:mli, file:src/graph.mli, include, interf, ocaml, quiet, traverse } +/home/chepycou/.opam/4.14.0/bin/ocamlc.opt -c -I src -o src/graph.cmi src/graph.mli # cached +# Target: src/gfile.cmi, tags: { byte, compile, extension:mli, file:src/gfile.mli, include, interf, ocaml, quiet, traverse } +/home/chepycou/.opam/4.14.0/bin/ocamlc.opt -c -I src -o src/gfile.cmi src/gfile.mli # cached +# Target: src/ftest.cmo, tags: { byte, compile, extension:cmo, extension:ml, file:src/ftest.cmo, file:src/ftest.ml, implem, include, ocaml, quiet, traverse } +/home/chepycou/.opam/4.14.0/bin/ocamlc.opt -c -I src -o src/ftest.cmo src/ftest.ml # cached +# Target: src/gfile.ml.depends, tags: { extension:ml, file:src/gfile.ml, include, ocaml, ocamldep, quiet, traverse } +/home/chepycou/.opam/4.14.0/bin/ocamldep.opt -modules src/gfile.ml > src/gfile.ml.depends # cached +# Target: src/graph.ml.depends, tags: { extension:ml, file:src/graph.ml, include, ocaml, ocamldep, quiet, traverse } +/home/chepycou/.opam/4.14.0/bin/ocamldep.opt -modules src/graph.ml > src/graph.ml.depends # cached +# Target: src/graph.cmx, tags: { compile, extension:cmx, extension:ml, file:src/graph.cmx, file:src/graph.ml, implem, include, native, ocaml, quiet, traverse } +/home/chepycou/.opam/4.14.0/bin/ocamlopt.opt -c -I src -o src/graph.cmx src/graph.ml # cached +# Target: src/gfile.cmx, tags: { compile, extension:cmx, extension:ml, file:src/gfile.cmx, file:src/gfile.ml, implem, include, native, ocaml, quiet, traverse } +/home/chepycou/.opam/4.14.0/bin/ocamlopt.opt -c -I src -o src/gfile.cmx src/gfile.ml # cached +# Target: src/ftest.cmx, tags: { compile, extension:cmx, extension:ml, file:src/ftest.cmx, file:src/ftest.ml, implem, include, native, ocaml, quiet, traverse } +/home/chepycou/.opam/4.14.0/bin/ocamlopt.opt -c -I src -o src/ftest.cmx src/ftest.ml # cached +# Target: src/ftest.native, tags: { dont_link_with, extension:native, file:src/ftest.native, include, link, native, ocaml, program, quiet, traverse } +/home/chepycou/.opam/4.14.0/bin/ocamlopt.opt -I src src/graph.cmx src/gfile.cmx src/ftest.cmx -o src/ftest.native # cached +# Compilation successful. diff --git a/_build/ocamlc.where b/_build/ocamlc.where new file mode 100644 index 0000000..8f0bc6b --- /dev/null +++ b/_build/ocamlc.where @@ -0,0 +1 @@ +/home/chepycou/.opam/4.14.0/lib/ocaml diff --git a/_build/src/ftest.cmi b/_build/src/ftest.cmi new file mode 100644 index 0000000..c4330dd Binary files /dev/null and b/_build/src/ftest.cmi differ diff --git a/_build/src/ftest.cmo b/_build/src/ftest.cmo new file mode 100644 index 0000000..0104d9c Binary files /dev/null and b/_build/src/ftest.cmo differ diff --git a/_build/src/ftest.cmx b/_build/src/ftest.cmx new file mode 100644 index 0000000..b50bfa3 Binary files /dev/null and b/_build/src/ftest.cmx differ diff --git a/_build/src/ftest.ml b/_build/src/ftest.ml new file mode 100644 index 0000000..80489df --- /dev/null +++ b/_build/src/ftest.ml @@ -0,0 +1,35 @@ +open Gfile + +let () = + + (* Check the number of command-line arguments *) + if Array.length Sys.argv <> 5 then + begin + Printf.printf + "\n ✻ Usage: %s infile source sink outfile\n\n%s%!" Sys.argv.(0) + (" 🟄 infile : input file containing a graph\n" ^ + " 🟄 source : identifier of the source vertex (used by the ford-fulkerson algorithm)\n" ^ + " 🟄 sink : identifier of the sink vertex (ditto)\n" ^ + " 🟄 outfile : output file in which the result should be written.\n\n") ; + exit 0 + end ; + + + (* Arguments are : infile(1) source-id(2) sink-id(3) outfile(4) *) + + let infile = Sys.argv.(1) + and outfile = Sys.argv.(4) + + (* These command-line arguments are not used for the moment. *) + and _source = int_of_string Sys.argv.(2) + and _sink = int_of_string Sys.argv.(3) + in + + (* Open file *) + let graph = from_file infile in + + (* Rewrite the graph that has been read. *) + let () = write_file outfile graph in + + () + diff --git a/_build/src/ftest.ml.depends b/_build/src/ftest.ml.depends new file mode 100644 index 0000000..a3b0417 --- /dev/null +++ b/_build/src/ftest.ml.depends @@ -0,0 +1 @@ +src/ftest.ml: Array Gfile Printf Sys diff --git a/_build/src/ftest.native b/_build/src/ftest.native new file mode 100755 index 0000000..459a763 Binary files /dev/null and b/_build/src/ftest.native differ diff --git a/_build/src/ftest.o b/_build/src/ftest.o new file mode 100644 index 0000000..fc2cec1 Binary files /dev/null and b/_build/src/ftest.o differ diff --git a/_build/src/gfile.cmi b/_build/src/gfile.cmi new file mode 100644 index 0000000..528fcc4 Binary files /dev/null and b/_build/src/gfile.cmi differ diff --git a/_build/src/gfile.cmx b/_build/src/gfile.cmx new file mode 100644 index 0000000..865caea Binary files /dev/null and b/_build/src/gfile.cmx differ diff --git a/_build/src/gfile.ml b/_build/src/gfile.ml new file mode 100644 index 0000000..9599cc3 --- /dev/null +++ b/_build/src/gfile.ml @@ -0,0 +1,101 @@ +open Graph +open Printf + +type path = string + +(* Format of text files: + % This is a comment + + % A node with its coordinates (which are not used). + n 88.8 209.7 + n 408.9 183.0 + + % The first node has id 0, the next is 1, and so on. + + % Edges: e source dest label + e 3 1 11 + e 0 2 8 + +*) + +let write_file path graph = + + (* Open a write-file. *) + let ff = open_out path in + + (* Write in this file. *) + fprintf ff "%% This is a graph.\n\n" ; + + (* Write all nodes (with fake coordinates) *) + n_iter_sorted graph (fun id -> fprintf ff "n %.1f 1.0\n" (float_of_int id)) ; + fprintf ff "\n" ; + + (* Write all arcs *) + e_iter graph (fun id1 id2 lbl -> fprintf ff "e %d %d %s\n" id1 id2 lbl) ; + + fprintf ff "\n%% End of graph\n" ; + + close_out ff ; + () + +(* Reads a line with a node. *) +let read_node id graph line = + try Scanf.sscanf line "n %f %f" (fun _ _ -> new_node graph id) + with e -> + Printf.printf "Cannot read node in line - %s:\n%s\n%!" (Printexc.to_string e) line ; + failwith "from_file" + +(* Ensure that the given node exists in the graph. If not, create it. + * (Necessary because the website we use to create online graphs does not generate correct files when some nodes have been deleted.) *) +let ensure graph id = if node_exists graph id then graph else new_node graph id + +(* Reads a line with an arc. *) +let read_arc graph line = + try Scanf.sscanf line "e %d %d %s" + (fun id1 id2 label -> new_arc (ensure (ensure graph id1) id2) id1 id2 label) + with e -> + Printf.printf "Cannot read arc in line - %s:\n%s\n%!" (Printexc.to_string e) line ; + failwith "from_file" + +(* Reads a comment or fail. *) +let read_comment graph line = + try Scanf.sscanf line " %%" graph + with _ -> + Printf.printf "Unknown line:\n%s\n%!" line ; + failwith "from_file" + +let from_file path = + + let infile = open_in path in + + (* Read all lines until end of file. + * n is the current node counter. *) + let rec loop n graph = + try + let line = input_line infile in + + (* Remove leading and trailing spaces. *) + let line = String.trim line in + + let (n2, graph2) = + (* Ignore empty lines *) + if line = "" then (n, graph) + + (* The first character of a line determines its content : n or e. *) + else match line.[0] with + | 'n' -> (n+1, read_node n graph line) + | 'e' -> (n, read_arc graph line) + + (* It should be a comment, otherwise we complain. *) + | _ -> (n, read_comment graph line) + in + loop n2 graph2 + + with End_of_file -> graph (* Done *) + in + + let final_graph = loop 0 empty_graph in + + close_in infile ; + final_graph + diff --git a/_build/src/gfile.ml.depends b/_build/src/gfile.ml.depends new file mode 100644 index 0000000..8f15142 --- /dev/null +++ b/_build/src/gfile.ml.depends @@ -0,0 +1 @@ +src/gfile.ml: Graph Printexc Printf Scanf String diff --git a/_build/src/gfile.mli b/_build/src/gfile.mli new file mode 100644 index 0000000..465e693 --- /dev/null +++ b/_build/src/gfile.mli @@ -0,0 +1,18 @@ +(* Read a graph from a file, + * Write a graph to a file. *) + +open Graph + +type path = string + +(* Values are read as strings. *) +val from_file: path -> string graph + +(* Similarly, we write only a string graph. + * If necessary, use gmap (to be written by you) to prepare the input graph. *) +val write_file: path -> string graph -> unit + + +(* The format of files is compatible with the files generated by: + https://algorithms.discrete.ma.tum.de/graph-algorithms/flow-ford-fulkerson/index_en.html +*) diff --git a/_build/src/gfile.mli.depends b/_build/src/gfile.mli.depends new file mode 100644 index 0000000..ae8dd20 --- /dev/null +++ b/_build/src/gfile.mli.depends @@ -0,0 +1 @@ +src/gfile.mli: Graph diff --git a/_build/src/gfile.o b/_build/src/gfile.o new file mode 100644 index 0000000..52f4f59 Binary files /dev/null and b/_build/src/gfile.o differ diff --git a/_build/src/graph.cmi b/_build/src/graph.cmi new file mode 100644 index 0000000..a1a8cfb Binary files /dev/null and b/_build/src/graph.cmi differ diff --git a/_build/src/graph.cmx b/_build/src/graph.cmx new file mode 100644 index 0000000..34042ca Binary files /dev/null and b/_build/src/graph.cmx differ diff --git a/_build/src/graph.ml b/_build/src/graph.ml new file mode 100644 index 0000000..2bef130 --- /dev/null +++ b/_build/src/graph.ml @@ -0,0 +1,49 @@ +type id = int + +type 'a out_arcs = (id * 'a) list + +(* A graph is just a list of pairs: a node & its outgoing arcs. *) +type 'a graph = (id * 'a out_arcs) list + +exception Graph_error of string + +let empty_graph = [] + +let node_exists gr id = List.mem_assoc id gr + +let out_arcs gr id = + try List.assoc id gr + with Not_found -> raise (Graph_error ("Node " ^ string_of_int id ^ " does not exist in this graph.")) + +let find_arc gr id1 id2 = + let out = out_arcs gr id1 in + try Some (List.assoc id2 out) + with Not_found -> None + +let new_node gr id = + if node_exists gr id then raise (Graph_error ("Node " ^ string_of_int id ^ " already exists in the graph.")) + else (id, []) :: gr + +let new_arc gr id1 id2 lbl = + + (* Existing out-arcs *) + let outa = out_arcs gr id1 in + + (* Update out-arcs. + * remove_assoc does not fail if id2 is not bound. *) + let outb = (id2, lbl) :: List.remove_assoc id2 outa in + + (* Replace out-arcs in the graph. *) + let gr2 = List.remove_assoc id1 gr in + (id1, outb) :: gr2 + +let n_iter gr f = List.iter (fun (id, _) -> f id) gr + +let n_iter_sorted gr f = n_iter (List.sort compare gr) f + +let n_fold gr f acu = List.fold_left (fun acu (id, _) -> f acu id) acu gr + +let e_iter gr f = List.iter (fun (id1, out) -> List.iter (fun (id2, x) -> f id1 id2 x) out) gr + +let e_fold gr f acu = List.fold_left (fun acu (id1, out) -> List.fold_left (fun acu (id2, x) -> f acu id1 id2 x) acu out) acu gr + diff --git a/_build/src/graph.ml.depends b/_build/src/graph.ml.depends new file mode 100644 index 0000000..c3353fc --- /dev/null +++ b/_build/src/graph.ml.depends @@ -0,0 +1 @@ +src/graph.ml: List diff --git a/_build/src/graph.mli b/_build/src/graph.mli new file mode 100644 index 0000000..dd9c265 --- /dev/null +++ b/_build/src/graph.mli @@ -0,0 +1,63 @@ + +(* Type of a directed graph in which arcs have labels of type 'a. *) +type 'a graph + +(* Each node has a unique identifier (a number). *) +type id = int + +exception Graph_error of string + + +(************** CONSTRUCTORS **************) + +(* The empty graph. *) +val empty_graph: 'a graph + +(* Add a new node with the given identifier. + * @raise Graph_error if the id already exists. *) +val new_node: 'a graph -> id -> 'a graph + +(* new_arc gr id1 id2 lbl : adds an arc from node id1 to node id2 with label lbl + * Both nodes must already exist in the graph. + * If the arc already exists, its label is replaced by lbl. + * @raise Graph_error if node id1 or id2 does not exist in the graph. *) +val new_arc: 'a graph -> id -> id -> 'a -> 'a graph + + +(************** GETTERS *****************) + +(* node_exists gr id indicates if the node with identifier id exists in graph gr. *) +val node_exists: 'a graph -> id -> bool + +(* Type of lists of outgoing arcs of a node. + * An arc is represented by a pair of the destination identifier and the arc label. *) +type 'a out_arcs = (id * 'a) list + +(* Find the out_arcs of a node. + * @raise Graph_error if the id is unknown in the graph. *) +val out_arcs: 'a graph -> id -> 'a out_arcs + +(* find_arc gr id1 id2 finds an arc between id1 and id2 and returns its label. Returns None if the arc does not exist. +* @raise Graph_error if id1 is unknown. *) +val find_arc: 'a graph -> id -> id -> 'a option + + +(************** COMBINATORS, ITERATORS **************) + +(* Iterate on all nodes, in no special order. *) +val n_iter: 'a graph -> (id -> unit) -> unit + +(* Like n_iter, but the nodes are sorted. *) +val n_iter_sorted: 'a graph -> (id -> unit) -> unit + +(* Fold on all (unsorted) nodes. You must remember what List.fold_left does. *) +val n_fold: 'a graph -> ('b -> id -> 'b) -> 'b -> 'b + + +(* Iter on all arcs (edges) *) +val e_iter: 'a graph -> (id -> id -> 'a -> unit) -> unit + +(* Fold on all arcs (edges) *) +val e_fold: 'a graph -> ('b -> id -> id -> 'a -> 'b) -> 'b -> 'b + + diff --git a/_build/src/graph.mli.depends b/_build/src/graph.mli.depends new file mode 100644 index 0000000..3515964 --- /dev/null +++ b/_build/src/graph.mli.depends @@ -0,0 +1 @@ +src/graph.mli: diff --git a/_build/src/graph.o b/_build/src/graph.o new file mode 100644 index 0000000..638e174 Binary files /dev/null and b/_build/src/graph.o differ diff --git a/ftest.native b/ftest.native new file mode 120000 index 0000000..e1b4378 --- /dev/null +++ b/ftest.native @@ -0,0 +1 @@ +/home/chepycou/Documents/cours/4-IR/functionalProgramming/Projet/repoGit/ocaml-maxflow-project/_build/src/ftest.native \ No newline at end of file