laser 0.7.0.pre1

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 (319) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +14 -0
  4. data/LICENSE +661 -0
  5. data/README.md +158 -0
  6. data/Rakefile +104 -0
  7. data/VERSION +1 -0
  8. data/bin/laser +7 -0
  9. data/design_docs/goals.md +57 -0
  10. data/design_docs/object_regex.md +426 -0
  11. data/design_docs/type_annotations.md +80 -0
  12. data/ext/laser/BasicBlock.cpp +572 -0
  13. data/ext/laser/BasicBlock.h +118 -0
  14. data/ext/laser/extconf.rb +3 -0
  15. data/features/laser.feature +25 -0
  16. data/features/step_definitions/laser_steps.rb +39 -0
  17. data/features/support/env.rb +14 -0
  18. data/features/support/testdata/1_input +1 -0
  19. data/features/support/testdata/1_output +1 -0
  20. data/features/support/testdata/2_input +4 -0
  21. data/features/support/testdata/2_output +4 -0
  22. data/features/support/testdata/3_input +8 -0
  23. data/features/support/testdata/3_output +11 -0
  24. data/features/support/testdata/4_input +5 -0
  25. data/features/support/testdata/4_output +5 -0
  26. data/features/support/testdata/5_input +13 -0
  27. data/laser.gemspec +382 -0
  28. data/lib/laser.rb +98 -0
  29. data/lib/laser/analysis/annotations.rb +95 -0
  30. data/lib/laser/analysis/annotations/annotation_config.yaml +3 -0
  31. data/lib/laser/analysis/annotations/comment_attachment_annotation.rb +66 -0
  32. data/lib/laser/analysis/annotations/node_pointers_annotation.rb +36 -0
  33. data/lib/laser/analysis/annotations/runtime_annotation.rb +55 -0
  34. data/lib/laser/analysis/argument_expansion.rb +132 -0
  35. data/lib/laser/analysis/arity.rb +34 -0
  36. data/lib/laser/analysis/bindings.rb +144 -0
  37. data/lib/laser/analysis/bootstrap/bootstrap.rb +298 -0
  38. data/lib/laser/analysis/bootstrap/laser_class.rb +106 -0
  39. data/lib/laser/analysis/bootstrap/laser_method.rb +255 -0
  40. data/lib/laser/analysis/bootstrap/laser_module.rb +403 -0
  41. data/lib/laser/analysis/bootstrap/laser_module_copy.rb +74 -0
  42. data/lib/laser/analysis/bootstrap/laser_object.rb +69 -0
  43. data/lib/laser/analysis/bootstrap/laser_proc.rb +150 -0
  44. data/lib/laser/analysis/bootstrap/laser_singleton_class.rb +44 -0
  45. data/lib/laser/analysis/comments.rb +35 -0
  46. data/lib/laser/analysis/control_flow.rb +28 -0
  47. data/lib/laser/analysis/control_flow/alias_analysis.rb +31 -0
  48. data/lib/laser/analysis/control_flow/basic_block.rb +105 -0
  49. data/lib/laser/analysis/control_flow/cfg_builder.rb +2505 -0
  50. data/lib/laser/analysis/control_flow/cfg_instruction.rb +190 -0
  51. data/lib/laser/analysis/control_flow/constant_propagation.rb +742 -0
  52. data/lib/laser/analysis/control_flow/control_flow_graph.rb +370 -0
  53. data/lib/laser/analysis/control_flow/lifetime_analysis.rb +91 -0
  54. data/lib/laser/analysis/control_flow/method_call_search.rb +26 -0
  55. data/lib/laser/analysis/control_flow/raise_properties.rb +25 -0
  56. data/lib/laser/analysis/control_flow/simulation.rb +385 -0
  57. data/lib/laser/analysis/control_flow/static_single_assignment.rb +185 -0
  58. data/lib/laser/analysis/control_flow/unreachability_analysis.rb +57 -0
  59. data/lib/laser/analysis/control_flow/unused_variables.rb +91 -0
  60. data/lib/laser/analysis/control_flow/yield_properties.rb +103 -0
  61. data/lib/laser/analysis/errors.rb +131 -0
  62. data/lib/laser/analysis/laser_utils.rb +18 -0
  63. data/lib/laser/analysis/lexical_analysis.rb +172 -0
  64. data/lib/laser/analysis/method_call.rb +68 -0
  65. data/lib/laser/analysis/protocol_registry.rb +30 -0
  66. data/lib/laser/analysis/scope.rb +118 -0
  67. data/lib/laser/analysis/sexp.rb +159 -0
  68. data/lib/laser/analysis/sexp_analysis.rb +40 -0
  69. data/lib/laser/analysis/sexp_extensions/constant_extraction.rb +115 -0
  70. data/lib/laser/analysis/sexp_extensions/source_location.rb +164 -0
  71. data/lib/laser/analysis/sexp_extensions/type_inference.rb +47 -0
  72. data/lib/laser/analysis/signature.rb +76 -0
  73. data/lib/laser/analysis/special_methods/send.rb +67 -0
  74. data/lib/laser/analysis/unused_methods.rb +21 -0
  75. data/lib/laser/analysis/visitor.rb +141 -0
  76. data/lib/laser/annotation_parser/annotations.treetop +126 -0
  77. data/lib/laser/annotation_parser/annotations_parser.rb +748 -0
  78. data/lib/laser/annotation_parser/class_annotations.treetop +82 -0
  79. data/lib/laser/annotation_parser/class_annotations_parser.rb +654 -0
  80. data/lib/laser/annotation_parser/overload.treetop +24 -0
  81. data/lib/laser/annotation_parser/overload_parser.rb +167 -0
  82. data/lib/laser/annotation_parser/parsers.rb +6 -0
  83. data/lib/laser/annotation_parser/structural.treetop +37 -0
  84. data/lib/laser/annotation_parser/structural_parser.rb +406 -0
  85. data/lib/laser/annotation_parser/useful_parsers.treetop +47 -0
  86. data/lib/laser/annotation_parser/useful_parsers_parser.rb +674 -0
  87. data/lib/laser/rake/task.rb +46 -0
  88. data/lib/laser/runner.rb +189 -0
  89. data/lib/laser/scanner.rb +169 -0
  90. data/lib/laser/standard_library/_thread.rb +110 -0
  91. data/lib/laser/standard_library/abbrev.rb +103 -0
  92. data/lib/laser/standard_library/array.rb +418 -0
  93. data/lib/laser/standard_library/base64.rb +91 -0
  94. data/lib/laser/standard_library/basic_object.rb +55 -0
  95. data/lib/laser/standard_library/benchmark.rb +556 -0
  96. data/lib/laser/standard_library/bignum.rb +185 -0
  97. data/lib/laser/standard_library/cgi.rb +275 -0
  98. data/lib/laser/standard_library/cgi/cookie.rb +147 -0
  99. data/lib/laser/standard_library/cgi/core.rb +791 -0
  100. data/lib/laser/standard_library/cgi/html.rb +1021 -0
  101. data/lib/laser/standard_library/cgi/session.rb +537 -0
  102. data/lib/laser/standard_library/cgi/session/pstore.rb +111 -0
  103. data/lib/laser/standard_library/cgi/util.rb +188 -0
  104. data/lib/laser/standard_library/class_definitions.rb +333 -0
  105. data/lib/laser/standard_library/comparable.rb +125 -0
  106. data/lib/laser/standard_library/complex.rb +162 -0
  107. data/lib/laser/standard_library/enumerable.rb +178 -0
  108. data/lib/laser/standard_library/exceptions.rb +135 -0
  109. data/lib/laser/standard_library/fixnum.rb +188 -0
  110. data/lib/laser/standard_library/float.rb +180 -0
  111. data/lib/laser/standard_library/hash.rb +237 -0
  112. data/lib/laser/standard_library/integer.rb +123 -0
  113. data/lib/laser/standard_library/laser_magic.rb +7 -0
  114. data/lib/laser/standard_library/nil_false_true.rb +113 -0
  115. data/lib/laser/standard_library/numbers.rb +192 -0
  116. data/lib/laser/standard_library/proc.rb +31 -0
  117. data/lib/laser/standard_library/set.rb +1348 -0
  118. data/lib/laser/standard_library/string.rb +666 -0
  119. data/lib/laser/standard_library/stringio.rb +2 -0
  120. data/lib/laser/standard_library/symbol.rb +125 -0
  121. data/lib/laser/standard_library/tsort.rb +242 -0
  122. data/lib/laser/support/acts_as_struct.rb +66 -0
  123. data/lib/laser/support/frequency.rb +55 -0
  124. data/lib/laser/support/inheritable_attributes.rb +145 -0
  125. data/lib/laser/support/module_extensions.rb +94 -0
  126. data/lib/laser/support/placeholder_object.rb +13 -0
  127. data/lib/laser/third_party/rgl/adjacency.rb +221 -0
  128. data/lib/laser/third_party/rgl/base.rb +228 -0
  129. data/lib/laser/third_party/rgl/bidirectional.rb +39 -0
  130. data/lib/laser/third_party/rgl/condensation.rb +47 -0
  131. data/lib/laser/third_party/rgl/connected_components.rb +138 -0
  132. data/lib/laser/third_party/rgl/control_flow.rb +170 -0
  133. data/lib/laser/third_party/rgl/depth_first_spanning_tree.rb +37 -0
  134. data/lib/laser/third_party/rgl/dominators.rb +124 -0
  135. data/lib/laser/third_party/rgl/dot.rb +93 -0
  136. data/lib/laser/third_party/rgl/graphxml.rb +51 -0
  137. data/lib/laser/third_party/rgl/implicit.rb +174 -0
  138. data/lib/laser/third_party/rgl/mutable.rb +117 -0
  139. data/lib/laser/third_party/rgl/rdot.rb +445 -0
  140. data/lib/laser/third_party/rgl/topsort.rb +72 -0
  141. data/lib/laser/third_party/rgl/transitivity.rb +180 -0
  142. data/lib/laser/third_party/rgl/traversal.rb +348 -0
  143. data/lib/laser/types/types.rb +433 -0
  144. data/lib/laser/version.rb +14 -0
  145. data/lib/laser/warning.rb +149 -0
  146. data/lib/laser/warning_sets/default.yml +13 -0
  147. data/lib/laser/warnings/assignment_in_condition.rb +20 -0
  148. data/lib/laser/warnings/comment_spacing.rb +31 -0
  149. data/lib/laser/warnings/extra_blank_lines.rb +30 -0
  150. data/lib/laser/warnings/extra_whitespace.rb +16 -0
  151. data/lib/laser/warnings/hash_symbol_18_warning.rb +63 -0
  152. data/lib/laser/warnings/hash_symbol_19_warning.rb +29 -0
  153. data/lib/laser/warnings/line_length.rb +115 -0
  154. data/lib/laser/warnings/misaligned_unindentation.rb +17 -0
  155. data/lib/laser/warnings/operator_spacing.rb +68 -0
  156. data/lib/laser/warnings/parens_on_declaration.rb +30 -0
  157. data/lib/laser/warnings/rescue_exception.rb +42 -0
  158. data/lib/laser/warnings/semicolon.rb +25 -0
  159. data/lib/laser/warnings/sexp_errors.rb +24 -0
  160. data/lib/laser/warnings/uncalled_method_warning.rb +7 -0
  161. data/lib/laser/warnings/useless_double_quotes.rb +38 -0
  162. data/spec/analysis_specs/annotations_spec.rb +47 -0
  163. data/spec/analysis_specs/annotations_specs/comment_attachment_spec.rb +68 -0
  164. data/spec/analysis_specs/annotations_specs/node_pointers_annotation_spec.rb +90 -0
  165. data/spec/analysis_specs/annotations_specs/runtime_annotation_spec.rb +135 -0
  166. data/spec/analysis_specs/annotations_specs/spec_helper.rb +33 -0
  167. data/spec/analysis_specs/argument_expansion_spec.rb +113 -0
  168. data/spec/analysis_specs/bindings_spec.rb +36 -0
  169. data/spec/analysis_specs/comment_spec.rb +93 -0
  170. data/spec/analysis_specs/control_flow_specs/cfg_instruction_spec.rb +111 -0
  171. data/spec/analysis_specs/control_flow_specs/constant_propagation_spec.rb +560 -0
  172. data/spec/analysis_specs/control_flow_specs/control_flow_graph_spec.rb +5 -0
  173. data/spec/analysis_specs/control_flow_specs/raise_properties_spec.rb +310 -0
  174. data/spec/analysis_specs/control_flow_specs/raise_type_inference_spec.rb +301 -0
  175. data/spec/analysis_specs/control_flow_specs/return_type_inference_spec.rb +431 -0
  176. data/spec/analysis_specs/control_flow_specs/simulation_spec.rb +158 -0
  177. data/spec/analysis_specs/control_flow_specs/spec_helper.rb +110 -0
  178. data/spec/analysis_specs/control_flow_specs/tuple_misuse_inference_spec.rb +125 -0
  179. data/spec/analysis_specs/control_flow_specs/unreachability_analysis_spec.rb +76 -0
  180. data/spec/analysis_specs/control_flow_specs/unused_variable_spec.rb +99 -0
  181. data/spec/analysis_specs/control_flow_specs/yield_properties_spec.rb +372 -0
  182. data/spec/analysis_specs/error_spec.rb +30 -0
  183. data/spec/analysis_specs/laser_class_spec.rb +322 -0
  184. data/spec/analysis_specs/lexical_analysis_spec.rb +184 -0
  185. data/spec/analysis_specs/protocol_registry_spec.rb +63 -0
  186. data/spec/analysis_specs/scope_annotation_spec.rb +1013 -0
  187. data/spec/analysis_specs/scope_spec.rb +126 -0
  188. data/spec/analysis_specs/sexp_analysis_spec.rb +30 -0
  189. data/spec/analysis_specs/sexp_extension_specs/constant_extraction_spec.rb +309 -0
  190. data/spec/analysis_specs/sexp_extension_specs/source_location_spec.rb +231 -0
  191. data/spec/analysis_specs/sexp_extension_specs/spec_helper.rb +1 -0
  192. data/spec/analysis_specs/sexp_extension_specs/type_inference_spec.rb +252 -0
  193. data/spec/analysis_specs/sexp_spec.rb +167 -0
  194. data/spec/analysis_specs/spec_helper.rb +27 -0
  195. data/spec/analysis_specs/unused_methods_spec.rb +65 -0
  196. data/spec/analysis_specs/visitor_spec.rb +64 -0
  197. data/spec/annotation_parser_specs/annotations_parser_spec.rb +89 -0
  198. data/spec/annotation_parser_specs/class_annotation_parser_spec.rb +120 -0
  199. data/spec/annotation_parser_specs/overload_parser_spec.rb +39 -0
  200. data/spec/annotation_parser_specs/parsers_spec.rb +14 -0
  201. data/spec/annotation_parser_specs/spec_helper.rb +1 -0
  202. data/spec/annotation_parser_specs/structural_parser_spec.rb +67 -0
  203. data/spec/laser_spec.rb +14 -0
  204. data/spec/rake_specs/spec_helper.rb +1 -0
  205. data/spec/rake_specs/task_spec.rb +67 -0
  206. data/spec/runner_spec.rb +207 -0
  207. data/spec/scanner_spec.rb +75 -0
  208. data/spec/spec_helper.rb +121 -0
  209. data/spec/standard_library/exceptions_spec.rb +19 -0
  210. data/spec/standard_library/globals_spec.rb +14 -0
  211. data/spec/standard_library/set_spec.rb +31 -0
  212. data/spec/standard_library/spec_helper.rb +1 -0
  213. data/spec/standard_library/standard_library_spec.rb +302 -0
  214. data/spec/support_specs/acts_as_struct_spec.rb +94 -0
  215. data/spec/support_specs/frequency_spec.rb +23 -0
  216. data/spec/support_specs/module_extensions_spec.rb +117 -0
  217. data/spec/support_specs/spec_helper.rb +1 -0
  218. data/spec/type_specs/spec_helper.rb +1 -0
  219. data/spec/type_specs/types_spec.rb +133 -0
  220. data/spec/warning_spec.rb +95 -0
  221. data/spec/warning_specs/assignment_in_condition_spec.rb +68 -0
  222. data/spec/warning_specs/comment_spacing_spec.rb +65 -0
  223. data/spec/warning_specs/extra_blank_lines_spec.rb +70 -0
  224. data/spec/warning_specs/extra_whitespace_spec.rb +33 -0
  225. data/spec/warning_specs/hash_symbol_18_warning_spec.rb +89 -0
  226. data/spec/warning_specs/hash_symbol_19_warning_spec.rb +63 -0
  227. data/spec/warning_specs/line_length_spec.rb +173 -0
  228. data/spec/warning_specs/misaligned_unindentation_spec.rb +35 -0
  229. data/spec/warning_specs/operator_spacing_spec.rb +104 -0
  230. data/spec/warning_specs/parens_on_declaration_spec.rb +57 -0
  231. data/spec/warning_specs/rescue_exception_spec.rb +105 -0
  232. data/spec/warning_specs/semicolon_spec.rb +58 -0
  233. data/spec/warning_specs/spec_helper.rb +1 -0
  234. data/spec/warning_specs/useless_double_quotes_spec.rb +74 -0
  235. data/status_reports/2010/12/2010-12-14.md +163 -0
  236. data/status_reports/2010/12/2010-12-23.md +298 -0
  237. data/status_reports/2010/12/2010-12-24.md +6 -0
  238. data/test/third_party_tests/rgl_tests/TestComponents.rb +65 -0
  239. data/test/third_party_tests/rgl_tests/TestCycles.rb +61 -0
  240. data/test/third_party_tests/rgl_tests/TestDirectedGraph.rb +125 -0
  241. data/test/third_party_tests/rgl_tests/TestDot.rb +18 -0
  242. data/test/third_party_tests/rgl_tests/TestEdge.rb +34 -0
  243. data/test/third_party_tests/rgl_tests/TestGraph.rb +71 -0
  244. data/test/third_party_tests/rgl_tests/TestGraphXML.rb +57 -0
  245. data/test/third_party_tests/rgl_tests/TestImplicit.rb +52 -0
  246. data/test/third_party_tests/rgl_tests/TestRdot.rb +863 -0
  247. data/test/third_party_tests/rgl_tests/TestTransitivity.rb +129 -0
  248. data/test/third_party_tests/rgl_tests/TestTraversal.rb +220 -0
  249. data/test/third_party_tests/rgl_tests/TestUnDirectedGraph.rb +102 -0
  250. data/test/third_party_tests/rgl_tests/examples/north/Graph.log +128 -0
  251. data/test/third_party_tests/rgl_tests/examples/north/g.10.0.graphml +28 -0
  252. data/test/third_party_tests/rgl_tests/examples/north/g.10.1.graphml +28 -0
  253. data/test/third_party_tests/rgl_tests/examples/north/g.10.11.graphml +31 -0
  254. data/test/third_party_tests/rgl_tests/examples/north/g.10.12.graphml +27 -0
  255. data/test/third_party_tests/rgl_tests/examples/north/g.10.13.graphml +27 -0
  256. data/test/third_party_tests/rgl_tests/examples/north/g.10.14.graphml +27 -0
  257. data/test/third_party_tests/rgl_tests/examples/north/g.10.15.graphml +26 -0
  258. data/test/third_party_tests/rgl_tests/examples/north/g.10.16.graphml +26 -0
  259. data/test/third_party_tests/rgl_tests/examples/north/g.10.17.graphml +26 -0
  260. data/test/third_party_tests/rgl_tests/examples/north/g.10.19.graphml +37 -0
  261. data/test/third_party_tests/rgl_tests/examples/north/g.10.2.graphml +28 -0
  262. data/test/third_party_tests/rgl_tests/examples/north/g.10.20.graphml +38 -0
  263. data/test/third_party_tests/rgl_tests/examples/north/g.10.22.graphml +43 -0
  264. data/test/third_party_tests/rgl_tests/examples/north/g.10.24.graphml +30 -0
  265. data/test/third_party_tests/rgl_tests/examples/north/g.10.25.graphml +45 -0
  266. data/test/third_party_tests/rgl_tests/examples/north/g.10.27.graphml +38 -0
  267. data/test/third_party_tests/rgl_tests/examples/north/g.10.28.graphml +30 -0
  268. data/test/third_party_tests/rgl_tests/examples/north/g.10.29.graphml +38 -0
  269. data/test/third_party_tests/rgl_tests/examples/north/g.10.3.graphml +26 -0
  270. data/test/third_party_tests/rgl_tests/examples/north/g.10.30.graphml +34 -0
  271. data/test/third_party_tests/rgl_tests/examples/north/g.10.31.graphml +42 -0
  272. data/test/third_party_tests/rgl_tests/examples/north/g.10.34.graphml +42 -0
  273. data/test/third_party_tests/rgl_tests/examples/north/g.10.37.graphml +28 -0
  274. data/test/third_party_tests/rgl_tests/examples/north/g.10.38.graphml +38 -0
  275. data/test/third_party_tests/rgl_tests/examples/north/g.10.39.graphml +36 -0
  276. data/test/third_party_tests/rgl_tests/examples/north/g.10.4.graphml +26 -0
  277. data/test/third_party_tests/rgl_tests/examples/north/g.10.40.graphml +37 -0
  278. data/test/third_party_tests/rgl_tests/examples/north/g.10.41.graphml +37 -0
  279. data/test/third_party_tests/rgl_tests/examples/north/g.10.42.graphml +26 -0
  280. data/test/third_party_tests/rgl_tests/examples/north/g.10.45.graphml +28 -0
  281. data/test/third_party_tests/rgl_tests/examples/north/g.10.46.graphml +32 -0
  282. data/test/third_party_tests/rgl_tests/examples/north/g.10.5.graphml +31 -0
  283. data/test/third_party_tests/rgl_tests/examples/north/g.10.50.graphml +30 -0
  284. data/test/third_party_tests/rgl_tests/examples/north/g.10.56.graphml +29 -0
  285. data/test/third_party_tests/rgl_tests/examples/north/g.10.57.graphml +32 -0
  286. data/test/third_party_tests/rgl_tests/examples/north/g.10.58.graphml +32 -0
  287. data/test/third_party_tests/rgl_tests/examples/north/g.10.6.graphml +26 -0
  288. data/test/third_party_tests/rgl_tests/examples/north/g.10.60.graphml +32 -0
  289. data/test/third_party_tests/rgl_tests/examples/north/g.10.61.graphml +34 -0
  290. data/test/third_party_tests/rgl_tests/examples/north/g.10.62.graphml +34 -0
  291. data/test/third_party_tests/rgl_tests/examples/north/g.10.68.graphml +30 -0
  292. data/test/third_party_tests/rgl_tests/examples/north/g.10.69.graphml +32 -0
  293. data/test/third_party_tests/rgl_tests/examples/north/g.10.7.graphml +29 -0
  294. data/test/third_party_tests/rgl_tests/examples/north/g.10.70.graphml +26 -0
  295. data/test/third_party_tests/rgl_tests/examples/north/g.10.71.graphml +27 -0
  296. data/test/third_party_tests/rgl_tests/examples/north/g.10.72.graphml +28 -0
  297. data/test/third_party_tests/rgl_tests/examples/north/g.10.74.graphml +29 -0
  298. data/test/third_party_tests/rgl_tests/examples/north/g.10.75.graphml +29 -0
  299. data/test/third_party_tests/rgl_tests/examples/north/g.10.78.graphml +27 -0
  300. data/test/third_party_tests/rgl_tests/examples/north/g.10.79.graphml +34 -0
  301. data/test/third_party_tests/rgl_tests/examples/north/g.10.8.graphml +29 -0
  302. data/test/third_party_tests/rgl_tests/examples/north/g.10.80.graphml +34 -0
  303. data/test/third_party_tests/rgl_tests/examples/north/g.10.82.graphml +35 -0
  304. data/test/third_party_tests/rgl_tests/examples/north/g.10.83.graphml +32 -0
  305. data/test/third_party_tests/rgl_tests/examples/north/g.10.85.graphml +34 -0
  306. data/test/third_party_tests/rgl_tests/examples/north/g.10.86.graphml +34 -0
  307. data/test/third_party_tests/rgl_tests/examples/north/g.10.88.graphml +37 -0
  308. data/test/third_party_tests/rgl_tests/examples/north/g.10.89.graphml +29 -0
  309. data/test/third_party_tests/rgl_tests/examples/north/g.10.9.graphml +26 -0
  310. data/test/third_party_tests/rgl_tests/examples/north/g.10.90.graphml +32 -0
  311. data/test/third_party_tests/rgl_tests/examples/north/g.10.91.graphml +31 -0
  312. data/test/third_party_tests/rgl_tests/examples/north/g.10.92.graphml +26 -0
  313. data/test/third_party_tests/rgl_tests/examples/north/g.10.93.graphml +32 -0
  314. data/test/third_party_tests/rgl_tests/examples/north/g.10.94.graphml +34 -0
  315. data/test/third_party_tests/rgl_tests/examples/north/g.12.8.graphml +40 -0
  316. data/test/third_party_tests/rgl_tests/examples/north/g.14.9.graphml +36 -0
  317. data/test/third_party_tests/rgl_tests/test_helper.rb +7 -0
  318. data/test/third_party_tests/test_inheritable_attributes.rb +187 -0
  319. metadata +470 -0
