roby 0.8.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (644) hide show
  1. checksums.yaml +7 -0
  2. data/.deep-cover.rb +3 -0
  3. data/.gitattributes +1 -0
  4. data/.gitignore +24 -0
  5. data/.simplecov +10 -0
  6. data/.travis.yml +17 -0
  7. data/.yardopts +4 -0
  8. data/Gemfile +15 -0
  9. data/README.md +11 -0
  10. data/Rakefile +47 -177
  11. data/benchmark/{alloc_misc.rb → attic/alloc_misc.rb} +2 -2
  12. data/benchmark/{discovery_latency.rb → attic/discovery_latency.rb} +19 -19
  13. data/benchmark/{garbage_collection.rb → attic/garbage_collection.rb} +9 -9
  14. data/benchmark/{genom.rb → attic/genom.rb} +0 -0
  15. data/benchmark/attic/transactions.rb +62 -0
  16. data/benchmark/plan_basic_operations.rb +28 -0
  17. data/benchmark/relations/graph.rb +63 -0
  18. data/benchmark/ruby/identity.rb +18 -0
  19. data/benchmark/ruby/set_intersect_vs_hash_merge.rb +39 -0
  20. data/benchmark/ruby/yield_vs_block.rb +35 -0
  21. data/benchmark/run +5 -0
  22. data/benchmark/synthetic_plan_modifications_with_transactions.rb +79 -0
  23. data/benchmark/transactions.rb +99 -51
  24. data/bin/roby +38 -197
  25. data/bin/roby-display +14 -0
  26. data/bin/roby-log +3 -176
  27. data/doc/guide/{src → attic}/abstraction/achieve_with.page +1 -1
  28. data/doc/guide/{src → attic}/abstraction/forwarding.page +1 -1
  29. data/doc/guide/{src → attic}/abstraction/hierarchy.page +1 -1
  30. data/doc/guide/{src → attic}/abstraction/index.page +1 -1
  31. data/doc/guide/{src → attic}/abstraction/task_models.page +1 -1
  32. data/doc/guide/{overview.rdoc → attic/cycle/api_overview.rdoc} +6 -1
  33. data/doc/guide/{src → attic}/cycle/cycle-overview.png +0 -0
  34. data/doc/guide/{src → attic}/cycle/cycle-overview.svg +0 -0
  35. data/doc/guide/attic/cycle/error_handling.page +98 -0
  36. data/doc/guide/{src → attic}/cycle/error_instantaneous_repair.png +0 -0
  37. data/doc/guide/{src → attic}/cycle/error_instantaneous_repair.svg +0 -0
  38. data/doc/guide/{src/cycle/error_handling.page → attic/cycle/error_sources.page} +46 -89
  39. data/doc/guide/{src → attic}/cycle/garbage_collection.page +1 -1
  40. data/doc/guide/{src → attic}/cycle/index.page +1 -1
  41. data/doc/guide/{src → attic}/cycle/propagation.page +11 -1
  42. data/doc/guide/{src → attic}/cycle/propagation_diamond.png +0 -0
  43. data/doc/guide/{src → attic}/cycle/propagation_diamond.svg +0 -0
  44. data/doc/guide/attic/plans/building_plans.page +89 -0
  45. data/doc/guide/attic/plans/code.page +192 -0
  46. data/doc/guide/{src/basics → attic/plans}/events.page +3 -4
  47. data/doc/guide/attic/plans/index.page +7 -0
  48. data/doc/guide/{plan_modifications.rdoc → attic/plans/plan_modifications.rdoc} +5 -3
  49. data/doc/guide/{src/basics → attic/plans}/plan_objects.page +2 -1
  50. data/doc/guide/attic/plans/querying_plans.page +5 -0
  51. data/doc/guide/{src/basics → attic/plans}/tasks.page +20 -20
  52. data/doc/guide/config.yaml +7 -4
  53. data/doc/guide/ext/extended_menu.rb +29 -0
  54. data/doc/guide/ext/init.rb +6 -0
  55. data/doc/guide/ext/rdoc_links.rb +7 -6
  56. data/doc/guide/src/advanced_concepts/history.page +5 -0
  57. data/doc/guide/src/advanced_concepts/index.page +11 -0
  58. data/doc/guide/src/advanced_concepts/recognizing_patterns.page +83 -0
  59. data/doc/guide/src/advanced_concepts/scheduling.page +87 -0
  60. data/doc/guide/src/advanced_concepts/transactions.page +5 -0
  61. data/doc/guide/src/advanced_concepts/unreachability.page +42 -0
  62. data/doc/guide/src/base.template +96 -0
  63. data/doc/guide/src/basics_shell_header.txt +5 -7
  64. data/doc/guide/src/building/action_coordination.page +96 -0
  65. data/doc/guide/src/building/actions.page +124 -0
  66. data/doc/guide/src/building/file_layout.page +71 -0
  67. data/doc/guide/src/building/index.page +50 -0
  68. data/doc/guide/src/building/patterns.page +86 -0
  69. data/doc/guide/src/building/patterns_forwarding.png +0 -0
  70. data/doc/guide/src/building/patterns_forwarding.svg +277 -0
  71. data/doc/guide/src/building/runtime.page +95 -0
  72. data/doc/guide/src/building/task_models.page +94 -0
  73. data/doc/guide/src/building/tasks.page +284 -0
  74. data/doc/guide/src/concepts/error_handling.page +100 -0
  75. data/doc/guide/src/concepts/exception_propagation.png +0 -0
  76. data/doc/guide/src/concepts/exception_propagation.svg +445 -0
  77. data/doc/guide/src/concepts/execution.page +85 -0
  78. data/doc/guide/src/concepts/execution.png +0 -0
  79. data/doc/guide/src/concepts/execution.svg +573 -0
  80. data/doc/guide/src/concepts/execution_cycle.png +0 -0
  81. data/doc/guide/src/concepts/garbage_collection.page +57 -0
  82. data/doc/guide/src/concepts/index.page +27 -0
  83. data/doc/guide/src/concepts/plans.page +101 -0
  84. data/doc/guide/src/concepts/policy.page +31 -0
  85. data/doc/guide/src/concepts/reactor.page +61 -0
  86. data/doc/guide/src/concepts/simple_plan_example.png +0 -0
  87. data/doc/guide/src/concepts/simple_plan_example.svg +376 -0
  88. data/doc/guide/src/default.template +9 -74
  89. data/doc/guide/src/event_relations/forward.page +71 -0
  90. data/doc/guide/src/event_relations/index.page +12 -0
  91. data/doc/guide/src/event_relations/scheduling_constraints.page +43 -0
  92. data/doc/guide/src/event_relations/signal.page +55 -0
  93. data/doc/guide/src/event_relations/temporal_constraints.page +77 -0
  94. data/doc/guide/src/htmldoc.metainfo +21 -8
  95. data/doc/guide/src/index.page +8 -3
  96. data/doc/guide/src/{introduction/install.page → installation/index.page} +37 -25
  97. data/doc/guide/src/installation/publications.page +14 -0
  98. data/doc/guide/src/{introduction → installation}/videos.page +14 -7
  99. data/doc/guide/src/interacting/index.page +16 -0
  100. data/doc/guide/src/interacting/run.page +33 -0
  101. data/doc/guide/src/interacting/shell.page +95 -0
  102. data/doc/guide/src/plugins/creating_plugins.page +72 -0
  103. data/doc/guide/src/plugins/index.page +27 -5
  104. data/doc/guide/src/plugins/{fault_tolerance.page → standard_plugins/fault_tolerance.page} +2 -2
  105. data/doc/guide/src/plugins/standard_plugins/index.page +11 -0
  106. data/doc/guide/src/plugins/{subsystems.page → standard_plugins/subsystems.page} +2 -2
  107. data/doc/guide/src/style_screen.css +687 -0
  108. data/doc/guide/src/task_relations/dependency.page +107 -0
  109. data/doc/guide/src/task_relations/executed_by.page +77 -0
  110. data/doc/guide/src/task_relations/index.page +12 -0
  111. data/doc/guide/src/task_relations/new_relations.page +119 -0
  112. data/doc/guide/src/task_relations/planned_by.page +46 -0
  113. data/doc/guide/src/tutorial/app.page +117 -0
  114. data/doc/guide/src/{basics → tutorial}/code_examples.page +6 -5
  115. data/doc/guide/src/{basics → tutorial}/dry.page +15 -15
  116. data/doc/guide/src/{basics → tutorial}/errors.page +43 -68
  117. data/doc/guide/src/tutorial/events.page +195 -0
  118. data/doc/guide/src/{basics → tutorial}/hierarchy.page +53 -52
  119. data/doc/guide/src/tutorial/index.page +13 -0
  120. data/doc/guide/src/tutorial/log_replay/goForward_1.png +0 -0
  121. data/doc/guide/src/tutorial/log_replay/goForward_2.png +0 -0
  122. data/doc/guide/src/tutorial/log_replay/goForward_3.png +0 -0
  123. data/doc/guide/src/{basics → tutorial}/log_replay/goForward_4.png +0 -0
  124. data/doc/guide/src/tutorial/log_replay/goForward_5.png +0 -0
  125. data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_1.png +0 -0
  126. data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_2.png +0 -0
  127. data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_3.png +0 -0
  128. data/doc/guide/src/tutorial/log_replay/moveto_code_error.png +0 -0
  129. data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_1.png +0 -0
  130. data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_2.png +0 -0
  131. data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_3.png +0 -0
  132. data/doc/guide/src/tutorial/log_replay/plan_repair_4.png +0 -0
  133. data/doc/guide/src/tutorial/log_replay/roby_log_main_window.png +0 -0
  134. data/doc/guide/src/{basics → tutorial}/log_replay/roby_log_relation_window.png +0 -0
  135. data/doc/guide/src/{basics → tutorial}/log_replay/roby_replay_event_representation.png +0 -0
  136. data/doc/guide/src/tutorial/relations_display.page +153 -0
  137. data/doc/guide/src/{basics → tutorial}/roby_cycle_overview.png +0 -0
  138. data/doc/guide/src/tutorial/shell.page +121 -0
  139. data/doc/guide/src/{basics → tutorial}/summary.page +1 -1
  140. data/doc/guide/src/tutorial/tasks.page +374 -0
  141. data/lib/roby.rb +102 -47
  142. data/lib/roby/actions.rb +17 -0
  143. data/lib/roby/actions/action.rb +80 -0
  144. data/lib/roby/actions/interface.rb +45 -0
  145. data/lib/roby/actions/library.rb +23 -0
  146. data/lib/roby/actions/models/action.rb +224 -0
  147. data/lib/roby/actions/models/coordination_action.rb +58 -0
  148. data/lib/roby/actions/models/interface.rb +22 -0
  149. data/lib/roby/actions/models/interface_base.rb +294 -0
  150. data/lib/roby/actions/models/library.rb +12 -0
  151. data/lib/roby/actions/models/method_action.rb +90 -0
  152. data/lib/roby/actions/task.rb +114 -0
  153. data/lib/roby/and_generator.rb +125 -0
  154. data/lib/roby/app.rb +2795 -829
  155. data/lib/roby/app/autotest_console_reporter.rb +138 -0
  156. data/lib/roby/app/base.rb +21 -0
  157. data/lib/roby/app/cucumber.rb +2 -0
  158. data/lib/roby/app/cucumber/controller.rb +439 -0
  159. data/lib/roby/app/cucumber/helpers.rb +280 -0
  160. data/lib/roby/app/cucumber/world.rb +32 -0
  161. data/lib/roby/app/debug.rb +136 -0
  162. data/lib/roby/app/gen.rb +2 -0
  163. data/lib/roby/app/rake.rb +178 -38
  164. data/lib/roby/app/robot_config.rb +9 -0
  165. data/lib/roby/app/robot_names.rb +115 -0
  166. data/lib/roby/app/run.rb +3 -2
  167. data/lib/roby/app/scripts.rb +72 -0
  168. data/lib/roby/app/scripts/autotest.rb +173 -0
  169. data/lib/roby/app/scripts/display.rb +2 -0
  170. data/lib/roby/app/scripts/restart.rb +52 -0
  171. data/lib/roby/app/scripts/results.rb +17 -8
  172. data/lib/roby/app/scripts/run.rb +155 -24
  173. data/lib/roby/app/scripts/shell.rb +147 -62
  174. data/lib/roby/app/scripts/test.rb +107 -22
  175. data/lib/roby/app/test_reporter.rb +74 -0
  176. data/lib/roby/app/test_server.rb +159 -0
  177. data/lib/roby/app/vagrant.rb +47 -0
  178. data/lib/roby/backports.rb +16 -0
  179. data/lib/roby/cli/display.rb +190 -0
  180. data/lib/roby/cli/exceptions.rb +17 -0
  181. data/lib/roby/cli/gen/actions/class.rb +5 -0
  182. data/lib/roby/cli/gen/actions/test.rb +6 -0
  183. data/lib/roby/cli/gen/app/.yardopts +6 -0
  184. data/lib/roby/cli/gen/app/README.md +28 -0
  185. data/lib/roby/cli/gen/app/Rakefile +15 -0
  186. data/{app → lib/roby/cli/gen/app}/config/app.yml +29 -39
  187. data/lib/roby/cli/gen/app/models/.gitattributes +1 -0
  188. data/{app → lib/roby/cli/gen/app/scripts}/controllers/.gitattributes +0 -0
  189. data/{app/data/.gitattributes → lib/roby/cli/gen/app/test/.gitignore} +0 -0
  190. data/lib/roby/cli/gen/class/class.rb +6 -0
  191. data/lib/roby/cli/gen/class/test.rb +7 -0
  192. data/lib/roby/cli/gen/helpers.rb +203 -0
  193. data/lib/roby/cli/gen/module/module.rb +5 -0
  194. data/lib/roby/cli/gen/module/test.rb +6 -0
  195. data/lib/roby/cli/gen/roby_app/config/init.rb +17 -0
  196. data/lib/roby/cli/gen/roby_app/config/robots/robot.rb +40 -0
  197. data/lib/roby/cli/gen/task/class.rb +44 -0
  198. data/lib/roby/cli/gen/task/test.rb +6 -0
  199. data/lib/roby/cli/gen_main.rb +120 -0
  200. data/lib/roby/cli/log.rb +276 -0
  201. data/lib/roby/cli/log/flamegraph.html +499 -0
  202. data/lib/roby/cli/log/flamegraph_renderer.rb +88 -0
  203. data/lib/roby/cli/main.rb +153 -0
  204. data/lib/roby/coordination.rb +60 -0
  205. data/lib/roby/coordination/action_script.rb +25 -0
  206. data/lib/roby/coordination/action_state_machine.rb +125 -0
  207. data/lib/roby/coordination/actions.rb +106 -0
  208. data/lib/roby/coordination/base.rb +145 -0
  209. data/lib/roby/coordination/calculus.rb +40 -0
  210. data/lib/roby/coordination/child.rb +28 -0
  211. data/lib/roby/coordination/event.rb +29 -0
  212. data/lib/roby/coordination/fault_handler.rb +25 -0
  213. data/lib/roby/coordination/fault_handling_task.rb +13 -0
  214. data/lib/roby/coordination/fault_response_table.rb +110 -0
  215. data/lib/roby/coordination/models/action_script.rb +64 -0
  216. data/lib/roby/coordination/models/action_state_machine.rb +224 -0
  217. data/lib/roby/coordination/models/actions.rb +191 -0
  218. data/lib/roby/coordination/models/arguments.rb +55 -0
  219. data/lib/roby/coordination/models/base.rb +176 -0
  220. data/lib/roby/coordination/models/capture.rb +86 -0
  221. data/lib/roby/coordination/models/child.rb +35 -0
  222. data/lib/roby/coordination/models/event.rb +41 -0
  223. data/lib/roby/coordination/models/exceptions.rb +42 -0
  224. data/lib/roby/coordination/models/fault_handler.rb +219 -0
  225. data/lib/roby/coordination/models/fault_response_table.rb +77 -0
  226. data/lib/roby/coordination/models/root.rb +22 -0
  227. data/lib/roby/coordination/models/script.rb +283 -0
  228. data/lib/roby/coordination/models/task.rb +184 -0
  229. data/lib/roby/coordination/models/task_from_action.rb +50 -0
  230. data/lib/roby/coordination/models/task_from_as_plan.rb +33 -0
  231. data/lib/roby/coordination/models/task_from_instanciation_object.rb +31 -0
  232. data/lib/roby/coordination/models/task_from_variable.rb +27 -0
  233. data/lib/roby/coordination/models/task_with_dependencies.rb +48 -0
  234. data/lib/roby/coordination/models/variable.rb +32 -0
  235. data/lib/roby/coordination/script.rb +200 -0
  236. data/lib/roby/coordination/script_instruction.rb +12 -0
  237. data/lib/roby/coordination/task.rb +45 -0
  238. data/lib/roby/coordination/task_base.rb +69 -0
  239. data/lib/roby/coordination/task_script.rb +293 -0
  240. data/lib/roby/coordination/task_state_machine.rb +308 -0
  241. data/lib/roby/decision_control.rb +33 -21
  242. data/lib/roby/distributed_object.rb +76 -0
  243. data/lib/roby/droby.rb +17 -0
  244. data/lib/roby/droby/droby_id.rb +6 -0
  245. data/lib/roby/droby/enable.rb +153 -0
  246. data/lib/roby/droby/event_logger.rb +189 -0
  247. data/lib/roby/droby/event_logging.rb +57 -0
  248. data/lib/roby/droby/exceptions.rb +14 -0
  249. data/lib/roby/droby/identifiable.rb +22 -0
  250. data/lib/roby/droby/logfile.rb +141 -0
  251. data/lib/roby/droby/logfile/client.rb +176 -0
  252. data/lib/roby/droby/logfile/file_format.md +97 -0
  253. data/lib/roby/droby/logfile/index.rb +117 -0
  254. data/lib/roby/droby/logfile/reader.rb +139 -0
  255. data/lib/roby/droby/logfile/server.rb +199 -0
  256. data/lib/roby/droby/logfile/writer.rb +114 -0
  257. data/lib/roby/droby/marshal.rb +264 -0
  258. data/lib/roby/droby/marshallable.rb +12 -0
  259. data/lib/roby/droby/null_event_logger.rb +25 -0
  260. data/lib/roby/droby/object_manager.rb +205 -0
  261. data/lib/roby/droby/peer_id.rb +6 -0
  262. data/lib/roby/droby/plan_rebuilder.rb +373 -0
  263. data/lib/roby/droby/rebuilt_plan.rb +160 -0
  264. data/lib/roby/droby/remote_droby_id.rb +6 -0
  265. data/lib/roby/droby/timepoints.rb +205 -0
  266. data/lib/roby/droby/timepoints_ctf.metadata.erb +101 -0
  267. data/lib/roby/droby/timepoints_ctf.rb +125 -0
  268. data/lib/roby/droby/v5.rb +14 -0
  269. data/lib/roby/droby/v5/builtin.rb +120 -0
  270. data/lib/roby/droby/v5/droby_class.rb +45 -0
  271. data/lib/roby/droby/v5/droby_constant.rb +81 -0
  272. data/lib/roby/droby/v5/droby_dump.rb +1026 -0
  273. data/lib/roby/droby/v5/droby_id.rb +44 -0
  274. data/lib/roby/droby/v5/droby_model.rb +82 -0
  275. data/lib/roby/droby/v5/peer_id.rb +10 -0
  276. data/lib/roby/droby/v5/remote_droby_id.rb +42 -0
  277. data/lib/roby/event.rb +79 -957
  278. data/lib/roby/event_constraints.rb +835 -0
  279. data/lib/roby/event_generator.rb +1047 -0
  280. data/lib/roby/event_structure/causal_link.rb +6 -0
  281. data/lib/roby/event_structure/forwarding.rb +6 -0
  282. data/lib/roby/event_structure/precedence.rb +7 -0
  283. data/lib/roby/event_structure/signal.rb +8 -0
  284. data/lib/roby/event_structure/temporal_constraints.rb +640 -0
  285. data/lib/roby/exceptions.rb +446 -152
  286. data/lib/roby/executable_plan.rb +549 -0
  287. data/lib/roby/execution_engine.rb +1997 -950
  288. data/lib/roby/filter_generator.rb +26 -0
  289. data/lib/roby/gui/chronicle_view.rb +225 -0
  290. data/lib/roby/gui/chronicle_widget.rb +925 -0
  291. data/lib/roby/gui/dot_id.rb +11 -0
  292. data/lib/roby/gui/exception_view.rb +44 -0
  293. data/lib/roby/gui/log_display.rb +273 -0
  294. data/lib/roby/gui/model_views.rb +2 -0
  295. data/lib/roby/gui/model_views/action_interface.rb +53 -0
  296. data/lib/roby/gui/model_views/task.rb +47 -0
  297. data/lib/roby/gui/model_views/task.rhtml +41 -0
  298. data/lib/roby/gui/object_info_view.rb +89 -0
  299. data/lib/roby/gui/plan_dot_layout.rb +427 -0
  300. data/lib/roby/gui/plan_rebuilder_widget.rb +357 -0
  301. data/lib/roby/gui/qt4_toMSecsSinceEpoch.rb +8 -0
  302. data/lib/roby/gui/relations_view.rb +278 -0
  303. data/lib/roby/gui/relations_view/relations.ui +139 -0
  304. data/lib/roby/gui/relations_view/relations_canvas.rb +1088 -0
  305. data/lib/roby/gui/relations_view/relations_config.rb +292 -0
  306. data/lib/roby/gui/relations_view/relations_view.ui +53 -0
  307. data/lib/roby/gui/scheduler_view.css +24 -0
  308. data/lib/roby/gui/scheduler_view.rb +46 -0
  309. data/lib/roby/gui/scheduler_view.rhtml +53 -0
  310. data/lib/roby/gui/stepping.rb +93 -0
  311. data/lib/roby/gui/stepping.ui +181 -0
  312. data/lib/roby/gui/styles.rb +81 -0
  313. data/lib/roby/gui/task_display_configuration.rb +42 -0
  314. data/lib/roby/gui/task_state_at.rb +38 -0
  315. data/lib/roby/hooks.rb +26 -0
  316. data/lib/roby/interface.rb +136 -469
  317. data/lib/roby/interface/async.rb +20 -0
  318. data/lib/roby/interface/async/action_monitor.rb +188 -0
  319. data/lib/roby/interface/async/interface.rb +498 -0
  320. data/lib/roby/interface/async/job_monitor.rb +213 -0
  321. data/lib/roby/interface/async/log.rb +238 -0
  322. data/lib/roby/interface/async/new_job_listener.rb +79 -0
  323. data/lib/roby/interface/async/ui_connector.rb +183 -0
  324. data/lib/roby/interface/client.rb +553 -0
  325. data/lib/roby/interface/command.rb +24 -0
  326. data/lib/roby/interface/command_argument.rb +16 -0
  327. data/lib/roby/interface/command_library.rb +92 -0
  328. data/lib/roby/interface/droby_channel.rb +174 -0
  329. data/lib/roby/interface/exceptions.rb +22 -0
  330. data/lib/roby/interface/interface.rb +655 -0
  331. data/lib/roby/interface/job.rb +47 -0
  332. data/lib/roby/interface/rest.rb +10 -0
  333. data/lib/roby/interface/rest/api.rb +29 -0
  334. data/lib/roby/interface/rest/helpers.rb +24 -0
  335. data/lib/roby/interface/rest/server.rb +212 -0
  336. data/lib/roby/interface/server.rb +154 -0
  337. data/lib/roby/interface/shell_client.rb +468 -0
  338. data/lib/roby/interface/shell_subcommand.rb +24 -0
  339. data/lib/roby/interface/subcommand_client.rb +35 -0
  340. data/lib/roby/interface/tcp.rb +168 -0
  341. data/lib/roby/models/arguments.rb +112 -0
  342. data/lib/roby/models/plan_object.rb +83 -0
  343. data/lib/roby/models/task.rb +835 -0
  344. data/lib/roby/models/task_event.rb +62 -0
  345. data/lib/roby/models/task_service.rb +78 -0
  346. data/lib/roby/or_generator.rb +88 -0
  347. data/lib/roby/plan.rb +1751 -864
  348. data/lib/roby/plan_object.rb +611 -0
  349. data/lib/roby/plan_service.rb +200 -0
  350. data/lib/roby/promise.rb +332 -0
  351. data/lib/roby/queries.rb +23 -0
  352. data/lib/roby/queries/and_matcher.rb +32 -0
  353. data/lib/roby/queries/any.rb +27 -0
  354. data/lib/roby/queries/code_error_matcher.rb +58 -0
  355. data/lib/roby/queries/event_generator_matcher.rb +9 -0
  356. data/lib/roby/queries/execution_exception_matcher.rb +165 -0
  357. data/lib/roby/queries/index.rb +165 -0
  358. data/lib/roby/queries/localized_error_matcher.rb +149 -0
  359. data/lib/roby/queries/matcher_base.rb +107 -0
  360. data/lib/roby/queries/none.rb +27 -0
  361. data/lib/roby/queries/not_matcher.rb +30 -0
  362. data/lib/roby/queries/op_matcher.rb +8 -0
  363. data/lib/roby/queries/or_matcher.rb +30 -0
  364. data/lib/roby/queries/plan_object_matcher.rb +363 -0
  365. data/lib/roby/queries/query.rb +188 -0
  366. data/lib/roby/queries/task_event_generator_matcher.rb +86 -0
  367. data/lib/roby/queries/task_matcher.rb +344 -0
  368. data/lib/roby/relations.rb +42 -678
  369. data/lib/roby/relations/bidirectional_directed_adjacency_graph.rb +492 -0
  370. data/lib/roby/relations/directed_relation_support.rb +268 -0
  371. data/lib/roby/relations/event_relation_graph.rb +19 -0
  372. data/lib/roby/relations/fork_merge_visitor.rb +154 -0
  373. data/lib/roby/relations/graph.rb +533 -0
  374. data/lib/roby/relations/models/directed_relation_support.rb +11 -0
  375. data/lib/roby/relations/models/graph.rb +75 -0
  376. data/lib/roby/relations/models/task_relation_graph.rb +18 -0
  377. data/lib/roby/relations/space.rb +380 -0
  378. data/lib/roby/relations/task_relation_graph.rb +20 -0
  379. data/lib/roby/robot.rb +85 -38
  380. data/lib/roby/schedulers/basic.rb +155 -25
  381. data/lib/roby/schedulers/null.rb +20 -0
  382. data/lib/roby/schedulers/reporting.rb +31 -0
  383. data/lib/roby/schedulers/state.rb +129 -0
  384. data/lib/roby/schedulers/temporal.rb +91 -0
  385. data/lib/roby/singletons.rb +87 -0
  386. data/lib/roby/standalone.rb +4 -2
  387. data/lib/roby/standard_errors.rb +405 -82
  388. data/lib/roby/state.rb +6 -3
  389. data/lib/roby/state/conf_model.rb +5 -0
  390. data/lib/roby/state/events.rb +181 -95
  391. data/lib/roby/state/goal_model.rb +77 -0
  392. data/lib/roby/state/open_struct.rb +591 -0
  393. data/lib/roby/state/open_struct_model.rb +68 -0
  394. data/lib/roby/state/pos.rb +45 -45
  395. data/lib/roby/state/shapes.rb +11 -11
  396. data/lib/roby/state/state_model.rb +303 -0
  397. data/lib/roby/state/task.rb +43 -0
  398. data/lib/roby/support.rb +88 -148
  399. data/lib/roby/task.rb +1361 -1750
  400. data/lib/roby/task_arguments.rb +428 -0
  401. data/lib/roby/task_event.rb +127 -0
  402. data/lib/roby/task_event_generator.rb +337 -0
  403. data/lib/roby/task_service.rb +6 -0
  404. data/lib/roby/task_structure/conflicts.rb +104 -0
  405. data/lib/roby/task_structure/dependency.rb +932 -0
  406. data/lib/roby/task_structure/error_handling.rb +118 -0
  407. data/lib/roby/task_structure/executed_by.rb +234 -0
  408. data/lib/roby/task_structure/planned_by.rb +90 -0
  409. data/lib/roby/tasks/aggregator.rb +37 -0
  410. data/lib/roby/tasks/external_process.rb +275 -0
  411. data/lib/roby/tasks/group.rb +27 -0
  412. data/lib/roby/tasks/null.rb +19 -0
  413. data/lib/roby/tasks/parallel.rb +43 -0
  414. data/lib/roby/tasks/sequence.rb +88 -0
  415. data/lib/roby/tasks/simple.rb +21 -0
  416. data/lib/roby/{thread_task.rb → tasks/thread.rb} +50 -24
  417. data/lib/roby/tasks/timeout.rb +17 -0
  418. data/lib/roby/tasks/virtual.rb +55 -0
  419. data/lib/roby/template_plan.rb +7 -0
  420. data/lib/roby/test/aruba_minitest.rb +74 -0
  421. data/lib/roby/test/assertion.rb +16 -0
  422. data/lib/roby/test/assertions.rb +490 -0
  423. data/lib/roby/test/common.rb +368 -591
  424. data/lib/roby/test/dsl.rb +149 -0
  425. data/lib/roby/test/error.rb +18 -0
  426. data/lib/roby/test/event_reporter.rb +83 -0
  427. data/lib/roby/test/execution_expectations.rb +1134 -0
  428. data/lib/roby/test/expect_execution.rb +151 -0
  429. data/lib/roby/test/minitest_helpers.rb +166 -0
  430. data/lib/roby/test/roby_app_helpers.rb +200 -0
  431. data/lib/roby/test/run_planners.rb +155 -0
  432. data/lib/roby/test/self.rb +112 -0
  433. data/lib/roby/test/spec.rb +198 -0
  434. data/lib/roby/test/tasks/empty_task.rb +4 -4
  435. data/lib/roby/test/tasks/goto.rb +28 -27
  436. data/lib/roby/test/teardown_plans.rb +100 -0
  437. data/lib/roby/test/testcase.rb +239 -307
  438. data/lib/roby/test/tools.rb +159 -155
  439. data/lib/roby/test/validate_state_machine.rb +75 -0
  440. data/lib/roby/transaction.rb +1125 -0
  441. data/lib/roby/transaction/event_generator_proxy.rb +63 -0
  442. data/lib/roby/transaction/plan_object_proxy.rb +99 -0
  443. data/lib/roby/transaction/plan_service_proxy.rb +43 -0
  444. data/lib/roby/transaction/proxying.rb +120 -0
  445. data/lib/roby/transaction/task_event_generator_proxy.rb +19 -0
  446. data/lib/roby/transaction/task_proxy.rb +135 -0
  447. data/lib/roby/until_generator.rb +30 -0
  448. data/lib/roby/version.rb +5 -0
  449. data/lib/roby/yard.rb +169 -0
  450. data/lib/yard-roby.rb +1 -0
  451. data/manifest.xml +32 -6
  452. data/roby.gemspec +59 -0
  453. metadata +788 -587
  454. data/Manifest.txt +0 -321
  455. data/NOTES +0 -4
  456. data/README.txt +0 -166
  457. data/TODO.txt +0 -146
  458. data/app/README.txt +0 -24
  459. data/app/Rakefile +0 -8
  460. data/app/config/ROBOT.rb +0 -5
  461. data/app/config/init.rb +0 -33
  462. data/app/config/roby.yml +0 -3
  463. data/app/controllers/ROBOT.rb +0 -2
  464. data/app/planners/ROBOT/main.rb +0 -6
  465. data/app/planners/main.rb +0 -5
  466. data/app/scripts/distributed +0 -3
  467. data/app/scripts/generate/bookmarks +0 -3
  468. data/app/scripts/replay +0 -3
  469. data/app/scripts/results +0 -3
  470. data/app/scripts/run +0 -3
  471. data/app/scripts/server +0 -3
  472. data/app/scripts/shell +0 -3
  473. data/app/scripts/test +0 -3
  474. data/app/tasks/.gitattributes +0 -0
  475. data/app/tasks/ROBOT/.gitattributes +0 -0
  476. data/bin/roby-shell +0 -25
  477. data/doc/guide/src/basics/app.page +0 -139
  478. data/doc/guide/src/basics/index.page +0 -11
  479. data/doc/guide/src/basics/log_replay/goForward_1.png +0 -0
  480. data/doc/guide/src/basics/log_replay/goForward_2.png +0 -0
  481. data/doc/guide/src/basics/log_replay/goForward_3.png +0 -0
  482. data/doc/guide/src/basics/log_replay/goForward_5.png +0 -0
  483. data/doc/guide/src/basics/log_replay/plan_repair_4.png +0 -0
  484. data/doc/guide/src/basics/log_replay/roby_log_main_window.png +0 -0
  485. data/doc/guide/src/basics/relations_display.page +0 -203
  486. data/doc/guide/src/basics/shell.page +0 -102
  487. data/doc/guide/src/default.css +0 -319
  488. data/doc/guide/src/introduction/index.page +0 -29
  489. data/doc/guide/src/introduction/publications.page +0 -14
  490. data/doc/guide/src/relations/dependency.page +0 -89
  491. data/doc/guide/src/relations/index.page +0 -12
  492. data/ext/droby/dump.cc +0 -175
  493. data/ext/droby/extconf.rb +0 -3
  494. data/ext/graph/algorithm.cc +0 -746
  495. data/ext/graph/extconf.rb +0 -7
  496. data/ext/graph/graph.cc +0 -575
  497. data/ext/graph/graph.hh +0 -183
  498. data/ext/graph/iterator_sequence.hh +0 -102
  499. data/ext/graph/undirected_dfs.hh +0 -226
  500. data/ext/graph/undirected_graph.hh +0 -421
  501. data/lib/roby/app/scripts/generate/bookmarks.rb +0 -162
  502. data/lib/roby/app/scripts/replay.rb +0 -31
  503. data/lib/roby/app/scripts/server.rb +0 -18
  504. data/lib/roby/basic_object.rb +0 -151
  505. data/lib/roby/config.rb +0 -14
  506. data/lib/roby/distributed.rb +0 -36
  507. data/lib/roby/distributed/base.rb +0 -448
  508. data/lib/roby/distributed/communication.rb +0 -875
  509. data/lib/roby/distributed/connection_space.rb +0 -616
  510. data/lib/roby/distributed/distributed_object.rb +0 -206
  511. data/lib/roby/distributed/drb.rb +0 -62
  512. data/lib/roby/distributed/notifications.rb +0 -531
  513. data/lib/roby/distributed/peer.rb +0 -555
  514. data/lib/roby/distributed/protocol.rb +0 -529
  515. data/lib/roby/distributed/proxy.rb +0 -343
  516. data/lib/roby/distributed/subscription.rb +0 -311
  517. data/lib/roby/distributed/transaction.rb +0 -498
  518. data/lib/roby/external_process_task.rb +0 -225
  519. data/lib/roby/graph.rb +0 -160
  520. data/lib/roby/log.rb +0 -3
  521. data/lib/roby/log/chronicle.rb +0 -303
  522. data/lib/roby/log/console.rb +0 -74
  523. data/lib/roby/log/data_stream.rb +0 -275
  524. data/lib/roby/log/dot.rb +0 -279
  525. data/lib/roby/log/event_stream.rb +0 -161
  526. data/lib/roby/log/file.rb +0 -396
  527. data/lib/roby/log/gui/basic_display.ui +0 -83
  528. data/lib/roby/log/gui/basic_display_ui.rb +0 -89
  529. data/lib/roby/log/gui/chronicle.rb +0 -26
  530. data/lib/roby/log/gui/chronicle_view.rb +0 -40
  531. data/lib/roby/log/gui/chronicle_view.ui +0 -70
  532. data/lib/roby/log/gui/chronicle_view_ui.rb +0 -90
  533. data/lib/roby/log/gui/data_displays.rb +0 -171
  534. data/lib/roby/log/gui/data_displays.ui +0 -155
  535. data/lib/roby/log/gui/data_displays_ui.rb +0 -146
  536. data/lib/roby/log/gui/notifications.rb +0 -26
  537. data/lib/roby/log/gui/relations.rb +0 -269
  538. data/lib/roby/log/gui/relations.ui +0 -123
  539. data/lib/roby/log/gui/relations_ui.rb +0 -120
  540. data/lib/roby/log/gui/relations_view.rb +0 -185
  541. data/lib/roby/log/gui/relations_view.ui +0 -149
  542. data/lib/roby/log/gui/relations_view_ui.rb +0 -144
  543. data/lib/roby/log/gui/replay.rb +0 -366
  544. data/lib/roby/log/gui/replay_controls.rb +0 -206
  545. data/lib/roby/log/gui/replay_controls.ui +0 -282
  546. data/lib/roby/log/gui/replay_controls_ui.rb +0 -249
  547. data/lib/roby/log/gui/runtime.rb +0 -130
  548. data/lib/roby/log/hooks.rb +0 -186
  549. data/lib/roby/log/logger.rb +0 -203
  550. data/lib/roby/log/notifications.rb +0 -244
  551. data/lib/roby/log/plan_rebuilder.rb +0 -468
  552. data/lib/roby/log/relations.rb +0 -1084
  553. data/lib/roby/log/server.rb +0 -547
  554. data/lib/roby/log/sqlite.rb +0 -47
  555. data/lib/roby/log/timings.rb +0 -233
  556. data/lib/roby/plan-object.rb +0 -371
  557. data/lib/roby/planning.rb +0 -13
  558. data/lib/roby/planning/loops.rb +0 -309
  559. data/lib/roby/planning/model.rb +0 -1012
  560. data/lib/roby/planning/task.rb +0 -180
  561. data/lib/roby/query.rb +0 -655
  562. data/lib/roby/relations/conflicts.rb +0 -67
  563. data/lib/roby/relations/dependency.rb +0 -358
  564. data/lib/roby/relations/ensured.rb +0 -19
  565. data/lib/roby/relations/error_handling.rb +0 -22
  566. data/lib/roby/relations/events.rb +0 -7
  567. data/lib/roby/relations/executed_by.rb +0 -208
  568. data/lib/roby/relations/influence.rb +0 -10
  569. data/lib/roby/relations/planned_by.rb +0 -63
  570. data/lib/roby/state/information.rb +0 -55
  571. data/lib/roby/state/state.rb +0 -367
  572. data/lib/roby/task-operations.rb +0 -186
  573. data/lib/roby/task_index.rb +0 -80
  574. data/lib/roby/test/distributed.rb +0 -230
  575. data/lib/roby/test/tasks/simple_task.rb +0 -23
  576. data/lib/roby/transactions.rb +0 -507
  577. data/lib/roby/transactions/proxy.rb +0 -325
  578. data/plugins/fault_injection/History.txt +0 -4
  579. data/plugins/fault_injection/README.txt +0 -34
  580. data/plugins/fault_injection/Rakefile +0 -12
  581. data/plugins/fault_injection/TODO.txt +0 -0
  582. data/plugins/fault_injection/app.rb +0 -52
  583. data/plugins/fault_injection/fault_injection.rb +0 -89
  584. data/plugins/fault_injection/test/test_fault_injection.rb +0 -78
  585. data/plugins/subsystems/README.txt +0 -37
  586. data/plugins/subsystems/Rakefile +0 -13
  587. data/plugins/subsystems/app.rb +0 -182
  588. data/plugins/subsystems/test/app/README +0 -24
  589. data/plugins/subsystems/test/app/Rakefile +0 -8
  590. data/plugins/subsystems/test/app/config/app.yml +0 -71
  591. data/plugins/subsystems/test/app/config/init.rb +0 -12
  592. data/plugins/subsystems/test/app/config/roby.yml +0 -3
  593. data/plugins/subsystems/test/app/planners/main.rb +0 -20
  594. data/plugins/subsystems/test/app/scripts/distributed +0 -3
  595. data/plugins/subsystems/test/app/scripts/replay +0 -3
  596. data/plugins/subsystems/test/app/scripts/results +0 -3
  597. data/plugins/subsystems/test/app/scripts/run +0 -3
  598. data/plugins/subsystems/test/app/scripts/server +0 -3
  599. data/plugins/subsystems/test/app/scripts/shell +0 -3
  600. data/plugins/subsystems/test/app/scripts/test +0 -3
  601. data/plugins/subsystems/test/app/tasks/services.rb +0 -15
  602. data/plugins/subsystems/test/test_subsystems.rb +0 -78
  603. data/test/distributed/test_communication.rb +0 -195
  604. data/test/distributed/test_connection.rb +0 -284
  605. data/test/distributed/test_execution.rb +0 -378
  606. data/test/distributed/test_mixed_plan.rb +0 -341
  607. data/test/distributed/test_plan_notifications.rb +0 -238
  608. data/test/distributed/test_protocol.rb +0 -525
  609. data/test/distributed/test_query.rb +0 -106
  610. data/test/distributed/test_remote_plan.rb +0 -491
  611. data/test/distributed/test_transaction.rb +0 -466
  612. data/test/mockups/external_process +0 -28
  613. data/test/mockups/tasks.rb +0 -27
  614. data/test/planning/test_loops.rb +0 -432
  615. data/test/planning/test_model.rb +0 -427
  616. data/test/planning/test_task.rb +0 -126
  617. data/test/relations/test_conflicts.rb +0 -42
  618. data/test/relations/test_dependency.rb +0 -324
  619. data/test/relations/test_ensured.rb +0 -38
  620. data/test/relations/test_executed_by.rb +0 -224
  621. data/test/relations/test_planned_by.rb +0 -56
  622. data/test/suite_core.rb +0 -29
  623. data/test/suite_distributed.rb +0 -10
  624. data/test/suite_planning.rb +0 -4
  625. data/test/suite_relations.rb +0 -8
  626. data/test/tasks/test_external_process.rb +0 -126
  627. data/test/tasks/test_thread_task.rb +0 -70
  628. data/test/test_bgl.rb +0 -528
  629. data/test/test_event.rb +0 -969
  630. data/test/test_exceptions.rb +0 -591
  631. data/test/test_execution_engine.rb +0 -987
  632. data/test/test_gui.rb +0 -20
  633. data/test/test_interface.rb +0 -43
  634. data/test/test_log.rb +0 -125
  635. data/test/test_log_server.rb +0 -133
  636. data/test/test_plan.rb +0 -418
  637. data/test/test_query.rb +0 -424
  638. data/test/test_relations.rb +0 -260
  639. data/test/test_state.rb +0 -432
  640. data/test/test_support.rb +0 -16
  641. data/test/test_task.rb +0 -1181
  642. data/test/test_testcase.rb +0 -138
  643. data/test/test_transactions.rb +0 -610
  644. data/test/test_transactions_proxy.rb +0 -216
