axiom 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (311) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +2 -1
  3. data/.rubocop.yml +7 -0
  4. data/.travis.yml +10 -7
  5. data/Gemfile +4 -0
  6. data/Gemfile.devtools +27 -13
  7. data/Guardfile +2 -2
  8. data/README.md +36 -30
  9. data/TODO +22 -24
  10. data/axiom.gemspec +9 -9
  11. data/benchmarks/memory.rb +1 -2
  12. data/benchmarks/speed.rb +7 -8
  13. data/config/flay.yml +1 -1
  14. data/config/reek.yml +19 -7
  15. data/config/rubocop.yml +6 -9
  16. data/lib/axiom.rb +28 -13
  17. data/lib/axiom/aggregate/mean.rb +4 -3
  18. data/lib/axiom/aggregate/sum.rb +1 -1
  19. data/lib/axiom/algebra/extension.rb +1 -1
  20. data/lib/axiom/algebra/join.rb +4 -27
  21. data/lib/axiom/algebra/product.rb +3 -3
  22. data/lib/axiom/algebra/projection.rb +2 -2
  23. data/lib/axiom/algebra/rename.rb +2 -2
  24. data/lib/axiom/algebra/rename/aliases.rb +3 -3
  25. data/lib/axiom/algebra/summarization.rb +3 -3
  26. data/lib/axiom/attribute.rb +5 -4
  27. data/lib/axiom/attribute/comparable.rb +15 -11
  28. data/lib/axiom/attribute/date.rb +1 -1
  29. data/lib/axiom/attribute/date_time.rb +1 -1
  30. data/lib/axiom/attribute/length_comparable.rb +39 -0
  31. data/lib/axiom/attribute/numeric.rb +1 -26
  32. data/lib/axiom/attribute/relation.rb +64 -0
  33. data/lib/axiom/attribute/string.rb +1 -28
  34. data/lib/axiom/attribute/time.rb +1 -1
  35. data/lib/axiom/attribute/tuple.rb +50 -0
  36. data/lib/axiom/attribute/value_comparable.rb +42 -0
  37. data/lib/axiom/function.rb +1 -1
  38. data/lib/axiom/function/binary.rb +4 -16
  39. data/lib/axiom/function/comparable.rb +1 -1
  40. data/lib/axiom/function/connective/conjunction.rb +1 -1
  41. data/lib/axiom/function/connective/disjunction.rb +1 -1
  42. data/lib/axiom/function/connective/negation.rb +1 -1
  43. data/lib/axiom/function/numeric/exponentiation.rb +1 -1
  44. data/lib/axiom/function/numeric/square_root.rb +1 -1
  45. data/lib/axiom/function/predicate/enumerable.rb +0 -14
  46. data/lib/axiom/function/predicate/exclusion.rb +1 -1
  47. data/lib/axiom/function/predicate/inclusion.rb +1 -1
  48. data/lib/axiom/function/proposition.rb +12 -25
  49. data/lib/axiom/function/unary.rb +92 -106
  50. data/lib/axiom/relation.rb +3 -3
  51. data/lib/axiom/relation/base.rb +15 -0
  52. data/lib/axiom/relation/header.rb +25 -22
  53. data/lib/axiom/relation/index.rb +91 -0
  54. data/lib/axiom/relation/keys.rb +3 -3
  55. data/lib/axiom/relation/materialized.rb +48 -4
  56. data/lib/axiom/relation/operation/binary.rb +5 -5
  57. data/lib/axiom/relation/operation/group.rb +95 -0
  58. data/lib/axiom/relation/operation/limit.rb +15 -15
  59. data/lib/axiom/relation/operation/offset.rb +12 -12
  60. data/lib/axiom/relation/operation/reverse.rb +9 -9
  61. data/lib/axiom/relation/operation/set.rb +1 -1
  62. data/lib/axiom/relation/operation/{order.rb → sorted.rb} +29 -28
  63. data/lib/axiom/relation/operation/{order → sorted}/direction.rb +4 -4
  64. data/lib/axiom/relation/operation/{order → sorted}/direction_set.rb +3 -3
  65. data/lib/axiom/relation/operation/ungroup.rb +82 -0
  66. data/lib/axiom/relation/operation/unwrap.rb +80 -0
  67. data/lib/axiom/relation/operation/wrap.rb +85 -0
  68. data/lib/axiom/relation/proxy.rb +5 -6
  69. data/lib/axiom/relation/variable.rb +1 -2
  70. data/lib/axiom/support/aliasable.rb +3 -5
  71. data/lib/axiom/support/equalizer.rb +10 -12
  72. data/lib/axiom/support/operation/binary.rb +3 -2
  73. data/lib/axiom/support/operation/unary.rb +1 -1
  74. data/lib/axiom/tuple.rb +76 -26
  75. data/lib/axiom/types/relation.rb +13 -0
  76. data/lib/axiom/types/tuple.rb +13 -0
  77. data/lib/axiom/version.rb +1 -1
  78. data/spec/integration/axiom/relation/efficient_enumerable_spec.rb +9 -9
  79. data/spec/integration/axiom/relation/writable_relations_spec.rb +12 -12
  80. data/spec/shared/invertible_method_behaviour.rb +1 -1
  81. data/spec/spec_helper.rb +8 -6
  82. data/spec/unit/axiom/aggregate/call_spec.rb +7 -12
  83. data/spec/unit/axiom/aggregate/class_methods/default_spec.rb +7 -2
  84. data/spec/unit/axiom/aggregate/default_spec.rb +1 -1
  85. data/spec/unit/axiom/aggregate/finalize_spec.rb +1 -1
  86. data/spec/unit/axiom/aggregate/maximum/type_spec.rb +2 -6
  87. data/spec/unit/axiom/aggregate/mean/class_methods/call_spec.rb +2 -2
  88. data/spec/unit/axiom/aggregate/mean/class_methods/finalize_spec.rb +10 -3
  89. data/spec/unit/axiom/aggregate/minimum/type_spec.rb +2 -6
  90. data/spec/unit/axiom/aggregate/sum/default_spec.rb +32 -6
  91. data/spec/unit/axiom/aggregate/sum/type_spec.rb +2 -6
  92. data/spec/unit/axiom/aggregate/variance/class_methods/call_spec.rb +6 -6
  93. data/spec/unit/axiom/algebra/difference/each_spec.rb +3 -3
  94. data/spec/unit/axiom/algebra/extension/class_methods/new_spec.rb +1 -1
  95. data/spec/unit/axiom/algebra/extension/each_spec.rb +2 -2
  96. data/spec/unit/axiom/algebra/intersection/each_spec.rb +3 -3
  97. data/spec/unit/axiom/algebra/join/each_spec.rb +6 -6
  98. data/spec/unit/axiom/algebra/product/each_spec.rb +2 -2
  99. data/spec/unit/axiom/algebra/projection/each_spec.rb +2 -2
  100. data/spec/unit/axiom/algebra/rename/directions_spec.rb +3 -3
  101. data/spec/unit/axiom/algebra/rename/each_spec.rb +2 -2
  102. data/spec/unit/axiom/algebra/restriction/delete_spec.rb +3 -3
  103. data/spec/unit/axiom/algebra/restriction/each_spec.rb +12 -11
  104. data/spec/unit/axiom/algebra/restriction/insert_spec.rb +3 -3
  105. data/spec/unit/axiom/algebra/restriction/methods/restrict_spec.rb +4 -4
  106. data/spec/unit/axiom/algebra/summarization/each_spec.rb +2 -2
  107. data/spec/unit/axiom/algebra/summarization/eql_spec.rb +1 -1
  108. data/spec/unit/axiom/algebra/summarization/summaries/summarize_by_spec.rb +4 -4
  109. data/spec/unit/axiom/algebra/summarization/summaries/to_hash_spec.rb +2 -2
  110. data/spec/unit/axiom/algebra/summarization/summary/summarize_by_spec.rb +1 -1
  111. data/spec/unit/axiom/algebra/union/each_spec.rb +4 -4
  112. data/spec/unit/axiom/aliasable/fixtures/classes.rb +3 -1
  113. data/spec/unit/axiom/aliasable/inheritable_alias_spec.rb +18 -27
  114. data/spec/unit/axiom/attribute/call_spec.rb +1 -1
  115. data/spec/unit/axiom/attribute/class_methods/coerce_spec.rb +57 -51
  116. data/spec/unit/axiom/attribute/class_methods/new_spec.rb +1 -1
  117. data/spec/unit/axiom/attribute/comparable/asc_spec.rb +4 -2
  118. data/spec/unit/axiom/attribute/comparable/desc_spec.rb +4 -2
  119. data/spec/unit/axiom/attribute/comparable/range_spec.rb +20 -0
  120. data/spec/unit/axiom/attribute/eql_spec.rb +1 -1
  121. data/spec/unit/axiom/attribute/equality_operator_spec.rb +1 -1
  122. data/spec/unit/axiom/attribute/include_predicate_spec.rb +1 -1
  123. data/spec/unit/axiom/attribute/name_spec.rb +1 -1
  124. data/spec/unit/axiom/attribute/optional_predicate_spec.rb +1 -1
  125. data/spec/unit/axiom/attribute/relation/class_methods/new_spec.rb +56 -0
  126. data/spec/unit/axiom/attribute/relation/class_methods/type_spec.rb +13 -0
  127. data/spec/unit/axiom/attribute/relation/header_spec.rb +13 -0
  128. data/spec/unit/axiom/attribute/relation/new_relation_spec.rb +15 -0
  129. data/spec/unit/axiom/attribute/rename_spec.rb +1 -1
  130. data/spec/unit/axiom/attribute/required_predicate_spec.rb +1 -1
  131. data/spec/unit/axiom/attribute/tuple/class_methods/new_spec.rb +56 -0
  132. data/spec/unit/axiom/attribute/tuple/class_methods/type_spec.rb +13 -0
  133. data/spec/unit/axiom/attribute/tuple/header_spec.rb +13 -0
  134. data/spec/unit/axiom/equalizer/class_method/new_spec.rb +24 -54
  135. data/spec/unit/axiom/evaluator/context/add_spec.rb +7 -7
  136. data/spec/unit/axiom/evaluator/context/element_reader_spec.rb +4 -4
  137. data/spec/unit/axiom/evaluator/context/functions_spec.rb +1 -1
  138. data/spec/unit/axiom/evaluator/context/method_missing_spec.rb +3 -3
  139. data/spec/unit/axiom/evaluator/context/respond_to_predicate_spec.rb +3 -3
  140. data/spec/unit/axiom/evaluator/context/send_spec.rb +8 -8
  141. data/spec/unit/axiom/function/binary/call_spec.rb +1 -1
  142. data/spec/unit/axiom/function/binary/type_spec.rb +12 -10
  143. data/spec/unit/axiom/function/comparable/class_methods/included_spec.rb +2 -2
  144. data/spec/unit/axiom/function/connective/negation/inverse_spec.rb +1 -1
  145. data/spec/unit/axiom/function/predicate/call_spec.rb +5 -4
  146. data/spec/unit/axiom/function/predicate/enumerable/call_spec.rb +12 -2
  147. data/spec/unit/axiom/function/predicate/eql_spec.rb +4 -3
  148. data/spec/unit/axiom/function/predicate/equality/methods/eq_spec.rb +5 -1
  149. data/spec/unit/axiom/function/predicate/exclusion/class_methods/call_spec.rb +37 -8
  150. data/spec/unit/axiom/function/predicate/exclusion/methods/exclude_spec.rb +6 -2
  151. data/spec/unit/axiom/function/predicate/greater_than/methods/gt_spec.rb +5 -1
  152. data/spec/unit/axiom/function/predicate/greater_than_or_equal_to/methods/gte_spec.rb +5 -1
  153. data/spec/unit/axiom/function/predicate/inclusion/class_methods/call_spec.rb +37 -8
  154. data/spec/unit/axiom/function/predicate/inclusion/methods/include_spec.rb +6 -2
  155. data/spec/unit/axiom/function/predicate/inequality/methods/ne_spec.rb +5 -1
  156. data/spec/unit/axiom/function/predicate/less_than/methods/lt_spec.rb +5 -1
  157. data/spec/unit/axiom/function/predicate/less_than_or_equal_to/methods/lte_spec.rb +5 -1
  158. data/spec/unit/axiom/function/predicate/match/methods/match_spec.rb +7 -3
  159. data/spec/unit/axiom/function/predicate/no_match/methods/no_match_spec.rb +6 -2
  160. data/spec/unit/axiom/function/proposition/call_spec.rb +6 -4
  161. data/spec/unit/axiom/function/proposition/class_methods/{new_spec.rb → coerce_spec.rb} +17 -17
  162. data/spec/unit/axiom/function/proposition/eql_spec.rb +4 -4
  163. data/spec/unit/axiom/function/proposition/equality_operator_spec.rb +3 -3
  164. data/spec/unit/axiom/function/proposition/inverse_spec.rb +4 -4
  165. data/spec/unit/axiom/function/proposition/rename_spec.rb +1 -1
  166. data/spec/unit/axiom/function/type_spec.rb +1 -1
  167. data/spec/unit/axiom/function/unary/call_spec.rb +1 -1
  168. data/spec/unit/axiom/function/unary/callable/call_spec.rb +3 -13
  169. data/spec/unit/axiom/function/unary/callable/included_spec.rb +2 -2
  170. data/spec/unit/axiom/function/unary/type_spec.rb +11 -1
  171. data/spec/unit/axiom/relation/base/eql_spec.rb +1 -1
  172. data/spec/unit/axiom/relation/base/equality_operator_spec.rb +138 -0
  173. data/spec/unit/axiom/relation/class_methods/new_spec.rb +7 -7
  174. data/spec/unit/axiom/relation/directions_spec.rb +2 -2
  175. data/spec/unit/axiom/relation/each_spec.rb +5 -5
  176. data/spec/unit/axiom/relation/element_reader_spec.rb +1 -1
  177. data/spec/unit/axiom/relation/empty/each_spec.rb +1 -1
  178. data/spec/unit/axiom/relation/empty_predicate_spec.rb +1 -1
  179. data/spec/unit/axiom/relation/eql_spec.rb +1 -1
  180. data/spec/unit/axiom/relation/equality_operator_spec.rb +1 -1
  181. data/spec/unit/axiom/relation/header/class_methods/coerce_spec.rb +2 -2
  182. data/spec/unit/axiom/relation/header/class_methods/new_spec.rb +3 -3
  183. data/spec/unit/axiom/relation/header/context_spec.rb +2 -2
  184. data/spec/unit/axiom/relation/header/each_spec.rb +2 -2
  185. data/spec/unit/axiom/relation/header/extend_spec.rb +1 -1
  186. data/spec/unit/axiom/relation/header/{call_spec.rb → fetch_spec.rb} +1 -1
  187. data/spec/unit/axiom/relation/header/project_spec.rb +1 -1
  188. data/spec/unit/axiom/relation/header/rename_spec.rb +19 -5
  189. data/spec/unit/axiom/relation/header/size_spec.rb +14 -0
  190. data/spec/unit/axiom/relation/header_spec.rb +1 -1
  191. data/spec/unit/axiom/relation/index/each_spec.rb +33 -0
  192. data/spec/unit/axiom/relation/index/element_reader_spec.rb +17 -0
  193. data/spec/unit/axiom/relation/index/left_shift_operator_spec.rb +23 -0
  194. data/spec/unit/axiom/relation/index/merge_spec.rb +19 -0
  195. data/spec/unit/axiom/relation/keys/class_methods/coerce_spec.rb +19 -2
  196. data/spec/unit/axiom/relation/keys/class_methods/new_spec.rb +1 -1
  197. data/spec/unit/axiom/relation/keys/each_spec.rb +2 -2
  198. data/spec/unit/axiom/relation/materialize_spec.rb +1 -1
  199. data/spec/unit/axiom/relation/materialized/class_methods/new_spec.rb +30 -4
  200. data/spec/unit/axiom/relation/materialized/directions_spec.rb +1 -1
  201. data/spec/unit/axiom/relation/materialized/materialized_predicate_spec.rb +1 -1
  202. data/spec/unit/axiom/relation/materialized_predicate_spec.rb +1 -1
  203. data/spec/unit/axiom/relation/operation/binary/class_methods/included_spec.rb +2 -2
  204. data/spec/unit/axiom/relation/operation/binary/class_methods/new_spec.rb +6 -6
  205. data/spec/unit/axiom/relation/operation/combination/class_methods/combine_tuples_spec.rb +4 -4
  206. data/spec/unit/axiom/relation/operation/group/each_spec.rb +33 -0
  207. data/spec/unit/axiom/relation/operation/group/header_spec.rb +22 -0
  208. data/spec/unit/axiom/relation/operation/group/methods/group_spec.rb +25 -0
  209. data/spec/unit/axiom/relation/operation/limit/class_methods/new_spec.rb +4 -4
  210. data/spec/unit/axiom/relation/operation/limit/directions_spec.rb +3 -3
  211. data/spec/unit/axiom/relation/operation/limit/each_spec.rb +4 -4
  212. data/spec/unit/axiom/relation/operation/limit/limit_spec.rb +2 -2
  213. data/spec/unit/axiom/relation/operation/offset/class_methods/new_spec.rb +4 -4
  214. data/spec/unit/axiom/relation/operation/offset/directions_spec.rb +3 -3
  215. data/spec/unit/axiom/relation/operation/offset/each_spec.rb +4 -4
  216. data/spec/unit/axiom/relation/operation/offset/offset_spec.rb +2 -2
  217. data/spec/unit/axiom/relation/operation/reverse/class_methods/new_spec.rb +6 -6
  218. data/spec/unit/axiom/relation/operation/reverse/directions_spec.rb +3 -3
  219. data/spec/unit/axiom/relation/operation/reverse/each_spec.rb +4 -4
  220. data/spec/unit/axiom/relation/operation/set/class_methods/included_spec.rb +2 -2
  221. data/spec/unit/axiom/relation/operation/{order → sorted}/ascending/class_methods/call_spec.rb +22 -1
  222. data/spec/unit/axiom/relation/operation/sorted/ascending/class_methods/reverse_spec.rb +11 -0
  223. data/spec/unit/axiom/relation/operation/{order/descending → sorted/ascending}/reverse_spec.rb +2 -2
  224. data/spec/unit/axiom/relation/operation/{order → sorted}/class_methods/new_spec.rb +4 -4
  225. data/spec/unit/axiom/relation/operation/{order → sorted}/delete_spec.rb +12 -6
  226. data/spec/unit/axiom/relation/operation/{order → sorted}/descending/class_methods/call_spec.rb +22 -1
  227. data/spec/unit/axiom/relation/operation/sorted/descending/class_methods/reverse_spec.rb +11 -0
  228. data/spec/unit/axiom/relation/operation/{order/ascending → sorted/descending}/reverse_spec.rb +2 -2
  229. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/attribute_spec.rb +4 -4
  230. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/call_spec.rb +7 -7
  231. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/class_methods/coerce_spec.rb +2 -2
  232. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/eql_predicate_spec.rb +4 -4
  233. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/name_spec.rb +4 -4
  234. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/rename_spec.rb +5 -5
  235. data/spec/unit/axiom/relation/operation/{order → sorted}/direction/reverse_spec.rb +9 -9
  236. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/attributes_spec.rb +1 -1
  237. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/class_methods/coerce_spec.rb +3 -3
  238. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/class_methods/new_spec.rb +1 -1
  239. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/eql_spec.rb +1 -1
  240. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/equality_operator_spec.rb +1 -1
  241. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/project_spec.rb +1 -1
  242. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/rename_spec.rb +1 -1
  243. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/reverse_spec.rb +2 -2
  244. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/sort_tuples_spec.rb +1 -1
  245. data/spec/unit/axiom/relation/operation/{order → sorted}/direction_set/to_ary_spec.rb +1 -1
  246. data/spec/unit/axiom/relation/operation/{order → sorted}/directions_spec.rb +1 -1
  247. data/spec/unit/axiom/relation/operation/{order → sorted}/each_spec.rb +3 -3
  248. data/spec/unit/axiom/relation/operation/{order → sorted}/eql_spec.rb +1 -1
  249. data/spec/unit/axiom/relation/operation/{order → sorted}/header_spec.rb +1 -1
  250. data/spec/unit/axiom/relation/operation/{order → sorted}/insert_spec.rb +12 -6
  251. data/spec/unit/axiom/relation/operation/{order → sorted}/methods/sort_by_spec.rb +24 -24
  252. data/spec/unit/axiom/relation/operation/sorted/methods/sort_spec.rb +19 -0
  253. data/spec/unit/axiom/relation/operation/ungroup/each_spec.rb +33 -0
  254. data/spec/unit/axiom/relation/operation/ungroup/header_spec.rb +19 -0
  255. data/spec/unit/axiom/relation/operation/ungroup/methods/ungroup_spec.rb +21 -0
  256. data/spec/unit/axiom/relation/operation/unwrap/each_spec.rb +33 -0
  257. data/spec/unit/axiom/relation/operation/unwrap/header_spec.rb +19 -0
  258. data/spec/unit/axiom/relation/operation/unwrap/methods/unwrap_spec.rb +21 -0
  259. data/spec/unit/axiom/relation/operation/wrap/each_spec.rb +33 -0
  260. data/spec/unit/axiom/relation/operation/wrap/header_spec.rb +22 -0
  261. data/spec/unit/axiom/relation/operation/wrap/methods/wrap_spec.rb +25 -0
  262. data/spec/unit/axiom/relation/proxy/each_spec.rb +2 -2
  263. data/spec/unit/axiom/relation/proxy/respond_to_predicate_spec.rb +48 -12
  264. data/spec/unit/axiom/relation/replace_spec.rb +8 -8
  265. data/spec/unit/axiom/tuple/class_methods/coerce_spec.rb +7 -1
  266. data/spec/unit/axiom/tuple/{call_spec.rb → fetch_spec.rb} +1 -1
  267. data/spec/unit/axiom/tuple/inspect_spec.rb +14 -0
  268. data/spec/unit/axiom/tuple/rename_spec.rb +17 -0
  269. data/spec/unit/axiom/tuple/size_spec.rb +14 -0
  270. data/spec/unit/axiom/tuple/to_ary_spec.rb +22 -5
  271. data/spec/unit/axiom/tuple/to_hash_spec.rb +14 -0
  272. data/spec/unit/axiom/types/relation/class_methods/primitive_spec.rb +13 -0
  273. data/spec/unit/axiom/types/tuple/class_methods/primitive_spec.rb +13 -0
  274. data/spec/unit/axiom/visitable/accept_spec.rb +1 -1
  275. data/spec/unit/date/pred_spec.rb +1 -1
  276. data/spec/unit/time/pred_spec.rb +1 -1
  277. metadata +631 -107
  278. data/spec/unit/axiom/aggregate/hash_spec.rb +0 -15
  279. data/spec/unit/axiom/algebra/extension/hash_spec.rb +0 -15
  280. data/spec/unit/axiom/algebra/projection/hash_spec.rb +0 -16
  281. data/spec/unit/axiom/algebra/rename/aliases/hash_spec.rb +0 -15
  282. data/spec/unit/axiom/algebra/rename/hash_spec.rb +0 -15
  283. data/spec/unit/axiom/algebra/restriction/hash_spec.rb +0 -15
  284. data/spec/unit/axiom/algebra/summarization/hash_spec.rb +0 -16
  285. data/spec/unit/axiom/attribute/hash_spec.rb +0 -21
  286. data/spec/unit/axiom/attribute/numeric/hash_spec.rb +0 -17
  287. data/spec/unit/axiom/attribute/string/hash_spec.rb +0 -25
  288. data/spec/unit/axiom/equalizer/methods/eql_spec.rb +0 -49
  289. data/spec/unit/axiom/equalizer/methods/equality_operator_spec.rb +0 -85
  290. data/spec/unit/axiom/function/binary/invertible/class_methods/included_spec.rb +0 -29
  291. data/spec/unit/axiom/function/predicate/hash_spec.rb +0 -16
  292. data/spec/unit/axiom/function/predicate/inverse_spec.rb +0 -17
  293. data/spec/unit/axiom/function/proposition/hash_spec.rb +0 -14
  294. data/spec/unit/axiom/function/unary/hash_spec.rb +0 -18
  295. data/spec/unit/axiom/function/unary/invertible/class_methods/included_spec.rb +0 -29
  296. data/spec/unit/axiom/operation/binary/hash_spec.rb +0 -16
  297. data/spec/unit/axiom/operation/unary/hash_spec.rb +0 -15
  298. data/spec/unit/axiom/relation/base/hash_spec.rb +0 -16
  299. data/spec/unit/axiom/relation/hash_spec.rb +0 -19
  300. data/spec/unit/axiom/relation/header/hash_spec.rb +0 -15
  301. data/spec/unit/axiom/relation/operation/limit/hash_spec.rb +0 -16
  302. data/spec/unit/axiom/relation/operation/offset/hash_spec.rb +0 -16
  303. data/spec/unit/axiom/relation/operation/order/ascending/class_methods/reverse_spec.rb +0 -11
  304. data/spec/unit/axiom/relation/operation/order/descending/class_methods/reverse_spec.rb +0 -11
  305. data/spec/unit/axiom/relation/operation/order/direction/hash_spec.rb +0 -15
  306. data/spec/unit/axiom/relation/operation/order/direction_set/hash_spec.rb +0 -15
  307. data/spec/unit/axiom/relation/operation/order/hash_spec.rb +0 -15
  308. data/spec/unit/axiom/relation/operation/order/methods/sort_spec.rb +0 -19
  309. data/spec/unit/axiom/relation/proxy/hash_spec.rb +0 -26
  310. data/spec/unit/axiom/relation/proxy/method_missing_spec.rb +0 -24
  311. data/spec/unit/axiom/tuple/hash_spec.rb +0 -15
