axiom-optimizer 0.1.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 (345) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +37 -0
  4. data/.rspec +4 -0
  5. data/.rvmrc +1 -0
  6. data/.travis.yml +35 -0
  7. data/CONTRIBUTING.md +11 -0
  8. data/Gemfile +10 -0
  9. data/Gemfile.devtools +57 -0
  10. data/Guardfile +23 -0
  11. data/LICENSE +20 -0
  12. data/README.md +111 -0
  13. data/Rakefile +5 -0
  14. data/TODO +144 -0
  15. data/axiom-optimizer.gemspec +25 -0
  16. data/config/flay.yml +3 -0
  17. data/config/flog.yml +2 -0
  18. data/config/mutant.yml +3 -0
  19. data/config/reek.yml +162 -0
  20. data/config/roodi.yml +16 -0
  21. data/config/yardstick.yml +2 -0
  22. data/lib/axiom-optimizer.rb +3 -0
  23. data/lib/axiom/optimizer.rb +168 -0
  24. data/lib/axiom/optimizer/aggregate.rb +16 -0
  25. data/lib/axiom/optimizer/aggregate/count.rb +17 -0
  26. data/lib/axiom/optimizer/aggregate/maximum.rb +17 -0
  27. data/lib/axiom/optimizer/aggregate/mean.rb +17 -0
  28. data/lib/axiom/optimizer/aggregate/minimum.rb +17 -0
  29. data/lib/axiom/optimizer/aggregate/standard_deviation.rb +17 -0
  30. data/lib/axiom/optimizer/aggregate/sum.rb +17 -0
  31. data/lib/axiom/optimizer/aggregate/variance.rb +17 -0
  32. data/lib/axiom/optimizer/algebra/difference.rb +68 -0
  33. data/lib/axiom/optimizer/algebra/extension.rb +97 -0
  34. data/lib/axiom/optimizer/algebra/intersection.rb +68 -0
  35. data/lib/axiom/optimizer/algebra/join.rb +184 -0
  36. data/lib/axiom/optimizer/algebra/product.rb +70 -0
  37. data/lib/axiom/optimizer/algebra/projection.rb +212 -0
  38. data/lib/axiom/optimizer/algebra/rename.rb +381 -0
  39. data/lib/axiom/optimizer/algebra/restriction.rb +373 -0
  40. data/lib/axiom/optimizer/algebra/summarization.rb +200 -0
  41. data/lib/axiom/optimizer/algebra/union.rb +68 -0
  42. data/lib/axiom/optimizer/function.rb +87 -0
  43. data/lib/axiom/optimizer/function/binary.rb +124 -0
  44. data/lib/axiom/optimizer/function/connective/binary.rb +245 -0
  45. data/lib/axiom/optimizer/function/connective/conjunction.rb +122 -0
  46. data/lib/axiom/optimizer/function/connective/disjunction.rb +122 -0
  47. data/lib/axiom/optimizer/function/connective/negation.rb +65 -0
  48. data/lib/axiom/optimizer/function/numeric.rb +34 -0
  49. data/lib/axiom/optimizer/function/numeric/absolute.rb +20 -0
  50. data/lib/axiom/optimizer/function/numeric/addition.rb +20 -0
  51. data/lib/axiom/optimizer/function/numeric/division.rb +20 -0
  52. data/lib/axiom/optimizer/function/numeric/exponentiation.rb +20 -0
  53. data/lib/axiom/optimizer/function/numeric/modulo.rb +20 -0
  54. data/lib/axiom/optimizer/function/numeric/multiplication.rb +20 -0
  55. data/lib/axiom/optimizer/function/numeric/square_root.rb +20 -0
  56. data/lib/axiom/optimizer/function/numeric/subtraction.rb +20 -0
  57. data/lib/axiom/optimizer/function/numeric/unary_minus.rb +20 -0
  58. data/lib/axiom/optimizer/function/numeric/unary_plus.rb +20 -0
  59. data/lib/axiom/optimizer/function/predicate.rb +61 -0
  60. data/lib/axiom/optimizer/function/predicate/comparable.rb +144 -0
  61. data/lib/axiom/optimizer/function/predicate/enumerable.rb +138 -0
  62. data/lib/axiom/optimizer/function/predicate/equality.rb +44 -0
  63. data/lib/axiom/optimizer/function/predicate/exclusion.rb +43 -0
  64. data/lib/axiom/optimizer/function/predicate/greater_than.rb +55 -0
  65. data/lib/axiom/optimizer/function/predicate/greater_than_or_equal_to.rb +55 -0
  66. data/lib/axiom/optimizer/function/predicate/inclusion.rb +43 -0
  67. data/lib/axiom/optimizer/function/predicate/inequality.rb +44 -0
  68. data/lib/axiom/optimizer/function/predicate/less_than.rb +55 -0
  69. data/lib/axiom/optimizer/function/predicate/less_than_or_equal_to.rb +55 -0
  70. data/lib/axiom/optimizer/function/predicate/match.rb +20 -0
  71. data/lib/axiom/optimizer/function/predicate/no_match.rb +20 -0
  72. data/lib/axiom/optimizer/function/string/length.rb +31 -0
  73. data/lib/axiom/optimizer/function/unary.rb +86 -0
  74. data/lib/axiom/optimizer/optimizable.rb +60 -0
  75. data/lib/axiom/optimizer/relation/materialized.rb +40 -0
  76. data/lib/axiom/optimizer/relation/operation/binary.rb +134 -0
  77. data/lib/axiom/optimizer/relation/operation/combination.rb +33 -0
  78. data/lib/axiom/optimizer/relation/operation/deletion.rb +20 -0
  79. data/lib/axiom/optimizer/relation/operation/insertion.rb +20 -0
  80. data/lib/axiom/optimizer/relation/operation/limit.rb +141 -0
  81. data/lib/axiom/optimizer/relation/operation/offset.rb +106 -0
  82. data/lib/axiom/optimizer/relation/operation/order.rb +85 -0
  83. data/lib/axiom/optimizer/relation/operation/reverse.rb +85 -0
  84. data/lib/axiom/optimizer/relation/operation/unary.rb +124 -0
  85. data/lib/axiom/optimizer/support/predicate_partition.rb +184 -0
  86. data/lib/axiom/optimizer/version.rb +10 -0
  87. data/spec/integration/axiom/algebra/difference/optimize_spec.rb +160 -0
  88. data/spec/integration/axiom/algebra/intersection/optimize_spec.rb +160 -0
  89. data/spec/integration/axiom/algebra/join/optimize_spec.rb +112 -0
  90. data/spec/integration/axiom/algebra/product/optimize_spec.rb +178 -0
  91. data/spec/integration/axiom/algebra/projection/optimize_spec.rb +250 -0
  92. data/spec/integration/axiom/algebra/rename/optimize_spec.rb +442 -0
  93. data/spec/integration/axiom/algebra/restriction/optimize_spec.rb +218 -0
  94. data/spec/integration/axiom/algebra/summarization/optimize_spec.rb +49 -0
  95. data/spec/integration/axiom/algebra/union/optimize_spec.rb +200 -0
  96. data/spec/integration/axiom/function/connective/conjunction/optimize_spec.rb +236 -0
  97. data/spec/integration/axiom/function/connective/disjunction/optimize_spec.rb +237 -0
  98. data/spec/integration/axiom/function/connective/negation/optimize_spec.rb +43 -0
  99. data/spec/integration/axiom/function/optimize_spec.rb +30 -0
  100. data/spec/integration/axiom/function/predicate/equality/optimize_spec.rb +92 -0
  101. data/spec/integration/axiom/function/predicate/exclusion/optimize_spec.rb +133 -0
  102. data/spec/integration/axiom/function/predicate/greater_than/optimize_spec.rb +102 -0
  103. data/spec/integration/axiom/function/predicate/greater_than_or_equal_to/optimize_spec.rb +102 -0
  104. data/spec/integration/axiom/function/predicate/inclusion/optimize_spec.rb +133 -0
  105. data/spec/integration/axiom/function/predicate/inequality/optimize_spec.rb +92 -0
  106. data/spec/integration/axiom/function/predicate/less_than/optimize_spec.rb +102 -0
  107. data/spec/integration/axiom/function/predicate/less_than_or_equal_to/optimize_spec.rb +102 -0
  108. data/spec/integration/axiom/relation/empty/optimize_spec.rb +13 -0
  109. data/spec/integration/axiom/relation/materialized/optimize_spec.rb +29 -0
  110. data/spec/integration/axiom/relation/operation/limit/optimize_spec.rb +142 -0
  111. data/spec/integration/axiom/relation/operation/offset/optimize_spec.rb +100 -0
  112. data/spec/integration/axiom/relation/operation/order/optimize_spec.rb +105 -0
  113. data/spec/integration/axiom/relation/operation/reverse/optimize_spec.rb +115 -0
  114. data/spec/integration/axiom/relation/optimize_spec.rb +23 -0
  115. data/spec/rcov.opts +7 -0
  116. data/spec/shared/function_connective_binary_optimize_behavior.rb +102 -0
  117. data/spec/shared/optimize_method_behavior.rb +16 -0
  118. data/spec/spec_helper.rb +38 -0
  119. data/spec/support/add_method_missing.rb +15 -0
  120. data/spec/support/config_alias.rb +3 -0
  121. data/spec/support/ice_nine_config.rb +6 -0
  122. data/spec/support/lazy_enumerable.rb +18 -0
  123. data/spec/unit/axiom/optimizer/algebra/difference/empty_left/optimize_spec.rb +19 -0
  124. data/spec/unit/axiom/optimizer/algebra/difference/empty_right/optimize_spec.rb +19 -0
  125. data/spec/unit/axiom/optimizer/algebra/difference/equal_operands/optimize_spec.rb +23 -0
  126. data/spec/unit/axiom/optimizer/algebra/extension/extensions_spec.rb +31 -0
  127. data/spec/unit/axiom/optimizer/algebra/extension/order_operand/optimizable_predicate_spec.rb +23 -0
  128. data/spec/unit/axiom/optimizer/algebra/extension/order_operand/optimize_spec.rb +22 -0
  129. data/spec/unit/axiom/optimizer/algebra/extension/unoptimized_operand/optimizable_predicate_spec.rb +37 -0
  130. data/spec/unit/axiom/optimizer/algebra/extension/unoptimized_operand/optimize_spec.rb +27 -0
  131. data/spec/unit/axiom/optimizer/algebra/intersection/empty_left/optimize_spec.rb +19 -0
  132. data/spec/unit/axiom/optimizer/algebra/intersection/empty_right/optimize_spec.rb +19 -0
  133. data/spec/unit/axiom/optimizer/algebra/intersection/equal_operands/optimize_spec.rb +19 -0
  134. data/spec/unit/axiom/optimizer/algebra/join/disjoint_headers/optimizable_predicate_spec.rb +29 -0
  135. data/spec/unit/axiom/optimizer/algebra/join/disjoint_headers/optimize_spec.rb +22 -0
  136. data/spec/unit/axiom/optimizer/algebra/join/equal_headers/optimizable_predicate_spec.rb +29 -0
  137. data/spec/unit/axiom/optimizer/algebra/join/equal_headers/optimize_spec.rb +23 -0
  138. data/spec/unit/axiom/optimizer/algebra/join/materialized_left/optimizable_predicate_spec.rb +42 -0
  139. data/spec/unit/axiom/optimizer/algebra/join/materialized_left/optimize_spec.rb +55 -0
  140. data/spec/unit/axiom/optimizer/algebra/join/materialized_right/optimizable_predicate_spec.rb +42 -0
  141. data/spec/unit/axiom/optimizer/algebra/join/materialized_right/optimize_spec.rb +55 -0
  142. data/spec/unit/axiom/optimizer/algebra/product/table_dee_left/optimizable_predicate_spec.rb +27 -0
  143. data/spec/unit/axiom/optimizer/algebra/product/table_dee_left/optimize_spec.rb +18 -0
  144. data/spec/unit/axiom/optimizer/algebra/product/table_dee_right/optimizable_predicate_spec.rb +27 -0
  145. data/spec/unit/axiom/optimizer/algebra/product/table_dee_right/optimize_spec.rb +18 -0
  146. data/spec/unit/axiom/optimizer/algebra/projection/empty_operand/optimizable_predicate_spec.rb +27 -0
  147. data/spec/unit/axiom/optimizer/algebra/projection/empty_operand/optimize_spec.rb +22 -0
  148. data/spec/unit/axiom/optimizer/algebra/projection/extension_operand/optimizable_predicate_spec.rb +35 -0
  149. data/spec/unit/axiom/optimizer/algebra/projection/extension_operand/optimize_spec.rb +22 -0
  150. data/spec/unit/axiom/optimizer/algebra/projection/projection_operand/optimizable_predicate_spec.rb +28 -0
  151. data/spec/unit/axiom/optimizer/algebra/projection/projection_operand/optimize_spec.rb +22 -0
  152. data/spec/unit/axiom/optimizer/algebra/projection/union_operand/optimizable_predicate_spec.rb +29 -0
  153. data/spec/unit/axiom/optimizer/algebra/projection/union_operand/optimize_spec.rb +25 -0
  154. data/spec/unit/axiom/optimizer/algebra/projection/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
  155. data/spec/unit/axiom/optimizer/algebra/projection/unoptimized_operand/optimize_spec.rb +22 -0
  156. data/spec/unit/axiom/optimizer/algebra/rename/aliases_spec.rb +23 -0
  157. data/spec/unit/axiom/optimizer/algebra/rename/empty_operand/optimizable_predicate_spec.rb +27 -0
  158. data/spec/unit/axiom/optimizer/algebra/rename/empty_operand/optimize_spec.rb +21 -0
  159. data/spec/unit/axiom/optimizer/algebra/rename/limit_operand/optimizable_predicate_spec.rb +28 -0
  160. data/spec/unit/axiom/optimizer/algebra/rename/limit_operand/optimize_spec.rb +23 -0
  161. data/spec/unit/axiom/optimizer/algebra/rename/offset_operand/optimizable_predicate_spec.rb +28 -0
  162. data/spec/unit/axiom/optimizer/algebra/rename/offset_operand/optimize_spec.rb +23 -0
  163. data/spec/unit/axiom/optimizer/algebra/rename/order_operand/optimizable_predicate_spec.rb +28 -0
  164. data/spec/unit/axiom/optimizer/algebra/rename/order_operand/optimize_spec.rb +22 -0
  165. data/spec/unit/axiom/optimizer/algebra/rename/projection_operand/optimizable_predicate_spec.rb +43 -0
  166. data/spec/unit/axiom/optimizer/algebra/rename/projection_operand/optimize_spec.rb +22 -0
  167. data/spec/unit/axiom/optimizer/algebra/rename/rename_operand/optimizable_predicate_spec.rb +30 -0
  168. data/spec/unit/axiom/optimizer/algebra/rename/rename_operand/optimize_spec.rb +22 -0
  169. data/spec/unit/axiom/optimizer/algebra/rename/rename_operand_and_empty_aliases/optimizable_predicate_spec.rb +37 -0
  170. data/spec/unit/axiom/optimizer/algebra/rename/rename_operand_and_empty_aliases/optimize_spec.rb +18 -0
  171. data/spec/unit/axiom/optimizer/algebra/rename/restriction_operand/optimizable_predicate_spec.rb +29 -0
  172. data/spec/unit/axiom/optimizer/algebra/rename/restriction_operand/optimize_spec.rb +23 -0
  173. data/spec/unit/axiom/optimizer/algebra/rename/reverse_operand/optimizable_predicate_spec.rb +27 -0
  174. data/spec/unit/axiom/optimizer/algebra/rename/reverse_operand/optimize_spec.rb +23 -0
  175. data/spec/unit/axiom/optimizer/algebra/rename/set_operand/optimizable_predicate_spec.rb +29 -0
  176. data/spec/unit/axiom/optimizer/algebra/rename/set_operand/optimize_spec.rb +23 -0
  177. data/spec/unit/axiom/optimizer/algebra/rename/unoptimized_operand/optimizable_predicate_spec.rb +29 -0
  178. data/spec/unit/axiom/optimizer/algebra/rename/unoptimized_operand/optimize_spec.rb +23 -0
  179. data/spec/unit/axiom/optimizer/algebra/restriction/combination_operand/optimizable_predicate_spec.rb +41 -0
  180. data/spec/unit/axiom/optimizer/algebra/restriction/combination_operand/optimize_spec.rb +35 -0
  181. data/spec/unit/axiom/optimizer/algebra/restriction/contradiction/optimizable_predicate_spec.rb +46 -0
  182. data/spec/unit/axiom/optimizer/algebra/restriction/contradiction/optimize_spec.rb +23 -0
  183. data/spec/unit/axiom/optimizer/algebra/restriction/join_operand/optimizable_predicate_spec.rb +51 -0
  184. data/spec/unit/axiom/optimizer/algebra/restriction/join_operand/optimize_spec.rb +48 -0
  185. data/spec/unit/axiom/optimizer/algebra/restriction/order_operand/optimizable_predicate_spec.rb +28 -0
  186. data/spec/unit/axiom/optimizer/algebra/restriction/order_operand/optimize_spec.rb +22 -0
  187. data/spec/unit/axiom/optimizer/algebra/restriction/predicate_spec.rb +18 -0
  188. data/spec/unit/axiom/optimizer/algebra/restriction/product_operand/optimizable_predicate_spec.rb +44 -0
  189. data/spec/unit/axiom/optimizer/algebra/restriction/product_operand/optimize_spec.rb +48 -0
  190. data/spec/unit/axiom/optimizer/algebra/restriction/restriction_operand/optimizable_predicate_spec.rb +30 -0
  191. data/spec/unit/axiom/optimizer/algebra/restriction/restriction_operand/optimize_spec.rb +24 -0
  192. data/spec/unit/axiom/optimizer/algebra/restriction/set_operand/optimizable_predicate_spec.rb +30 -0
  193. data/spec/unit/axiom/optimizer/algebra/restriction/set_operand/optimize_spec.rb +24 -0
  194. data/spec/unit/axiom/optimizer/algebra/restriction/tautology/optimizable_predicate_spec.rb +33 -0
  195. data/spec/unit/axiom/optimizer/algebra/restriction/tautology/optimize_spec.rb +19 -0
  196. data/spec/unit/axiom/optimizer/algebra/restriction/unoptimized_operand/optimizable_predicate_spec.rb +44 -0
  197. data/spec/unit/axiom/optimizer/algebra/restriction/unoptimized_operand/optimize_spec.rb +24 -0
  198. data/spec/unit/axiom/optimizer/algebra/summarization/empty_operand/class_methods/extension_default_spec.rb +22 -0
  199. data/spec/unit/axiom/optimizer/algebra/summarization/empty_operand/optimizable_predicate_spec.rb +29 -0
  200. data/spec/unit/axiom/optimizer/algebra/summarization/empty_operand/optimize_spec.rb +47 -0
  201. data/spec/unit/axiom/optimizer/algebra/summarization/empty_summarize_per/optimizable_predicate_spec.rb +29 -0
  202. data/spec/unit/axiom/optimizer/algebra/summarization/empty_summarize_per/optimize_spec.rb +25 -0
  203. data/spec/unit/axiom/optimizer/algebra/summarization/order_operand/optimizable_predicate_spec.rb +23 -0
  204. data/spec/unit/axiom/optimizer/algebra/summarization/order_operand/optimize_spec.rb +22 -0
  205. data/spec/unit/axiom/optimizer/algebra/summarization/summarize_per_spec.rb +29 -0
  206. data/spec/unit/axiom/optimizer/algebra/summarization/summarizers_spec.rb +31 -0
  207. data/spec/unit/axiom/optimizer/algebra/summarization/unoptimized_operand/optimizable_predicate_spec.rb +49 -0
  208. data/spec/unit/axiom/optimizer/algebra/summarization/unoptimized_operand/optimize_spec.rb +30 -0
  209. data/spec/unit/axiom/optimizer/algebra/union/empty_left/optimize_spec.rb +19 -0
  210. data/spec/unit/axiom/optimizer/algebra/union/empty_right/optimize_spec.rb +19 -0
  211. data/spec/unit/axiom/optimizer/algebra/union/equal_operands/optimize_spec.rb +19 -0
  212. data/spec/unit/axiom/optimizer/class_methods/chain_spec.rb +56 -0
  213. data/spec/unit/axiom/optimizer/function/binary/constant_operands/optimizable_predicate_spec.rb +36 -0
  214. data/spec/unit/axiom/optimizer/function/binary/constant_operands/optimize_spec.rb +18 -0
  215. data/spec/unit/axiom/optimizer/function/binary/left_spec.rb +28 -0
  216. data/spec/unit/axiom/optimizer/function/binary/right_spec.rb +28 -0
  217. data/spec/unit/axiom/optimizer/function/binary/unoptimized_operands/optimizable_predicate_spec.rb +37 -0
  218. data/spec/unit/axiom/optimizer/function/binary/unoptimized_operands/optimize_spec.rb +23 -0
  219. data/spec/unit/axiom/optimizer/function/class_methods/optimize_functions_spec.rb +26 -0
  220. data/spec/unit/axiom/optimizer/function/class_methods/optimize_operand_spec.rb +22 -0
  221. data/spec/unit/axiom/optimizer/function/connective/binary/constant_operands/optimize_spec.rb +16 -0
  222. data/spec/unit/axiom/optimizer/function/connective/binary/equal_operands/optimizable_predicate_spec.rb +29 -0
  223. data/spec/unit/axiom/optimizer/function/connective/binary/equal_operands/optimize_spec.rb +19 -0
  224. data/spec/unit/axiom/optimizer/function/connective/binary/left_spec.rb +16 -0
  225. data/spec/unit/axiom/optimizer/function/connective/binary/redundant_left/optimizable_predicate_spec.rb +28 -0
  226. data/spec/unit/axiom/optimizer/function/connective/binary/redundant_left/optimize_spec.rb +23 -0
  227. data/spec/unit/axiom/optimizer/function/connective/binary/redundant_right/optimizable_predicate_spec.rb +28 -0
  228. data/spec/unit/axiom/optimizer/function/connective/binary/redundant_right/optimize_spec.rb +23 -0
  229. data/spec/unit/axiom/optimizer/function/connective/binary/right_spec.rb +16 -0
  230. data/spec/unit/axiom/optimizer/function/connective/conjunction/contradiction/optimizable_predicate_spec.rb +64 -0
  231. data/spec/unit/axiom/optimizer/function/connective/conjunction/contradiction/optimize_spec.rb +19 -0
  232. data/spec/unit/axiom/optimizer/function/connective/conjunction/optimizable_to_exclusion/optimizable_predicate_spec.rb +61 -0
  233. data/spec/unit/axiom/optimizer/function/connective/conjunction/optimizable_to_exclusion/optimize_spec.rb +76 -0
  234. data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_left/optimizable_predicate_spec.rb +29 -0
  235. data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_left/optimize_spec.rb +19 -0
  236. data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_right/optimizable_predicate_spec.rb +29 -0
  237. data/spec/unit/axiom/optimizer/function/connective/conjunction/tautology_right/optimize_spec.rb +19 -0
  238. data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_left/optimizable_predicate_spec.rb +29 -0
  239. data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_left/optimize_spec.rb +19 -0
  240. data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_right/optimizable_predicate_spec.rb +29 -0
  241. data/spec/unit/axiom/optimizer/function/connective/disjunction/contradiction_right/optimize_spec.rb +19 -0
  242. data/spec/unit/axiom/optimizer/function/connective/disjunction/optimizable_to_inclusion/optimizable_predicate_spec.rb +61 -0
  243. data/spec/unit/axiom/optimizer/function/connective/disjunction/optimizable_to_inclusion/optimize_spec.rb +76 -0
  244. data/spec/unit/axiom/optimizer/function/connective/disjunction/tautology/optimizable_predicate_spec.rb +64 -0
  245. data/spec/unit/axiom/optimizer/function/connective/disjunction/tautology/optimize_spec.rb +19 -0
  246. data/spec/unit/axiom/optimizer/function/connective/negation/constant_operand/optimize_spec.rb +16 -0
  247. data/spec/unit/axiom/optimizer/function/connective/negation/invertible_operand/optimizable_predicate_spec.rb +28 -0
  248. data/spec/unit/axiom/optimizer/function/connective/negation/invertible_operand/optimize_spec.rb +22 -0
  249. data/spec/unit/axiom/optimizer/function/connective/negation/operand_spec.rb +14 -0
  250. data/spec/unit/axiom/optimizer/function/predicate/comparable/never_comparable/optimizable_predicate_spec.rb +74 -0
  251. data/spec/unit/axiom/optimizer/function/predicate/comparable/never_equivalent/optimizable_predicate_spec.rb +74 -0
  252. data/spec/unit/axiom/optimizer/function/predicate/comparable/normalizable_operands/optimizable_predicate_spec.rb +43 -0
  253. data/spec/unit/axiom/optimizer/function/predicate/comparable/normalizable_operands/optimize_spec.rb +21 -0
  254. data/spec/unit/axiom/optimizer/function/predicate/constant_operands/optimize_spec.rb +16 -0
  255. data/spec/unit/axiom/optimizer/function/predicate/contradiction/optimize_spec.rb +18 -0
  256. data/spec/unit/axiom/optimizer/function/predicate/enumerable/class_methods/sort_by_value_spec.rb +27 -0
  257. data/spec/unit/axiom/optimizer/function/predicate/enumerable/empty_right/optimizable_predicate_spec.rb +78 -0
  258. data/spec/unit/axiom/optimizer/function/predicate/enumerable/one_right/optimizable_predicate_spec.rb +78 -0
  259. data/spec/unit/axiom/optimizer/function/predicate/enumerable/unoptimized_operands/optimizable_predicate_spec.rb +51 -0
  260. data/spec/unit/axiom/optimizer/function/predicate/enumerable/unoptimized_operands/optimize_spec.rb +66 -0
  261. data/spec/unit/axiom/optimizer/function/predicate/equality/tautology/optimizable_predicate_spec.rb +29 -0
  262. data/spec/unit/axiom/optimizer/function/predicate/exclusion/empty_right/optimize_spec.rb +45 -0
  263. data/spec/unit/axiom/optimizer/function/predicate/exclusion/one_right/optimize_spec.rb +65 -0
  264. data/spec/unit/axiom/optimizer/function/predicate/greater_than/contradiction/optimizable_predicate_spec.rb +43 -0
  265. data/spec/unit/axiom/optimizer/function/predicate/greater_than/tautology/optimizable_predicate_spec.rb +28 -0
  266. data/spec/unit/axiom/optimizer/function/predicate/greater_than_or_equal_to/contradiction/optimizable_predicate_spec.rb +43 -0
  267. data/spec/unit/axiom/optimizer/function/predicate/greater_than_or_equal_to/tautology/optimizable_predicate_spec.rb +43 -0
  268. data/spec/unit/axiom/optimizer/function/predicate/inclusion/empty_right/optimize_spec.rb +45 -0
  269. data/spec/unit/axiom/optimizer/function/predicate/inclusion/one_right/optimize_spec.rb +66 -0
  270. data/spec/unit/axiom/optimizer/function/predicate/inequality/contradiction/optimizable_predicate_spec.rb +29 -0
  271. data/spec/unit/axiom/optimizer/function/predicate/less_than/contradiction/optimizable_predicate_spec.rb +43 -0
  272. data/spec/unit/axiom/optimizer/function/predicate/less_than/tautology/optimizable_predicate_spec.rb +28 -0
  273. data/spec/unit/axiom/optimizer/function/predicate/less_than_or_equal_to/contradiction/optimizable_predicate_spec.rb +43 -0
  274. data/spec/unit/axiom/optimizer/function/predicate/less_than_or_equal_to/tautology/optimizable_predicate_spec.rb +43 -0
  275. data/spec/unit/axiom/optimizer/function/predicate/tautology/optimize_spec.rb +18 -0
  276. data/spec/unit/axiom/optimizer/function/unary/constant_operand/optimizable_predicate_spec.rb +27 -0
  277. data/spec/unit/axiom/optimizer/function/unary/constant_operand/optimize_spec.rb +18 -0
  278. data/spec/unit/axiom/optimizer/function/unary/operand_spec.rb +27 -0
  279. data/spec/unit/axiom/optimizer/function/unary/unoptimized_operand/optimizable_predicate_spec.rb +27 -0
  280. data/spec/unit/axiom/optimizer/function/unary/unoptimized_operand/optimize_spec.rb +18 -0
  281. data/spec/unit/axiom/optimizer/function/util/class_methods/attribute_spec.rb +21 -0
  282. data/spec/unit/axiom/optimizer/function/util/class_methods/constant_spec.rb +27 -0
  283. data/spec/unit/axiom/optimizer/function/util/class_methods/max_spec.rb +27 -0
  284. data/spec/unit/axiom/optimizer/function/util/class_methods/min_spec.rb +27 -0
  285. data/spec/unit/axiom/optimizer/operation_spec.rb +13 -0
  286. data/spec/unit/axiom/optimizer/optimizable/class_methods/optimizer_spec.rb +34 -0
  287. data/spec/unit/axiom/optimizer/optimizable/optimize_spec.rb +38 -0
  288. data/spec/unit/axiom/optimizer/optimizable_predicate_spec.rb +17 -0
  289. data/spec/unit/axiom/optimizer/optimize_spec.rb +17 -0
  290. data/spec/unit/axiom/optimizer/predicate_partition/left_spec.rb +149 -0
  291. data/spec/unit/axiom/optimizer/predicate_partition/remainder_spec.rb +149 -0
  292. data/spec/unit/axiom/optimizer/predicate_partition/right_spec.rb +149 -0
  293. data/spec/unit/axiom/optimizer/relation/materialized/empty_operand/optimizable_predicate_spec.rb +22 -0
  294. data/spec/unit/axiom/optimizer/relation/materialized/empty_operand/optimize_spec.rb +21 -0
  295. data/spec/unit/axiom/optimizer/relation/operation/binary/empty_left/optimizable_predicate_spec.rb +28 -0
  296. data/spec/unit/axiom/optimizer/relation/operation/binary/empty_right/optimizable_predicate_spec.rb +28 -0
  297. data/spec/unit/axiom/optimizer/relation/operation/binary/equal_operands/optimizable_predicate_spec.rb +31 -0
  298. data/spec/unit/axiom/optimizer/relation/operation/binary/left_spec.rb +15 -0
  299. data/spec/unit/axiom/optimizer/relation/operation/binary/materialized_operands/optimizable_predicate_spec.rb +37 -0
  300. data/spec/unit/axiom/optimizer/relation/operation/binary/materialized_operands/optimize_spec.rb +22 -0
  301. data/spec/unit/axiom/optimizer/relation/operation/binary/order_left/optimizable_predicate_spec.rb +23 -0
  302. data/spec/unit/axiom/optimizer/relation/operation/binary/order_left/optimize_spec.rb +23 -0
  303. data/spec/unit/axiom/optimizer/relation/operation/binary/order_right/optimizable_predicate_spec.rb +23 -0
  304. data/spec/unit/axiom/optimizer/relation/operation/binary/order_right/optimize_spec.rb +23 -0
  305. data/spec/unit/axiom/optimizer/relation/operation/binary/right_spec.rb +15 -0
  306. data/spec/unit/axiom/optimizer/relation/operation/binary/unoptimized_operands/optimizable_predicate_spec.rb +40 -0
  307. data/spec/unit/axiom/optimizer/relation/operation/binary/unoptimized_operands/optimize_spec.rb +24 -0
  308. data/spec/unit/axiom/optimizer/relation/operation/combination/optimize_spec.rb +18 -0
  309. data/spec/unit/axiom/optimizer/relation/operation/limit/equal_limit_operand/optimizable_predicate_spec.rb +33 -0
  310. data/spec/unit/axiom/optimizer/relation/operation/limit/equal_limit_operand/optimize_spec.rb +18 -0
  311. data/spec/unit/axiom/optimizer/relation/operation/limit/limit_operand/optimizable_predicate_spec.rb +27 -0
  312. data/spec/unit/axiom/optimizer/relation/operation/limit/limit_operand/optimize_spec.rb +35 -0
  313. data/spec/unit/axiom/optimizer/relation/operation/limit/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
  314. data/spec/unit/axiom/optimizer/relation/operation/limit/unoptimized_operand/optimize_spec.rb +22 -0
  315. data/spec/unit/axiom/optimizer/relation/operation/limit/zero_limit/optimizable_predicate_spec.rb +27 -0
  316. data/spec/unit/axiom/optimizer/relation/operation/limit/zero_limit/optimize_spec.rb +22 -0
  317. data/spec/unit/axiom/optimizer/relation/operation/offset/offset_operand/optimizable_predicate_spec.rb +27 -0
  318. data/spec/unit/axiom/optimizer/relation/operation/offset/offset_operand/optimize_spec.rb +21 -0
  319. data/spec/unit/axiom/optimizer/relation/operation/offset/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
  320. data/spec/unit/axiom/optimizer/relation/operation/offset/unoptimized_operand/optimize_spec.rb +22 -0
  321. data/spec/unit/axiom/optimizer/relation/operation/offset/zero_offset/optimizable_predicate_spec.rb +27 -0
  322. data/spec/unit/axiom/optimizer/relation/operation/offset/zero_offset/optimize_spec.rb +17 -0
  323. data/spec/unit/axiom/optimizer/relation/operation/order/one_limit_operand/optimizable_predicate_spec.rb +33 -0
  324. data/spec/unit/axiom/optimizer/relation/operation/order/one_limit_operand/optimize_spec.rb +18 -0
  325. data/spec/unit/axiom/optimizer/relation/operation/order/order_operand/optimizable_predicate_spec.rb +27 -0
  326. data/spec/unit/axiom/optimizer/relation/operation/order/order_operand/optimize_spec.rb +22 -0
  327. data/spec/unit/axiom/optimizer/relation/operation/order/unoptimized_operand/optimizable_predicate_spec.rb +28 -0
  328. data/spec/unit/axiom/optimizer/relation/operation/order/unoptimized_operand/optimize_spec.rb +23 -0
  329. data/spec/unit/axiom/optimizer/relation/operation/reverse/order_operand/optimizable_predicate_spec.rb +27 -0
  330. data/spec/unit/axiom/optimizer/relation/operation/reverse/order_operand/optimize_spec.rb +22 -0
  331. data/spec/unit/axiom/optimizer/relation/operation/reverse/reverse_operand/optimizable_predicate_spec.rb +27 -0
  332. data/spec/unit/axiom/optimizer/relation/operation/reverse/reverse_operand/optimize_spec.rb +19 -0
  333. data/spec/unit/axiom/optimizer/relation/operation/reverse/unoptimized_operand/optimizable_predicate_spec.rb +27 -0
  334. data/spec/unit/axiom/optimizer/relation/operation/reverse/unoptimized_operand/optimize_spec.rb +24 -0
  335. data/spec/unit/axiom/optimizer/relation/operation/unary/empty_operand/optimizable_predicate_spec.rb +23 -0
  336. data/spec/unit/axiom/optimizer/relation/operation/unary/empty_operand/optimize_spec.rb +17 -0
  337. data/spec/unit/axiom/optimizer/relation/operation/unary/header_spec.rb +15 -0
  338. data/spec/unit/axiom/optimizer/relation/operation/unary/materialized_operand/optimizable_predicate_spec.rb +23 -0
  339. data/spec/unit/axiom/optimizer/relation/operation/unary/materialized_operand/optimize_spec.rb +20 -0
  340. data/spec/unit/axiom/optimizer/relation/operation/unary/operand_spec.rb +16 -0
  341. data/spec/unit/axiom/optimizer/relation/operation/unary/order_operand/optimizable_predicate_spec.rb +28 -0
  342. data/spec/unit/axiom/optimizer/relation/operation/unary/order_operand/optimize_spec.rb +27 -0
  343. data/spec/unit/axiom/optimizer/relation/operation/unary/unchanged_header/optimizable_predicate_spec.rb +24 -0
  344. data/spec/unit/axiom/optimizer/relation/operation/unary/unchanged_header/optimize_spec.rb +14 -0
  345. metadata +697 -0