@@ -0,0 +1,72 @@
1
+ # topsort.rb
2
+
3
+ require 'laser/third_party/rgl/traversal'
4
+
5
+ module RGL
6
+
7
+ # Topological Sort Iterator
8
+ #
9
+ # The topological sort algorithm creates a linear ordering of the vertices
10
+ # such that if edge (u,v) appears in the graph, then u comes before v in
11
+ # the ordering. The graph must be a directed acyclic graph (DAG).
12
+ #
13
+ # The iterator can also be applied to undirected graph or to a DG graph
14
+ # which contains a cycle. In this case, the Iterator does not reach all
15
+ # vertices. The implementation of acyclic? uses this fact.
16
+
17
+ class TopsortIterator
18
+
19
+ include GraphIterator
20
+
21
+ def initialize (g)
22
+ super(g)
23
+ set_to_begin
24
+ end
25
+
26
+ def set_to_begin # :nodoc:
27
+ @waiting = Array.new
28
+ @inDegrees = Hash.new(0)
29
+
30
+ graph.each_vertex do |u|
31
+ @inDegrees[u] = 0 unless @inDegrees.has_key?(u)
32
+ graph.each_adjacent(u) do |v|
33
+ @inDegrees[v] += 1
34
+ end
35
+ end
36
+
37
+ @inDegrees.each_pair do |v, indegree|
38
+ @waiting.push(v) if indegree.zero?
39
+ end
40
+ end
41
+
42
+ def basic_forward # :nodoc:
43
+ u = @waiting.pop
44
+ graph.each_adjacent(u) do |v|
45
+ @inDegrees[v] -= 1
46
+ @waiting.push(v) if @inDegrees[v].zero?
47
+ end
48
+ u
49
+ end
50
+
51
+ def at_beginning?; true; end # :nodoc: FIXME
52
+ def at_end?; @waiting.empty?; end # :nodoc:
53
+
54
+ end # class TopsortIterator
55
+
56
+ module Graph
57
+
58
+ # Returns a TopsortIterator.
59
+
60
+ def topsort_iterator
61
+ TopsortIterator.new(self)
62
+ end
63
+
64
+ # Returns true if the graph contains no cycles. This is only meaningful
65
+ # for directed graphs. Returns false for undirected graphs.
66
+
67
+ def acyclic?
68
+ topsort_iterator.count == num_vertices
69
+ end
70
+
71
+ end # module Graph
72
+ end # module RGL
@@ -0,0 +1,180 @@
1
+ require 'enumerator'
2
+
3
+ require 'laser/third_party/rgl/adjacency'
4
+ require 'laser/third_party/rgl/base'
5
+ require 'laser/third_party/rgl/connected_components'
6
+ require 'laser/third_party/rgl/condensation'
7
+
8
+ module RGL
9
+ module Graph
10
+ # Returns an RGL::DirectedAdjacencyGraph which is the transitive closure of
11
+ # this graph. Meaning, for each path u -> ... -> v in this graph, the path
12
+ # is copied and the edge u -> v is added. This method supports working with
13
+ # cyclic graphs by ensuring that edges are created between every pair of
14
+ # vertices in the cycle, including self-referencing edges.
15
+ #
16
+ # This method should run in O(|V||E|) time, where |V| and |E| are the number
17
+ # of vertices and edges respectively.
18
+ #
19
+ # Raises RGL::NotDirectedError if run on an undirected graph.
20
+ def transitive_closure
21
+ raise NotDirectedError,
22
+ "transitive_closure only supported for directed graphs" unless directed?
23
+
24
+ # Compute a condensation graph in order to hide cycles.
25
+ cg = condensation_graph
26
+
27
+ # Use a depth first search to calculate the transitive closure over the
28
+ # condensation graph. This ensures that as we traverse up the graph we
29
+ # know the transitive closure of each subgraph rooted at each node
30
+ # starting at the leaves. Subsequent root nodes which consume these
31
+ # subgraphs by way of the nodes' immediate successors can then immediately
32
+ # add edges to the roots of the subgraphs and to every successor of those
33
+ # roots.
34
+ tc_cg = DirectedAdjacencyGraph.new
35
+ cg.depth_first_search do |v|
36
+ # For each vertex v, w, and x where the edges v -> w and w -> x exist in
37
+ # the source graph, add edges v -> w and v -> x to the target graph.
38
+ cg.each_adjacent(v) do |w|
39
+ tc_cg.add_edge(v, w)
40
+ tc_cg.each_adjacent(w) do |x|
41
+ tc_cg.add_edge(v, x)
42
+ end
43
+ end
44
+ # Ensure that a vertex with no in or out edges is added to the graph.
45
+ tc_cg.add_vertex(v)
46
+ end
47
+
48
+ # Expand the condensed transitive closure.
49
+ #
50
+ # For each trivial strongly connected component in the condensed graph,
51
+ # add the single node it contains to the new graph and add edges for each
52
+ # edge the node begins in the original graph.
53
+ # For each NON-trivial strongly connected component in the condensed
54
+ # graph, add each node it contains to the new graph and add edges to
55
+ # every node in the strongly connected component, including self
56
+ # referential edges. Then for each edge of the original graph from any
57
+ # of the contained nodes, add edges from each of the contained nodes to
58
+ # all the edge targets.
59
+ g = DirectedAdjacencyGraph.new
60
+ tc_cg.each_vertex do |scc|
61
+ scc.each do |v|
62
+ # Add edges between all members of non-trivial strongly connected
63
+ # components (size > 1) and ensure that self referential edges are
64
+ # added when necessary for trivial strongly connected components.
65
+ if scc.size > 1 || has_edge?(v, v) then
66
+ scc.each do |w|
67
+ g.add_edge(v, w)
68
+ end
69
+ end
70
+ # Ensure that a vertex with no in or out edges is added to the graph.
71
+ g.add_vertex(v)
72
+ end
73
+ # Add an edge from every member of a strongly connected component to
74
+ # every member of each strongly connected component to which the former
75
+ # points.
76
+ tc_cg.each_adjacent(scc) do |scc2|
77
+ scc.each do |v|
78
+ scc2.each do |w|
79
+ g.add_edge(v, w)
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ # Finally, the transitive closure...
86
+ g
87
+ end
88
+
89
+ # Returns an RGL::DirectedAdjacencyGraph which is the transitive reduction
90
+ # of this graph. Meaning, that each edge u -> v is omitted if path
91
+ # u -> ... -> v exists. This method supports working with cyclic graphs;
92
+ # however, cycles are arbitrarily simplified which may lead to variant,
93
+ # although equally valid, results on equivalent graphs.
94
+ #
95
+ # This method should run in O(|V||E|) time, where |V| and |E| are the number
96
+ # of vertices and edges respectively.
97
+ #
98
+ # Raises RGL::NotDirectedError if run on an undirected graph.
99
+ def transitive_reduction
100
+ raise NotDirectedError,
101
+ "transitive_reduction only supported for directed graphs" unless directed?
102
+
103
+ # Compute a condensation graph in order to hide cycles.
104
+ cg = condensation_graph
105
+
106
+ # Use a depth first search to compute the transitive reduction over the
107
+ # condensed graph. This is similar to the computation of the transitive
108
+ # closure over the graph in that for any node of the graph all nodes
109
+ # reachable from the node are tracked. Using a depth first search ensures
110
+ # that all nodes reachable from a target node are known when considering
111
+ # whether or not to add an edge pointing to that target.
112
+ tr_cg = DirectedAdjacencyGraph.new
113
+ paths_from = {}
114
+ cg.depth_first_search do |v|
115
+ paths_from[v] = Set.new
116
+ cg.each_adjacent(v) do |w|
117
+ # Only add the edge v -> w if there is no other edge v -> x such that
118
+ # w is reachable from x. Make sure to completely skip the case where
119
+ # x == w.
120
+ unless Enumerator.new(cg, :each_adjacent, v).any? do |x|
121
+ x != w && paths_from[x].include?(w)
122
+ end then
123
+ tr_cg.add_edge(v, w)
124
+
125
+ # For each vertex v, track all nodes reachable from v by adding node
126
+ # w to the list as well as all the nodes readable from w.
127
+ paths_from[v] << w
128
+ paths_from[v].merge(paths_from[w])
129
+ end
130
+ end
131
+ # Ensure that a vertex with no in or out edges is added to the graph.
132
+ tr_cg.add_vertex(v)
133
+ end
134
+
135
+ # Expand the condensed transitive reduction.
136
+ #
137
+ # For each trivial strongly connected component in the condensed graph,
138
+ # add the single node it contains to the new graph and add edges for each
139
+ # edge the node begins in the original graph.
140
+ # For each NON-trivial strongly connected component in the condensed
141
+ # graph, add each node it contains to the new graph and add arbitrary
142
+ # edges between the nodes to form a simple cycle. Then for each strongly
143
+ # connected component adjacent to the current one, find and add the first
144
+ # edge which exists in the original graph, starts in the first strongly
145
+ # connected component, and ends in the second strongly connected
146
+ # component.
147
+ g = DirectedAdjacencyGraph.new
148
+ tr_cg.each_vertex do |scc|
149
+ # Make a cycle of the contents of non-trivial strongly connected
150
+ # components.
151
+ scc_arr = scc.to_a
152
+ if scc.size > 1 || has_edge?(scc_arr.first, scc_arr.first) then
153
+ 0.upto(scc_arr.size - 2) do |idx|
154
+ g.add_edge(scc_arr[idx], scc_arr[idx + 1])
155
+ end
156
+ g.add_edge(scc_arr.last, scc_arr.first)
157
+ end
158
+
159
+ # Choose a single edge between the members of two different strongly
160
+ # connected component to add to the graph.
161
+ edges = Enumerator.new(self, :each_edge)
162
+ tr_cg.each_adjacent(scc) do |scc2|
163
+ g.add_edge(
164
+ *edges.find do |v, w|
165
+ scc.member?(v) && scc2.member?(w)
166
+ end
167
+ )
168
+ end
169
+
170
+ # Ensure that a vertex with no in or out edges is added to the graph.
171
+ scc.each do |v|
172
+ g.add_vertex(v)
173
+ end
174
+ end
175
+
176
+ # Finally, the transitive reduction...
177
+ g
178
+ end
179
+ end # module Graph
180
+ end # module RGL
@@ -0,0 +1,348 @@
1
+ # traversal.rb
2
+ #
3
+ # This file defines the basic graph traversal algorithm for DFS and BFS search.
4
+ # They are implemented as an RGL::GraphIterator, which is a Stream of vertices
5
+ # of a given graph. The streams are not reversable.
6
+ #
7
+ # Beside being an iterator in the sense of the Stream mixin, RGL::BFSIterator
8
+ # and RGL::DFSIterator follow the BGL
9
+ # Visitor[http://www.boost.org/libs/graph/doc/visitor_concepts.html] Concepts
10
+ # in a slightly modified fashion (especially for the RGL::DFSIterator).
11
+
12
+ require 'laser/third_party/rgl/base'
13
+ require 'stream'
14
+
15
+ module RGL
16
+
17
+ module GraphWrapper # :nodoc:
18
+
19
+ attr_accessor :graph
20
+
21
+ # Creates a new GraphWrapper on _graph_.
22
+ def initialize (graph)
23
+ @graph = graph
24
+ end
25
+
26
+ end # module GraphWrapper
27
+
28
+ # A GraphIterator is the abstract superclass of all Iterators on graphs.
29
+ # Each such iterator should implement the protocol defined in module Stream.
30
+ module GraphIterator
31
+ include Stream
32
+ include GraphWrapper
33
+ end
34
+
35
+ # Module GraphVisitor defines the BGL
36
+ # BFS[http://www.boost.org/libs/graph/doc/BFSVisitor.html] Visitor Concept).
37
+ #
38
+ # Visitors provide a mechanism for extending an algorithm (i.e., for
39
+ # customizing what is done at each step of the algorithm). They allow users
40
+ # to insert their own operations at various steps within a graph algorithm.
41
+ #
42
+ # Graph algorithms typically have multiple event points where one may want to
43
+ # insert a call-back. Therefore, visitors have several methods that
44
+ # correspond to the various event points. Each algorithm has a different
45
+ # set of event points. The following are common to both DFS and BFS search.
46
+ #
47
+ # * examine_vertex
48
+ # * finish_vertex
49
+ # * examine_edge
50
+ # * tree_edge
51
+ # * back_edge
52
+ # * forward_edge
53
+ #
54
+ # These methods are all called handle_* and can be set to appropriate blocks,
55
+ # using the methods set_*_event_handler, which are defined for each event
56
+ # mentioned above.
57
+ #
58
+ # As an alternative, you can also override the handle_* methods in a
59
+ # subclass, to configure the algorithm (as an example, see TarjanSccVisitor).
60
+ #
61
+ # During a graph traversal, vertices are *colored* using the colors :GRAY
62
+ # (when waiting) and :BLACK when finished. All other vertices are :WHITE.
63
+ # The color_map is also maintained in the visitor.
64
+
65
+ module GraphVisitor
66
+
67
+ include GraphWrapper
68
+
69
+ attr_reader :color_map
70
+
71
+ # Create a new GraphVisitor on _graph_.
72
+
73
+ def initialize (graph)
74
+ super graph
75
+ reset
76
+ end
77
+
78
+ # Mark each vertex unvisited (i.e. :WHITE)
79
+
80
+ def reset
81
+ @color_map = Hash.new(:WHITE)
82
+ end
83
+
84
+ # Returns true if vertex _v_ is colored :BLACK (i.e. finished).
85
+
86
+ def finished_vertex? (v)
87
+ @color_map[v] == :BLACK
88
+ end
89
+
90
+ # Attach a map to the visitor which records the distance of a visited
91
+ # vertex to the start vertex.
92
+ #
93
+ # This is similar to BGLs
94
+ # distance_recorder[http://www.boost.org/libs/graph/doc/distance_recorder.html].
95
+ #
96
+ # After the distance_map is attached, the visitor has a new method
97
+ # distance_to_root, which answers the distance to the start vertex.
98
+
99
+ def attach_distance_map (map = Hash.new(0))
100
+ @dist_map = map
101
+
102
+ class << self
103
+
104
+ def handle_tree_edge (u, v)
105
+ super
106
+ @dist_map[v] = @dist_map[u] + 1
107
+ end
108
+
109
+ # Answer the distance to the start vertex.
110
+
111
+ def distance_to_root (v)
112
+ @dist_map[v]
113
+ end
114
+
115
+ end # class
116
+ end
117
+
118
+ # Shall we follow the edge (u,v); i.e. v has color :WHITE
119
+
120
+ def follow_edge? (u, v) # :nodoc:
121
+ @color_map[v] == :WHITE
122
+ end
123
+
124
+ # == Visitor Event Points
125
+
126
+ def self.def_event_handler (m)
127
+ params = m =~ /edge/ ? "u,v" : "u"
128
+ self.class_eval %{
129
+ def handle_#{m} (#{params})
130
+ @#{m}_event_handler.call(#{params}) if defined? @#{m}_event_handler
131
+ end
132
+
133
+ def set_#{m}_event_handler (&b)
134
+ @#{m}_event_handler = b
135
+ end
136
+ }
137
+ end
138
+
139
+ %w[examine_vertex finish_vertex examine_edge tree_edge back_edge
140
+ forward_edge].each do |m|
141
+ def_event_handler(m)
142
+ end
143
+
144
+ end # module GraphVisitor
145
+
146
+ # A BFSIterator can be used to traverse a graph from a given start vertex in
147
+ # breath first search order. Since the Iterator also mixins the GraphVisitor,
148
+ # it provides all event points defined there.
149
+ #
150
+ # The vertices which are not yet visited are held in the queue @waiting.
151
+ # During the traversal, vertices are *colored* using the colors :GRAY
152
+ # (when waiting) and :BLACK when finished. All other vertices are :WHITE.
153
+ #
154
+ # For more doc see the BGL
155
+ # BFS[http://www.boost.org/libs/graph/doc/BFSVisitor.html] Visitor Concept .
156
+ #
157
+ # See the implementation of bfs_search_tree_from for an example usage.
158
+
159
+ class BFSIterator
160
+
161
+ include GraphIterator
162
+ include GraphVisitor
163
+
164
+ attr_accessor :start_vertex
165
+
166
+ # Create a new BFSIterator on _graph_, starting at vertex _start_.
167
+
168
+ def initialize (graph, start=graph.detect{ |x| true })
169
+ super(graph)
170
+ @start_vertex = start
171
+ set_to_begin
172
+ end
173
+
174
+ # Returns true if the @color_map has only one entry (for the start vertex).
175
+
176
+ def at_beginning? # :nodoc:
177
+ @color_map.size == 1
178
+ end
179
+
180
+ # Returns true if @waiting is empty.
181
+
182
+ def at_end?
183
+ @waiting.empty?
184
+ end
185
+
186
+ # Reset the iterator to the initial state (i.e. at_beginning? == true).
187
+
188
+ def set_to_begin
189
+ color_map[@start_vertex] = :GRAY
190
+ @waiting = [@start_vertex] # a queue
191
+ handle_tree_edge(nil, @start_vertex) # discovers start vertex
192
+ end
193
+
194
+ def basic_forward # :nodoc:
195
+ u = next_vertex
196
+ handle_examine_vertex(u)
197
+ graph.each_adjacent(u) { |v|
198
+ handle_examine_edge(u, v)
199
+ if follow_edge?(u, v) # (u,v) is a tree edge
200
+ handle_tree_edge(u, v) # also discovers v
201
+ color_map[v] = :GRAY # color of v was :WHITE
202
+ @waiting.push(v)
203
+ else # (u,v) is a non tree edge
204
+ if color_map[v] == :GRAY
205
+ handle_back_edge(u, v) # (u,v) has gray target
206
+ else
207
+ handle_forward_edge(u, v) # (u,v) has black target
208
+ end
209
+ end
210
+ }
211
+ color_map[u] = :BLACK
212
+ handle_finish_vertex(u) # finish vertex
213
+ u
214
+ end
215
+
216
+ protected
217
+
218
+ def next_vertex # :nodoc:
219
+ # waiting is a queue
220
+ @waiting.shift
221
+ end
222
+ end # class BFSIterator
223
+
224
+
225
+ module Graph
226
+
227
+ # Returns a BFSIterator, starting at vertex _v_.
228
+
229
+ def bfs_iterator (v = self.detect { |x| true})
230
+ BFSIterator.new(self, v)
231
+ end
232
+
233
+ # Returns a DirectedAdjacencyGraph, which represents a BFS search tree
234
+ # starting at _v_. This method uses the tree_edge_event of BFSIterator
235
+ # to record all tree edges of the search tree in the result.
236
+
237
+ def bfs_search_tree_from (v)
238
+ require 'laser/third_party/rgl/adjacency'
239
+ bfs = bfs_iterator(v)
240
+ tree = DirectedAdjacencyGraph.new
241
+ bfs.set_tree_edge_event_handler { |from, to|
242
+ tree.add_edge(from, to)
243
+ }
244
+ bfs.set_to_end # does the search
245
+ tree
246
+ end
247
+
248
+ end # module Graph
249
+
250
+
251
+ # Iterator for a depth first search, starting at a given vertex. The only
252
+ # difference from BFSIterator is that @waiting is a stack, instead of a queue.
253
+ #
254
+ # Note that this is different from DFSVisitor, which is used in the recursive
255
+ # version for depth first search (see depth_first_search).
256
+
257
+ class DFSIterator < BFSIterator
258
+
259
+ def next_vertex
260
+ # waiting is a stack
261
+ @waiting.pop
262
+ end
263
+
264
+ end # class DFSIterator
265
+
266
+
267
+ # A DFSVisitor is needed by the depth_first_search and depth_first_visit
268
+ # methods of a graph. Besides the eventpoint of GraphVisitor, it provides
269
+ # an additional eventpoint start_vertex, which is called when a
270
+ # depth_first_search starts a new subtree of the depth first forest that is
271
+ # defined by the search.
272
+ #
273
+ # Note that the discover_vertex event defined in the BGL
274
+ # DFSVisitor[http://www.boost.org/libs/graph/doc/DFSVisitor.html] is not
275
+ # this is also defined in the common mixin GraphVisitor of DFSVisitor,
276
+ # DFSIterator, and BFSIterator.
277
+
278
+ class DFSVisitor
279
+
280
+ include GraphVisitor
281
+
282
+ GraphVisitor.def_event_handler("start_vertex")
283
+
284
+ end # class DFSVisitor
285
+
286
+
287
+ module Graph
288
+
289
+ # Returns a DFSIterator staring at vertex _v_.
290
+
291
+ def dfs_iterator (v = self.detect { |x| true })
292
+ DFSIterator.new(self, v)
293
+ end
294
+
295
+ # Do a recursive DFS search on the whole graph. If a block is passed,
296
+ # it is called on each _finish_vertex_ event. See
297
+ # strongly_connected_components for an example usage.
298
+
299
+ def depth_first_search (vis = DFSVisitor.new(self), &b)
300
+ each_vertex do |u|
301
+ unless vis.finished_vertex?(u)
302
+ vis.handle_start_vertex(u)
303
+ depth_first_visit(u, vis, &b)
304
+ end
305
+ end
306
+ end
307
+
308
+ # Start a depth first search at vertex _u_. The block _b_ is called on
309
+ # each finish_vertex event.
310
+
311
+ def depth_first_visit (u, vis = DFSVisitor.new(self), &b)
312
+ vis.color_map[u] = :GRAY
313
+ vis.handle_examine_vertex(u)
314
+ each_adjacent(u) { |v|
315
+ vis.handle_examine_edge(u, v)
316
+ if vis.follow_edge?(u, v) # (u,v) is a tree edge
317
+ vis.handle_tree_edge(u, v) # also discovers v
318
+ vis.color_map[v] = :GRAY # color of v was :WHITE
319
+ depth_first_visit(v, vis, &b)
320
+ else # (u,v) is a non tree edge
321
+ if vis.color_map[v] == :GRAY
322
+ vis.handle_back_edge(u, v) # (u,v) has gray target
323
+ else
324
+ vis.handle_forward_edge(u, v) # (u,v) is a cross or forward edge
325
+ end
326
+ end
327
+ }
328
+ vis.color_map[u] = :BLACK
329
+ vis.handle_finish_vertex(u) # finish vertex
330
+ b.call(u)
331
+ end
332
+
333
+ end # module Graph
334
+
335
+ =begin
336
+ def acyclic?
337
+ has_cycle = false
338
+ dfs = DFSIterator.new(self)
339
+ dfs.set_back_edge_event {has_cycle = true}
340
+ dfs_each(dfs) do |x|
341
+ puts x,has_cycle,dfs.inspect
342
+ return false if has_cycle
343
+ end
344
+ true
345
+ end
346
+ =end
347
+
348
+ end # module RGL