stupidedi 1.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 (500) hide show
  1. data/README.md +215 -0
  2. data/Rakefile +108 -0
  3. data/bin/edi-ed +71 -0
  4. data/bin/edi-pp +81 -0
  5. data/doc/Defining.md +0 -0
  6. data/doc/Generating.md +321 -0
  7. data/doc/LICENSE.md +0 -0
  8. data/doc/Navigating.md +645 -0
  9. data/doc/Parsing.md +0 -0
  10. data/doc/Serializing.md +7 -0
  11. data/doc/Tokenizing.md +0 -0
  12. data/doc/Validating.md +0 -0
  13. data/doc/design/Parser.md +0 -0
  14. data/doc/design/Reader.md +0 -0
  15. data/lib/ruby/array.rb +164 -0
  16. data/lib/ruby/blank.rb +67 -0
  17. data/lib/ruby/enumerable.rb +35 -0
  18. data/lib/ruby/exception.rb +33 -0
  19. data/lib/ruby/hash.rb +4 -0
  20. data/lib/ruby/instance_exec.rb +26 -0
  21. data/lib/ruby/module.rb +79 -0
  22. data/lib/ruby/object.rb +63 -0
  23. data/lib/ruby/string.rb +73 -0
  24. data/lib/ruby/symbol.rb +24 -0
  25. data/lib/ruby/to_d.rb +81 -0
  26. data/lib/ruby/to_date.rb +33 -0
  27. data/lib/ruby/to_time.rb +24 -0
  28. data/lib/ruby/try.rb +43 -0
  29. data/lib/stupidedi/blank_slate.rb +11 -0
  30. data/lib/stupidedi/builder/builder_dsl.rb +281 -0
  31. data/lib/stupidedi/builder/constraint_table.rb +418 -0
  32. data/lib/stupidedi/builder/generation.rb +112 -0
  33. data/lib/stupidedi/builder/instruction.rb +102 -0
  34. data/lib/stupidedi/builder/instruction_table.rb +204 -0
  35. data/lib/stupidedi/builder/navigation.rb +655 -0
  36. data/lib/stupidedi/builder/state_machine.rb +55 -0
  37. data/lib/stupidedi/builder/states/abstract_state.rb +332 -0
  38. data/lib/stupidedi/builder/states/failure_state.rb +69 -0
  39. data/lib/stupidedi/builder/states/functional_group_state.rb +97 -0
  40. data/lib/stupidedi/builder/states/initial_state.rb +63 -0
  41. data/lib/stupidedi/builder/states/interchange_state.rb +94 -0
  42. data/lib/stupidedi/builder/states/loop_state.rb +79 -0
  43. data/lib/stupidedi/builder/states/table_state.rb +96 -0
  44. data/lib/stupidedi/builder/states/transaction_set_state.rb +112 -0
  45. data/lib/stupidedi/builder/states/transmission_state.rb +59 -0
  46. data/lib/stupidedi/builder/tokenization.rb +196 -0
  47. data/lib/stupidedi/builder.rb +23 -0
  48. data/lib/stupidedi/color.rb +93 -0
  49. data/lib/stupidedi/config/code_list_config.rb +42 -0
  50. data/lib/stupidedi/config/editor_config.rb +51 -0
  51. data/lib/stupidedi/config/functional_group_config.rb +62 -0
  52. data/lib/stupidedi/config/interchange_config.rb +79 -0
  53. data/lib/stupidedi/config/transaction_set_config.rb +91 -0
  54. data/lib/stupidedi/config.rb +101 -0
  55. data/lib/stupidedi/editor/00501.rb +341 -0
  56. data/lib/stupidedi/editor/005010/N2.rb +0 -0
  57. data/lib/stupidedi/editor/005010/N3.rb +0 -0
  58. data/lib/stupidedi/editor/005010/N4.rb +63 -0
  59. data/lib/stupidedi/editor/005010/NM1.rb +0 -0
  60. data/lib/stupidedi/editor/005010.rb +469 -0
  61. data/lib/stupidedi/editor/X222-HC837.rb +195 -0
  62. data/lib/stupidedi/editor/abstract_ed.rb +36 -0
  63. data/lib/stupidedi/editor/claim_ack.rb +9 -0
  64. data/lib/stupidedi/editor/implementation_ack.rb +213 -0
  65. data/lib/stupidedi/editor/interchange_ack.rb +9 -0
  66. data/lib/stupidedi/editor/result.rb +100 -0
  67. data/lib/stupidedi/editor/result_set.rb +69 -0
  68. data/lib/stupidedi/editor/transaction_set_ed.rb +275 -0
  69. data/lib/stupidedi/editor/transmission_ed.rb +90 -0
  70. data/lib/stupidedi/editor.rb +37 -0
  71. data/lib/stupidedi/either.rb +287 -0
  72. data/lib/stupidedi/exceptions/invalid_element_error.rb +8 -0
  73. data/lib/stupidedi/exceptions/invalid_schema_error.rb +8 -0
  74. data/lib/stupidedi/exceptions/output_error.rb +8 -0
  75. data/lib/stupidedi/exceptions/parse_error.rb +8 -0
  76. data/lib/stupidedi/exceptions/stupidedi_error.rb +8 -0
  77. data/lib/stupidedi/exceptions/tokenize_error.rb +8 -0
  78. data/lib/stupidedi/exceptions/zipper_error.rb +8 -0
  79. data/lib/stupidedi/exceptions.rb +11 -0
  80. data/lib/stupidedi/guides/005010/X214-HN277.rb +409 -0
  81. data/lib/stupidedi/guides/005010/X221-HP835.rb +613 -0
  82. data/lib/stupidedi/guides/005010/X221A1-HP835.rb +613 -0
  83. data/lib/stupidedi/guides/005010/X222-HC837P.rb +2291 -0
  84. data/lib/stupidedi/guides/005010/X222A1-HC837P.rb +2297 -0
  85. data/lib/stupidedi/guides/005010/X231-FA999.rb +123 -0
  86. data/lib/stupidedi/guides/005010/X231A1-FA999.rb +119 -0
  87. data/lib/stupidedi/guides/005010/element_reqs.rb +38 -0
  88. data/lib/stupidedi/guides/005010/guide_builder.rb +180 -0
  89. data/lib/stupidedi/guides/005010/segment_reqs.rb +32 -0
  90. data/lib/stupidedi/guides/005010.rb +64 -0
  91. data/lib/stupidedi/guides.rb +5 -0
  92. data/lib/stupidedi/inspect.rb +26 -0
  93. data/lib/stupidedi/reader/input/abstract_input.rb +133 -0
  94. data/lib/stupidedi/reader/input/delegated_input.rb +111 -0
  95. data/lib/stupidedi/reader/input/file_input.rb +155 -0
  96. data/lib/stupidedi/reader/input.rb +30 -0
  97. data/lib/stupidedi/reader/position.rb +69 -0
  98. data/lib/stupidedi/reader/result.rb +168 -0
  99. data/lib/stupidedi/reader/segment_dict.rb +175 -0
  100. data/lib/stupidedi/reader/separators.rb +85 -0
  101. data/lib/stupidedi/reader/stream_reader.rb +172 -0
  102. data/lib/stupidedi/reader/token_reader.rb +466 -0
  103. data/lib/stupidedi/reader/tokens/component_element_tok.rb +56 -0
  104. data/lib/stupidedi/reader/tokens/composite_element_tok.rb +64 -0
  105. data/lib/stupidedi/reader/tokens/repeated_element_tok.rb +64 -0
  106. data/lib/stupidedi/reader/tokens/segment_tok.rb +51 -0
  107. data/lib/stupidedi/reader/tokens/simple_element_tok.rb +63 -0
  108. data/lib/stupidedi/reader.rb +121 -0
  109. data/lib/stupidedi/schema/abstract_def.rb +74 -0
  110. data/lib/stupidedi/schema/abstract_use.rb +73 -0
  111. data/lib/stupidedi/schema/code_list.rb +94 -0
  112. data/lib/stupidedi/schema/element_def.rb +173 -0
  113. data/lib/stupidedi/schema/element_req.rb +56 -0
  114. data/lib/stupidedi/schema/element_use.rb +251 -0
  115. data/lib/stupidedi/schema/functional_group_def.rb +114 -0
  116. data/lib/stupidedi/schema/interchange_def.rb +93 -0
  117. data/lib/stupidedi/schema/loop_def.rb +152 -0
  118. data/lib/stupidedi/schema/repeat_count.rb +85 -0
  119. data/lib/stupidedi/schema/segment_def.rb +108 -0
  120. data/lib/stupidedi/schema/segment_req.rb +43 -0
  121. data/lib/stupidedi/schema/segment_use.rb +98 -0
  122. data/lib/stupidedi/schema/syntax_note.rb +63 -0
  123. data/lib/stupidedi/schema/table_def.rb +139 -0
  124. data/lib/stupidedi/schema/transaction_set_def.rb +88 -0
  125. data/lib/stupidedi/schema.rb +28 -0
  126. data/lib/stupidedi/sets/absolute_set.rb +297 -0
  127. data/lib/stupidedi/sets/abstract_set.rb +174 -0
  128. data/lib/stupidedi/sets/null_set.rb +125 -0
  129. data/lib/stupidedi/sets/relative_complement.rb +137 -0
  130. data/lib/stupidedi/sets/relative_set.rb +269 -0
  131. data/lib/stupidedi/sets/universal_set.rb +104 -0
  132. data/lib/stupidedi/sets.rb +57 -0
  133. data/lib/stupidedi/tail_call.rb +109 -0
  134. data/lib/stupidedi/thread_local.rb +174 -0
  135. data/lib/stupidedi/values/abstract_element_val.rb +19 -0
  136. data/lib/stupidedi/values/abstract_val.rb +130 -0
  137. data/lib/stupidedi/values/composite_element_val.rb +95 -0
  138. data/lib/stupidedi/values/functional_group_val.rb +102 -0
  139. data/lib/stupidedi/values/interchange_val.rb +86 -0
  140. data/lib/stupidedi/values/invalid_envelope_val.rb +61 -0
  141. data/lib/stupidedi/values/invalid_segment_val.rb +78 -0
  142. data/lib/stupidedi/values/loop_val.rb +70 -0
  143. data/lib/stupidedi/values/repeated_element_val.rb +105 -0
  144. data/lib/stupidedi/values/segment_val.rb +104 -0
  145. data/lib/stupidedi/values/segment_val_group.rb +20 -0
  146. data/lib/stupidedi/values/simple_element_val.rb +80 -0
  147. data/lib/stupidedi/values/table_val.rb +66 -0
  148. data/lib/stupidedi/values/transaction_set_val.rb +66 -0
  149. data/lib/stupidedi/values/transmission_val.rb +52 -0
  150. data/lib/stupidedi/values.rb +21 -0
  151. data/lib/stupidedi/version.rb +3 -0
  152. data/lib/stupidedi/versions/functional_groups/004010/element_defs.rb +54 -0
  153. data/lib/stupidedi/versions/functional_groups/004010/element_reqs.rb +18 -0
  154. data/lib/stupidedi/versions/functional_groups/004010/element_types/date_val.rb +527 -0
  155. data/lib/stupidedi/versions/functional_groups/004010/element_types/fixnum_val.rb +335 -0
  156. data/lib/stupidedi/versions/functional_groups/004010/element_types/float_val.rb +299 -0
  157. data/lib/stupidedi/versions/functional_groups/004010/element_types/identifier_val.rb +287 -0
  158. data/lib/stupidedi/versions/functional_groups/004010/element_types/string_val.rb +338 -0
  159. data/lib/stupidedi/versions/functional_groups/004010/element_types/time_val.rb +309 -0
  160. data/lib/stupidedi/versions/functional_groups/004010/element_types.rb +124 -0
  161. data/lib/stupidedi/versions/functional_groups/004010/functional_group_def.rb +30 -0
  162. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/GE.rb +20 -0
  163. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/GS.rb +27 -0
  164. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/SE.rb +20 -0
  165. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/ST.rb +20 -0
  166. data/lib/stupidedi/versions/functional_groups/004010/segment_defs.rb +23 -0
  167. data/lib/stupidedi/versions/functional_groups/004010/segment_reqs.rb +18 -0
  168. data/lib/stupidedi/versions/functional_groups/004010/syntax_notes.rb +174 -0
  169. data/lib/stupidedi/versions/functional_groups/004010.rb +38 -0
  170. data/lib/stupidedi/versions/functional_groups/005010/element_defs.rb +1405 -0
  171. data/lib/stupidedi/versions/functional_groups/005010/element_reqs.rb +18 -0
  172. data/lib/stupidedi/versions/functional_groups/005010/element_types/date_val.rb +577 -0
  173. data/lib/stupidedi/versions/functional_groups/005010/element_types/fixnum_val.rb +322 -0
  174. data/lib/stupidedi/versions/functional_groups/005010/element_types/float_val.rb +354 -0
  175. data/lib/stupidedi/versions/functional_groups/005010/element_types/identifier_val.rb +368 -0
  176. data/lib/stupidedi/versions/functional_groups/005010/element_types/operators.rb +117 -0
  177. data/lib/stupidedi/versions/functional_groups/005010/element_types/string_val.rb +398 -0
  178. data/lib/stupidedi/versions/functional_groups/005010/element_types/time_val.rb +327 -0
  179. data/lib/stupidedi/versions/functional_groups/005010/element_types.rb +132 -0
  180. data/lib/stupidedi/versions/functional_groups/005010/functional_group_def.rb +30 -0
  181. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK1.rb +21 -0
  182. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK2.rb +21 -0
  183. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK9.rb +28 -0
  184. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AMT.rb +21 -0
  185. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/BHT.rb +24 -0
  186. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/BPR.rb +49 -0
  187. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CAS.rb +56 -0
  188. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CL1.rb +22 -0
  189. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CLM.rb +41 -0
  190. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CLP.rb +34 -0
  191. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CN1.rb +24 -0
  192. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR1.rb +32 -0
  193. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR2.rb +35 -0
  194. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR3.rb +25 -0
  195. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CRC.rb +26 -0
  196. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CTP.rb +36 -0
  197. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CTX.rb +24 -0
  198. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CUR.rb +57 -0
  199. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DMG.rb +34 -0
  200. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DN1.rb +22 -0
  201. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DN2.rb +24 -0
  202. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DTM.rb +24 -0
  203. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DTP.rb +21 -0
  204. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/FRM.rb +25 -0
  205. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/GE.rb +20 -0
  206. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/GS.rb +27 -0
  207. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HCP.rb +39 -0
  208. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HI.rb +31 -0
  209. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HL.rb +22 -0
  210. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK3.rb +22 -0
  211. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK4.rb +22 -0
  212. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK5.rb +24 -0
  213. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/K3.rb +21 -0
  214. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LIN.rb +69 -0
  215. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LQ.rb +22 -0
  216. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LX.rb +19 -0
  217. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MEA.rb +39 -0
  218. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MIA.rb +45 -0
  219. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MOA.rb +28 -0
  220. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N1.rb +24 -0
  221. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N2.rb +20 -0
  222. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N3.rb +20 -0
  223. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N4.rb +30 -0
  224. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/NM1.rb +35 -0
  225. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/NTE.rb +20 -0
  226. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/OI.rb +24 -0
  227. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PAT.rb +31 -0
  228. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PER.rb +32 -0
  229. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PLB.rb +40 -0
  230. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PRV.rb +26 -0
  231. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PS1.rb +21 -0
  232. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PWK.rb +30 -0
  233. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/QTY.rb +25 -0
  234. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/RDM.rb +23 -0
  235. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/REF.rb +23 -0
  236. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SBR.rb +28 -0
  237. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SE.rb +20 -0
  238. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/ST.rb +21 -0
  239. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/STC.rb +30 -0
  240. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV1.rb +44 -0
  241. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV2.rb +29 -0
  242. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV3.rb +30 -0
  243. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV5.rb +29 -0
  244. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SVC.rb +26 -0
  245. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SVD.rb +24 -0
  246. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TOO.rb +21 -0
  247. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TRN.rb +22 -0
  248. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TS2.rb +40 -0
  249. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TS3.rb +45 -0
  250. data/lib/stupidedi/versions/functional_groups/005010/segment_defs.rb +227 -0
  251. data/lib/stupidedi/versions/functional_groups/005010/segment_reqs.rb +18 -0
  252. data/lib/stupidedi/versions/functional_groups/005010/syntax_notes.rb +165 -0
  253. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/FA999.rb +38 -0
  254. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HB271.rb +85 -0
  255. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HC837.rb +163 -0
  256. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HI278.rb +64 -0
  257. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HN277.rb +74 -0
  258. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HP835.rb +68 -0
  259. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HR276.rb +57 -0
  260. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HS270.rb +53 -0
  261. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/RA820.rb +240 -0
  262. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs.rb +68 -0
  263. data/lib/stupidedi/versions/functional_groups/005010.rb +38 -0
  264. data/lib/stupidedi/versions/functional_groups.rb +8 -0
  265. data/lib/stupidedi/versions/interchanges/00401/element_defs.rb +224 -0
  266. data/lib/stupidedi/versions/interchanges/00401/interchange_def.rb +45 -0
  267. data/lib/stupidedi/versions/interchanges/00401/segment_defs/IEA.rb +20 -0
  268. data/lib/stupidedi/versions/interchanges/00401/segment_defs/ISA.rb +34 -0
  269. data/lib/stupidedi/versions/interchanges/00401/segment_defs/TA1.rb +23 -0
  270. data/lib/stupidedi/versions/interchanges/00401/segment_defs.rb +28 -0
  271. data/lib/stupidedi/versions/interchanges/00401.rb +23 -0
  272. data/lib/stupidedi/versions/interchanges/00501/element_defs.rb +269 -0
  273. data/lib/stupidedi/versions/interchanges/00501/interchange_def.rb +47 -0
  274. data/lib/stupidedi/versions/interchanges/00501/segment_defs/IEA.rb +20 -0
  275. data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISA.rb +34 -0
  276. data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISB.rb +18 -0
  277. data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISE.rb +18 -0
  278. data/lib/stupidedi/versions/interchanges/00501/segment_defs/TA1.rb +23 -0
  279. data/lib/stupidedi/versions/interchanges/00501/segment_defs/TA3.rb +18 -0
  280. data/lib/stupidedi/versions/interchanges/00501/segment_defs.rb +37 -0
  281. data/lib/stupidedi/versions/interchanges/00501.rb +23 -0
  282. data/lib/stupidedi/versions/interchanges.rb +8 -0
  283. data/lib/stupidedi/versions.rb +6 -0
  284. data/lib/stupidedi/writer/claredi.rb +142 -0
  285. data/lib/stupidedi/writer/default.rb +124 -0
  286. data/lib/stupidedi/writer.rb +6 -0
  287. data/lib/stupidedi/zipper/abstract_cursor.rb +351 -0
  288. data/lib/stupidedi/zipper/dangling_cursor.rb +103 -0
  289. data/lib/stupidedi/zipper/edited_cursor.rb +157 -0
  290. data/lib/stupidedi/zipper/memoized_cursor.rb +131 -0
  291. data/lib/stupidedi/zipper/path.rb +124 -0
  292. data/lib/stupidedi/zipper/root_cursor.rb +120 -0
  293. data/lib/stupidedi/zipper.rb +25 -0
  294. data/lib/stupidedi.rb +66 -0
  295. data/spec/examples/integration/generating.example +551 -0
  296. data/spec/examples/integration/navigating.example +214 -0
  297. data/spec/examples/integration/parsing.example +445 -0
  298. data/spec/examples/ruby/array.example +476 -0
  299. data/spec/examples/ruby/blank.example +62 -0
  300. data/spec/examples/ruby/count.example +68 -0
  301. data/spec/examples/ruby/object.example +99 -0
  302. data/spec/examples/ruby/string.example +111 -0
  303. data/spec/examples/ruby/symbol.example +117 -0
  304. data/spec/examples/ruby/to_d.example +90 -0
  305. data/spec/examples/ruby/try.example +50 -0
  306. data/spec/examples/stupidedi/either.example +375 -0
  307. data/spec/examples/stupidedi/reader/failure.example +68 -0
  308. data/spec/examples/stupidedi/reader/input/delegated_input.example +292 -0
  309. data/spec/examples/stupidedi/reader/separators.example +73 -0
  310. data/spec/examples/stupidedi/reader/stream_reader.example +48 -0
  311. data/spec/examples/stupidedi/reader/success.example +34 -0
  312. data/spec/examples/stupidedi/reader/token_reader.example +775 -0
  313. data/spec/examples/stupidedi/reader.example +168 -0
  314. data/spec/examples/stupidedi/sets/absolute_set.example +1577 -0
  315. data/spec/examples/stupidedi/sets/null_set.example +2 -0
  316. data/spec/examples/stupidedi/sets/relative_set.example +2 -0
  317. data/spec/examples/stupidedi/sets/universal_set.example +1 -0
  318. data/spec/examples/stupidedi/versions/005010/element_types/an.example +201 -0
  319. data/spec/examples/stupidedi/versions/005010/element_types/dt.example +258 -0
  320. data/spec/examples/stupidedi/versions/005010/element_types/id.example +192 -0
  321. data/spec/examples/stupidedi/versions/005010/element_types/nn.example +177 -0
  322. data/spec/examples/stupidedi/versions/005010/element_types/r.example +178 -0
  323. data/spec/examples/stupidedi/versions/005010/element_types/tm.example +2 -0
  324. data/spec/examples/stupidedi/zipper/abstract_cursor.example +417 -0
  325. data/spec/examples/stupidedi/zipper.example +9 -0
  326. data/spec/fixtures/X186-AG824/1-bad.txt +21 -0
  327. data/spec/fixtures/X186-AG824/1-good.txt +17 -0
  328. data/spec/fixtures/X186-AG824/2-bad.txt +26 -0
  329. data/spec/fixtures/X186-AG824/2-good.txt +21 -0
  330. data/spec/fixtures/X186-AG824/3-bad.txt +87 -0
  331. data/spec/fixtures/X186-AG824/3-good.txt +61 -0
  332. data/spec/fixtures/X212-HN277/1-bad.txt +54 -0
  333. data/spec/fixtures/X212-HN277/1-good.txt +46 -0
  334. data/spec/fixtures/X212-HN277/2-bad.txt +37 -0
  335. data/spec/fixtures/X212-HN277/2-good.txt +29 -0
  336. data/spec/fixtures/X212-HN277/3-bad.txt +22 -0
  337. data/spec/fixtures/X212-HN277/3-good.txt +17 -0
  338. data/spec/fixtures/X212-HN277/4-bad.txt +30 -0
  339. data/spec/fixtures/X212-HN277/4-good.txt +24 -0
  340. data/spec/fixtures/X212-HR276/1-bad.txt +53 -0
  341. data/spec/fixtures/X212-HR276/1-good.txt +46 -0
  342. data/spec/fixtures/X212-HR276/2-bad.txt +45 -0
  343. data/spec/fixtures/X212-HR276/2-good.txt +38 -0
  344. data/spec/fixtures/X212-HR276/3-bad.txt +32 -0
  345. data/spec/fixtures/X212-HR276/3-good.txt +26 -0
  346. data/spec/fixtures/X212-HR276/4-bad.txt +32 -0
  347. data/spec/fixtures/X212-HR276/4-good.txt +26 -0
  348. data/spec/fixtures/X214-HN277/1-bad.txt +58 -0
  349. data/spec/fixtures/X214-HN277/1-good.txt +47 -0
  350. data/spec/fixtures/X214-HN277/2-bad.txt +34 -0
  351. data/spec/fixtures/X214-HN277/2-good.txt +22 -0
  352. data/spec/fixtures/X214-HN277/3-bad.txt +64 -0
  353. data/spec/fixtures/X214-HN277/3-good.txt +54 -0
  354. data/spec/fixtures/X214-HN277/4-bad.txt +77 -0
  355. data/spec/fixtures/X214-HN277/4-good.txt +63 -0
  356. data/spec/fixtures/X216-HI278/1-bad.txt +42 -0
  357. data/spec/fixtures/X216-HI278/1-good.txt +27 -0
  358. data/spec/fixtures/X216-HI278/2-bad.txt +43 -0
  359. data/spec/fixtures/X216-HI278/2-good.txt +29 -0
  360. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-1.txt +24 -0
  361. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-1_Clean.txt +20 -0
  362. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-2.txt +46 -0
  363. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-2_Clean.txt +30 -0
  364. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-3.txt +38 -0
  365. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-3_Clean.txt +24 -0
  366. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4a.txt +39 -0
  367. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4a_Clean.txt +24 -0
  368. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4b.txt +43 -0
  369. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4b_Clean.txt +25 -0
  370. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-5.txt +63 -0
  371. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-5_Clean.txt +41 -0
  372. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-6.txt +36 -0
  373. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-6_Clean.txt +20 -0
  374. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-1r.txt +34 -0
  375. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-1r_Clean.txt +23 -0
  376. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-2r.txt +46 -0
  377. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-2r_Clean.txt +31 -0
  378. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-3r.txt +44 -0
  379. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-3r_Clean.txt +26 -0
  380. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-4ar_Clean.txt +28 -0
  381. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-4br_Clean.txt +35 -0
  382. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-5r.txt +60 -0
  383. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-5r_Clean.txt +42 -0
  384. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-6r.txt +40 -0
  385. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-6r_Clean.txt +24 -0
  386. data/spec/fixtures/X218-RA820/1-bad.txt +31 -0
  387. data/spec/fixtures/X218-RA820/1-good.txt +25 -0
  388. data/spec/fixtures/X218-RA820/2-bad.txt +37 -0
  389. data/spec/fixtures/X218-RA820/2-good.txt +29 -0
  390. data/spec/fixtures/X218-RA820/3-bad.txt +29 -0
  391. data/spec/fixtures/X218-RA820/3-good.txt +23 -0
  392. data/spec/fixtures/X218-RA820/4-bad.txt +36 -0
  393. data/spec/fixtures/X218-RA820/4-good.txt +27 -0
  394. data/spec/fixtures/X220-BE834/1-bad.txt +35 -0
  395. data/spec/fixtures/X220-BE834/1-good.txt +29 -0
  396. data/spec/fixtures/X220-BE834/10-bad.txt +26 -0
  397. data/spec/fixtures/X220-BE834/10-good.txt +19 -0
  398. data/spec/fixtures/X220-BE834/2-bad.txt +31 -0
  399. data/spec/fixtures/X220-BE834/2-good.txt +23 -0
  400. data/spec/fixtures/X220-BE834/3-bad.txt +36 -0
  401. data/spec/fixtures/X220-BE834/3-good.txt +26 -0
  402. data/spec/fixtures/X220-BE834/4-bad.txt +27 -0
  403. data/spec/fixtures/X220-BE834/4-good.txt +21 -0
  404. data/spec/fixtures/X220-BE834/5-bad.txt +26 -0
  405. data/spec/fixtures/X220-BE834/5-good.txt +17 -0
  406. data/spec/fixtures/X220-BE834/6-bad.txt +25 -0
  407. data/spec/fixtures/X220-BE834/6-good.txt +20 -0
  408. data/spec/fixtures/X220-BE834/7-bad.txt +25 -0
  409. data/spec/fixtures/X220-BE834/7-good.txt +20 -0
  410. data/spec/fixtures/X220-BE834/8-bad.txt +25 -0
  411. data/spec/fixtures/X220-BE834/8-good.txt +20 -0
  412. data/spec/fixtures/X220-BE834/9-bad.txt +27 -0
  413. data/spec/fixtures/X220-BE834/9-good.txt +21 -0
  414. data/spec/fixtures/X221-HP835/1-bad.txt +58 -0
  415. data/spec/fixtures/X221-HP835/1-good.txt +40 -0
  416. data/spec/fixtures/X221-HP835/2-bad.txt +51 -0
  417. data/spec/fixtures/X221-HP835/2-good.txt +40 -0
  418. data/spec/fixtures/X221-HP835/3a-bad.txt +78 -0
  419. data/spec/fixtures/X221-HP835/3a-good.txt +49 -0
  420. data/spec/fixtures/X221-HP835/3b-bad.txt +60 -0
  421. data/spec/fixtures/X221-HP835/3b-good.txt +32 -0
  422. data/spec/fixtures/X221-HP835/3c-bad.txt +55 -0
  423. data/spec/fixtures/X221-HP835/3c-good.txt +34 -0
  424. data/spec/fixtures/X222-HC837/1-bad.txt +60 -0
  425. data/spec/fixtures/X222-HC837/1-good.txt +53 -0
  426. data/spec/fixtures/X222-HC837/10a-bad.txt +52 -0
  427. data/spec/fixtures/X222-HC837/10a-good.txt +40 -0
  428. data/spec/fixtures/X222-HC837/10b-bad.txt +99 -0
  429. data/spec/fixtures/X222-HC837/10b-good.txt +80 -0
  430. data/spec/fixtures/X222-HC837/10c-bad.txt +105 -0
  431. data/spec/fixtures/X222-HC837/10c-good.txt +80 -0
  432. data/spec/fixtures/X222-HC837/11-bad.txt +69 -0
  433. data/spec/fixtures/X222-HC837/11-good.txt +45 -0
  434. data/spec/fixtures/X222-HC837/12-bad.txt +73 -0
  435. data/spec/fixtures/X222-HC837/12-good.txt +51 -0
  436. data/spec/fixtures/X222-HC837/13-bad.txt +64 -0
  437. data/spec/fixtures/X222-HC837/13-good.txt +46 -0
  438. data/spec/fixtures/X222-HC837/3a-bad.txt +83 -0
  439. data/spec/fixtures/X222-HC837/3a-good.txt +59 -0
  440. data/spec/fixtures/X222-HC837/3b-bad.txt +97 -0
  441. data/spec/fixtures/X222-HC837/3b-good.txt +70 -0
  442. data/spec/fixtures/X222-HC837/3c-bad.txt +95 -0
  443. data/spec/fixtures/X222-HC837/3c-good.txt +74 -0
  444. data/spec/fixtures/X222-HC837/4-bad.txt +67 -0
  445. data/spec/fixtures/X222-HC837/4-good.txt +48 -0
  446. data/spec/fixtures/X222-HC837/5-bad.txt +73 -0
  447. data/spec/fixtures/X222-HC837/5-good.txt +60 -0
  448. data/spec/fixtures/X222-HC837/6-bad.txt +50 -0
  449. data/spec/fixtures/X222-HC837/6-good.txt +39 -0
  450. data/spec/fixtures/X222-HC837/7-bad.txt +93 -0
  451. data/spec/fixtures/X222-HC837/7-good.txt +78 -0
  452. data/spec/fixtures/X222-HC837/8-bad.txt +64 -0
  453. data/spec/fixtures/X222-HC837/8-good.txt +52 -0
  454. data/spec/fixtures/X222-HC837/9-bad.txt +56 -0
  455. data/spec/fixtures/X222-HC837/9-good.txt +38 -0
  456. data/spec/fixtures/X223-HC837/1-bad.txt +66 -0
  457. data/spec/fixtures/X223-HC837/1-good.txt +53 -0
  458. data/spec/fixtures/X223-HC837/2-bad.txt +69 -0
  459. data/spec/fixtures/X223-HC837/2-good.txt +60 -0
  460. data/spec/fixtures/X223-HC837/3-bad.txt +89 -0
  461. data/spec/fixtures/X223-HC837/3-good.txt +61 -0
  462. data/spec/fixtures/X223-HC837/4-bad.txt +60 -0
  463. data/spec/fixtures/X223-HC837/4-good.txt +40 -0
  464. data/spec/fixtures/X223-HC837/5-bad.txt +75 -0
  465. data/spec/fixtures/X223-HC837/5-good.txt +58 -0
  466. data/spec/fixtures/X224-HC837/1-bad.txt +54 -0
  467. data/spec/fixtures/X224-HC837/1-good.txt +44 -0
  468. data/spec/fixtures/X224-HC837/2a-bad.txt +52 -0
  469. data/spec/fixtures/X224-HC837/2a-good.txt +42 -0
  470. data/spec/fixtures/X224-HC837/2b-bad.txt +67 -0
  471. data/spec/fixtures/X224-HC837/2b-good.txt +52 -0
  472. data/spec/fixtures/X224-HC837/3-bad.txt +67 -0
  473. data/spec/fixtures/X224-HC837/3-good.txt +51 -0
  474. data/spec/fixtures/X224-HC837/4-bad.txt +49 -0
  475. data/spec/fixtures/X224-HC837/4-good.txt +40 -0
  476. data/spec/fixtures/X230-FA997/1-bad.txt +19 -0
  477. data/spec/fixtures/X230-FA997/1-good.txt +16 -0
  478. data/spec/fixtures/X231-FA999/1-bad.txt +20 -0
  479. data/spec/fixtures/X231-FA999/1-good.txt +20 -0
  480. data/spec/fixtures/X279-HB271/1-bad.txt +36 -0
  481. data/spec/fixtures/X279-HB271/1-good.txt +30 -0
  482. data/spec/fixtures/X279-HB271/2-bad.txt +22 -0
  483. data/spec/fixtures/X279-HB271/2-good.txt +16 -0
  484. data/spec/fixtures/X279-HB271/3-bad.txt +44 -0
  485. data/spec/fixtures/X279-HB271/3-good.txt +36 -0
  486. data/spec/fixtures/X279-HS270/1-bad.txt +29 -0
  487. data/spec/fixtures/X279-HS270/1-good.txt +23 -0
  488. data/spec/fixtures/X279-HS270/2-bad.txt +32 -0
  489. data/spec/fixtures/X279-HS270/2-good.txt +25 -0
  490. data/spec/spec_helper.rb +34 -0
  491. data/spec/support/fixtures.rb +26 -0
  492. data/spec/support/matchers/either_matchers.rb +26 -0
  493. data/spec/support/matchers/navigation_matchers.rb +247 -0
  494. data/spec/support/node.rb +41 -0
  495. data/spec/support/quickcheck/characters.rb +28 -0
  496. data/spec/support/quickcheck/property.rb +105 -0
  497. data/spec/support/quickcheck/serialized_edi.rb +399 -0
  498. data/spec/support/quickcheck.rb +302 -0
  499. data/spec/support/rcov.rb +34 -0
  500. metadata +577 -0