@@ -0,0 +1,268 @@
1
+ module Roby
2
+ module Relations
3
+ # Base support for relations. It is mixed in objects on which a
4
+ # Relations::Space applies on, like Task for TaskStructure and EventGenerator
5
+ # for EventStructure.
6
+ #
7
+ # See also the definition of Relations::Graph#add_relation and
8
+ # Relations::Graph#remove_relation for the possibility to define hooks that
9
+ # get called when a new edge involving +self+ as a vertex gets added and
10
+ # removed
11
+ module DirectedRelationSupport
12
+ attr_reader :relation_graphs
13
+
14
+ def relation_graph_for(rel)
15
+ relation_graphs.fetch(rel)
16
+ end
17
+
18
+ # Enumerate all relations that are relevant for this plan object
19
+ #
20
+ # Unlike {#each_relation_graph}, which enumerate only the graphs
21
+ # that include self, it enumerates all possible relations for self
22
+ #
23
+ # @yieldparam [Class<Graph>]
24
+ def each_relation
25
+ return enum_for(__method__) if !block_given?
26
+ relation_graphs.each do |k, g|
27
+ yield(k) if k != g
28
+ end
29
+ end
30
+
31
+ # Enumerate the relation graphs that include this vertex
32
+ #
33
+ # @yieldparam [Graph]
34
+ def each_relation_graph
35
+ return enum_for(__method__) if !block_given?
36
+ relation_graphs.each do |k, g|
37
+ yield(g) if g.has_vertex?(self) && (k == g)
38
+ end
39
+ end
40
+
41
+ # Enumerate the relation graphs that include this vertex and that
42
+ # are subgraphs of no other graphs
43
+ #
44
+ # @yieldparam [Graph]
45
+ def each_root_relation_graph
46
+ return enum_for(__method__) if !block_given?
47
+ each_relation_graph do |g|
48
+ yield(g) if g.root_relation?
49
+ end
50
+ end
51
+
52
+ def root?(relation = nil)
53
+ if relation
54
+ relation_graphs[relation].root?(self)
55
+ else
56
+ each_relation_graph.all? { |g| g.root?(self) }
57
+ end
58
+ end
59
+
60
+ def leaf?(relation = nil)
61
+ if relation
62
+ relation_graphs[relation].leaf?(self)
63
+ else
64
+ each_relation_graph.all? { |g| g.leaf?(self) }
65
+ end
66
+ end
67
+
68
+ def child_object?(object, relation = nil)
69
+ relation_graphs[relation].has_edge?(self, object)
70
+ end
71
+
72
+ def parent_object?(object, relation = nil)
73
+ relation_graphs[relation].has_edge?(object, self)
74
+ end
75
+
76
+ def related_object?(object, relation = nil)
77
+ parent_object?(object, relation) || child_object?(object, relation)
78
+ end
79
+
80
+ def each_parent_object(graph, &block)
81
+ relation_graphs[graph].each_in_neighbour(self, &block)
82
+ end
83
+
84
+ def each_in_neighbour(graph, &block)
85
+ relation_graphs[graph].each_in_neighbour(self, &block)
86
+ end
87
+
88
+ def each_child_object(graph, &block)
89
+ relation_graphs[graph].each_out_neighbour(self, &block)
90
+ end
91
+
92
+ def each_out_neighbour(graph, &block)
93
+ relation_graphs[graph].each_out_neighbour(self, &block)
94
+ end
95
+
96
+ def sorted_relations
97
+ Relations.all_relations.
98
+ find_all do |rel|
99
+ (rel = relation_graphs.fetch(rel, nil)) && rel.has_vertex?(self)
100
+ end
101
+ end
102
+
103
+ # Yields each relation this vertex is part of, starting with the most
104
+ # specialized relations
105
+ def each_relation_sorted(&block)
106
+ sorted_relations.each(&block)
107
+ end
108
+
109
+ # Removes +self+ from all the graphs it is included in.
110
+ def clear_vertex(remove_strong: true)
111
+ for rel in sorted_relations
112
+ graph = relation_graphs[rel]
113
+ if remove_strong || !graph.strong?
114
+ if graph.remove_vertex(self)
115
+ removed = true
116
+ end
117
+ end
118
+ end
119
+ removed
120
+ end
121
+ alias :clear_relations :clear_vertex
122
+
123
+ def enum_relations
124
+ Roby.warn_deprecated "DirectedRelationSupport#enum_relations is deprecated, use #each_relation instead"
125
+ each_relation
126
+ end
127
+
128
+ # The array of relations this object is part of
129
+ def relations; each_relation.to_a end
130
+
131
+ # Computes and returns the set of objects related with this one (parent
132
+ # or child). If +relation+ is given, enumerate only for this relation,
133
+ # otherwise enumerate for all relations. If +result+ is given, it is a
134
+ # Set in which the related objects are added
135
+ def related_objects(relation = nil, result = Set.new)
136
+ if relation
137
+ result.merge(parent_objects(relation))
138
+ result.merge(child_objects(relation))
139
+ else
140
+ each_root_relation_graph do |g|
141
+ result.merge(g.in_neighbours(self))
142
+ result.merge(g.out_neighbours(self))
143
+ end
144
+ end
145
+ result
146
+ end
147
+
148
+ def enum_parent_objects(relation)
149
+ Roby.warn_deprecated "#enum_parent_objects is deprecated, use #parent_objects or #each_parent_object instead"
150
+ parent_objects(relation)
151
+ end
152
+
153
+ def parent_objects(relation)
154
+ relation_graphs[relation].in_neighbours(self)
155
+ end
156
+
157
+ def enum_child_objects(relation)
158
+ Roby.warn_deprecated "#enum_child_objects is deprecated, use #parent_objects or #each_parent_object instead"
159
+ child_objects(relation)
160
+ end
161
+
162
+ def child_objects(relation)
163
+ relation_graphs[relation].out_neighbours(self)
164
+ end
165
+
166
+ # Add a new child object in the +relation+ relation. This calls
167
+ # * #adding_child_object on +self+ and #adding_parent_object on +child+
168
+ # just before the relation is added
169
+ # * #added_child_object on +self+ and #added_parent_object on +child+
170
+ # just after
171
+ def add_child_object(child, relation, info = nil)
172
+ relation_graphs[relation].add_relation(self, child, info)
173
+ end
174
+
175
+ # Add a new parent object in the +relation+ relation
176
+ # * #adding_child_object on +parent+ and #adding_parent_object on
177
+ # +self+ just before the relation is added
178
+ # * #added_child_object on +parent+ and #added_child_object on +self+
179
+ # just after
180
+ def add_parent_object(parent, relation, info = nil)
181
+ relation_graphs[parent].add_child_object(self, relation, info)
182
+ end
183
+
184
+ # Remove all edges in which +self+ is the source and +child+ the
185
+ # target. If +relation+ is given, it removes only the edge in that
186
+ # relation graph.
187
+ def remove_child_object(child, relation = nil)
188
+ if !relation
189
+ for rel in sorted_relations
190
+ rel.remove_relation(self, child)
191
+ end
192
+ else
193
+ relation_graphs[relation].remove_relation(self, child)
194
+ end
195
+ end
196
+
197
+ # Remove all edges in which +self+ is the source. If +relation+
198
+ # is given, it removes only the edges in that relation graph.
199
+ def remove_children(relation = nil)
200
+ if !relation
201
+ for rel in sorted_relations
202
+ remove_children(rel)
203
+ end
204
+ return
205
+ end
206
+
207
+ children = child_objects(relation).to_a
208
+ for child in children
209
+ remove_child_object(child, relation)
210
+ end
211
+ end
212
+
213
+ # Remove all edges in which +child+ is the source and +self+ the
214
+ # target. If +relation+ is given, it removes only the edge in that
215
+ # relation graph.
216
+ def remove_parent_object(parent, relation = nil)
217
+ parent.remove_child_object(self, relation)
218
+ end
219
+
220
+ # Remove all edges in which +self+ is the target. If +relation+
221
+ # is given, it removes only the edges in that relation graph.
222
+ def remove_parents(relation = nil)
223
+ if !relation
224
+ for rel in sorted_relations
225
+ remove_parents(rel)
226
+ end
227
+ return
228
+ end
229
+
230
+ parents = parent_objects(relation).to_a
231
+ for parent in parents
232
+ remove_parent_object(relation, parent)
233
+ end
234
+ end
235
+
236
+ # Remove all relations that point to or come from +to+ If +to+ is nil,
237
+ # it removes all edges in which +self+ is involved.
238
+ #
239
+ # If +relation+ is not nil, only edges of that relation graph are removed.
240
+ def remove_relations(relation = nil)
241
+ if !relation
242
+ for rel in sorted_relations
243
+ remove_relations(rel)
244
+ end
245
+ return
246
+ end
247
+ relation = relation_graphs[relation]
248
+ return if !relation.has_vertex?(self)
249
+
250
+ each_parent_object(relation).to_a.each do |parent|
251
+ relation.remove_relation(parent, self)
252
+ end
253
+
254
+ each_child_object(relation).to_a.each do |child|
255
+ relation.remove_relation(self, child)
256
+ end
257
+ end
258
+
259
+ def [](object, graph)
260
+ relation_graphs[graph].edge_info(self, object)
261
+ end
262
+
263
+ def []=(object, relation, value)
264
+ relation_graphs[relation].set_edge_info(self, object, value)
265
+ end
266
+ end
267
+ end
268
+ end
@@ -0,0 +1,19 @@
1
+ module Roby
2
+ module Relations
3
+ # Subclass of Relations::Space for events. Its main usage is to keep track of
4
+ # which tasks are related in a given relation through their events.
5
+ #
6
+ # I.e. if events 'a' and 'b' are parts of the tasks ta and tb, and
7
+ #
8
+ # a -> b
9
+ #
10
+ # in this relation graph, then
11
+ #
12
+ # relation.related_tasks?(ta, tb)
13
+ #
14
+ # will return true
15
+ class EventRelationGraph < Relations::Graph
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,154 @@
1
+ module Roby
2
+ module Relations
3
+ # @api private
4
+ #
5
+ # A graph visitor which propagates a value through a subgraph of an
6
+ # acyclic graph, copying the value using #fork at graph forks, and
7
+ # merging them back with #merge when reaching a merge point
8
+ class ForkMergeVisitor < RGL::DFSVisitor
9
+ # The vertex from which we start visiting
10
+ attr_reader :origin
11
+
12
+ # The neighbours of this vertex that should be visited.
13
+ attr_reader :origin_neighbours
14
+
15
+ # A mapping from vertex to the propagated object for this vertex
16
+ attr_reader :vertex_to_object
17
+
18
+ # The pending merges, i.e. a collection of objects gathered so far
19
+ # at a merge point
20
+ attr_reader :pending_merges
21
+
22
+ # The in-degree of each node in the subgraph defined by {#origin}
23
+ # and {#origin_neighbours}
24
+ attr_reader :in_degree
25
+
26
+ # The out-degree of each node in the subgraph defined by {#origin}
27
+ # and {#origin_neighbours}
28
+ attr_reader :out_degree
29
+
30
+ # @param graph the directed graph we propagate the value in
31
+ # @param origin the vertex from which to propagate
32
+ # @param [#include?] origin_neighbours the neighbours of 'origin' to
33
+ # propagate towards
34
+ # @param [#fork,#merge] object the object to propagate in the graph
35
+ def initialize(graph, object, origin, origin_neighbours = graph.out_neighbours(origin))
36
+ super(graph)
37
+ @origin = origin
38
+ @origin_neighbours = origin_neighbours
39
+
40
+ @vertex_to_object = Hash[origin => object]
41
+ @pending_merges = Hash.new { |h, k| h[k] = Array.new }
42
+
43
+ @in_degree, @out_degree = compute_in_out_degrees(origin, origin_neighbours)
44
+ end
45
+
46
+ def visit
47
+ graph.depth_first_visit(origin, self) {}
48
+ end
49
+
50
+ # A visitor that counts the in/out degree of vertices contained in a
51
+ # subgraph
52
+ class SubgraphDegreeCounter < RGL::DFSVisitor
53
+ attr_reader :out_degree
54
+ attr_reader :in_degree
55
+ def initialize(graph)
56
+ @out_degree = Hash.new(0)
57
+ @in_degree = Hash.new(0)
58
+ super(graph)
59
+ end
60
+ def handle_tree_edge(u, v)
61
+ out_degree[u] += 1
62
+ in_degree[v] += 1
63
+ end
64
+ def handle_back_edge(u, v)
65
+ out_degree[u] += 1
66
+ in_degree[v] += 1
67
+ end
68
+ def handle_forward_edge(u, v)
69
+ out_degree[u] += 1
70
+ in_degree[v] += 1
71
+ end
72
+ end
73
+
74
+ # Computes the in and out degree of the subgraph starting at
75
+ # 'origin', following the out-edges of 'origin' that go towards
76
+ # 'origin_neighbours'
77
+ def compute_in_out_degrees(origin, origin_neighbours)
78
+ visitor = SubgraphDegreeCounter.new(graph)
79
+ origin_neighbours.each do |v|
80
+ next if visitor.color_map[v] != :WHITE
81
+ graph.depth_first_visit(v, visitor) { }
82
+ end
83
+ in_degree, out_degree = visitor.in_degree, visitor.out_degree
84
+
85
+ in_degree[origin] = 0
86
+ out_degree[origin] = origin_neighbours.size
87
+ origin_neighbours.each do |v|
88
+ in_degree[v] += 1
89
+ end
90
+ return in_degree, out_degree
91
+ end
92
+
93
+ def follow_edge?(u, v)
94
+ if u == origin
95
+ return if !origin_neighbours.include?(v)
96
+ end
97
+
98
+ degree = in_degree[v]
99
+ if degree == 1
100
+ true
101
+ else
102
+ (pending_merges[v].size + 1) == degree
103
+ end
104
+ end
105
+
106
+ def handle_forward_edge(u, v)
107
+ if u == origin
108
+ return if !origin_neighbours.include?(v)
109
+ end
110
+
111
+ obj = vertex_to_object.fetch(u)
112
+ if obj
113
+ if out_degree[u] > 1
114
+ obj = fork_object(obj)
115
+ end
116
+ obj = propagate_object(u, v, obj)
117
+ end
118
+ if in_degree[v] > 1
119
+ pending_merges[v] << obj
120
+ else
121
+ vertex_to_object[v] = obj
122
+ end
123
+ end
124
+
125
+ def handle_tree_edge(u, v)
126
+ obj = vertex_to_object.fetch(u)
127
+ if obj
128
+ if out_degree[u] > 1
129
+ obj = fork_object(obj)
130
+ end
131
+ obj = propagate_object(u, v, obj)
132
+ end
133
+
134
+ if in_degree[v] > 1
135
+ obj = (pending_merges.delete(v) << obj).compact.inject { |a, b| a.merge(b) }
136
+ end
137
+ vertex_to_object[v] = obj
138
+ end
139
+
140
+ def handle_back_edge(u, v)
141
+ raise "#handle_back_edge should never happen in a fork-merge traversal"
142
+ end
143
+
144
+ def propagate_object(u, v, obj)
145
+ obj
146
+ end
147
+
148
+ def fork_object(obj)
149
+ obj.fork
150
+ end
151
+ end
152
+ end
153
+ end
154
+
@@ -0,0 +1,533 @@
1
+ module Roby
2
+ module Relations
3
+ # A relation graph
4
+ #
5
+ # Relation graphs extend the base graph class
6
+ # {BidirectionalDirectedAdjacencyGraph} by adding the ability to
7
+ # arrange the graphs in a hierarchy (where a 'child' is a subgraph of a
8
+ # 'parent'), and the modification methods {#add_relation} and
9
+ # {#remove_relation} that maintain consistency in the hierarchy.
10
+ # Moreover, it allows to set an {#observer} object that listens to graph
11
+ # modifications (Roby uses it to emit relation hooks on plan objects
12
+ # when included in a {ExecutablePlan}).
13
+ #
14
+ # Note that the underlying methods {#add_edge} and {#remove_edge}
15
+ # are still available in cases where the hooks should not be called
16
+ # *and* hierarchy consistency is maintained by other means (e.g. when
17
+ # copying a plan).
18
+ #
19
+ # Finally, it is possible for {#add_edge} to update an existing edge
20
+ # info. For this purpose, a subclass has to implement the {#merge_info}
21
+ # method which is called with the old and new info and should return the
22
+ # merged object. The default implementation raises ArgumentError
23
+ class Graph < BidirectionalDirectedAdjacencyGraph
24
+ extend Models::Graph
25
+
26
+ # True if this relation graph is a DAG
27
+ #
28
+ # This property is not enforced by the Graph class itself as in a
29
+ # lot of cases it would be too expensive. When used in Roby, it is
30
+ # either enforced by {ExecutablePlan} or when committing a
31
+ # transaction
32
+ attr_predicate :dag
33
+ # True if this relation should be seen by remote peers
34
+ attr_predicate :distribute
35
+ # If this relation is weak
36
+ #
37
+ # Weak relations are not considered during garbage collection
38
+ attr_predicate :weak
39
+ # If this relation is strong
40
+ #
41
+ # Strong relations mark parts of the plan that can't be exchanged
42
+ # bit-by-bit. I.e. {Plan#replace_task} will ignore those relations.
43
+ attr_predicate :strong
44
+
45
+ # If this relation embeds some additional information
46
+ attr_predicate :embeds_info?
47
+
48
+ # Whether edges in this relation should be copied on replacement or
49
+ # moved. The default is to move.
50
+ attr_predicate :copy_on_replace
51
+
52
+ # The relation parent (if any)
53
+ #
54
+ # @see superset_of recursive_subsets
55
+ attr_accessor :parent
56
+
57
+ # The set of graphs that are directly children of self in the graph
58
+ # hierarchy. They are subgraphs of self, but not all the existing
59
+ # subgraphs of self
60
+ #
61
+ # @see superset_of recursive_subsets
62
+ attr_reader :subsets
63
+
64
+ # An object that is called for relation modifications
65
+ #
66
+ # The relation will call the following hooks.
67
+ #
68
+ # Addition/removal hooks are called once per modification in the
69
+ # relation hierarchy. They get a 'relations' array which is the list
70
+ # of relation IDs (i.e. graph classes, e.g.
71
+ # {TaskStructure::Dependency}) which are concerned with the
72
+ # modification. This array is sorted from the downmost in the
73
+ # relation hierarchy (i.e. the most specialized) up to the upmost
74
+ # (the biggest superset).
75
+ #
76
+ # adding_edge(from, to, relations, info)
77
+ # added_edge(from, to, relations, info)
78
+ #
79
+ # Before and after a new edge is added between two vertices in the
80
+ # graph. 'info' is the edge info that is set for the edge in the
81
+ # first element of 'relations' (the other relations get nil)
82
+ #
83
+ # updating_edge(from, to, relation, info)
84
+ # updated_edge(from, to, relation, info)
85
+ #
86
+ # Before and after the edge info is set on a given edge. 'relation'
87
+ # is a single relation ID.
88
+ #
89
+ # removing_edge(from, to, relations)
90
+ # removed_edge(from, to, relations)
91
+ #
92
+ # Before and after an edge has been removed.
93
+ attr_reader :observer
94
+
95
+ # Creates a relation graph with the given name and options. The
96
+ # following options are recognized:
97
+ # +dag+::
98
+ # if the graph is a DAG. If true, add_relation will check that
99
+ # no cycle is created
100
+ # +subsets+::
101
+ # a set of Relations::Graph objects that are children of this one.
102
+ # See #superset_of.
103
+ # +distributed+::
104
+ # if this relation graph should be seen by remote hosts
105
+ def initialize(
106
+ observer: nil,
107
+ distribute: self.class.distribute?,
108
+ dag: self.class.dag?,
109
+ weak: self.class.weak?,
110
+ strong: self.class.strong?,
111
+ copy_on_replace: self.class.copy_on_replace?,
112
+ noinfo: !self.class.embeds_info?,
113
+ subsets: Set.new)
114
+
115
+ @observer = observer
116
+ @distribute = distribute
117
+ @dag = dag
118
+ @weak = weak
119
+ @strong = strong
120
+ @copy_on_replace = copy_on_replace
121
+ @embeds_info = !noinfo
122
+
123
+ # If the relation is a single-child relation, it expects to have
124
+ # this ivar set
125
+ if respond_to?(:single_child_accessor)
126
+ @single_child_accessor = "@#{self.class.child_name}"
127
+ end
128
+
129
+ @subsets = Set.new
130
+ subsets.each { |g| superset_of(g) }
131
+
132
+ super()
133
+ end
134
+
135
+ # Tests whether a vertex is reachable from this one
136
+ #
137
+ # This is at worst O(E), i.e. the number of vertices that are
138
+ # reachable from the source vertex.
139
+ #
140
+ # If you want to do a lot of these queries, or if you want to check
141
+ # for acyclicity, RGL offers better alternatives.
142
+ #
143
+ # @param [Object] u the origin vertex
144
+ # @param [Object] v the vertex whose reachability we want to test
145
+ # from 'u'
146
+ def reachable?(u, v)
147
+ depth_first_visit(u) { |o| return true if o == v }
148
+ false
149
+ end
150
+
151
+ def to_s
152
+ "#{self.class.name}:#{object_id.to_s(16)}"
153
+ end
154
+
155
+ def inspect; to_s end
156
+
157
+ # Copy a subgraph of self into another graph
158
+ #
159
+ # This method allows to define a mapping of vertices from self
160
+ # (source set) into vertices of another graph (target set), and
161
+ # copies the edges that exist between the vertices of the source set
162
+ # to edges between the corresponding vertices of target set
163
+ #
164
+ # @param [Graph] graph the target graph
165
+ # @param [Hash<Object,Object>] a mapping from the subgraph vertices
166
+ # in self to the corresponding vertices in the target graph
167
+ def copy_subgraph_to(graph, mappings)
168
+ mappings.each do |v, mapped_v|
169
+ each_out_neighbour(v) do |child|
170
+ if mapped_child = mappings[child]
171
+ graph.add_edge(mapped_v, mapped_child,
172
+ edge_info(v, child))
173
+ end
174
+ end
175
+ end
176
+ end
177
+
178
+ def find_edge_difference(graph, mapping)
179
+ if graph.num_edges != num_edges
180
+ return [:num_edges_differ]
181
+ end
182
+
183
+ each_edge do |parent, child|
184
+ m_parent, m_child = mapping[parent], mapping[child]
185
+ if !m_parent
186
+ return [:missing_mapping, parent]
187
+ elsif !m_child
188
+ return [:missing_mapping, child]
189
+ elsif !graph.has_vertex?(m_parent) || !graph.has_vertex?(m_child) || !graph.has_edge?(m_parent, m_child)
190
+ return [:missing_edge, parent, child]
191
+ elsif edge_info(parent, child) != graph.edge_info(m_parent, m_child)
192
+ return [:differing_edge_info, parent, child]
193
+ end
194
+ end
195
+ nil
196
+ end
197
+
198
+ # Moves a vertex relations onto another
199
+ #
200
+ # @param [Object] from the vertex whose relations are going to be
201
+ # moved
202
+ # @param [Object] to the vertex on which the relations will be
203
+ # added
204
+ # @param [Boolean] remove whether 'from' should be removed from the
205
+ # graph after replacement
206
+ def replace_vertex(from, to, remove: true)
207
+ edges = Array.new
208
+ each_in_neighbour(from) do |parent|
209
+ if parent != to
210
+ add_edge(parent, to, edge_info(parent, from))
211
+ edges << [parent, from]
212
+ end
213
+ end
214
+ each_out_neighbour(from) do |child|
215
+ if to != child
216
+ add_edge(to, child, edge_info(from, child))
217
+ edges << [from, child]
218
+ end
219
+ end
220
+
221
+ edges.each do |parent, child|
222
+ remove_relation(parent, child)
223
+ end
224
+
225
+ if remove
226
+ remove_vertex(from)
227
+ end
228
+ end
229
+
230
+ # Add the vertices and edges of a graph in self
231
+ #
232
+ # @param [Graph] graph the graph whose relations should be added to
233
+ # self
234
+ def merge!(graph)
235
+ merge(graph)
236
+ graph.clear
237
+ end
238
+
239
+ # @api private
240
+ #
241
+ # Updates the edge information of an existing info, or does nothing
242
+ # if the edge does not exist
243
+ #
244
+ # If the edge has a non-nil info already, the graph's #merge_info is
245
+ # called to merge the existing and new information. If #merge_info
246
+ # returns nil, the update is aborted
247
+ #
248
+ # @param from the edge parent object
249
+ # @param to the edge child object
250
+ # @param info the new edge info
251
+ # @return [Boolean] true if the edge existed and false otherwise
252
+ def try_updating_existing_edge_info(from, to, info)
253
+ return false if !has_edge?(from, to)
254
+
255
+ if !(old_info = edge_info(from, to)).nil?
256
+ if old_info == info
257
+ return true
258
+ elsif !(info = merge_info(from, to, old_info, info))
259
+ raise ArgumentError, "trying to change edge information in #{self} for #{from} => #{to}: old was #{old_info} and new is #{info}"
260
+ end
261
+ end
262
+ set_edge_info(from, to, info)
263
+ true
264
+ end
265
+
266
+ # Add an edge between two objects
267
+ #
268
+ # Unlike {BidirectionalDirectedAdjacencyGraph#add_edge}, it will
269
+ # update the edge info (using {#merge_info}) if the edge already
270
+ # exists.
271
+ #
272
+ # @return true if a new edge was created
273
+ def add_edge(a, b, info)
274
+ if !try_updating_existing_edge_info(a, b, info)
275
+ super
276
+ true
277
+ end
278
+ end
279
+
280
+ # Add an edge between +from+ and +to+. The relation is added on all
281
+ # parent relation graphs as well. If #dag? is true on +self+ or on one
282
+ # of its parents, the method will raise {CycleFoundError} in case the new
283
+ # edge would create a cycle.
284
+ #
285
+ # If +from+ or +to+ define the following hooks:
286
+ # adding_parent_object(parent, relations, info)
287
+ # adding_child_object(child, relations, info)
288
+ # added_parent_object(parent, relations, info)
289
+ # added_child_object(child, relations, info)
290
+ #
291
+ # then these hooks get respectively called before and after having
292
+ # added the relation, where +relations+ is the set of
293
+ # Relations::Graph
294
+ # instances where the edge has been added. It can be either [+self+] if
295
+ # the edge does not already exist in it, or [+self+, +parent+,
296
+ # <tt>parent.parent</tt>, ...] if the parent, grandparent, ... graphs
297
+ # do not include the edge either.
298
+ def add_relation(from, to, info = nil)
299
+ # First check if we're trying to change the edge information
300
+ # rather than creating a new edge
301
+ if try_updating_existing_edge_info(from, to, info)
302
+ return
303
+ end
304
+
305
+ new_relations = []
306
+ new_relations_ids = []
307
+ rel = self
308
+ while rel
309
+ if !rel.has_edge?(from, to)
310
+ new_relations << rel
311
+ new_relations_ids << rel.class
312
+ end
313
+ rel = rel.parent
314
+ end
315
+
316
+ if !new_relations.empty?
317
+ if observer
318
+ observer.adding_edge(from, to, new_relations_ids, info)
319
+ end
320
+ for rel in new_relations
321
+ rel.add_edge(from, to, (info if self == rel))
322
+ end
323
+ if observer
324
+ observer.added_edge(from, to, new_relations_ids, info)
325
+ end
326
+ end
327
+ end
328
+
329
+ # Set the information of an object relation
330
+ def set_edge_info(from, to, info)
331
+ if observer
332
+ observer.updating_edge_info(from, to, self.class, info)
333
+ end
334
+ super
335
+ if observer
336
+ observer.updated_edge_info(from, to, self.class, info)
337
+ end
338
+ end
339
+
340
+ # Method used in {#add_relation} and {#add_edge} to merge existing
341
+ # information with new information
342
+ #
343
+ # It is safe to raise from within this method
344
+ #
345
+ # @return [nil,Object] if nil, the update is aborted. If non-nil,
346
+ # it is the new information
347
+ def merge_info(from, to, old, new)
348
+ raise ArgumentError, "cannot update edge information in #{self}: #merge_info is not implemented"
349
+ end
350
+
351
+ alias :remove_vertex! :remove_vertex
352
+
353
+ def remove_vertex(object)
354
+ if !observer
355
+ return super
356
+ end
357
+
358
+ rel = self
359
+ relations, relations_ids = [], []
360
+ while rel
361
+ relations << rel
362
+ relations_ids << rel.class
363
+ rel = rel.parent
364
+ end
365
+
366
+ removed_relations = Array.new
367
+ in_neighbours(object).each { |parent| removed_relations << parent << object }
368
+ out_neighbours(object).each { |child| removed_relations << object << child }
369
+
370
+ removed_relations.each_slice(2) do |parent, child|
371
+ observer.removing_edge(parent, child, relations_ids)
372
+ end
373
+ relations.each { |rel| rel.remove_vertex!(object) }
374
+ removed_relations.each_slice(2) do |parent, child|
375
+ observer.removed_edge(parent, child, relations_ids)
376
+ end
377
+ !removed_relations.empty?
378
+ end
379
+
380
+ # Remove the relation between +from+ and +to+, in this graph and in its
381
+ # parent graphs as well.
382
+ #
383
+ # If +from+ or +to+ define the following hooks:
384
+ # removing_child_object(child, relations)
385
+ # removed_child_object(child, relations)
386
+ #
387
+ # then these hooks get respectively called once before and once after
388
+ # having removed the relation, where +relations+ is the set of
389
+ # Relations::Graph instances where the edge has been removed. It is always
390
+ # <tt>[self, parent, parent.parent, ...]</tt> up to the root relation
391
+ # which is a superset of +self+.
392
+ def remove_relation(from, to)
393
+ if !has_edge?(from, to)
394
+ return
395
+ end
396
+
397
+ rel = self
398
+ relations, relations_ids = [], []
399
+ while rel
400
+ relations << rel
401
+ relations_ids << rel.class
402
+ rel = rel.parent
403
+ end
404
+
405
+ if observer
406
+ observer.removing_edge(from, to, relations_ids)
407
+ end
408
+ for rel in relations
409
+ rel.remove_edge(from, to)
410
+ end
411
+ if observer
412
+ observer.removed_edge(from, to, relations_ids)
413
+ end
414
+ end
415
+
416
+ # Compute the set of all graphs that are subsets of this one in the
417
+ # subset hierarchy
418
+ def recursive_subsets
419
+ result = Set.new
420
+ queue = subsets.to_a.dup
421
+ while !queue.empty?
422
+ g = queue.shift
423
+ result << g
424
+ queue.concat(g.subsets.to_a)
425
+ end
426
+ result
427
+ end
428
+
429
+ # True if this relation does not have a parent
430
+ def root_relation?; !parent end
431
+
432
+ # Returns true if +relation+ is included in this relation (i.e. it is
433
+ # either the same relation or one of its children)
434
+ #
435
+ # See also #superset_of
436
+ def subset?(relation)
437
+ self.eql?(relation) || subsets.any? { |subrel| subrel.subset?(relation) }
438
+ end
439
+
440
+ # The root in this graph's hierarchy
441
+ def root_graph
442
+ g = self
443
+ while g.parent
444
+ g = g.parent
445
+ end
446
+ g
447
+ end
448
+
449
+ # Tests the presence of an edge in this graph or in its supersets
450
+ #
451
+ # See #superset_of for a description of the parent mechanism
452
+ def has_edge_in_hierarchy?(source, target)
453
+ root_graph.has_edge?(source, target)
454
+ end
455
+
456
+ # Declare that +self+ is a superset of +relation+. Once this is done,
457
+ # the system manages two constraints:
458
+ # * new relations added with {#add_relation} are also added in self
459
+ # * a relation can only exist in one subset of self
460
+ #
461
+ # One single graph can be the superset of multiple subgraphs (these are
462
+ # stored in the {#subsets} attribute), but one graph can have only one
463
+ # parent {#parent}.
464
+ #
465
+ # This operation can be called only if the new subset is empty (no
466
+ # edges and no vertices)
467
+ #
468
+ # @param [Graph] relation the relation that should be added as a
469
+ # subset of self
470
+ # @raise [ArgumentError] if 'relation' is not empty
471
+ def superset_of(relation)
472
+ if !relation.empty?
473
+ raise ArgumentError, "cannot pass a non-empty graph to #superset_of"
474
+ end
475
+
476
+ relation.parent = self
477
+ subsets << relation
478
+ end
479
+
480
+ def remove(vertex)
481
+ Roby.warn_deprecated "Graph#remove is deprecated, use #remove_vertex instead"
482
+ remove_vertex(vertex)
483
+ end
484
+
485
+ def link(a, b, info)
486
+ Roby.warn_deprecated "Graph#link is deprecated, use #add_edge instead"
487
+ add_edge(a, b, info)
488
+ end
489
+
490
+ def linked?(parent, child)
491
+ Roby.warn_deprecated "Graph#linked? is deprecated, use #add_edge instead"
492
+ has_edge?(parent, child)
493
+ end
494
+
495
+ def unlink(parent, child)
496
+ Roby.warn_deprecated "Graph#unlink is deprecated, use #remove_edge instead"
497
+ remove_edge(parent, child)
498
+ end
499
+
500
+ def each_parent_vertex(object, &block)
501
+ Roby.warn_deprecated "#each_parent_vertex has been replaced by #each_in_neighbour"
502
+ each_in_neighbour(object, &block)
503
+ end
504
+
505
+ def each_child_vertex(object, &block)
506
+ Roby.warn_deprecated "#each_child_vertex has been replaced by #each_out_neighbour"
507
+ each_out_neighbour(object, &block)
508
+ end
509
+
510
+ def copy_to(target)
511
+ Roby.warn_deprecated "Graph#copy_to is deprecated, use #merge instead (WARN: a.copy_to(b) is b.merge(a) !"
512
+ target.merge(self)
513
+ end
514
+
515
+ def size
516
+ Roby.warn_deprecated "Graph#size is deprecated, use #num_vertices instead"
517
+ num_vertices
518
+ end
519
+
520
+ def include?(object)
521
+ Roby.warn_deprecated "Graph#include? is deprecated, use #has_vertex? instead"
522
+ has_vertex?(object)
523
+ end
524
+
525
+ # @deprecated use {#has_edge_in_hierarchy?}
526
+ def linked_in_hierarchy?(source, target)
527
+ Roby.warn_deprecated "#linked_in_hierarchy? is deprecated, use #has_edge_in_hierarchy? instead"
528
+ has_edge_in_hierarchy?(source, target)
529
+ end
530
+ end
531
+ end
532
+ end
533
+