@@ -0,0 +1,106 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Relation
6
+ module Operation
7
+
8
+ # Abstract base class representing Offset optimizations
9
+ class Offset < Unary
10
+
11
+ private
12
+
13
+ # Return the operation offset
14
+ #
15
+ # @return [Integer]
16
+ #
17
+ # @api private
18
+ def offset
19
+ operation.offset
20
+ end
21
+
22
+ # Optimize when the offset is zero
23
+ class ZeroOffset < self
24
+
25
+ # Test if the offset is zero
26
+ #
27
+ # @return [Boolean]
28
+ #
29
+ # @api private
30
+ def optimizable?
31
+ offset.zero?
32
+ end
33
+
34
+ # An Offset with an offset of zero is a noop
35
+ #
36
+ # @return [Relation]
37
+ #
38
+ # @api private
39
+ def optimize
40
+ operand
41
+ end
42
+
43
+ end # class ZeroOffset
44
+
45
+ # Optimize when the operand is an Offset
46
+ class OffsetOperand < self
47
+
48
+ # Test if the operand is an Offset
49
+ #
50
+ # @return [Boolean]
51
+ #
52
+ # @api private
53
+ def optimizable?
54
+ operand.kind_of?(operation.class)
55
+ end
56
+
57
+ # Flatten Offset operations using the sum of the offsets
58
+ #
59
+ # @return [Boolean]
60
+ #
61
+ # @api private
62
+ def optimize
63
+ operand.operand.drop(sum_offset)
64
+ end
65
+
66
+ private
67
+
68
+ # Return the sum of the operation and operand offsets
69
+ #
70
+ # @return [Integer]
71
+ #
72
+ # @api private
73
+ def sum_offset
74
+ offset + operand.offset
75
+ end
76
+
77
+ end # class OffsetOperand
78
+
79
+ # Optimize when operand is optimizable
80
+ class UnoptimizedOperand < self
81
+ include Function::Unary::UnoptimizedOperand
82
+
83
+ # Return an Offset with an optimized operand
84
+ #
85
+ # @return [Offset]
86
+ #
87
+ # @api private
88
+ def optimize
89
+ operand.drop(offset)
90
+ end
91
+
92
+ end # class UnoptimizedOperand
93
+
94
+ Axiom::Relation::Operation::Offset.optimizer = chain(
95
+ ZeroOffset,
96
+ OffsetOperand,
97
+ EmptyOperand,
98
+ MaterializedOperand,
99
+ UnoptimizedOperand
100
+ )
101
+
102
+ end # class Offset
103
+ end # module Operation
104
+ end # module Relation
105
+ end # class Optimizer
106
+ end # module Axiom
@@ -0,0 +1,85 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Relation
6
+ module Operation
7
+
8
+ # Abstract base class representing Order optimizations
9
+ class Order < Unary
10
+
11
+ # Optimize when the operand is an Order
12
+ class OrderOperand < self
13
+
14
+ # Test if the operand is an Order
15
+ #
16
+ # @return [Boolean]
17
+ #
18
+ # @api private
19
+ def optimizable?
20
+ operand.kind_of?(operation.class)
21
+ end
22
+
23
+ # Flatten Order operations using the operation directions
24
+ #
25
+ # @return [Order]
26
+ #
27
+ # @api private
28
+ def optimize
29
+ operand.operand.sort_by { operation.directions }
30
+ end
31
+
32
+ end # class OrderOperand
33
+
34
+ # Optimize when the operand is a Limit with a limit of 1
35
+ class OneLimitOperand < self
36
+
37
+ # Test if the operand is an Limit with a limit of 1
38
+ #
39
+ # @return [Boolean]
40
+ #
41
+ # @api private
42
+ def optimizable?
43
+ operand.kind_of?(Axiom::Relation::Operation::Limit) &&
44
+ operand.limit == 1
45
+ end
46
+
47
+ # An Order of a Limit with a limit of 1 is a noop
48
+ #
49
+ # @return [Limit]
50
+ #
51
+ # @api private
52
+ def optimize
53
+ operand
54
+ end
55
+
56
+ end # class OneLimitOperand
57
+
58
+ # Optimize when operand is optimizable
59
+ class UnoptimizedOperand < self
60
+ include Function::Unary::UnoptimizedOperand
61
+
62
+ # Return an Order with an optimized operand
63
+ #
64
+ # @return [Offset]
65
+ #
66
+ # @api private
67
+ def optimize
68
+ operand.sort_by { operation.directions }
69
+ end
70
+
71
+ end # class UnoptimizedOperand
72
+
73
+ Axiom::Relation::Operation::Order.optimizer = chain(
74
+ OrderOperand,
75
+ OneLimitOperand,
76
+ EmptyOperand,
77
+ MaterializedOperand,
78
+ UnoptimizedOperand
79
+ )
80
+
81
+ end # class Order
82
+ end # module Operation
83
+ end # module Relation
84
+ end # class Optimizer
85
+ end # module Axiom
@@ -0,0 +1,85 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Relation
6
+ module Operation
7
+
8
+ # Abstract base class representing Reverse optimizations
9
+ class Reverse < Order
10
+
11
+ # Optimize when the operand is a Reverse
12
+ class ReverseOperand < self
13
+
14
+ # Test if the operand is a Reverse
15
+ #
16
+ # @return [Boolean]
17
+ #
18
+ # @api private
19
+ def optimizable?
20
+ operand.kind_of?(operation.class)
21
+ end
22
+
23
+ # A Reverse of a Reverse is a noop
24
+ #
25
+ # @return [Relation]
26
+ #
27
+ # @api private
28
+ def optimize
29
+ operand.operand
30
+ end
31
+
32
+ end # class ReverseOperand
33
+
34
+ # Optimize when the operand is an Order
35
+ class OrderOperand < self
36
+
37
+ # Test if the operand is an Order
38
+ #
39
+ # @return [Boolean]
40
+ #
41
+ # @api private
42
+ def optimizable?
43
+ operand.kind_of?(Axiom::Relation::Operation::Order)
44
+ end
45
+
46
+ # Flatten Reverse operation and Order operand into an Order
47
+ #
48
+ # @return [Order]
49
+ #
50
+ # @api private
51
+ def optimize
52
+ operand.operand.sort_by { operation.directions }
53
+ end
54
+
55
+ end # class OrderOperand
56
+
57
+ # Optimize when operand is optimizable
58
+ class UnoptimizedOperand < self
59
+ include Function::Unary::UnoptimizedOperand
60
+
61
+ # Return an Reverse with an optimized operand
62
+ #
63
+ # @return [Reverse]
64
+ #
65
+ # @api private
66
+ def optimize
67
+ operand.reverse
68
+ end
69
+
70
+ end # class UnoptimizedOperand
71
+
72
+ Axiom::Relation::Operation::Reverse.optimizer = chain(
73
+ ReverseOperand,
74
+ OrderOperand,
75
+ OneLimitOperand,
76
+ EmptyOperand,
77
+ MaterializedOperand,
78
+ UnoptimizedOperand
79
+ )
80
+
81
+ end # class Reverse
82
+ end # module Operation
83
+ end # module Relation
84
+ end # class Optimizer
85
+ end # module Axiom
@@ -0,0 +1,124 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+ module Relation
6
+ module Operation
7
+
8
+ # Abstract base class representing Unary relation optimizations
9
+ class Unary < Optimizer
10
+ include Function::Unary
11
+
12
+ # The operation header
13
+ #
14
+ # @return [Header]
15
+ #
16
+ # @api private
17
+ attr_reader :header
18
+
19
+ # Initialize a Unary optimizer
20
+ #
21
+ # @return [undefined]
22
+ #
23
+ # @api private
24
+ def initialize(*)
25
+ super
26
+ @header = operation.header
27
+ end
28
+
29
+ # Optimize when the operand is an Order
30
+ module OrderOperand
31
+
32
+ # Test if the operand is an Order
33
+ #
34
+ # @return [Boolean]
35
+ #
36
+ # @api private
37
+ def optimizable?
38
+ operand.kind_of?(Axiom::Relation::Operation::Order)
39
+ end
40
+
41
+ # Drop the Order and wrap the operand
42
+ #
43
+ # @return [Order]
44
+ #
45
+ # @api private
46
+ def optimize
47
+ wrap_operand
48
+ end
49
+
50
+ end # module OrderOperand
51
+
52
+ # Optimize when the header is not changed
53
+ class UnchangedHeader < self
54
+
55
+ # Test if the operation header are the same as the operand's
56
+ #
57
+ # @return [Boolean]
58
+ #
59
+ # @api private
60
+ def optimizable?
61
+ header == operand.header
62
+ end
63
+
64
+ # A Projection, Rename or Extension with an unchanged header is a noop
65
+ #
66
+ # @return [Relation]
67
+ #
68
+ # @api private
69
+ def optimize
70
+ operand
71
+ end
72
+
73
+ end # class UnchangedHeader
74
+
75
+ # Optimize when the operand is Empty
76
+ class EmptyOperand < self
77
+
78
+ # Test if the operand is empty
79
+ #
80
+ # @return [Boolean]
81
+ #
82
+ # @api private
83
+ def optimizable?
84
+ operand.kind_of?(Axiom::Relation::Empty)
85
+ end
86
+
87
+ # A Unary operation on an empty operand is empty
88
+ #
89
+ # @return [Relation::Empty]
90
+ #
91
+ # @api private
92
+ def optimize
93
+ operand
94
+ end
95
+
96
+ end # class EmptyOperand
97
+
98
+ # Optimize when the operand is Materialized
99
+ class MaterializedOperand < self
100
+
101
+ # Test if the operand is materialized
102
+ #
103
+ # @return [Boolean]
104
+ #
105
+ # @api private
106
+ def optimizable?
107
+ operand.kind_of?(Axiom::Relation::Materialized)
108
+ end
109
+
110
+ # Return the materialized operation
111
+ #
112
+ # @return [Relation::Materialized]
113
+ #
114
+ # @api private
115
+ def optimize
116
+ operation.materialize
117
+ end
118
+
119
+ end # class MaterializedOperand
120
+ end # class Unary
121
+ end # module Operation
122
+ end # module Relation
123
+ end # class Optimizer
124
+ end # module Axiom
@@ -0,0 +1,184 @@
1
+ # encoding: utf-8
2
+
3
+ module Axiom
4
+ class Optimizer
5
+
6
+ # Partition a predicate to distribute it over binary operations
7
+ class PredicatePartition
8
+ include Adamantium
9
+
10
+ TAUTOLOGY = Axiom::Function::Proposition::Tautology.instance
11
+
12
+ # Returns the predicate for the left header
13
+ #
14
+ # @return [Function]
15
+ #
16
+ # @api private
17
+ attr_reader :left
18
+
19
+ # Returns the predicate for the right header
20
+ #
21
+ # @return [Function]
22
+ #
23
+ # @api private
24
+ attr_reader :right
25
+
26
+ # Returns the remainder predicate
27
+ #
28
+ # @return [Function]
29
+ #
30
+ # @api private
31
+ attr_reader :remainder
32
+
33
+ # Initialize a Predication Partition
34
+ #
35
+ # @example
36
+ # partition = PredicatePartition.new(predicate, left_header, right_header)
37
+ #
38
+ # @param [Function] predicate
39
+ #
40
+ # @param [Header] left_header
41
+ #
42
+ # @param [Header] right_header
43
+ #
44
+ # @return [undefined]
45
+ #
46
+ # @api private
47
+ def initialize(predicate, left_header, right_header)
48
+ @left = TAUTOLOGY
49
+ @right = TAUTOLOGY
50
+ @remainder = TAUTOLOGY
51
+
52
+ @left_header = left_header
53
+ @right_header = right_header
54
+
55
+ partition!(predicate)
56
+ end
57
+
58
+ private
59
+
60
+ # Partition the predicate into a left, right and remainder predicates
61
+ #
62
+ # @param [Function] predicate
63
+ #
64
+ # @return [undefined]
65
+ #
66
+ # @api private
67
+ def partition!(predicate)
68
+ each_operand(predicate) do |operand|
69
+ case operand
70
+ when Axiom::Function::Binary then partition_binary!(operand)
71
+ when Axiom::Function::Unary then partition_unary!(operand)
72
+ when Axiom::Attribute::Boolean then partition_attribute!(operand)
73
+ else
74
+ partition_proposition!(operand)
75
+ end
76
+ end
77
+ end
78
+
79
+ # Partition the binary function up into a left, right and remainder predicates
80
+ #
81
+ # @param [Function::Binary] function
82
+ #
83
+ # @return [undefined]
84
+ #
85
+ # @api private
86
+ def partition_binary!(function)
87
+ operands = [ function.left, function.right ].select do |operand|
88
+ operand.kind_of?(Axiom::Attribute)
89
+ end
90
+
91
+ left_operands = @left_header & operands
92
+ right_operands = @right_header & operands
93
+
94
+ if (left_operands - right_operands).empty? || (right_operands - left_operands).empty?
95
+ @left &= function if left_operands.any?
96
+ @right &= function if right_operands.any?
97
+ else
98
+ @remainder &= function
99
+ end
100
+ end
101
+
102
+ # Partition the unary function up into the left and right predicates
103
+ #
104
+ # @param [Function::Unary] function
105
+ #
106
+ # @return [undefined]
107
+ #
108
+ # @api private
109
+ def partition_unary!(function)
110
+ operand = function.operand
111
+ @left &= function if @left_header.include?(operand)
112
+ @right &= function if @right_header.include?(operand)
113
+ end
114
+
115
+ # Partition the attribute up into the left and right predicates
116
+ #
117
+ # @param [Attribute] attribute
118
+ #
119
+ # @return [undefined]
120
+ #
121
+ # @api private
122
+ def partition_attribute!(attribute)
123
+ @left &= attribute if @left_header.include?(attribute)
124
+ @right &= attribute if @right_header.include?(attribute)
125
+ end
126
+
127
+ # Partition the proposition up into the left, right and remainder predicates
128
+ #
129
+ # @param [Function::Proposition] proposition
130
+ #
131
+ # @return [undefined]
132
+ #
133
+ # @api private
134
+ def partition_proposition!(proposition)
135
+ @remainder &= proposition
136
+ @left &= proposition
137
+ @right &= proposition
138
+ end
139
+
140
+ # Yield each operand in the predicate recursively
141
+ #
142
+ # @param [Function] predicate
143
+ #
144
+ # @yield [operand]
145
+ #
146
+ # @yieldparam [Function] operand
147
+ # each operand in the predicate
148
+ #
149
+ # @yieldreturn [undefined]
150
+ #
151
+ # @return [undefined]
152
+ #
153
+ # @api private
154
+ def each_operand(predicate, &block)
155
+ case predicate
156
+ when Axiom::Function::Connective::Disjunction then each_operand(predicate.inverse.optimize, &block)
157
+ when Axiom::Function::Connective::Conjunction then each_conjunction(predicate, &block)
158
+ else
159
+ block.call(predicate)
160
+ end
161
+ end
162
+
163
+ # Yield each operand of the conjunction
164
+ #
165
+ # @param [Function::Connective::Conjunction] conjunction
166
+ #
167
+ # @yield [operand]
168
+ #
169
+ # @yieldparam [Function] operand
170
+ # each operand in the conjunction
171
+ #
172
+ # @yieldreturn [undefined]
173
+ #
174
+ # @return [undefined]
175
+ #
176
+ # @api private
177
+ def each_conjunction(conjunction, &block)
178
+ each_operand(conjunction.left, &block)
179
+ each_operand(conjunction.right, &block)
180
+ end
181
+
182
+ end # class PredicatePartition
183
+ end # class Optimizer
184
+ end # module Axiom