Class: Roby::RelationGraph
- Inherits:
-
BGL::Graph
- Object
- BGL::Graph
- Roby::RelationGraph
- Includes:
- Distributed::DRobyConstant::Dump
- Defined in:
- lib/roby/relations.rb,
lib/roby/distributed/protocol.rb
Overview
This class manages the graph defined by an object relation in Roby. Relation graphs are managed in hierarchies (for instance, in EventStructure, Precedence is a superset of CausalLink, and CausalLink a superset of both Forwarding and Signal). In this hierarchy, at each level, an edge cannot be present in more than one graph. Nonetheless, it is possible for a parent relation to have an edge which is present in none of its children.
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
The relation name.
-
#options ⇒ Object
readonly
The graph options as given to RelationSpace#relation.
-
#parent ⇒ Object
The relation parent if any.
-
#subsets ⇒ Object
readonly
The set of graphs.
-
#support ⇒ Object
The Ruby module that gets included in graph objects.
Instance Method Summary collapse
- #__bgl_link ⇒ Object
-
#add_relation(from, to, info = nil) ⇒ Object
If #dag? is true, it checks that the new relation does not create a cycle.
-
#initialize(name, options = {}) ⇒ RelationGraph
constructor
if this relation graph should be seen by remote hosts.
-
#link(from, to, info) ⇒ Object
Reimplemented from BGL::Graph.
-
#linked_in_hierarchy?(source, target) ⇒ Boolean
Returns
trueif there is an edgesource->targetin this graph or in one of its parents. -
#remove_relation(from, to) ⇒ Object
Remove the relation between
fromandto, in this graph and in its parent graphs as well. -
#root_relation? ⇒ Boolean
True if this relation does not have a parent.
-
#subset?(relation) ⇒ Boolean
Returns true if
relationis included in this relation (i.e. it is either the same relation or one of its children). -
#superset_of(relation) ⇒ Object
Declare that
relationis a superset of this relation. - #to_s ⇒ Object
Methods included from Distributed::DRobyConstant::Dump
Methods inherited from BGL::Graph
#components, #each_bfs, #each_dfs, #each_edge, #each_vertex, #generated_subgraphs, #include?, #initialize_copy, #insert, #linked?, #neighborhood, #prune, #reachable?, #remove, #replace_vertex, #same_graph?, #topological_sort, #unlink
Constructor Details
#initialize(name, options = {}) ⇒ RelationGraph
if this relation graph should be seen by remote hosts
201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/roby/relations.rb', line 201 def initialize(name, = {}) @name = name @options = @subsets = ValueSet.new @distribute = [:distribute] @dag = [:dag] @weak = [:weak] if [:subsets] [:subsets].each(&method(:superset_of)) end end |
Instance Attribute Details
#name ⇒ Object (readonly)
The relation name
183 184 185 |
# File 'lib/roby/relations.rb', line 183 def name @name end |
#options ⇒ Object (readonly)
The graph options as given to RelationSpace#relation
189 190 191 |
# File 'lib/roby/relations.rb', line 189 def @options end |
#parent ⇒ Object
The relation parent if any
185 186 187 |
# File 'lib/roby/relations.rb', line 185 def parent @parent end |
#subsets ⇒ Object (readonly)
The set of graphs
187 188 189 |
# File 'lib/roby/relations.rb', line 187 def subsets @subsets end |
#support ⇒ Object
The Ruby module that gets included in graph objects
368 369 370 |
# File 'lib/roby/relations.rb', line 368 def support @support end |
Instance Method Details
#__bgl_link ⇒ Object
295 |
# File 'lib/roby/relations.rb', line 295 alias :__bgl_link :link |
#add_relation(from, to, info = nil) ⇒ Object
If #dag? is true, it checks that the new relation does not create a cycle
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/roby/relations.rb', line 234 def add_relation(from, to, info = nil) # Get the toplevel DAG in our relation hierarchy. We only test for the # DAG property on this one, as it is the union of all its children top_dag = nil new_relations = [] rel = self while rel top_dag = rel if rel.dag? new_relations << rel rel = rel.parent end if top_dag && !top_dag.linked?(from, to) && top_dag.reachable?(to, from) raise CycleFoundError, "cannot add a #{from} -> #{to} relation since it would create a cycle" end # Now compute the set of relations in which we really have to add a # new relation top_rel = new_relations.last if top_rel.linked?(from, to) if !(old_info = from[to, top_rel]).nil? if old_info != info raise ArgumentError, "trying to change edge information" end end changed_info = [new_relations.pop] while !new_relations.empty? if new_relations.last.linked?(from, to) changed_info << new_relations.pop else break end end for rel in changed_info from[to, rel] = info end end unless new_relations.empty? if from.respond_to?(:adding_child_object) from.adding_child_object(to, new_relations, info) end if to.respond_to?(:adding_parent_object) to.adding_parent_object(from, new_relations, info) end for rel in new_relations rel.__bgl_link(from, to, info) end if from.respond_to?(:added_child_object) from.added_child_object(to, new_relations, info) end if to.respond_to?(:added_parent_object) to.added_parent_object(from, new_relations, info) end end end |
#link(from, to, info) ⇒ Object
Reimplemented from BGL::Graph. Unlike this implementation, it is possible to add an already existing edge if the info parameter matches.
299 300 301 302 303 304 305 306 307 |
# File 'lib/roby/relations.rb', line 299 def link(from, to, info) if linked?(from, to) if info != from[to, self] raise ArgumentError, "trying to change edge information" end return end super end |
#linked_in_hierarchy?(source, target) ⇒ Boolean
Returns true if there is an edge source -> target in this graph or in one of its parents
346 347 348 |
# File 'lib/roby/relations.rb', line 346 def linked_in_hierarchy?(source, target) # :nodoc: linked?(source, target) || (parent.linked?(source, target) if parent) end |
#remove_relation(from, to) ⇒ Object
Remove the relation between from and to, in this graph and in its parent graphs as well
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
# File 'lib/roby/relations.rb', line 311 def remove_relation(from, to) rel = self relations = [] while rel relations << rel rel = rel.parent end if from.respond_to?(:removing_child_object) from.removing_child_object(to, relations) end if to.respond_to?(:removing_parent_object) to.removing_parent_object(from, relations) end for rel in relations rel.unlink(from, to) end if from.respond_to?(:removed_child_object) from.removed_child_object(to, relations) end if to.respond_to?(:removed_parent_object) to.removed_parent_object(from, relations) end end |
#root_relation? ⇒ Boolean
True if this relation does not have a parent
227 |
# File 'lib/roby/relations.rb', line 227 def root_relation?; !parent end |
#subset?(relation) ⇒ Boolean
Returns true if relation is included in this relation (i.e. it is either the same relation or one of its children)
340 341 342 |
# File 'lib/roby/relations.rb', line 340 def subset?(relation) self.eql?(relation) || subsets.any? { |subrel| subrel.subset?(relation) } end |
#superset_of(relation) ⇒ Object
Declare that relation is a superset of this relation
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
# File 'lib/roby/relations.rb', line 351 def superset_of(relation) relation.each_edge do |source, target, info| if linked_in_hierarchy?(source, target) raise ArgumentError, "relation and self already share an edge" end end relation.parent = self subsets << relation # Copy the relations of the child into this graph relation.each_edge do |source, target, info| source.add_child_object(target, self, info) end end |
#to_s ⇒ Object
224 |
# File 'lib/roby/relations.rb', line 224 def to_s; name end |