@@ -31,7 +31,7 @@ module Axiom
31
31
  #
32
32
  # @api public
33
33
  def inverse
34
- self.class.new(left, Division.new(1, right)).memoize(:inverse, self)
34
+ self.class.new(left, Division.new(1, right)).memoize(inverse: self)
35
35
  end
36
36
 
37
37
  module Methods
@@ -46,7 +46,7 @@ module Axiom
46
46
  #
47
47
  # @api public
48
48
  def inverse
49
- Exponentiation.new(operand, 2).memoize(:inverse, self)
49
+ Exponentiation.new(operand, 2).memoize(inverse: self)
50
50
  end
51
51
 
52
52
  # Return the type returned from #call
@@ -18,20 +18,6 @@ module Axiom
18
18
  enumerable.respond_to?(:cover?) ? :cover? : :include?
19
19
  end
20
20
 
21
- # Initialize an Enumerable predicate
22
- #
23
- # @param [Object] left
24
- # the attribute or object to test for in the Enumerable
25
- # @param [Enumerable] right
26
- # the enumerable to test
27
- #
28
- # @return [undefined]
29
- #
30
- # @api private
31
- def initialize(left, right)
32
- super(left, freeze_object(right))
33
- end
34
-
35
21
  # Evaluate the enumerable function using the tuple
