relation.ml
7.88 KB
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
open Xstd
(* type 'a nodes = 'a IntMap.t *)
type 'a edges = 'a IntMap.t IntMap.t
type 'a tree = Tree of int * 'a * 'a tree list | Visited of int * 'a
(* Klucze zewnętrznego słownika określamy jako parent,
klucze wewnętrznego słownika określamy jako child. *)
let empty = IntMap.empty
let add_new r parent child v =
let children = try IntMap.find r parent with Not_found -> IntMap.empty in
if IntMap.mem children child then
failwith ("add_new: " ^ string_of_int parent ^ "-->" ^ string_of_int child ^ " is already in graph")
else
let children = IntMap.add children child v in
IntMap.add r parent children
let add r parent child v =
let children = try IntMap.find r parent with Not_found -> IntMap.empty in
let children = IntMap.add children child v in
IntMap.add r parent children
let add_inc r parent child v merge_fun =
let children = try IntMap.find r parent with Not_found -> IntMap.empty in
let children = IntMap.add_inc children child v (merge_fun v) in
IntMap.add r parent children
let mem_parent r parent =
IntMap.mem r parent
let rec find_descendants_rec r descendants parent =
if IntSet.mem descendants parent then descendants else
let descendants = IntSet.add descendants parent in
let children = try IntMap.find r parent with Not_found -> IntMap.empty in
IntMap.fold children descendants (fun descendants child _ -> find_descendants_rec r descendants child)
let find_descendants r parent =
IntSet.remove (find_descendants_rec r IntSet.empty parent) parent
let test_reverse ra rb =
IntMap.iter ra (fun parent_a children_a ->
IntMap.iter children_a (fun parent_b v ->
try
let children_b = IntMap.find rb parent_b in
if IntMap.mem children_b parent_a then ()
else print_endline ("test_reverse_rel a: " ^ string_of_int parent_a)
with Not_found -> print_endline ("test_reverse_rel b: " ^ string_of_int parent_b)))
let reverse r =
IntMap.fold r IntMap.empty (fun r parent children ->
IntMap.fold children r (fun r child v ->
add r child parent v))
let sum ra rb merge_fun =
IntMap.fold rb ra (fun r parent children ->
IntMap.fold children r (fun r child v ->
add_inc r parent child v merge_fun))
let select_childless selected r =
IntMap.fold r selected (fun selected parent _ ->
IntSet.remove selected parent)
let rec descendants_tree_rec r visited parent v =
if IntSet.mem visited parent then visited, Visited(parent,v) else
let visited = IntSet.add visited parent in
let children = try IntMap.find r parent with Not_found -> IntMap.empty in
let visited, l = IntMap.fold children (visited, []) (fun (visited,l) child v ->
let visited,tree = descendants_tree_rec r visited child v in
visited, tree :: l) in
visited, Tree(parent,v,l)
let descendants_tree r parent v =
snd (descendants_tree_rec r IntSet.empty parent v)
let rec create_spaces n =
if n = 0 then "" else " " ^ (create_spaces (n - 1))
let rec print_tree_rec file node_fun level = function
Tree(parent,cost,children) ->
Printf.fprintf file "%s%s\n" (create_spaces (2*level)) (node_fun parent cost);
Xlist.iter children (print_tree_rec file node_fun (level+1))
| Visited(parent,cost) ->
Printf.fprintf file "%sVISITED %s\n" (create_spaces (2*level)) (node_fun parent cost)
let print_tree file tree node_fun =
print_tree_rec file node_fun 0 tree
let rec create_tree_xml file node_fun = function
Tree(parent,cost,children) ->
Xml.Element("node",node_fun parent cost,Xlist.map children (create_tree_xml file node_fun))
| Visited(parent,cost) ->
Xml.Element("node",node_fun parent cost,[])
let print_tree_xml file tree node_fun =
let xml = create_tree_xml file node_fun tree in
Printf.fprintf file "%s" (Xml.to_string_fmt xml)
let rec print_tree_as_graph_rec file node_fun edge_fun grand_parent = function
Tree(parent,cost,children) ->
Printf.fprintf file " %d [label=\"%s\"]\n" parent (node_fun parent);
if grand_parent <> (-1) then Printf.fprintf file " %d -> %d [label=\"%s\"]\n" grand_parent parent (edge_fun cost);
Xlist.iter children (print_tree_as_graph_rec file node_fun edge_fun parent)
| Visited(parent,cost) ->
Printf.fprintf file " %d [label=\"%s\"]\n" parent (node_fun parent);
if grand_parent <> (-1) then Printf.fprintf file " %d -> %d [label=\"%s\"]\n" grand_parent parent (edge_fun cost)
let print_tree_as_graph path name tree node_fun edge_fun =
File.file_out (path ^ name ^ ".gv") (fun file ->
(*if lr then Printf.fprintf file "digraph G {\n node [shape=box]\n rankdir = LR\n"
else*) Printf.fprintf file "digraph G {\n node [shape=box]\n";
print_tree_as_graph_rec file node_fun edge_fun (-1) tree;
Printf.fprintf file "}\n");
Sys.chdir path;
ignore (Sys.command ("dot -Tpng " ^ name ^ ".gv -o " ^ name ^ ".png"));
Sys.chdir "..";
()
let print file r cost_fun =
IntMap.iter r (fun parent children ->
IntMap.iter children (fun child cost ->
Printf.fprintf file "%d\t%d\t%s\n" parent child (cost_fun cost)))
let rec find_connected_components_rec r is_included_fun visited conn parent =
(* if parent = "28358" then print_endline "find_connected_components_rec 1"; *)
if IntSet.mem visited parent || not (is_included_fun parent) then conn,visited else (
(* if parent = "28358" then print_endline "find_connected_components_rec 2"; *)
let conn = IntSet.add conn parent in
let visited = IntSet.add visited parent in
let l = try IntMap.find r parent with Not_found -> [] in
(* if parent = "28358" then Printf.printf "find_connected_components_rec 3: |conn|=%d\n%!" (IntSet.size conn); *)
Xlist.fold l (conn,visited) (fun (conn,visited) parent ->
find_connected_components_rec r is_included_fun visited conn parent))
let find_connected_components r is_included_fun =
let l,_ = IntMap.fold r ([],IntSet.empty) (fun (l,visited) parent _ ->
if IntSet.mem visited parent then l,visited else
let conn,visited = find_connected_components_rec r is_included_fun visited IntSet.empty parent in
(* if IntSet.mem conn "28358" then print_endline "find_connected_components 1"; *)
conn :: l, visited) in
l
(* find_connected_components r threshold (fun id -> (IntMap.find synmap id).syn_no_hipo >= threshold) *)
(*
(* UWAGA: to działa gdy selektor jest monotoniczny względem relacji *)
let select_node_set edges selected =
IntMap.fold edges IntMap.empty (fun edges pid nodes ->
let nodes = IntSet.fold nodes IntSet.empty (fun nodes id ->
if IntSet.mem selected id then IntSet.add nodes id else nodes) in
if IntSet.is_empty nodes then edges else
IntMap.add edges pid nodes)
let get_all_ids edges =
IntMap.fold edges IntSet.empty (fun ids id nodes ->
IntSet.fold nodes (IntSet.add ids id) IntSet.add)
let select_maximal_ids edges =
let selected = get_all_ids edges in
IntMap.fold edges selected (fun selected _ nodes ->
IntSet.fold nodes selected (fun selected id ->
IntSet.remove selected id))
let select_maximal_ids2 selected edges =
IntMap.fold edges selected (fun selected _ nodes ->
IntSet.fold nodes selected (fun selected id ->
IntSet.remove selected id))
let print_graph path name lr edges node_fun =
let ids = get_all_ids edges in
let max_ids = select_maximal_ids edges in
File.file_out (path ^ name ^ ".gv") (fun file ->
if lr then Printf.fprintf file "digraph G {\n node [shape=box]\n rankdir = LR\n"
else Printf.fprintf file "digraph G {\n node [shape=box]\n";
IntSet.iter ids (fun id ->
if IntSet.mem max_ids id then
Printf.fprintf file " %d [color=\".7 .3 1.0\",style=filled,label=\"%s\"]\n" id (node_fun id)
else Printf.fprintf file " %d [label=\"%s\"]\n" id (node_fun id));
IntMap.iter edges (fun id1 nodes ->
IntSet.iter nodes (fun id2 ->
Printf.fprintf file " %d -> %d\n" id1 id2));
Printf.fprintf file "}\n");
Sys.chdir path;
ignore (Sys.command ("dot -Tpng " ^ name ^ ".gv -o " ^ name ^ ".png"));
Sys.chdir "..";
()
*)