@@ -0,0 +1,1577 @@
1
+ # encoding: UTF-8
2
+ require "spec_helper"
3
+
4
+ describe Stupidedi::Sets::AbsoluteSet do
5
+ include QuickCheck::Macro
6
+
7
+ def mksubset(universe)
8
+ universe.copy(:mask => rand(2**universe.size))
9
+ end
10
+
11
+ def mksingleton(universe)
12
+ universe.copy(:mask => (2**(rand(universe.size) + 1) >> 1))
13
+ end
14
+
15
+ let(:items) { %w(a b c d e f g h i j k l m n o p q r s t u v w x y z) }
16
+
17
+ let(:universe) { Stupidedi::Sets.absolute(items) }
18
+ let(:single) { universe.copy(:mask => 0b00000000000000000000000001) }
19
+ let(:subset) { universe.copy(:mask => 0b10101010101010101010101010) }
20
+ let(:null) { universe.copy(:mask => 0b00000000000000000000000000) }
21
+
22
+ describe "#to_a" do
23
+ specify "|A| == |A.to_a|" do
24
+ null.size.should == null.to_a.size
25
+ single.size.should == single.to_a.size
26
+ subset.size.should == subset.to_a.size
27
+ universe.size.should == universe.to_a.size
28
+ end
29
+
30
+ property("if x ∉ A then x ∉ A.to_a") do
31
+ a = mksubset(universe)
32
+ [a, a.to_a]
33
+ end.check do |a, to_a|
34
+ universe.each do |x|
35
+ unless a.include?(x)
36
+ to_a.should_not include(x)
37
+ end
38
+ end
39
+ end
40
+
41
+ property("if x ∈ A then x ∈ A.to_a") do
42
+ a = mksubset(universe)
43
+ [a, a.to_a]
44
+ end.check do |a, to_a|
45
+ universe.each do |x|
46
+ if a.include?(x)
47
+ to_a.should include(x)
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ describe "#first" do
54
+ property("{x}.first = x") do
55
+ x = choose(universe.to_a)
56
+ a = universe & [x]
57
+ [a, x]
58
+ end.check do |a, x|
59
+ a.first.should == x
60
+ end
61
+
62
+ property("A.first ∈ A") do
63
+ mksubset(universe)
64
+ end.check do |a|
65
+ a.should include(a.first)
66
+ end
67
+ end
68
+
69
+ describe "#map(&block)" do
70
+ specify "A.map{|a| a } = A" do
71
+ null.map{|a| a }.should == null
72
+ single.map{|a| a }.should == single
73
+ subset.map{|a| a }.should == subset
74
+ universe.map{|a| a }.should == universe
75
+ end
76
+
77
+ property("A.map{|a| a } = A") do
78
+ mksubset(universe)
79
+ end.check do |subset|
80
+ subset.map{|a| a }.should == subset
81
+ end
82
+
83
+ specify "A.map{|a| b } raises an error, given b ∉ U and A ≠ ∅" do
84
+ lambda { single.map{|a| "A" }}.should \
85
+ raise_error(/universe does not contain element/)
86
+
87
+ lambda { subset.map{|a| "A" }}.should \
88
+ raise_error(/universe does not contain element/)
89
+
90
+ lambda { universe.map{|a| "A" }}.should \
91
+ raise_error(/universe does not contain element/)
92
+ end
93
+
94
+ specify "A.map{|a| b } = {b}, given b ∈ U, A ≠ ∅" do
95
+ single.map{|a| "a" }.should == %w(a)
96
+ subset.map{|a| subset.first }.should == [subset.first]
97
+ universe.map{|a| "z" }.should == %w(z)
98
+ end
99
+
100
+ property("A.map{|a| b } = {b}, given b ∈ U, A ≠ ∅") do
101
+ [mksubset(universe), choose(universe.to_a)]
102
+ end.check do |subset, e|
103
+ subset.map{|a| e }.should == [e]
104
+ end
105
+ end
106
+
107
+ describe "#select(&block)" do
108
+ specify "A.select{|a| true } = A" do
109
+ null.select{|a| true }.should == null
110
+ single.select{|a| true }.should == single
111
+ subset.select{|a| true }.should == subset
112
+ universe.select{|a| true }.should == universe
113
+ end
114
+
115
+ property("A.select{|a| true } = A") do
116
+ mksubset(universe)
117
+ end.check do |subset|
118
+ subset.select{|a| true }.should == subset
119
+ end
120
+
121
+ specify "A.select{|a| false } = ∅" do
122
+ null.select{|a| false }.should == null
123
+ single.select{|a| false }.should == null
124
+ subset.select{|a| false }.should == null
125
+ universe.select{|a| false }.should == null
126
+ end
127
+
128
+ property("A.select{|a| false } = ∅") do
129
+ mksubset(universe)
130
+ end.check do |subset|
131
+ subset.select{|a| false }.should == null
132
+ end
133
+
134
+ specify "A.select{|a| a == b } = {b}, given b ∈ U, A ≠ ∅" do
135
+ single.select{|a| a == "a" }.should == %w(a)
136
+ subset.select{|a| a == subset.first }.should == [subset.first]
137
+ universe.select{|a| a == "a" }.should == %w(a)
138
+ end
139
+
140
+ property("A.select{|a| a == b } = {b}, given b ∈ U, A ≠ ∅") do
141
+ subset = mksubset(universe)
142
+ element = choose(subset.to_a)
143
+ [subset, element]
144
+ end.check do |subset, e|
145
+ subset.select{|a| a == e }.should == [e]
146
+ end
147
+ end
148
+
149
+ describe "#reject(&block)" do
150
+ specify "A.reject{|a| false } = A" do
151
+ null.reject{|a| false }.should == null
152
+ single.reject{|a| false }.should == single
153
+ subset.reject{|a| false }.should == subset
154
+ universe.reject{|a| false }.should == universe
155
+ end
156
+
157
+ property("A.reject{|a| false } = A") do
158
+ mksubset(universe)
159
+ end.check do |subset|
160
+ subset.reject{|a| false }.should == subset
161
+ end
162
+
163
+ specify "A.reject{|a| true } = ∅" do
164
+ null.reject{|a| true }.should == null
165
+ single.reject{|a| true }.should == null
166
+ subset.reject{|a| true }.should == null
167
+ universe.reject{|a| true }.should == null
168
+ end
169
+
170
+ property("A.reject{|a| true } = ∅") do
171
+ mksubset(universe)
172
+ end.check do |subset|
173
+ subset.reject{|a| true }.should == null
174
+ end
175
+
176
+ specify "A.reject{|a| a != b } = {b}, given b ∈ U, A ≠ ∅" do
177
+ single.reject{|a| a != "a" }.should == %w(a)
178
+ subset.reject{|a| a != subset.first }.should == [subset.first]
179
+ universe.reject{|a| a != "a" }.should == %w(a)
180
+ end
181
+
182
+ property("A.reject{|a| a != b } = {b}, given b ∈ U, A ≠ ∅") do
183
+ subset = mksubset(universe)
184
+ element = choose(subset.to_a)
185
+ [subset, element]
186
+ end.check do |subset, e|
187
+ subset.reject{|a| a != e }.should == [e]
188
+ end
189
+ end
190
+
191
+ describe "#include?(element)" do
192
+ specify "x ∉ ∅, for all x" do
193
+ null.should_not include("a")
194
+ null.should_not include("A")
195
+ end
196
+
197
+ specify "x ∉ A, for all x ∉ U" do
198
+ single.should_not include("A")
199
+ subset.should_not include("A")
200
+ universe.should_not include("A")
201
+ end
202
+
203
+ specify "x ∈ {x}, for all x" do
204
+ single.should include("a")
205
+ end
206
+
207
+ property("x ∈ {x}, for all x") do
208
+ mksingleton(universe)
209
+ end.check do |singleton|
210
+ singleton.should include(singleton.first)
211
+ end
212
+
213
+ property("x ∉ A, for all x ∈ ¬A") do
214
+ mksubset(universe)
215
+ end.check do |a|
216
+ (~a).each{|e| a.should_not include(e) }
217
+ end
218
+ end
219
+
220
+ describe "#finite?" do
221
+ it "is true" do
222
+ null.should be_finite
223
+ single.should be_finite
224
+ subset.should be_finite
225
+ universe.should be_finite
226
+ end
227
+ end
228
+
229
+ describe "#empty?" do
230
+ specify "∅.empty? is true" do
231
+ null.should be_empty
232
+ end
233
+
234
+ specify "{x}.empty? is false" do
235
+ single.should_not be_empty
236
+ end
237
+ end
238
+
239
+ describe "#size" do
240
+ specify "∅.size == 0" do
241
+ null.size == 0
242
+ end
243
+
244
+ specify "{x}.size == 1" do
245
+ single.size.should == 1
246
+ end
247
+ end
248
+
249
+ describe "#complement" do
250
+ specify "A ∩ ¬A = ∅" do
251
+ (null & ~null).should == null
252
+ (single & ~single).should == null
253
+ (subset & ~subset).should == null
254
+ (universe & ~universe).should == null
255
+ end
256
+
257
+ property("A ∩ ¬A = ∅") do
258
+ mksubset(universe)
259
+ end.check do |a|
260
+ (a & ~a).should == null
261
+ end
262
+
263
+ specify "A ∪ ¬A = U" do
264
+ (null | ~null).should == universe
265
+ (single | ~single).should == universe
266
+ (subset | ~subset).should == universe
267
+ (universe | ~universe).should == universe
268
+ end
269
+
270
+ property("A ∪ ¬A = U") do
271
+ mksubset(universe)
272
+ end.check do |a|
273
+ (a | ~a).should == universe
274
+ end
275
+
276
+ specify "A ⊖ ¬A = U" do
277
+ (null ^ ~null).should == universe
278
+ (single ^ ~single).should == universe
279
+ (subset ^ ~subset).should == universe
280
+ (universe ^ ~universe).should == universe
281
+ end
282
+
283
+ property("A ⊖ ¬A = U") do
284
+ mksubset(universe)
285
+ end.check do |a|
286
+ (a ^ ~a).should == universe
287
+ end
288
+
289
+ specify "A ∖ ¬A = A" do
290
+ (null - ~null).should == null
291
+ (single - ~single).should == single
292
+ (subset - ~subset).should == subset
293
+ (universe - ~universe).should == universe
294
+ end
295
+
296
+ property("A ∖ ¬A = A") do
297
+ mksubset(universe)
298
+ end.check do |a|
299
+ (a - ~a).should == a
300
+ end
301
+
302
+ specify "x ∉ ¬A, for all x ∉ U" do
303
+ (~null).should_not include("A")
304
+ (~single).should_not include("A")
305
+ (~subset).should_not include("A")
306
+ (~universe).should_not include("A")
307
+ end
308
+
309
+ property("x ∈ ¬A, for all x ∈ U and x ∉ A") do
310
+ mksubset(universe)
311
+ end.check do |a|
312
+ (~a).each{|e| a.should_not include(e) }
313
+ end
314
+
315
+ property("x ∉ ¬A, for all x ∈ U and x ∈ A") do
316
+ mksubset(universe)
317
+ end.check do |a|
318
+ a.each{|e| (~a).should_not include(e) }
319
+ end
320
+
321
+ specify "¬U = ∅" do
322
+ (~universe).should == null
323
+ end
324
+
325
+ specify "¬∅ = U" do
326
+ (~null).should == universe
327
+ end
328
+
329
+ # Identity
330
+ specify "¬(¬A) = A" do
331
+ (~(~null)).should == null
332
+ (~(~single)).should == single
333
+ (~(~subset)).should == subset
334
+ (~(~universe)).should == universe
335
+ end
336
+
337
+ property("¬(¬A) = A") do
338
+ mksubset(universe)
339
+ end.check do |a|
340
+ (~(~a)).should == a
341
+ end
342
+
343
+ # De Morgan's Laws
344
+ property("¬(A ∪ B) = ¬A ∩ ¬B") do
345
+ [mksubset(universe), mksubset(universe)]
346
+ end.check do |a, b|
347
+ (~(a | b)).should == (~a & ~b)
348
+ end
349
+
350
+ property("¬(A ∩ B) = ¬A ∪ ¬B") do
351
+ [mksubset(universe), mksubset(universe)]
352
+ end.check do |a, b|
353
+ (~(a & b)).should == (~a | ~b)
354
+ end
355
+
356
+ # Uniqueness of Complements
357
+ property("B = ¬A, given A ∪ B = U and A ∩ B = ∅") do
358
+ # Create a smaller universe, because the chances of choosing
359
+ # two random subsets from 2**26 possible, that happen to be
360
+ # disjoint is very small.
361
+ universe = Stupidedi::Sets.absolute(%w(a b c d e f))
362
+
363
+ a = mksubset(universe)
364
+ b = mksubset(universe)
365
+
366
+ guard(a | b == universe)
367
+ guard(a & b == null)
368
+
369
+ [a, b]
370
+ end.check(2, 500) do |a, b|
371
+ b.should == ~a
372
+ end
373
+ end
374
+
375
+ describe "#union(other)" do
376
+ property("x ∈ A ∪ B, for all x ∈ A") do
377
+ a = mksubset(universe)
378
+ b = mksubset(universe)
379
+ [a, b, (a | b)]
380
+ end.check do |a, b, union|
381
+ a.each{|x| union.should include(x) }
382
+ end
383
+
384
+ property("x ∈ A ∪ B, for all x ∈ B") do
385
+ a = mksubset(universe)
386
+ b = mksubset(universe)
387
+ [a, b, (a | b)]
388
+ end.check do |a, b, union|
389
+ b.each{|x| union.should include(x) }
390
+ end
391
+
392
+ property("x ∉ A ∪ B, for all x ∉ A and x ∉ B") do
393
+ a = mksubset(universe)
394
+ b = mksubset(universe)
395
+ [a, b, (a | b)]
396
+ end.check do |a, b, union|
397
+ universe.each do |x|
398
+ unless a.include?(x) or b.include?(x)
399
+ union.should_not include(x)
400
+ end
401
+ end
402
+ end
403
+
404
+ property("A ∪ B = A, given B ⊂ A") do
405
+ # Create a smaller universe, because the chances of choosing
406
+ # two random subsets from 2**26 possible, that happen to be
407
+ # subsets of each other is very small.
408
+ universe = Stupidedi::Sets.absolute(%w(a b c d e f))
409
+
410
+ a = mksubset(universe)
411
+ b = mksubset(universe)
412
+ guard(b < a)
413
+
414
+ [a, b]
415
+ end.check do |a, b|
416
+ (a | b).should == a
417
+ end
418
+
419
+ property("A ∪ B = B, given B ⊃ A") do
420
+ # Create a smaller universe, because the chances of choosing
421
+ # two random subsets from 2**26 possible, that happen to be
422
+ # subsets of each other is very small.
423
+ universe = Stupidedi::Sets.absolute(%w(a b c d e f))
424
+
425
+ a = mksubset(universe)
426
+ b = mksubset(universe)
427
+ guard(b > a)
428
+
429
+ [a, b]
430
+ end.check do |a, b|
431
+ (a | b).should == b
432
+ end
433
+
434
+ property("A ∪ B ⊇ A") do
435
+ [mksubset(universe), mksubset(universe)]
436
+ end.check do |a, b|
437
+ (a | b).should >= a
438
+ end
439
+
440
+ property("A ∪ B ⊇ B") do
441
+ [mksubset(universe), mksubset(universe)]
442
+ end.check do |a, b|
443
+ (a | b).should >= b
444
+ end
445
+
446
+ property("A ∪ B ⊃ A, given A ∩ B = ∅") do
447
+ # Create a smaller universe, because the chances of choosing
448
+ # two random subsets from 2**26 possible, that happen to be
449
+ # disjoint is very small.
450
+ universe = Stupidedi::Sets.absolute(%w(a b c d e f))
451
+
452
+ a = mksubset(universe)
453
+ b = mksubset(universe)
454
+ guard(b & a == null)
455
+
456
+ [a, b]
457
+ end.check do |a, b|
458
+ (a | b) > a
459
+ end
460
+
461
+ # Absorption
462
+ property("A ∪ (A ∩ B) = A") do
463
+ [mksubset(universe), mksubset(universe)]
464
+ end.check do |a, b|
465
+ (a | (a & b)).should == a
466
+ end
467
+
468
+ # Idempotent
469
+ specify "A ∪ A = A" do
470
+ (null + null).should == null
471
+ (single + single).should == single
472
+ (subset + subset).should == subset
473
+ (universe + universe).should == universe
474
+ end
475
+
476
+ # Domination
477
+ specify "A ∪ U = U" do
478
+ (null + universe).should == universe
479
+ (single + universe).should == universe
480
+ (subset + universe).should == universe
481
+ (universe + universe).should == universe
482
+ end
483
+
484
+ # Complement
485
+ specify "A ∪ ¬A = U" do
486
+ (null | ~null).should == universe
487
+ (single | ~single).should == universe
488
+ (subset | ~subset).should == universe
489
+ (universe | ~universe).should == universe
490
+ end
491
+
492
+ # Identity
493
+ specify "A ∪ ∅ = A" do
494
+ (null + null).should == null
495
+ (single + null).should == single
496
+ (subset + null).should == subset
497
+ (universe + null).should == universe
498
+ end
499
+
500
+ # Distributive
501
+ property("A ∪ (B ∩ C) = (A ∪ B) ∩ (A ∪ C)") do
502
+ [mksubset(universe), mksubset(universe), mksubset(universe)]
503
+ end.check do |a, b, c|
504
+ (a | (b & c)).should == ((a | b) & (a | c))
505
+ end
506
+
507
+ # Commutative
508
+ property("A ∪ B = B ∪ A") do
509
+ [mksubset(universe), mksubset(universe)]
510
+ end.check do |a, b|
511
+ (a | b).should == (b | a)
512
+ end
513
+
514
+ # Associative
515
+ property("(A ∪ B) ∪ C = A ∪ (B ∪ C)") do
516
+ [mksubset(universe), mksubset(universe), mksubset(universe)]
517
+ end.check do |a, b, c|
518
+ ((a | b) | c).should == (a | (b | c))
519
+ end
520
+
521
+ context "if B is a RelativeSet" do
522
+ context "and B ⊆ U" do
523
+ property("then A ∪ B = A ∪ Sets.absolute(B, U)") do
524
+ [mksubset(universe), mksubset(universe)]
525
+ end.check do |a, b|
526
+ r = Stupidedi::Sets.build(b.to_a)
527
+
528
+ (a | b).should == (a | r)
529
+ (a | r).should == (a | b)
530
+ (a | r).should be_a(Stupidedi::Sets::AbsoluteSet)
531
+ end
532
+ end
533
+
534
+ context "and B ⊈ U" do
535
+ property("then A ∪ B raises an error") do
536
+ a = mksubset(universe)
537
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
538
+ universe.to_a.map(&:upcase)))
539
+ [a, b]
540
+ end.check do |a, b|
541
+ r = Stupidedi::Sets.build(b.to_a)
542
+
543
+ lambda { a | r }.should \
544
+ raise_error(/universe does not contain/)
545
+ end
546
+ end
547
+ end
548
+
549
+ context "if B is a RelativeComplement" do
550
+ context "and ¬B ⊆ U" do
551
+ property("then A ∪ B = B ∪ A") do
552
+ a = mksubset(universe)
553
+ b = mksubset(universe)
554
+
555
+ [a, Stupidedi::Sets.complement(b.to_a)]
556
+ end.check do |a, b|
557
+ (a | b).should == b | a
558
+ (a | b).should be_a(Stupidedi::Sets::RelativeComplement)
559
+ end
560
+ end
561
+
562
+ context "and ¬B ⊈ U" do
563
+ property("then A ∪ B = B ∪ A") do
564
+ a = mksubset(universe)
565
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
566
+ universe.to_a.map(&:upcase)))
567
+
568
+ [a, Stupidedi::Sets.complement(b.to_a)]
569
+ end.check do |a, b|
570
+ (a | b).should == b | a
571
+ (a | b).should be_a(Stupidedi::Sets::RelativeComplement)
572
+ end
573
+ end
574
+ end
575
+
576
+ context "if B is an Array" do
577
+ context "and B ⊆ U" do
578
+ property("then A ∪ B = A ∪ Sets.absolute(B, U)") do
579
+ [mksubset(universe), mksubset(universe)]
580
+ end.check do |a, b|
581
+ r = b.to_a
582
+
583
+ (a | b).should == (a | r)
584
+ (a | r).should == (a | b)
585
+ (a | r).should be_a(Stupidedi::Sets::AbsoluteSet)
586
+ end
587
+ end
588
+
589
+ context "and B ⊈ U" do
590
+ property("then A ∪ B raises an error") do
591
+ a = mksubset(universe)
592
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
593
+ universe.to_a.map(&:upcase)))
594
+ [a, b]
595
+ end.check do |a, b|
596
+ r = b.to_a
597
+
598
+ lambda { a | r }.should \
599
+ raise_error(/universe does not contain/)
600
+ end
601
+ end
602
+ end
603
+ end
604
+
605
+ describe "#intersection(other)" do
606
+ property("x ∈ A ∩ B, for all x ∈ A and x ∈ B") do
607
+ a = mksubset(universe)
608
+ b = mksubset(universe)
609
+ [a, b, (a & b)]
610
+ end.check do |a, b, intersection|
611
+ a.each do |x|
612
+ if b.include?(x)
613
+ intersection.should include(x)
614
+ end
615
+ end
616
+ end
617
+
618
+ property("x ∉ A ∩ B, for all x ∉ A") do
619
+ a = mksubset(universe)
620
+ b = mksubset(universe)
621
+ [a, b, (a & b)]
622
+ end.check do |a, b, intersection|
623
+ universe.each do |x|
624
+ unless a.include?(x)
625
+ intersection.should_not include(x)
626
+ end
627
+ end
628
+ end
629
+
630
+ property("x ∉ A ∩ B, for all x ∉ B") do
631
+ a = mksubset(universe)
632
+ b = mksubset(universe)
633
+ [a, b, (a & b)]
634
+ end.check do |a, b, intersection|
635
+ universe.each do |x|
636
+ unless b.include?(x)
637
+ intersection.should_not include(x)
638
+ end
639
+ end
640
+ end
641
+
642
+ specify "A ∩ U = A" do
643
+ (null & universe).should == null
644
+ (single & universe).should == single
645
+ (subset & universe).should == subset
646
+ (universe & universe).should == universe
647
+ end
648
+
649
+ property("A ∩ B = A, given B ⊇ A") do
650
+ # Create a smaller universe, because the chances of choosing
651
+ # two random subsets from 2**26 possible, that happen to be
652
+ # subsets of each other is very small.
653
+ universe = Stupidedi::Sets.absolute(%w(a b c d e f))
654
+
655
+ a = mksubset(universe)
656
+ b = mksubset(universe)
657
+ guard(b >= a)
658
+
659
+ [a, b]
660
+ end.check do |a, b|
661
+ (a & b).should == a
662
+ end
663
+
664
+ property("A ∩ B = B, given B ⊆ A") do
665
+ # Create a smaller universe, because the chances of choosing
666
+ # two random subsets from 2**26 possible, that happen to be
667
+ # subsets of each other is very small.
668
+ universe = Stupidedi::Sets.absolute(%w(a b c d e f))
669
+
670
+ a = mksubset(universe)
671
+ b = mksubset(universe)
672
+ guard(b <= a)
673
+
674
+ [a, b]
675
+ end.check do |a, b|
676
+ (a & b).should == b
677
+ end
678
+
679
+ # Absorption
680
+ property("A ∩ (A ∪ B) = A") do
681
+ [mksubset(universe), mksubset(universe)]
682
+ end.check do |a, b|
683
+ (a & (a | b)).should == a
684
+ end
685
+
686
+ # Idempotent
687
+ specify "A ∩ A = A" do
688
+ (null & null).should == null
689
+ (single & single).should == single
690
+ (subset & subset).should == subset
691
+ (universe & universe).should == universe
692
+ end
693
+
694
+ # Domination
695
+ specify "A ∩ ∅ = ∅" do
696
+ (null & null).should == null
697
+ (single & null).should == null
698
+ (subset & null).should == null
699
+ (universe & null).should == null
700
+ end
701
+
702
+ # Complement
703
+ specify "A ∩ ¬A = ∅" do
704
+ (null & ~null).should == null
705
+ (single & ~single).should == null
706
+ (subset & ~subset).should == null
707
+ (universe & ~universe).should == null
708
+ end
709
+
710
+ # Distributive
711
+ property("A ∩ (B ∪ C) = (A ∩ B) ∪ (A ∩ C)") do
712
+ [mksubset(universe), mksubset(universe), mksubset(universe)]
713
+ end.check do |a, b, c|
714
+ (a & (b | c)).should == ((a & b) | (a & c))
715
+ end
716
+
717
+ # Commutative
718
+ property("A ∩ B = B ∩ A") do
719
+ [mksubset(universe), mksubset(universe)]
720
+ end.check do |a, b|
721
+ (a & b).should == (b & a)
722
+ end
723
+
724
+ # Associative
725
+ property("(A ∩ B) ∩ C = A ∩ (B ∩ C)") do
726
+ [mksubset(universe), mksubset(universe), mksubset(universe)]
727
+ end.check do |a, b, c|
728
+ ((a & b) & c).should == (a & (b & c))
729
+ end
730
+
731
+ context "if B is a RelativeSet" do
732
+ context "and B ⊆ U" do
733
+ property("then A ∩ B = A ∩ Sets.absolute(B, U)") do
734
+ [mksubset(universe), mksubset(universe)]
735
+ end.check do |a, b|
736
+ r = Stupidedi::Sets.build(b.to_a)
737
+
738
+ (a & b).should == (a & r)
739
+ (a & r).should == (a & b)
740
+ (a & r).should be_a(Stupidedi::Sets::AbsoluteSet)
741
+ end
742
+ end
743
+
744
+ context "and B ⊈ U" do
745
+ property("then A ∩ B = A ∩ Sets.absolute(B ∩ U, U)") do
746
+ a = mksubset(universe)
747
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
748
+ universe.to_a.map(&:upcase)))
749
+ [a, b]
750
+ end.check do |a, b|
751
+ r = Stupidedi::Sets.build(b.to_a) # B
752
+ b = universe.select{|x| b.include?(x) } # B ∩ U
753
+
754
+ (a & b).should == (a & r)
755
+ (a & r).should == (a & b)
756
+ (a & r).should be_a(Stupidedi::Sets::AbsoluteSet)
757
+ end
758
+ end
759
+ end
760
+
761
+ context "if B is a RelativeComplement" do
762
+ context "and ¬B ⊆ U" do
763
+ property("then A ∩ B = B ∩ A") do
764
+ a = mksubset(universe)
765
+ b = mksubset(universe)
766
+
767
+ [a, Stupidedi::Sets.complement(b.to_a)]
768
+ end.check do |a, b|
769
+ (a & b).should == b & a
770
+ (a & b).should be_a(Stupidedi::Sets::AbsoluteSet)
771
+ end
772
+ end
773
+
774
+ context "and ¬B ⊈ U" do
775
+ property("then A ∩ B = B ∩ A") do
776
+ a = mksubset(universe)
777
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
778
+ universe.to_a.map(&:upcase)))
779
+
780
+ [a, Stupidedi::Sets.complement(b.to_a)]
781
+ end.check do |a, b|
782
+ (a & b).should == b & a
783
+ (a & b).should be_a(Stupidedi::Sets::AbsoluteSet)
784
+ end
785
+ end
786
+ end
787
+
788
+ context "if B is an Array" do
789
+ context "and B ⊆ U" do
790
+ property("then A ∩ B = A ∩ Sets.absolute(B, U)") do
791
+ [mksubset(universe), mksubset(universe)]
792
+ end.check do |a, b|
793
+ r = b.to_a
794
+
795
+ (a & b).should == (a & r)
796
+ (a & r).should == (a & b)
797
+ (a & r).should be_a(Stupidedi::Sets::AbsoluteSet)
798
+ end
799
+ end
800
+
801
+ context "and B ⊈ U" do
802
+ property("then A ∩ B = A ∩ Sets.absolute(B ∩ U, U)") do
803
+ a = mksubset(universe)
804
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
805
+ universe.to_a.map(&:upcase)))
806
+ [a, b]
807
+ end.check do |a, b|
808
+ r = b.to_a # B
809
+ b = universe.select{|x| b.include?(x) } # B ∩ U
810
+
811
+ (a & b).should == (a & r)
812
+ (a & r).should == (a & b)
813
+ (a & r).should be_a(Stupidedi::Sets::AbsoluteSet)
814
+ end
815
+ end
816
+ end
817
+ end
818
+
819
+ describe "#difference(other)" do
820
+ property("x ∈ A ∖ B, for all x ∈ A and x ∉ B") do
821
+ a = mksubset(universe)
822
+ b = mksubset(universe)
823
+ [a, b, (a - b)]
824
+ end.check do |a, b, difference|
825
+ a.each do |x|
826
+ unless b.include?(x)
827
+ difference.should include(x)
828
+ end
829
+ end
830
+ end
831
+
832
+ property("x ∉ A ∖ B, for all x ∉ A") do
833
+ a = mksubset(universe)
834
+ b = mksubset(universe)
835
+ [a, b, (a - b)]
836
+ end.check do |a, b, difference|
837
+ universe.each do |x|
838
+ unless a.include?(x)
839
+ difference.should_not include(x)
840
+ end
841
+ end
842
+ end
843
+
844
+ property("x ∉ A ∖ B, for all x ∈ B") do
845
+ a = mksubset(universe)
846
+ b = mksubset(universe)
847
+ [a, b, (a - b)]
848
+ end.check do |a, b, difference|
849
+ b.each do |x|
850
+ difference.include?(x).should be_false
851
+ end
852
+ end
853
+
854
+ specify "U ∖ A = ¬A" do
855
+ (universe - null).should == ~null
856
+ (universe - single).should == ~single
857
+ (universe - subset).should == ~subset
858
+ (universe - universe).should == ~universe
859
+ end
860
+
861
+ specify "∅ ∖ A = ∅" do
862
+ (null - null).should == null
863
+ (null - single).should == null
864
+ (null - subset).should == null
865
+ (null - universe).should == null
866
+ end
867
+
868
+ specify "A ∖ A = ∅" do
869
+ (null - null).should == null
870
+ (single - single).should == null
871
+ (subset - subset).should == null
872
+ (universe - universe).should == null
873
+ end
874
+
875
+ specify "A ∖ ∅ = A" do
876
+ (null - null).should == null
877
+ (single - null).should == single
878
+ (subset - null).should == subset
879
+ (universe - null).should == universe
880
+ end
881
+
882
+ specify "A ∖ U = ∅" do
883
+ (null - universe).should == null
884
+ (single - universe).should == null
885
+ (subset - universe).should == null
886
+ (universe - universe).should == null
887
+ end
888
+
889
+ property("A ∖ B = A, given A ∩ B = ∅")
890
+
891
+ property("A ∖ B ⊂ A, given A ∩ B ≠ ∅") do
892
+ a = mksubset(universe)
893
+ b = mksubset(universe)
894
+ guard(a & b != null)
895
+
896
+ [a, b]
897
+ end.check do |a, b|
898
+ (a - b).should < a
899
+ end
900
+
901
+ property("A ∖ B ≠ B ∖ A, given A ≠ B") do
902
+ a = mksubset(universe)
903
+ b = mksubset(universe)
904
+ guard(a != b)
905
+
906
+ [a, b]
907
+ end.check do |a, b|
908
+ (a - b).should_not == (b - a)
909
+ end
910
+
911
+ property("C ∖ (A ∩ B) = (C ∖ A) ∪ (C ∖ B)") do
912
+ [mksubset(universe), mksubset(universe), mksubset(universe)]
913
+ end.check do |a, b, c|
914
+ (c - (a & b)).should == ((c - a) | (c - b))
915
+ end
916
+
917
+ property("C ∖ (A ∪ B) = (C ∖ A) ∩ (C ∖ B)") do
918
+ [mksubset(universe), mksubset(universe), mksubset(universe)]
919
+ end.check do |a, b, c|
920
+ (c - (a | b)).should == ((c - a) & (c - b))
921
+ end
922
+
923
+ property("C ∖ (B ∖ A) = (A ∩ C) ∪ (C ∖ B)") do
924
+ [mksubset(universe), mksubset(universe), mksubset(universe)]
925
+ end.check do |a, b, c|
926
+ (c - (b - a)).should == ((a & c) | (c - b))
927
+ end
928
+
929
+ # property("(B ∖ A) ∩ C = (B ∩ C) ∖ A = B ∩ (C ∖ A)") do
930
+ # [mksubset(universe), mksubset(universe), mksubset(universe)]
931
+ # end.check do |a, b, c|
932
+ # end
933
+
934
+ property("(B ∖ A) ∪ C = (B ∪ C) ∖ (A ∖ C)") do
935
+ [mksubset(universe), mksubset(universe), mksubset(universe)]
936
+ end.check do |a, b, c|
937
+ ((b - a) | c).should == ((b | c) - (a - c))
938
+ end
939
+
940
+ property("B ∖ A = ¬A ∩ B") do
941
+ [mksubset(universe), mksubset(universe)]
942
+ end.check do |a, b|
943
+ (b - a).should == (~a & b)
944
+ end
945
+
946
+ property("¬(B ∖ A) = A ∪ ¬B") do
947
+ [mksubset(universe), mksubset(universe)]
948
+ end.check do |a, b|
949
+ (~(b - a)).should == (a | ~b)
950
+ end
951
+
952
+ context "if B is a RelativeSet" do
953
+ context "and B ⊆ U" do
954
+ property("then A ∖ B = A ∖ Sets.absolute(B, U)") do
955
+ [mksubset(universe), mksubset(universe)]
956
+ end.check do |a, b|
957
+ r = Stupidedi::Sets.build(b.to_a)
958
+
959
+ (a - b).should == (a - r)
960
+ (a - r).should == (a - b)
961
+ (a - r).should be_a(Stupidedi::Sets::AbsoluteSet)
962
+ end
963
+ end
964
+
965
+ context "and B ⊈ U" do
966
+ property("then A ∖ B = A ∖ Sets.absolute(B ∩ U, U)") do
967
+ a = mksubset(universe)
968
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
969
+ universe.to_a.map(&:upcase)))
970
+ [a, b]
971
+ end.check do |a, b|
972
+ r = Stupidedi::Sets.build(b.to_a) # B
973
+ b = universe.select{|x| b.include?(x) } # B ∩ U
974
+
975
+ (a - b).should == (a - r)
976
+ (a - r).should == (a - b)
977
+ (a - r).should be_a(Stupidedi::Sets::AbsoluteSet)
978
+ end
979
+ end
980
+ end
981
+
982
+ context "if B is a RelativeComplement" do
983
+ context "and ¬B ⊆ U" do
984
+ property("then A ∖ B = A ∩ ¬B") do
985
+ a = mksubset(universe)
986
+ b = mksubset(universe)
987
+
988
+ [a, Stupidedi::Sets.complement(b.to_a)]
989
+ end.check do |a, b|
990
+ (a - b).should == (a & ~b)
991
+ (a - b).should be_a(Stupidedi::Sets::AbsoluteSet)
992
+ end
993
+ end
994
+
995
+ context "and ¬B ⊈ U" do
996
+ property("then A ∖ B = A ∩ ¬B") do
997
+ a = mksubset(universe)
998
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
999
+ universe.to_a.map(&:upcase)))
1000
+
1001
+ [a, Stupidedi::Sets.complement(b.to_a)]
1002
+ end.check do |a, b|
1003
+ (a - b).should == (a & ~b)
1004
+ (a - b).should be_a(Stupidedi::Sets::AbsoluteSet)
1005
+ end
1006
+ end
1007
+ end
1008
+
1009
+ context "if B is an Array" do
1010
+ context "and B ⊆ U" do
1011
+ property("then A ∖ B = A ∖ Sets.absolute(B, U)") do
1012
+ [mksubset(universe), mksubset(universe)]
1013
+ end.check do |a, b|
1014
+ r = b.to_a
1015
+
1016
+ (a - b).should == (a - r)
1017
+ (a - r).should == (a - b)
1018
+ (a - r).should be_a(Stupidedi::Sets::AbsoluteSet)
1019
+ end
1020
+ end
1021
+
1022
+ context "and B ⊈ U" do
1023
+ property("then A ∖ B = A ∖ Sets.absolute(B ∩ U, U)") do
1024
+ a = mksubset(universe)
1025
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
1026
+ universe.to_a.map(&:upcase)))
1027
+ [a, b]
1028
+ end.check do |a, b|
1029
+ r = b.to_a # B
1030
+ b = universe.select{|x| b.include?(x) } # B ∩ U
1031
+
1032
+ (a - b).should == (a - r)
1033
+ (a - r).should == (a - b)
1034
+ (a - r).should be_a(Stupidedi::Sets::AbsoluteSet)
1035
+ end
1036
+ end
1037
+ end
1038
+ end
1039
+
1040
+ describe "#symmetric_difference(other)" do
1041
+ specify "A ⊖ A = ∅" do
1042
+ (null ^ null).should == null
1043
+ (single ^ single).should == null
1044
+ (subset ^ subset).should == null
1045
+ (universe ^ universe).should == null
1046
+ end
1047
+
1048
+ specify "A ⊖ U = ¬A" do
1049
+ (null ^ universe).should == ~null
1050
+ (single ^ universe).should == ~single
1051
+ (subset ^ universe).should == ~subset
1052
+ (universe ^ universe).should == ~universe
1053
+ end
1054
+
1055
+ specify "A ⊖ ∅ = A" do
1056
+ (null ^ null).should == null
1057
+ (single ^ null).should == single
1058
+ (subset ^ null).should == subset
1059
+ (universe ^ null).should == universe
1060
+ end
1061
+
1062
+ property("A ⊖ B = (A ∖ B) ∪ (B ∖ A)") do
1063
+ [mksubset(universe), mksubset(universe)]
1064
+ end.check do |a, b|
1065
+ (a ^ b).should == ((a - b) | (b - a))
1066
+ end
1067
+
1068
+ property("A ⊖ B = (A ∪ B) ∖ (A ∩ B)") do
1069
+ [mksubset(universe), mksubset(universe)]
1070
+ end.check do |a, b|
1071
+ (a ^ b).should == ((a | b) - (a & b))
1072
+ end
1073
+
1074
+ property("A ⊖ B = B ⊖ A") do
1075
+ [mksubset(universe), mksubset(universe)]
1076
+ end.check do |a, b|
1077
+ (a ^ b).should == (b ^ a)
1078
+ end
1079
+
1080
+ property("(A ⊖ B) ⊖ C = A ⊖ (B ⊖ C)") do
1081
+ [mksubset(universe), mksubset(universe), mksubset(universe)]
1082
+ end.check do |a, b, c|
1083
+ ((a ^ b) ^ c).should == (a ^ (b ^ c))
1084
+ end
1085
+
1086
+ property("(A ⊖ B) ⊖ (B ⊖ C) = A ⊖ C") do
1087
+ [mksubset(universe), mksubset(universe), mksubset(universe)]
1088
+ end.check do |a, b, c|
1089
+ ((a ^ b) ^ (b ^ c)).should == (a ^ c)
1090
+ end
1091
+
1092
+ property("A ∩ (B ⊖ C) = (A ∩ B) ⊖ (A ∩ C)") do
1093
+ [mksubset(universe), mksubset(universe), mksubset(universe)]
1094
+ end.check do |a, b, c|
1095
+ (a & (b ^ c)).should == ((a & b) ^ (a & c))
1096
+ end
1097
+
1098
+ context "if B is a RelativeSet" do
1099
+ context "and B ⊆ U" do
1100
+ property("then A ⊖ B = A ⊖ Sets.absolute(B, U)") do
1101
+ [mksubset(universe), mksubset(universe)]
1102
+ end.check do |a, b|
1103
+ r = Stupidedi::Sets.build(b.to_a)
1104
+
1105
+ (a ^ b).should == (a ^ r)
1106
+ (a ^ r).should == (a ^ b)
1107
+ (a ^ r).should be_a(Stupidedi::Sets::AbsoluteSet)
1108
+ end
1109
+ end
1110
+
1111
+ context "and B ⊈ U" do
1112
+ property("then A ⊖ B raises an error") do
1113
+ a = mksubset(universe)
1114
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
1115
+ universe.to_a.map(&:upcase)))
1116
+ [a, b]
1117
+ end.check do |a, b|
1118
+ r = Stupidedi::Sets.build(b.to_a)
1119
+
1120
+ lambda { a ^ r }.should \
1121
+ raise_error(/universe does not contain/)
1122
+ end
1123
+ end
1124
+ end
1125
+
1126
+ context "if B is a RelativeComplement" do
1127
+ context "and ¬B ⊆ U" do
1128
+ property("then A ⊖ B = B ⊖ A") do
1129
+ a = mksubset(universe)
1130
+ b = mksubset(universe)
1131
+
1132
+ [a, Stupidedi::Sets.complement(b.to_a)]
1133
+ end.check do |a, b|
1134
+ (a ^ b).should == b ^ a
1135
+ (a ^ b).should be_a(Stupidedi::Sets::AbsoluteSet)
1136
+ end
1137
+ end
1138
+
1139
+ context "and ¬B ⊈ U" do
1140
+ property("then A ⊖ B = B ⊖ A") do
1141
+ a = mksubset(universe)
1142
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
1143
+ universe.to_a.map(&:upcase)))
1144
+
1145
+ [a, Stupidedi::Sets.complement(b.to_a)]
1146
+ end.check do |a, b|
1147
+ (a ^ b).should == b ^ a
1148
+ (a ^ b).should be_a(Stupidedi::Sets::AbsoluteSet)
1149
+ end
1150
+ end
1151
+ end
1152
+
1153
+ context "if B is an Array" do
1154
+ context "and B ⊆ U" do
1155
+ property("then A ⊖ B = A ⊖ Sets.absolute(B, U)") do
1156
+ [mksubset(universe), mksubset(universe)]
1157
+ end.check do |a, b|
1158
+ r = b.to_a
1159
+
1160
+ (a ^ b).should == (a ^ r)
1161
+ (a ^ r).should == (a ^ b)
1162
+ (a ^ r).should be_a(Stupidedi::Sets::AbsoluteSet)
1163
+ end
1164
+ end
1165
+
1166
+ context "and B ⊈ U" do
1167
+ property("then A ⊖ B raises an error") do
1168
+ a = mksubset(universe)
1169
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
1170
+ universe.to_a.map(&:upcase)))
1171
+ [a, b]
1172
+ end.check do |a, b|
1173
+ r = b.to_a
1174
+
1175
+ lambda { a ^ r }.should \
1176
+ raise_error(/universe does not contain/)
1177
+ end
1178
+ end
1179
+ end
1180
+ end
1181
+
1182
+ describe "#subset?(other)" do
1183
+ # Reflexivity
1184
+ specify "A ⊆ A" do
1185
+ null.should <= null
1186
+ single.should <= single
1187
+ subset.should <= subset
1188
+ universe.should <= universe
1189
+ end
1190
+
1191
+ # Antisymmetry
1192
+ property("A ⊆ B and B ⊆ A, given A = B") do
1193
+ universe = Stupidedi::Sets.absolute(%w(a b c d e f))
1194
+
1195
+ a = mksubset(universe)
1196
+ b = mksubset(universe)
1197
+ guard(a == b)
1198
+
1199
+ [a, b]
1200
+ end.check(5, 200) do |a, b|
1201
+ a.should <= b
1202
+ b.should <= a
1203
+ end
1204
+
1205
+ property("A = B, given A ⊆ B and B ⊆ A") do
1206
+ universe = Stupidedi::Sets.absolute(%w(a b c d e f))
1207
+
1208
+ a = mksubset(universe)
1209
+ b = mksubset(universe)
1210
+ guard(a <= b)
1211
+ guard(b <= a)
1212
+
1213
+ [a, b]
1214
+ end.check(5, 200) do |a, b|
1215
+ a.should == b
1216
+ end
1217
+
1218
+ # Transitivity
1219
+ property("A ⊆ C, given A ⊆ B and B ⊆ C") do
1220
+ universe = Stupidedi::Sets.absolute(%w(a b c d e f))
1221
+
1222
+ a = mksubset(universe)
1223
+ b = mksubset(universe)
1224
+ c = mksubset(universe)
1225
+ guard(a <= b)
1226
+ guard(b <= c)
1227
+
1228
+ [a, b, c]
1229
+ end.check(5, 200) do |a, b, c|
1230
+ a.should <= c
1231
+ end
1232
+
1233
+ # Existence of a Least Element
1234
+ specify "∅ ⊆ A" do
1235
+ null.should <= null
1236
+ null.should <= single
1237
+ null.should <= subset
1238
+ null.should <= universe
1239
+ end
1240
+
1241
+ # Existence of a Greatest Element
1242
+ specify "A ⊆ U" do
1243
+ null.should <= universe
1244
+ single.should <= universe
1245
+ subset.should <= universe
1246
+ universe.should <= universe
1247
+ end
1248
+
1249
+ # Existence of Joins
1250
+ property("A ⊆ A ∪ B") do
1251
+ [mksubset(universe), mksubset(universe)]
1252
+ end.check do |a, b|
1253
+ a.should <= (a | b)
1254
+ end
1255
+
1256
+ # Existence of meets
1257
+ property("A ∪ B ⊇ C, given C ⊆ A and C ⊆ B") do
1258
+ universe = Stupidedi::Sets.absolute(%w(a b c d e f))
1259
+
1260
+ a = mksubset(universe)
1261
+ b = mksubset(universe)
1262
+ c = mksubset(universe)
1263
+ guard(c <= a)
1264
+ guard(c <= b)
1265
+
1266
+ [a, b, c]
1267
+ end.check(5, 200) do |a, b, c|
1268
+ (a | b).should >= c
1269
+ end
1270
+
1271
+ # Equivalent Statements
1272
+ property("A ⊆ B => ...") do
1273
+ [mksubset(universe), mksubset(universe)]
1274
+ end.check do |a, b|
1275
+ if a <= b
1276
+ (a & b).should == a
1277
+ (a | b).should == b
1278
+ (a - b).should == null
1279
+ (~b).should <= (~a)
1280
+ end
1281
+ end
1282
+
1283
+ # Equivalent Statements
1284
+ property("A ∩ B = A => ...") do
1285
+ [mksubset(universe), mksubset(universe)]
1286
+ end.check do |a, b|
1287
+ if (a & b) == a
1288
+ a.should <= b
1289
+ (a | b).should == b
1290
+ (a - b).should == null
1291
+ (~b).should <= (~a)
1292
+ end
1293
+ end
1294
+
1295
+ # Equivalent Statements
1296
+ property("A ∪ B = B => ...") do
1297
+ [mksubset(universe), mksubset(universe)]
1298
+ end.check do |a, b|
1299
+ if (a | b) == b
1300
+ a.should <= b
1301
+ (a & b).should == a
1302
+ (a - b).should == null
1303
+ (~b).should <= (~a)
1304
+ end
1305
+ end
1306
+
1307
+ # Equivalent Statements
1308
+ property("A ∖ B = ∅ => ...") do
1309
+ [mksubset(universe), mksubset(universe)]
1310
+ end.check do |a, b|
1311
+ if (a - b) == null
1312
+ a.should <= b
1313
+ (a & b).should == a
1314
+ (a | b).should == b
1315
+ (~b).should <= (~a)
1316
+ end
1317
+ end
1318
+
1319
+ # Equivalent Statements
1320
+ property("¬B ⊆ ¬A => ...") do
1321
+ [mksubset(universe), mksubset(universe)]
1322
+ end.check do |a, b|
1323
+ if (~b) <= (~a)
1324
+ a.should <= b
1325
+ (a & b).should == a
1326
+ (a | b).should == b
1327
+ (a - b).should == null
1328
+ end
1329
+ end
1330
+
1331
+ context "if B is a RelativeSet" do
1332
+ context "and B ⊆ U" do
1333
+ property("then A ⊆ B = A ⊆ Sets.absolute(B, U)") do
1334
+ [mksubset(universe), mksubset(universe)]
1335
+ end.check do |a, b|
1336
+ r = Stupidedi::Sets.build(b.to_a)
1337
+ (a <= b).should == (a <= r)
1338
+ end
1339
+ end
1340
+
1341
+ context "and B ⊈ U" do
1342
+ property("then A ⊈ B = A ⊆ Sets.absolute(B ∩ U, U)") do
1343
+ a = mksubset(universe)
1344
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
1345
+ universe.to_a.map(&:upcase)))
1346
+ [a, b]
1347
+ end.check do |a, b|
1348
+ r = Stupidedi::Sets.build(b.to_a) # B
1349
+ b = universe.select{|x| b.include?(x) } # B ∩ U
1350
+ (a <= b).should == (a <= r)
1351
+ end
1352
+ end
1353
+ end
1354
+
1355
+ context "if B is a RelativeComplement(C)" do
1356
+ context "and C ⊆ U" do
1357
+ property("then A ⊆ ¬C ≡ A ∩ C = ∅") do
1358
+ [mksubset(universe), mksubset(universe)]
1359
+ end.check do |a, c|
1360
+ b = Stupidedi::Sets.complement(c.to_a)
1361
+ (a <= b).should == ((a & c) == null)
1362
+ end
1363
+ end
1364
+
1365
+ context "and C ⊈ U" do
1366
+ property("then A ⊆ ¬C ≡ A ∩ C = ∅") do
1367
+ a = mksubset(universe)
1368
+ c = mksubset(Stupidedi::Sets.absolute(universe.to_a +
1369
+ universe.to_a.map(&:upcase)))
1370
+ [a, c]
1371
+ end.check do |a, c|
1372
+ b = Stupidedi::Sets.complement(c.to_a)
1373
+ (a <= b).should == ((a & c) == null)
1374
+ end
1375
+ end
1376
+ end
1377
+
1378
+ context "when B is an Array" do
1379
+ context "and B ⊆ U" do
1380
+ property("then A ⊆ B = A ⊆ Sets.absolute(B, U)") do
1381
+ [mksubset(universe), mksubset(universe)]
1382
+ end.check do |a, b|
1383
+ r = b.to_a
1384
+ (a <= b).should == (a <= r)
1385
+ end
1386
+ end
1387
+
1388
+ context "and B ⊈ U" do
1389
+ property("then A ⊆ B = A ⊆ Sets.absolute(B ∩ U, U)") do
1390
+ a = mksubset(universe)
1391
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
1392
+ universe.to_a.map(&:upcase)))
1393
+ [a, b]
1394
+ end.check do |a, b|
1395
+ r = b.to_a # B
1396
+ b = universe.select{|x| b.include?(x) } # B ∩ U
1397
+
1398
+ (a <= b).should == (a <= r)
1399
+ end
1400
+ end
1401
+ end
1402
+ end
1403
+
1404
+ describe "#==(other)" do
1405
+ # Reflexive
1406
+ specify "A = A" do
1407
+ null.should == null
1408
+ single.should == single
1409
+ subset.should == subset
1410
+ universe.should == universe
1411
+ end
1412
+
1413
+ # Symmetric
1414
+ property("if A = B then B = A") do
1415
+ universe = Stupidedi::Sets.absolute(%w(a b c d e f))
1416
+ [mksubset(universe), mksubset(universe)]
1417
+ end.check do |a, b|
1418
+ if a == b
1419
+ b.should == a
1420
+ end
1421
+ end
1422
+
1423
+ # Transitive
1424
+ property("if A = B and B = C then A = C") do
1425
+ universe = Stupidedi::Sets.absolute(%w(a b c d e f))
1426
+ [mksubset(universe), mksubset(universe), mksubset(universe)]
1427
+ end.check do |a, b, c|
1428
+ if a == b and b == c
1429
+ a.should == c
1430
+ end
1431
+ end
1432
+
1433
+ context "if B is a RelativeSet" do
1434
+ context "and B ⊆ U" do
1435
+ property("then A = B ≡ A = Sets.absolute(B, U)") do
1436
+ [mksubset(universe), mksubset(universe)]
1437
+ end.check do |a, b|
1438
+ r = Stupidedi::Sets.build(b.to_a)
1439
+ (a == b).should == (a == r)
1440
+ end
1441
+ end
1442
+
1443
+ context "and B ⊈ U" do
1444
+ property("then A = B ≡ A = Sets.absolute(B ∩ U, U)") do
1445
+ a = mksubset(universe)
1446
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
1447
+ universe.to_a.map(&:upcase)))
1448
+ [a, b]
1449
+ end.check do |a, b|
1450
+ r = Stupidedi::Sets.build(b.to_a) # B
1451
+ b = universe.select{|x| b.include?(x) } # B ∩ U
1452
+ (a == b).should == (a == r)
1453
+ end
1454
+ end
1455
+ end
1456
+
1457
+ context "if B is a RelativeComplement" do
1458
+ context "and ¬B ⊆ U" do
1459
+ property("then A = B ≡ B = A") do
1460
+ a = mksubset(universe)
1461
+ b = mksubset(universe)
1462
+
1463
+ [a, Stupidedi::Sets.complement(b.to_a)]
1464
+ end.check do |a, b|
1465
+ (a == b).should == (b == a)
1466
+ end
1467
+ end
1468
+
1469
+ context "and ¬B ⊈ U" do
1470
+ property("then A = B ≡ B = A") do
1471
+ a = mksubset(universe)
1472
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
1473
+ universe.to_a.map(&:upcase)))
1474
+
1475
+ [a, Stupidedi::Sets.complement(b.to_a)]
1476
+ end.check do |a, b|
1477
+ (a == b).should == (b == a)
1478
+ end
1479
+ end
1480
+ end
1481
+
1482
+ context "if B is an Array" do
1483
+ context "and B ⊆ U" do
1484
+ property("then A = B ≡ A = Sets.absolute(B, U)") do
1485
+ [mksubset(universe), mksubset(universe)]
1486
+ end.check do |a, b|
1487
+ r = b.to_a
1488
+ (a == b).should == (a == r)
1489
+ end
1490
+ end
1491
+
1492
+ context "and B ⊈ U" do
1493
+ property("then A = B ≡ A = Sets.absolute(B ∩ U, U)") do
1494
+ a = mksubset(universe)
1495
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
1496
+ universe.to_a.map(&:upcase)))
1497
+ [a, b]
1498
+ end.check do |a, b|
1499
+ r = b.to_a # B
1500
+ b = universe.select{|x| b.include?(x) } # B ∩ U
1501
+
1502
+ (a == b).should == (a == r)
1503
+ end
1504
+ end
1505
+ end
1506
+ end
1507
+
1508
+ describe "#replace(other)" do
1509
+ context "if B is an AbsoluteSet" do
1510
+ context "and B.universe = U" do
1511
+ property("then A.replace(B) = B") do
1512
+ [mksubset(universe), mksubset(universe)]
1513
+ end.check do |a, b|
1514
+ a.replace(b).should == b
1515
+ end
1516
+ end
1517
+
1518
+ context "and B.universe ≠ U" do
1519
+ property("then A.replace(B) = B") do
1520
+ a = mksubset(universe)
1521
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
1522
+ universe.to_a.map(&:upcase)))
1523
+ [a, b]
1524
+ end.check do |a, b|
1525
+ a.replace(b).should == b
1526
+ end
1527
+ end
1528
+ end
1529
+
1530
+ context "if B is a RelativeSet" do
1531
+ property("then A.replace(B) = B") do
1532
+ a = mksubset(universe)
1533
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
1534
+ universe.to_a.map(&:upcase)))
1535
+ [a, Stupidedi::Sets.build(b.to_a)]
1536
+ end.check do |a, b|
1537
+ a.replace(b).should == b
1538
+ end
1539
+ end
1540
+
1541
+ context "if B is a RelativeComplement" do
1542
+ property("then A.replace(B) = B") do
1543
+ a = mksubset(universe)
1544
+ b = mksubset(Stupidedi::Sets.absolute(universe.to_a +
1545
+ universe.to_a.map(&:upcase)))
1546
+ [a, Stupidedi::Sets.complement(b.to_a)]
1547
+ end.check do |a, b|
1548
+ a.replace(b).should == b
1549
+ end
1550
+ end
1551
+
1552
+ context "if B is an Array" do
1553
+ context "and B ⊆ U" do
1554
+ property("then A.replace(B) ≡ Sets.absolute(B, U)") do
1555
+ [mksubset(universe), mksubset(universe)]
1556
+ end.check do |a, b|
1557
+ a.replace(b.to_a).should == b
1558
+ end
1559
+ end
1560
+
1561
+ context "and B ⊈ U" do
1562
+ property("then A.replace(B) raises an error") do
1563
+ a = mksubset(universe)
1564
+ b = mksubset(universe)
1565
+ c = mksubset(universe)
1566
+ guard(!c.empty?)
1567
+
1568
+ [a, (b.to_a | c.to_a.map(&:upcase))]
1569
+ end.check do |a, b|
1570
+ lambda { a.replace(b) }.should \
1571
+ raise_error(/universe does not contain/)
1572
+ end
1573
+ end
1574
+ end
1575
+ end
1576
+
1577
+ end