36
22
  #
37
23
  # @example
@@ -22,7 +22,7 @@ module Axiom
22
22
  #
23
23
  # @api public
24
24
  def self.call(left, right)
25
- ! right.send(Enumerable.compare_method(right), left)
25
+ !right.public_send(Enumerable.compare_method(right), left)
26
26
  end
27
27
 
28
28
  # Return the inverse predicate class
@@ -22,7 +22,7 @@ module Axiom
22
22
  #
23
23
  # @api public
24
24
  def self.call(left, right)
25
- right.send(Enumerable.compare_method(right), left)
25
+ right.public_send(Enumerable.compare_method(right), left)
26
26
  end
27
27
 
28
28
  # Return the inverse predicate class
@@ -5,8 +5,7 @@ module Axiom
5
5
 
6
6
  # Abstract base class for logical propositions
7
7
  class Proposition < Function
8
- include AbstractType,
9
- Singleton,
8
+ include Singleton,
10
9
  Function::Connective::Conjunction::Methods,
11
10
  Function::Connective::Disjunction::Methods,
12
11
  Function::Connective::Negation::Methods
@@ -24,36 +23,24 @@ module Axiom
24
23
  Types::Boolean
25
24
  end
26
25
 
27
- # Instantiate a new Proposition
26
+ # Coerce a boolean into a proposition
28
27
  #
29
- # @example using a true value
30
- # tautology = Proposition.new(true)
31
- #
32
- # @example using a false value
33
- # contradiction = Proposition.new(false)
28
+ # @param [Object] object
34
29
  #
35
30
  # @return [Proposition]
31
+ # returned twhen the object can be coerced into a proposition
36
32
  #
37
- # @overload self.new(true)
38
- # Return the Tautology singleton instance
39
- #
40
- # @param [Array(true)] args
41
- #
42
- # @return [Tautology]
43
- #
44
- # @overload self.new(false)
45
- # Return the Contradiction singleton instance
46
- #
47
- # @param [Array(false)] args
48
- #
49
- # @return [Contradiction]
33
+ # @raise [ArgumentError]
34
+ # raised when the object cannot be coerced into a proposition
50
35
  #
51
36
  # @api public
52
- def self.new(*args)
53
- if args.empty?
54
- super
37
+ def self.coerce(object)
38
+ case object
39
+ when Proposition then object
40
+ when true then Tautology.instance
41
+ when false then Contradiction.instance
55
42
  else
56
- (args.first.equal?(true) ? Tautology : Contradiction).instance
43
+ fail ArgumentError, "Invalid object #{object.inspect}"
57
44
  end
58
45
  end
59
46
 
@@ -3,134 +3,120 @@
3
3
  module Axiom
4
4
  class Function
5
5
 
6
- # Mixin for unary functions
7
- module Unary
8
- include Operation::Unary
9
- include Equalizer.new(:operand)
6
+ # Mixin for unary functions
7
+ module Unary
8
+ include Operation::Unary
9
+ include Equalizer.new(:operand)
10
10
 
11
- # Mixin for adding #call to unary function classes
12
- module Callable
11
+ # Mixin for adding #call to unary function classes
12
+ module Callable
13
13
 
14
- # Hook called when module is included
15
- #
16
- # @param [Module] descendant
17
- # the module or class including Callable
18
- #
19
- # @return [self]
20
- #
21
- # @api private
22
- def included(descendant)
23
- super
24
- descendant.extend(Callable)
25
- self
26
- end
27
-
28
- # Return the response from the unary operation called on the value
29
- #
30
- # @example
31
- # callable.call(value) # => any object
32
- #
33
- # @param [Object] value
34
- #
35
- # @return [Object]
36
- #
37
- # @api public
38
- def call(value)
39
- value.send(operation)
40
- end
41
-
42
- end # module Callable
43
-
44
- extend Callable
45
-
46
- # Evaluate the unary connective using the tuple
14
+ # Hook called when module is included
47
15
  #
48
- # @example
49
- # unary.call(tuple) # => true or false
50
- #
51
- # @param [Tuple] tuple
52
- # the tuple to pass to operand#call
16
+ # @param [Module] descendant
17
+ # the module or class including Callable
53
18
  #
54
- # @return [Boolean]
19
+ # @return [self]
55
20
  #
56
- # @api public
57
- def call(tuple)
58
- util = self.class
59
- util.call(util.extract_value(operand, tuple))
21
+ # @api private
22
+ def included(descendant)
23
+ super
24
+ descendant.extend(Callable)
25
+ self
60
26
  end
61
27
 
62
- # Rename the contained attributes with the provided aliases
28
+ # Return the response from the unary operation called on the value
63
29
  #
64
30
  # @example
65
- # renamed = unary.rename(aliases)
31
+ # callable.call(value) # => any object
66
32
  #
67
- # @param [Algebra::Rename::Aliases] aliases
68
- # the old and new attributes
33
+ # @param [Object] value
69
34
  #
70
- # @return [self]
71
- # if the operand is not renamed
72
- # @return [Unary]
73
- # if the operand is renamed
74
- #
75
- # @todo handle case where operand is a literal
35
+ # @return [Object]
76
36
  #
77
37
  # @api public
78
- def rename(aliases)
79
- util = self.class
80
- renamed_operand = util.rename_attributes(operand, aliases)
81
-
82
- if operand.equal?(renamed_operand)
83
- self
84
- else
85
- util.new(renamed_operand)
86
- end
38
+ def call(value)
39
+ value.public_send(operation)
87
40
  end
88
41
 
89
- # Return the type returned from #call
42
+ end # module Callable
43
+
44
+ extend Callable
45
+
46
+ # Evaluate the unary connective using the tuple
47
+ #
48
+ # @example
49
+ # unary.call(tuple) # => true or false
50
+ #
51
+ # @param [Tuple] tuple
52
+ # the tuple to pass to operand#call
53
+ #
54
+ # @return [Boolean]
55
+ #
56
+ # @api public
57
+ def call(tuple)
58
+ util = self.class
59
+ util.call(util.extract_value(operand, tuple))
60
+ end
61
+
62
+ # Rename the contained attributes with the provided aliases
63
+ #
64
+ # @example
65
+ # renamed = unary.rename(aliases)
66
+ #
67
+ # @param [Algebra::Rename::Aliases] aliases
68
+ # the old and new attributes
69
+ #
70
+ # @return [self]
71
+ # if the operand is not renamed
72
+ # @return [Unary]
73
+ # if the operand is renamed
74
+ #
75
+ # @todo handle case where operand is a literal
76
+ #
77
+ # @api public
78
+ def rename(aliases)
79
+ util = self.class
80
+ renamed_operand = util.rename_attributes(operand, aliases)
81
+
82
+ if operand.equal?(renamed_operand)
83
+ self
84
+ else
85
+ util.new(renamed_operand)
86
+ end
87
+ end
88
+
89
+ # Return the type returned from #call
90
+ #
91
+ # @example
92
+ # type = unary.type # => Axiom::Types::Numeric
93
+ #
94
+ # @return [Class<Types::Numeric>]
95
+ #
96
+ # @api public
97
+ def type
98
+ Attribute.infer_type(operand)
99
+ end
100
+
101
+ # Mixin for invertable unary functions
102
+ module Invertible
103
+ include Adamantium
104
+
105
+ # Return the inverse function
90
106
  #
91
107
  # @example
92
- # type = unary.type # => Axiom::Types::Numeric
108
+ # inverse = function.inverse
93
109
  #
94
- # @return [Class<Types::Numeric>]
110
+ # @return [Function]
95
111
  #
96
112
  # @api public
97
- def type
98
- Attribute.infer_type(operand)
113
+ def inverse
114
+ self.class.inverse.new(operand).memoize(inverse: self)
99
115
  end
100
116
 
101
- # Mixin for invertable unary functions
102
- module Invertible
103
-
104
- # Hook called when module is included
105
- #
106
- # @param [Module] descendant
107
- # the module or class including Invertible
108
- #
109
- # @return [undefined]
110
- #
111
- # @api private
112
- def self.included(descendant)
113
- super
114
- descendant.memoize :inverse
115
- end
116
-
117
- private_class_method :included
118
-
119
- # Return the inverse function
120
- #
121
- # @example
122
- # inverse = function.inverse
123
- #
124
- # @return [Function]
125
- #
126
- # @todo move this to classes that use it
127
- #
128
- # @api public
129
- def inverse
130
- self.class.inverse.new(operand).memoize(:inverse, self)
131
- end
117
+ memoize :inverse
132
118
 
133
- end # module Invertible
134
- end # module Unary
119
+ end # module Invertible
120
+ end # module Unary
135
121
  end # class Function
136
122
  end # module Axiom
@@ -24,11 +24,11 @@ module Axiom
24
24
 
25
25
  # The relation sort order
26
26
  #
27
- # @return [Operation::Order::DirectionSet]
27
+ # @return [Operation::Sorted::DirectionSet]
28
28
  #
29
29
  # @api private
30
30
  def directions
31
- Operation::Order::DirectionSet::EMPTY
31
+ Operation::Sorted::DirectionSet::EMPTY
32
32
  end
33
33
 
34
34
  # Instantiate a new Relation
@@ -238,7 +238,7 @@ module Axiom
238
238
  #
239
239
  # @api private
240
240
  def self.coerce(header, object)
241
- if object.kind_of?(Relation) || ! object.kind_of?(Enumerable)
241
+ if object.kind_of?(Relation) || !object.kind_of?(Enumerable)
242
242
  object
243
243
  else
244
244
  Relation.new(header, object)
@@ -34,6 +34,21 @@ module Axiom
34
34
  @name = name.to_sym
35
35
  end
36
36
 
37
+ # Compare the base relation with other relation for equivalency
38
+ #
39
+ # @example
40
+ # base == other # => true or false
41
+ #
42
+ # @param [Relation] other
43
+ # the other relation to compare with
44
+ #
45
+ # @return [Boolean]
46
+ #
47
+ # @api public
48
+ def ==(other)
49
+ super && (!other.respond_to?(:name) || name == other.name)
50
+ end
51
+
37
52
  end # class Base
38
53
  end # class Relation
39
54
  end # module Axiom
@@ -10,7 +10,7 @@ module Axiom
10
10
  include Equalizer.new(:to_set, :keys)
11
11
 
12
12
  inheritable_alias(
13
- :[] => :call,
13
+ :[] => :fetch,
14
14
  :& => :intersect,
15
15
  :| => :union,
16
16
  :- => :difference
@@ -23,6 +23,16 @@ module Axiom
23
23
  # @api private
24
24
  attr_reader :keys
25
25
 
26
+ # Convert the Header into an Array
27
+ #
28
+ # @example
29
+ # array = header.to_ary
30
+ #
31
+ # @return [Array]
32
+ #
33
+ # @api public
34
+ attr_reader :to_ary
35
+
26
36
  # Coerce an Array-like object into a Header
27
37
  #
28
38
  # @param [Header, #to_ary] object
@@ -61,7 +71,7 @@ module Axiom
61
71
  # @return [Header]
62
72
  #
63
73
  # @api public
64
- def self.new(attributes = EMPTY_ARRAY, _options = EMPTY_HASH)
74
+ def self.new(attributes = EMPTY_ARRAY, *)
65
75
  assert_unique_names(attributes.map(&:name))
66
76
  super
67
77
  end
@@ -90,7 +100,7 @@ module Axiom
90
100
  def self.assert_unique_names(names)
91
101
  duplicates = duplicate_names(names)
92
102
  if duplicates
93
- raise DuplicateNameError, "duplicate names: #{duplicates.inspect}"
103
+ fail DuplicateNameError, "duplicate names: #{duplicates}"
94
104
  end
95
105
  end
96
106
 
@@ -123,9 +133,9 @@ module Axiom
123
133
  # @return [undefined]
124
134
  #
125
135
  # @api public
126
- def initialize(attributes, options)
127
- @attributes = freeze_object(attributes)
128
- @attribute_for = Hash[@attributes.map(&:name).zip(@attributes)]
136
+ def initialize(attributes, options = EMPTY_HASH)
137
+ @to_ary = self.class.freezer.call(attributes)
138
+ @attribute_for = Hash[@to_ary.map(&:name).zip(@to_ary)]
129
139
  @keys = coerce_keys(options.fetch(:keys, EMPTY_ARRAY))
130
140
  end
131
141
 
@@ -160,9 +170,9 @@ module Axiom
160
170
  # the attribute when the name is known
161
171
  #
162
172
  # @api public
163
- def call(name)
173
+ def fetch(name)
164
174
  @attribute_for.fetch(Attribute.name_from(name)) do |attribute_name|
165
- raise(
175
+ fail(
166
176
  UnknownAttributeError,
167
177
  "the attribute #{attribute_name} is unknown"
168
178
  )
@@ -220,10 +230,8 @@ module Axiom
220
230
  #
221
231
  # @api public
222
232
  def rename(aliases)
223
- new(
224
- map { |attribute| aliases[attribute] },
225
- keys: keys.rename(aliases)
226
- )
233
+ aliases = Algebra::Rename::Aliases.coerce(self, aliases)
234
+ new(map(&aliases.method(:[])), keys: keys.rename(aliases))
227
235
  end
228
236
 
229
237
  # Return the intersection of the header with another header
@@ -296,16 +304,13 @@ module Axiom
296
304
  Evaluator::Context.new(self, &block)
297
305
  end
298
306
 
299
- # Convert the Header into an Array
307
+ # The number of attributes
300
308
  #
301
- # @example
302
- # array = header.to_ary
303
- #
304
- # @return [Array]
309
+ # @return [Integer]
305
310
  #
306
311
  # @api public
307
- def to_ary
308
- @attributes
312
+ def size
313
+ to_ary.size
309
314
  end
310
315
 
311
316
  # Test if there are no attributes
@@ -352,9 +357,7 @@ module Axiom
352
357
  #
353
358
  # @api private
354
359
  def coerce(*args)
355
- self.class.coerce(*args) do |attribute|
356
- @attribute_for[attribute]
357
- end
360
+ self.class.coerce(*args, &@attribute_for.method(:[]))
358
361
  end
359
362
 
360
363
  # Represent an empty set of attributes