pione 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (366) hide show
  1. data/.gitignore +14 -0
  2. data/Gemfile +5 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +94 -0
  5. data/Rakefile +118 -0
  6. data/bin/pione-broker +5 -0
  7. data/bin/pione-clean +5 -0
  8. data/bin/pione-client +5 -0
  9. data/bin/pione-eval +111 -0
  10. data/bin/pione-relay +5 -0
  11. data/bin/pione-relay-account-db +5 -0
  12. data/bin/pione-relay-client-db +5 -0
  13. data/bin/pione-search-log +30 -0
  14. data/bin/pione-syntax-checker +5 -0
  15. data/bin/pione-task-worker +5 -0
  16. data/bin/pione-tuple-space-provider +5 -0
  17. data/bin/pione-tuple-space-receiver +5 -0
  18. data/bin/pione-tuple-space-viewer +5 -0
  19. data/demo/demo.rb +311 -0
  20. data/demo/public/base.css +94 -0
  21. data/demo/public/demo.js +107 -0
  22. data/demo/public/index.html +91 -0
  23. data/demo/public/jquery-1.8.3.min.js +2 -0
  24. data/example/CountChar/CountChar.pione +64 -0
  25. data/example/CountChar/misc/CountChar.rb +22 -0
  26. data/example/CountChar/text/aidokushono_insho.txt +32 -0
  27. data/example/CountChar/text/aikokuka_shokan.txt +108 -0
  28. data/example/CountChar/text/carlyle_hakubutsukan.txt +58 -0
  29. data/example/CountChar/text/dark_minister.txt +2440 -0
  30. data/example/CountChar/text/kaikano_otto.txt +61 -0
  31. data/example/CountChar/text/kaikon.txt +30 -0
  32. data/example/CountChar/text/nagashimano_shi.txt +45 -0
  33. data/example/CountChar/text/saikachibuchi.txt +80 -0
  34. data/example/CountChar/text/saikonihonno_josei.txt +91 -0
  35. data/example/CountChar/text/taishojugonenno_bundan.txt +21 -0
  36. data/example/FeatureExample/FeatureExample.pione +7 -0
  37. data/example/Fib/Fib.pione +56 -0
  38. data/example/Fib/FibBC.pione +56 -0
  39. data/example/HelloWorld/HelloWorld.pione +5 -0
  40. data/example/LucasNumber/LucasNumber.pione +64 -0
  41. data/example/MakePair/MakePair.pione +14 -0
  42. data/example/MakePair/data/1.i +0 -0
  43. data/example/MakePair/data/2.i +0 -0
  44. data/example/MakePair/data/3.i +0 -0
  45. data/example/MakePair/data/4.i +0 -0
  46. data/example/MakePair/data/5.i +0 -0
  47. data/example/SieveOfEratosthenes/SieveOfEratosthenes.pione +61 -0
  48. data/example/SingleParticlesWithRef/Makefile +289 -0
  49. data/example/SingleParticlesWithRef/SingleParticlesWithRef.Makefile +153 -0
  50. data/example/SingleParticlesWithRef/SingleParticlesWithRef.pione +116 -0
  51. data/example/SingleParticlesWithRef/SingleParticlesWithRefFull.pione +400 -0
  52. data/example/SingleParticlesWithRef/data/121p-shift-0-0-0.roi +0 -0
  53. data/example/SingleParticlesWithRef/data/121p-shift-0-120-0.roi +0 -0
  54. data/example/SingleParticlesWithRef/data/121p-shift-0-180-0.roi +0 -0
  55. data/example/SingleParticlesWithRef/data/121p-shift-0-240-0.roi +0 -0
  56. data/example/SingleParticlesWithRef/data/121p-shift-0-300-0.roi +0 -0
  57. data/example/SingleParticlesWithRef/data/121p-shift-0-60-0.roi +0 -0
  58. data/example/SingleParticlesWithRef/data/121p-shift-120-0-0.roi +0 -0
  59. data/example/SingleParticlesWithRef/data/121p-shift-120-120-0.roi +0 -0
  60. data/example/SingleParticlesWithRef/data/121p-shift-120-180-0.roi +0 -0
  61. data/example/SingleParticlesWithRef/data/121p-shift-120-240-0.roi +0 -0
  62. data/example/SingleParticlesWithRef/data/121p-shift-120-300-0.roi +0 -0
  63. data/example/SingleParticlesWithRef/data/121p-shift-120-60-0.roi +0 -0
  64. data/example/SingleParticlesWithRef/data/121p-shift-180-0-0.roi +0 -0
  65. data/example/SingleParticlesWithRef/data/121p-shift-180-120-0.roi +0 -0
  66. data/example/SingleParticlesWithRef/data/121p-shift-180-180-0.roi +0 -0
  67. data/example/SingleParticlesWithRef/data/121p-shift-180-240-0.roi +0 -0
  68. data/example/SingleParticlesWithRef/data/121p-shift-180-300-0.roi +0 -0
  69. data/example/SingleParticlesWithRef/data/121p-shift-180-60-0.roi +0 -0
  70. data/example/SingleParticlesWithRef/data/121p-shift-240-0-0.roi +0 -0
  71. data/example/SingleParticlesWithRef/data/121p-shift-240-120-0.roi +0 -0
  72. data/example/SingleParticlesWithRef/data/121p-shift-240-180-0.roi +0 -0
  73. data/example/SingleParticlesWithRef/data/121p-shift-240-240-0.roi +0 -0
  74. data/example/SingleParticlesWithRef/data/121p-shift-240-300-0.roi +0 -0
  75. data/example/SingleParticlesWithRef/data/121p-shift-240-60-0.roi +0 -0
  76. data/example/SingleParticlesWithRef/data/121p-shift-300-0-0.roi +0 -0
  77. data/example/SingleParticlesWithRef/data/121p-shift-300-120-0.roi +0 -0
  78. data/example/SingleParticlesWithRef/data/121p-shift-300-180-0.roi +0 -0
  79. data/example/SingleParticlesWithRef/data/121p-shift-300-240-0.roi +0 -0
  80. data/example/SingleParticlesWithRef/data/121p-shift-300-300-0.roi +0 -0
  81. data/example/SingleParticlesWithRef/data/121p-shift-300-60-0.roi +0 -0
  82. data/example/SingleParticlesWithRef/data/121p-shift-60-0-0.roi +0 -0
  83. data/example/SingleParticlesWithRef/data/121p-shift-60-120-0.roi +0 -0
  84. data/example/SingleParticlesWithRef/data/121p-shift-60-180-0.roi +0 -0
  85. data/example/SingleParticlesWithRef/data/121p-shift-60-240-0.roi +0 -0
  86. data/example/SingleParticlesWithRef/data/121p-shift-60-300-0.roi +0 -0
  87. data/example/SingleParticlesWithRef/data/121p-shift-60-60-0.roi +0 -0
  88. data/example/SingleParticlesWithRef/data/121p-shift-noise-0-0-0.roi +0 -0
  89. data/example/SingleParticlesWithRef/data/121p-shift-noise-0-120-0.roi +0 -0
  90. data/example/SingleParticlesWithRef/data/121p-shift-noise-0-180-0.roi +0 -0
  91. data/example/SingleParticlesWithRef/data/121p-shift-noise-0-240-0.roi +0 -0
  92. data/example/SingleParticlesWithRef/data/121p-shift-noise-0-300-0.roi +0 -0
  93. data/example/SingleParticlesWithRef/data/121p-shift-noise-0-60-0.roi +0 -0
  94. data/example/SingleParticlesWithRef/data/121p-shift-noise-120-0-0.roi +0 -0
  95. data/example/SingleParticlesWithRef/data/121p-shift-noise-120-120-0.roi +0 -0
  96. data/example/SingleParticlesWithRef/data/121p-shift-noise-120-180-0.roi +0 -0
  97. data/example/SingleParticlesWithRef/data/121p-shift-noise-120-240-0.roi +0 -0
  98. data/example/SingleParticlesWithRef/data/121p-shift-noise-120-300-0.roi +0 -0
  99. data/example/SingleParticlesWithRef/data/121p-shift-noise-120-60-0.roi +0 -0
  100. data/example/SingleParticlesWithRef/data/121p-shift-noise-180-0-0.roi +0 -0
  101. data/example/SingleParticlesWithRef/data/121p-shift-noise-180-120-0.roi +0 -0
  102. data/example/SingleParticlesWithRef/data/121p-shift-noise-180-180-0.roi +0 -0
  103. data/example/SingleParticlesWithRef/data/121p-shift-noise-180-240-0.roi +0 -0
  104. data/example/SingleParticlesWithRef/data/121p-shift-noise-180-300-0.roi +0 -0
  105. data/example/SingleParticlesWithRef/data/121p-shift-noise-180-60-0.roi +0 -0
  106. data/example/SingleParticlesWithRef/data/121p-shift-noise-240-0-0.roi +0 -0
  107. data/example/SingleParticlesWithRef/data/121p-shift-noise-240-120-0.roi +0 -0
  108. data/example/SingleParticlesWithRef/data/121p-shift-noise-240-180-0.roi +0 -0
  109. data/example/SingleParticlesWithRef/data/121p-shift-noise-240-240-0.roi +0 -0
  110. data/example/SingleParticlesWithRef/data/121p-shift-noise-240-300-0.roi +0 -0
  111. data/example/SingleParticlesWithRef/data/121p-shift-noise-240-60-0.roi +0 -0
  112. data/example/SingleParticlesWithRef/data/121p-shift-noise-300-0-0.roi +0 -0
  113. data/example/SingleParticlesWithRef/data/121p-shift-noise-300-120-0.roi +0 -0
  114. data/example/SingleParticlesWithRef/data/121p-shift-noise-300-180-0.roi +0 -0
  115. data/example/SingleParticlesWithRef/data/121p-shift-noise-300-240-0.roi +0 -0
  116. data/example/SingleParticlesWithRef/data/121p-shift-noise-300-300-0.roi +0 -0
  117. data/example/SingleParticlesWithRef/data/121p-shift-noise-300-60-0.roi +0 -0
  118. data/example/SingleParticlesWithRef/data/121p-shift-noise-60-0-0.roi +0 -0
  119. data/example/SingleParticlesWithRef/data/121p-shift-noise-60-120-0.roi +0 -0
  120. data/example/SingleParticlesWithRef/data/121p-shift-noise-60-180-0.roi +0 -0
  121. data/example/SingleParticlesWithRef/data/121p-shift-noise-60-240-0.roi +0 -0
  122. data/example/SingleParticlesWithRef/data/121p-shift-noise-60-300-0.roi +0 -0
  123. data/example/SingleParticlesWithRef/data/121p-shift-noise-60-60-0.roi +0 -0
  124. data/example/SingleParticlesWithRef/data/121p-shift.pdb +3381 -0
  125. data/example/SingleParticlesWithRef/data/all.ref2d +0 -0
  126. data/example/SingleParticlesWithRef/data/all.ref3d +0 -0
  127. data/example/Sum/Sum.pione +52 -0
  128. data/example/SyntaxError/call_rule_error.pione +6 -0
  129. data/example/SyntaxError/feature_line_error.pione +7 -0
  130. data/example/SyntaxError/flow_block_error.pione +5 -0
  131. data/example/SyntaxError/input_line_error.pione +6 -0
  132. data/example/SyntaxError/invalid_rule_name.pione +6 -0
  133. data/example/SyntaxError/param_line_error.pione +7 -0
  134. data/example/SyntaxError/variable-binding-error.pione +11 -0
  135. data/lib/pione.rb +241 -0
  136. data/lib/pione/agent/basic-agent.rb +333 -0
  137. data/lib/pione/agent/broker.rb +274 -0
  138. data/lib/pione/agent/command-listener.rb +47 -0
  139. data/lib/pione/agent/input-generator.rb +194 -0
  140. data/lib/pione/agent/logger.rb +65 -0
  141. data/lib/pione/agent/process-manager.rb +38 -0
  142. data/lib/pione/agent/rule-provider.rb +64 -0
  143. data/lib/pione/agent/task-worker.rb +274 -0
  144. data/lib/pione/agent/trivial-routine-worker.rb +28 -0
  145. data/lib/pione/agent/tuple-space-client.rb +146 -0
  146. data/lib/pione/agent/tuple-space-server-client-life-checker.rb +29 -0
  147. data/lib/pione/command-option/basic-option.rb +42 -0
  148. data/lib/pione/command-option/child-process-option.rb +17 -0
  149. data/lib/pione/command-option/common-option.rb +29 -0
  150. data/lib/pione/command-option/daemon-option.rb +12 -0
  151. data/lib/pione/command-option/presence-notifier-option.rb +15 -0
  152. data/lib/pione/command-option/task-worker-owner-option.rb +17 -0
  153. data/lib/pione/command-option/tuple-space-provider-option.rb +26 -0
  154. data/lib/pione/command-option/tuple-space-provider-owner-option.rb +16 -0
  155. data/lib/pione/command-option/tuple-space-receiver-option.rb +12 -0
  156. data/lib/pione/command/basic-command.rb +126 -0
  157. data/lib/pione/command/child-process.rb +43 -0
  158. data/lib/pione/command/daemon-process.rb +18 -0
  159. data/lib/pione/command/front-owner-command.rb +37 -0
  160. data/lib/pione/command/pione-broker.rb +53 -0
  161. data/lib/pione/command/pione-clean.rb +16 -0
  162. data/lib/pione/command/pione-client.rb +273 -0
  163. data/lib/pione/command/pione-relay-account-db.rb +85 -0
  164. data/lib/pione/command/pione-relay-client-db.rb +80 -0
  165. data/lib/pione/command/pione-relay.rb +47 -0
  166. data/lib/pione/command/pione-syntax-checker.rb +103 -0
  167. data/lib/pione/command/pione-task-worker.rb +123 -0
  168. data/lib/pione/command/pione-tuple-space-provider.rb +87 -0
  169. data/lib/pione/command/pione-tuple-space-receiver.rb +55 -0
  170. data/lib/pione/command/pione-tuple-space-viewer.rb +151 -0
  171. data/lib/pione/command/tuple-space-provider-owner.rb +6 -0
  172. data/lib/pione/front/basic-front.rb +64 -0
  173. data/lib/pione/front/broker-front.rb +30 -0
  174. data/lib/pione/front/client-front.rb +28 -0
  175. data/lib/pione/front/relay-front.rb +19 -0
  176. data/lib/pione/front/task-worker-front.rb +16 -0
  177. data/lib/pione/front/task-worker-owner.rb +42 -0
  178. data/lib/pione/front/tuple-space-provider-front.rb +22 -0
  179. data/lib/pione/front/tuple-space-provider-owner.rb +11 -0
  180. data/lib/pione/front/tuple-space-receiver-front.rb +18 -0
  181. data/lib/pione/model/assignment.rb +89 -0
  182. data/lib/pione/model/basic-model.rb +395 -0
  183. data/lib/pione/model/binary-operator.rb +80 -0
  184. data/lib/pione/model/block.rb +233 -0
  185. data/lib/pione/model/boolean.rb +138 -0
  186. data/lib/pione/model/call-rule.rb +69 -0
  187. data/lib/pione/model/data-expr.rb +360 -0
  188. data/lib/pione/model/feature-expr.rb +794 -0
  189. data/lib/pione/model/float.rb +107 -0
  190. data/lib/pione/model/integer.rb +140 -0
  191. data/lib/pione/model/list.rb +104 -0
  192. data/lib/pione/model/message.rb +80 -0
  193. data/lib/pione/model/package.rb +48 -0
  194. data/lib/pione/model/parameters.rb +282 -0
  195. data/lib/pione/model/rule-expr.rb +120 -0
  196. data/lib/pione/model/rule-io.rb +166 -0
  197. data/lib/pione/model/rule.rb +294 -0
  198. data/lib/pione/model/string.rb +111 -0
  199. data/lib/pione/model/undefined-value.rb +24 -0
  200. data/lib/pione/model/variable-table.rb +315 -0
  201. data/lib/pione/model/variable.rb +87 -0
  202. data/lib/pione/parser/block-parser.rb +83 -0
  203. data/lib/pione/parser/common-parser.rb +145 -0
  204. data/lib/pione/parser/document-parser.rb +58 -0
  205. data/lib/pione/parser/error-message.yml +4 -0
  206. data/lib/pione/parser/expr-parser.rb +266 -0
  207. data/lib/pione/parser/feature-expr-parser.rb +105 -0
  208. data/lib/pione/parser/flow-element-parser.rb +181 -0
  209. data/lib/pione/parser/literal-parser.rb +182 -0
  210. data/lib/pione/parser/rule-definition-parser.rb +163 -0
  211. data/lib/pione/parser/syntax-error.rb +61 -0
  212. data/lib/pione/patch/array-patch.rb +3 -0
  213. data/lib/pione/patch/drb-patch.rb +467 -0
  214. data/lib/pione/patch/monitor-patch.rb +16 -0
  215. data/lib/pione/patch/rinda-patch.rb +759 -0
  216. data/lib/pione/patch/uri-patch.rb +66 -0
  217. data/lib/pione/relay/receiver-socket.rb +69 -0
  218. data/lib/pione/relay/relay-account-db.rb +55 -0
  219. data/lib/pione/relay/relay-client-db.rb +53 -0
  220. data/lib/pione/relay/relay-socket.rb +215 -0
  221. data/lib/pione/relay/trampoline.rb +22 -0
  222. data/lib/pione/relay/transmitter-socket.rb +167 -0
  223. data/lib/pione/resource/basic-resource.rb +92 -0
  224. data/lib/pione/resource/dropbox-resource.rb +106 -0
  225. data/lib/pione/resource/ftp.rb +84 -0
  226. data/lib/pione/resource/local.rb +113 -0
  227. data/lib/pione/rule-handler/action-handler.rb +184 -0
  228. data/lib/pione/rule-handler/basic-handler.rb +217 -0
  229. data/lib/pione/rule-handler/flow-handler.rb +339 -0
  230. data/lib/pione/rule-handler/root-handler.rb +23 -0
  231. data/lib/pione/rule-handler/system-handler.rb +13 -0
  232. data/lib/pione/system/common.rb +22 -0
  233. data/lib/pione/system/config.rb +20 -0
  234. data/lib/pione/system/document.rb +81 -0
  235. data/lib/pione/system/file-cache.rb +150 -0
  236. data/lib/pione/system/global.rb +346 -0
  237. data/lib/pione/system/identifier.rb +61 -0
  238. data/lib/pione/system/init.rb +16 -0
  239. data/lib/pione/system/object.rb +35 -0
  240. data/lib/pione/transformer/block-transformer.rb +23 -0
  241. data/lib/pione/transformer/document-transformer.rb +36 -0
  242. data/lib/pione/transformer/expr-transformer.rb +89 -0
  243. data/lib/pione/transformer/feature-expr-transformer.rb +56 -0
  244. data/lib/pione/transformer/flow-element-transformer.rb +66 -0
  245. data/lib/pione/transformer/literal-transformer.rb +76 -0
  246. data/lib/pione/transformer/rule-definition-transformer.rb +62 -0
  247. data/lib/pione/transformer/transformer-module.rb +37 -0
  248. data/lib/pione/tuple-space/data-finder.rb +165 -0
  249. data/lib/pione/tuple-space/presence-notifier.rb +83 -0
  250. data/lib/pione/tuple-space/relay.rb +9 -0
  251. data/lib/pione/tuple-space/tuple-space-provider.rb +85 -0
  252. data/lib/pione/tuple-space/tuple-space-receiver.rb +140 -0
  253. data/lib/pione/tuple-space/tuple-space-server-interface.rb +60 -0
  254. data/lib/pione/tuple-space/tuple-space-server.rb +156 -0
  255. data/lib/pione/tuple-space/update-criteria.rb +96 -0
  256. data/lib/pione/tuple/agent-tuple.rb +10 -0
  257. data/lib/pione/tuple/attribute-tuple.rb +7 -0
  258. data/lib/pione/tuple/base-uri-tuple.rb +9 -0
  259. data/lib/pione/tuple/basic-tuple.rb +317 -0
  260. data/lib/pione/tuple/bye-tuple.rb +9 -0
  261. data/lib/pione/tuple/command-tuple.rb +9 -0
  262. data/lib/pione/tuple/data-tuple.rb +18 -0
  263. data/lib/pione/tuple/dry-run-tuple.rb +8 -0
  264. data/lib/pione/tuple/exception-tuple.rb +11 -0
  265. data/lib/pione/tuple/finished-tuple.rb +17 -0
  266. data/lib/pione/tuple/foreground-tuple.rb +7 -0
  267. data/lib/pione/tuple/log-tuple.rb +14 -0
  268. data/lib/pione/tuple/process-info-tuple.rb +9 -0
  269. data/lib/pione/tuple/request-rule-tuple.rb +9 -0
  270. data/lib/pione/tuple/rule-tuple.rb +10 -0
  271. data/lib/pione/tuple/shift-tuple.rb +13 -0
  272. data/lib/pione/tuple/task-tuple.rb +36 -0
  273. data/lib/pione/tuple/task-worker-resource-tuple.rb +9 -0
  274. data/lib/pione/tuple/working-tuple.rb +13 -0
  275. data/lib/pione/uri-scheme/basic-scheme.rb +40 -0
  276. data/lib/pione/uri-scheme/broadcast-scheme.rb +11 -0
  277. data/lib/pione/uri-scheme/dropbox-scheme.rb +9 -0
  278. data/lib/pione/uri-scheme/local-scheme.rb +28 -0
  279. data/lib/pione/util/error-report.rb +12 -0
  280. data/lib/pione/util/log.rb +79 -0
  281. data/lib/pione/util/message.rb +155 -0
  282. data/lib/pione/util/misc.rb +73 -0
  283. data/lib/pione/util/terminal.rb +78 -0
  284. data/lib/pione/util/waiter-table.rb +53 -0
  285. data/lib/pione/version.rb +3 -0
  286. data/misc/env.sh +2 -0
  287. data/misc/test-drb-stop-service.rb +34 -0
  288. data/misc/test-ensure-and-thread-kill.rb +40 -0
  289. data/misc/test-many-waiters-client.rb +56 -0
  290. data/misc/test-many-waiters-server.rb +14 -0
  291. data/misc/write_and_take_test.png +0 -0
  292. data/misc/write_and_take_test.rb +36 -0
  293. data/pione.gemspec +49 -0
  294. data/test/agent/spec_basic-agent.rb +170 -0
  295. data/test/agent/spec_broker.rb +36 -0
  296. data/test/agent/spec_command-listener.rb +30 -0
  297. data/test/agent/spec_input-generator.rb +123 -0
  298. data/test/agent/spec_logger.rb +71 -0
  299. data/test/agent/spec_rule-provider.rb +65 -0
  300. data/test/agent/spec_task-worker.rb +307 -0
  301. data/test/agent/spec_tuple-space-client.rb +30 -0
  302. data/test/model/spec_assignment.rb +51 -0
  303. data/test/model/spec_binary-operator.rb +39 -0
  304. data/test/model/spec_block.rb +154 -0
  305. data/test/model/spec_boolean.rb +115 -0
  306. data/test/model/spec_call-rule.rb +23 -0
  307. data/test/model/spec_data-expr.rb +312 -0
  308. data/test/model/spec_feature-expr.rb +359 -0
  309. data/test/model/spec_feature-expr.yml +16 -0
  310. data/test/model/spec_float.rb +141 -0
  311. data/test/model/spec_integer.rb +141 -0
  312. data/test/model/spec_list.rb +26 -0
  313. data/test/model/spec_message.rb +42 -0
  314. data/test/model/spec_package.rb +15 -0
  315. data/test/model/spec_parameters.rb +148 -0
  316. data/test/model/spec_rule-expr.rb +66 -0
  317. data/test/model/spec_rule-io.rb +32 -0
  318. data/test/model/spec_rule.rb +158 -0
  319. data/test/model/spec_string.rb +106 -0
  320. data/test/model/spec_variable-table.rb +117 -0
  321. data/test/model/spec_variable.rb +84 -0
  322. data/test/parser/spec_block-parser.rb +5 -0
  323. data/test/parser/spec_block-parser.yml +85 -0
  324. data/test/parser/spec_common-parser.rb +281 -0
  325. data/test/parser/spec_expr-parser.rb +6 -0
  326. data/test/parser/spec_expr-parser.yml +82 -0
  327. data/test/parser/spec_feature-expr-parser.rb +32 -0
  328. data/test/parser/spec_feature-expr-parser.yml +25 -0
  329. data/test/parser/spec_flow-element-parser.rb +5 -0
  330. data/test/parser/spec_flow-element-parser.yml +180 -0
  331. data/test/parser/spec_literal-parser.rb +5 -0
  332. data/test/parser/spec_literal-parser.yml +123 -0
  333. data/test/parser/spec_rule-definition-parser.rb +5 -0
  334. data/test/parser/spec_rule-definition-parser.yml +93 -0
  335. data/test/patch/spec_rinda-patch.rb +32 -0
  336. data/test/patch/spec_uri-patch.rb +23 -0
  337. data/test/rule-handler/spec_action-handler.rb +135 -0
  338. data/test/rule-handler/spec_flow-handler.rb +127 -0
  339. data/test/spec_common.rb +14 -0
  340. data/test/spec_data-finder.rb +88 -0
  341. data/test/spec_data-finder.yml +115 -0
  342. data/test/spec_document.rb +76 -0
  343. data/test/spec_identifier.rb +29 -0
  344. data/test/spec_log.rb +52 -0
  345. data/test/spec_object.rb +20 -0
  346. data/test/spec_resource.rb +73 -0
  347. data/test/spec_update-criteria.rb +83 -0
  348. data/test/test-util.rb +223 -0
  349. data/test/transformer/spec_block-transformer.rb +26 -0
  350. data/test/transformer/spec_expr-transformer.rb +106 -0
  351. data/test/transformer/spec_feature-expr-transformer.rb +21 -0
  352. data/test/transformer/spec_flow-element-transformer.rb +154 -0
  353. data/test/transformer/spec_literal-transformer.rb +58 -0
  354. data/test/transformer/spec_rule-definition-transformer.rb +168 -0
  355. data/test/tuple-space/spec_tuple-space-provider.rb +36 -0
  356. data/test/tuple-space/spec_tuple-space-receiver.rb +32 -0
  357. data/test/tuple-space/spec_tuple-space-server.rb +49 -0
  358. data/test/tuple/spec_basic-tuple.rb +87 -0
  359. data/test/tuple/spec_data-tuple.rb +85 -0
  360. data/test/tuple/spec_finished-tuple.rb +61 -0
  361. data/test/tuple/spec_task-tuple.rb +127 -0
  362. data/test/tuple/spec_working-tuple.rb +58 -0
  363. data/test/uri-scheme/spec_broadcast-scheme.rb +40 -0
  364. data/test/uri-scheme/spec_dropbox-scheme.rb +31 -0
  365. data/test/uri-scheme/spec_local-scheme.rb +69 -0
  366. metadata +660 -0
@@ -0,0 +1,794 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Pione::Model
4
+ # Feature is selection system between task and task worker.
5
+ module Feature
6
+ class << self
7
+ # Returns feature conjunction.
8
+ # @param [Array<Expr>] exprs
9
+ # feature expression list
10
+ # @return [Expr]
11
+ # conjuncted expression
12
+ def and(*exprs)
13
+ AndExpr.new(*exprs)
14
+ end
15
+
16
+ # Returns feature disjunction.
17
+ # @param [Array<Expr>] exprs
18
+ # feature expression list
19
+ # @return [Expr]
20
+ # disjuncted expression
21
+ def or(*exprs)
22
+ OrExpr.new(*exprs)
23
+ end
24
+
25
+ # Returns empty feature.
26
+ # @return [Expr]
27
+ # empty feature
28
+ def empty
29
+ empty ||= EmptyFeature.new
30
+ end
31
+
32
+ # Returns boundless feature
33
+ # @return [Expr]
34
+ # boundless feature
35
+ def boundless
36
+ boundless ||= BoundlessFeature.new
37
+ end
38
+ end
39
+
40
+ # Expr is a super class for all feature expressions.
41
+ class Expr < BasicModel
42
+ set_pione_model_type TypeFeature
43
+
44
+ # Returns itself.
45
+ # @return [Expr]
46
+ # itself
47
+ def simplify
48
+ return self
49
+ end
50
+
51
+ # Returns true if the feature is empty.
52
+ # @return [Boolean]
53
+ # false
54
+ def empty?
55
+ return false
56
+ end
57
+
58
+ # Returns true if the other matches the feature.
59
+ # @return [Boolean]
60
+ # true if the other matches the feature
61
+ def match(other)
62
+ raise ArgumentError.new(other) unless other.kind_of?(Expr)
63
+ Sentence.new(self, other).decide
64
+ end
65
+
66
+ alias :=== :match
67
+ end
68
+
69
+ # SpecialFeature is a class for empty feature and boundless feature.
70
+ class SpecialFeature < Expr
71
+ # @api private
72
+ def task_id_string
73
+ "Feature::SpecialFeature<#{symbol}>"
74
+ end
75
+
76
+ # @api private
77
+ def textize
78
+ "#{symbol}"
79
+ end
80
+
81
+ # @api private
82
+ def ==(other)
83
+ other.kind_of?(self.class)
84
+ end
85
+
86
+ alias :eql? :==
87
+
88
+ # @api private
89
+ def hash
90
+ true.hash
91
+ end
92
+ end
93
+
94
+ # EmptyFeature is a class for empty feature that is one of special
95
+ # features. This is written as '*', that means the worker has no specific
96
+ # ability in provider expression and the task has no specific request in
97
+ # request expression.
98
+ class EmptyFeature < SpecialFeature
99
+ # Returns "*".
100
+ # return [Boolean]
101
+ # "*"
102
+ def symbol
103
+ "*"
104
+ end
105
+
106
+ # Returns true because empty feature is empty.
107
+ # @return [Boolean]
108
+ # true
109
+ def empty?
110
+ true
111
+ end
112
+
113
+ # @api private
114
+ def ==(other)
115
+ return false unless other.kind_of?(Expr)
116
+ other.empty?
117
+ end
118
+ end
119
+
120
+ # BoundlessFeature is a class for whole feature that is one of special
121
+ # features. This is written as '@', that means the worker has boundless
122
+ # ability in provider expression and the task has boundless ability request
123
+ # in request expression.
124
+ class BoundlessFeature < SpecialFeature
125
+ def symbol
126
+ "@"
127
+ end
128
+ end
129
+
130
+ # Operator is superclass of all operator classes.
131
+ class Operator < Expr; end
132
+
133
+ # UnaryOperator is a class for provider opeators and request operator.
134
+ class UnaryOperator < Operator
135
+ attr_reader :symbol
136
+
137
+ # Returns the operator symbol.
138
+ # @return [String]
139
+ # operator symbol
140
+ # @example
141
+ # # requisite feature
142
+ # +
143
+ # @example
144
+ # # blocking feature
145
+ # -
146
+ # @example
147
+ # # preferred feature
148
+ # ?
149
+ # @example
150
+ # # possible operator
151
+ # ^
152
+ # @example
153
+ # # restrictive opeator
154
+ # !
155
+ def self.operator
156
+ @operator
157
+ end
158
+
159
+ # Creates a new operator.
160
+ # @param [Symbol] symbol
161
+ # feature symbol
162
+ def initialize(symbol)
163
+ @symbol = symbol
164
+ super()
165
+ end
166
+
167
+ # @api private
168
+ def task_id_string
169
+ "Feature::UnaryOperator<#{self.operator},#{@symbol}>"
170
+ end
171
+
172
+ # @api private
173
+ def textize
174
+ "%s%s" % [self.operator, @symbol]
175
+ end
176
+
177
+ # @api private
178
+ def as_string
179
+ self.class.operator + @symbol.to_s
180
+ end
181
+
182
+ # @api private
183
+ def ==(other)
184
+ other.kind_of?(self.class) and @symbol == other.symbol
185
+ end
186
+
187
+ alias :eql? :==
188
+
189
+ # @api private
190
+ def hash
191
+ @symbol.hash
192
+ end
193
+ end
194
+
195
+ # ProviderOperator is a class for provider operators.
196
+ class ProviderExpr < UnaryOperator; end
197
+
198
+ # PossibleOperator is a class for possible feature expressions. Possible
199
+ # feature are written like as "^X", these represent feature's possible
200
+ # ability.
201
+ class PossibleExpr < ProviderExpr
202
+ @operator = "^"
203
+ end
204
+
205
+ # RestrictiveExpr is a class for restrictive feature expression.
206
+ # @example
207
+ # !X
208
+ class RestrictiveExpr < ProviderExpr
209
+ @operator = "!"
210
+ end
211
+
212
+ # RequestOperator is a class for task's feature expression operators.
213
+ class RequestExpr < UnaryOperator; end
214
+
215
+ # Requisite Operator is a class for requisite feature expressions. Requisite
216
+ # Feature are written like as "+X", these represent feature's requiste
217
+ # ability.
218
+ # @example
219
+ # +X
220
+ class RequisiteExpr < RequestExpr
221
+ @operator = "+"
222
+ end
223
+
224
+ # BlockingExpr is a class for blocking feature expressions. Blocking Feature
225
+ # are written like as "-X", these represent the ability that block to
226
+ # execute the task.
227
+ # @example
228
+ # -X
229
+ class BlockingExpr < RequestExpr
230
+ @operator = "-"
231
+ end
232
+
233
+ # PreferredExpr is a class for preferred feature expressions. Preferred
234
+ # Feature are written like as "?X", these represent that task workers what
235
+ # the feature have take the task.
236
+ class PreferredExpr < RequestExpr
237
+ @operator = "?"
238
+ end
239
+
240
+ # Connective is a superclass of AndExpr and OrExpr. This represents
241
+ # connection of some features.
242
+ class Connective < Expr
243
+ attr_reader :elements
244
+
245
+ # Creates a new connective.
246
+ # @param [Array<Expr>] elements
247
+ # feature list
248
+ def initialize(*elements)
249
+ @elements = Set.new
250
+ elements.each {|elt| add(elt) }
251
+ super()
252
+ end
253
+
254
+ # Adds the element from the connective set and unifies by it.
255
+ # @param [Expr] elt
256
+ # feature element
257
+ # @return [void]
258
+ def add(elt)
259
+ if elt.kind_of?(self.class)
260
+ elt.elements.each {|e| unify(e) }
261
+ else
262
+ unify(elt)
263
+ end
264
+ end
265
+
266
+ # Deletes the element from the connective set.
267
+ # @param [Expr] elt
268
+ # feature element
269
+ # @return [void]
270
+ def delete(elt)
271
+ @elements.delete(elt)
272
+ if @elements.empty?
273
+ @elements.add(EmptyFeature.new)
274
+ end
275
+ end
276
+
277
+ # Unifies connective set by the element.
278
+ # @param [Expr] elt
279
+ # feature element
280
+ # @return [void]
281
+ def unify(elt)
282
+ unless self.class::UNIFICATIONS.any?{|name| __send__(name, elt)}
283
+ @elements.add(elt)
284
+ end
285
+ end
286
+
287
+ # Simplifies the connective by unifing and up-rising single element.
288
+ # @return [Expr]
289
+ # simplified feature
290
+ def simplify
291
+ if @elements.size == 1
292
+ return @elements.first.simplify
293
+ else
294
+ elements = @elements.map{|e| e.simplify}
295
+ @elements.clear
296
+ elements.each {|e| add(e)}
297
+ return self
298
+ end
299
+ end
300
+
301
+ # Returns true if the connective set is empty.
302
+ # @return [Boolean]
303
+ # true if the connective set is empty
304
+ def empty?
305
+ return true if @elements.empty?
306
+ return true if @elements == Set.new([Feature.empty])
307
+ return false unless @elements.size == 1
308
+ return @elements.first.empty?
309
+ end
310
+
311
+ # @api private
312
+ def task_id_string
313
+ "Feature::Connective<#{self.class.name},[%s]>" % [
314
+ @elements.map{|elt| elt.task_id_string}.join(",")
315
+ ]
316
+ end
317
+
318
+ # @api private
319
+ def textize
320
+ "#{self.class.name}(%s)" % [
321
+ @elements.map{|elt| elt.textize}.join(",")
322
+ ]
323
+ end
324
+
325
+ # @api private
326
+ def ==(other)
327
+ return true if empty? and other.kind_of?(Expr) and other.empty?
328
+ other.kind_of?(self.class) and @elements == other.elements
329
+ end
330
+
331
+ alias :eql? :==
332
+
333
+ # @api private
334
+ def hash
335
+ @elements.hash
336
+ end
337
+
338
+ # Clone with cloning the elements set.
339
+ # @api private
340
+ def clone
341
+ obj = super
342
+ elements = @elements.clone
343
+ obj.instance_eval { @elements = elements }
344
+ return obj
345
+ end
346
+ end
347
+
348
+ class AndExpr < Connective
349
+ UNIFICATIONS =
350
+ [ :unify_redundant_feature,
351
+ :summarize_or,
352
+ :background_preferred_feature,
353
+ :unify_by_restrictive_feature
354
+ ]
355
+
356
+ module UnificationMethod
357
+ def unify_redundant_feature(elt)
358
+ # Γ & Γ -> Γ
359
+ # Δ & Δ -> Δ
360
+ return @elements.include?(elt)
361
+ end
362
+
363
+ def summarize_or(elt)
364
+ if elt.kind_of?(OrExpr)
365
+ if target = @elements.find {|e|
366
+ if e.kind_of?(OrExpr)
367
+ not((e.elements & elt.elements).empty?)
368
+ end
369
+ }
370
+ # (Γ1 | Γ2) & (Γ1 | Γ3) -> Γ1 | (Γ2 & Γ3)
371
+ @elements.delete(target)
372
+ union = target.elements & elt.elements
373
+ union_expr = if union.length > 1
374
+ OrExpr.new(*union.to_a)
375
+ else
376
+ union.to_a.first
377
+ end
378
+ add(
379
+ OrExpr.new(
380
+ union_expr,
381
+ AndExpr.new(
382
+ OrExpr.new(*(target.elements - union).to_a),
383
+ OrExpr.new(*(elt.elements - union).to_a)
384
+ )
385
+ )
386
+ )
387
+ return true
388
+ else
389
+ # Γ1 & (Γ1 | Γ3) -> Γ1
390
+ return not((@elements & elt.elements).empty?)
391
+ end
392
+ else
393
+ # (Γ1 | Γ2) & Γ1 -> Γ1
394
+ if @elements.reject!{|e| e == elt }
395
+ add(elt)
396
+ return true
397
+ end
398
+ end
399
+ return false
400
+ end
401
+
402
+ def background_preferred_feature(elt)
403
+ case elt
404
+ when PreferredExpr
405
+ # !X & ?X -> !X
406
+ # ^X & ?X -> ^X
407
+ return @elements.any? {|e|
408
+ e.symbol == elt.symbol &&
409
+ (e.kind_of?(RequisiteExpr) || e.kind_of?(BlockingExpr))
410
+ }
411
+ when RequisiteExpr, BlockingExpr
412
+ # ?X & !X -> !X
413
+ # ?X & ^X -> ^X
414
+ if @elements.reject! {|e|
415
+ if e.kind_of?(PreferredExpr)
416
+ e.symbol == elt.symbol
417
+ end
418
+ }
419
+ add(elt)
420
+ return true
421
+ end
422
+ end
423
+ return false
424
+ end
425
+
426
+ def unify_by_restrictive_feature(elt)
427
+ case elt
428
+ when RestrictiveExpr
429
+ # ^X & !X -> !X
430
+ if @elements.reject! {|e|
431
+ if e.kind_of?(PossibleExpr)
432
+ e.symbol == elt.symbol
433
+ end
434
+ }
435
+ add(elt)
436
+ return true
437
+ end
438
+ when PossibleExpr
439
+ # !X & ^X -> !X
440
+ return @elements.any? {|e|
441
+ if e.kind_of?(RestrictiveExpr)
442
+ e.symbol == elt.symbol
443
+ end
444
+ }
445
+ end
446
+ return false
447
+ end
448
+ end
449
+
450
+ include UnificationMethod
451
+
452
+ # Makes an expander for response test.
453
+ def expander
454
+ # convert or-clause into expander
455
+ elements = @elements.map do |elt|
456
+ elt.kind_of?(OrExpr) ? elt.expander : elt
457
+ end
458
+ # return an enumerator
459
+ return Enumerator.new {|y| choose_concrete_expr(y, elements, [], nil, 0) }
460
+ end
461
+
462
+ private
463
+
464
+ require 'fiber'
465
+
466
+ # Chooses a concrete expression that expand or-clause.
467
+ def choose_concrete_expr(y, orig, list, fiber, i)
468
+ if orig.size == i
469
+ # when reach the terminateion of elements, yield a concrete expression
470
+ y << AndExpr.new(*convert_cons_list_into_array(list))
471
+ else
472
+ # or-clause
473
+ if orig[i].kind_of?(Enumerator)
474
+ # create a new fiber
475
+ _fiber = Fiber.new do
476
+ loop do
477
+ # rewind unreached enumerators
478
+ orig.each_with_index do |e, ii|
479
+ e.rewind if ii > i && e.kind_of?(Enumerator)
480
+ end
481
+ # choose next
482
+ choose_concrete_expr(y, orig, [orig[i].next, list], _fiber, i+1)
483
+ # retrun fiber loop
484
+ Fiber.yield
485
+ end
486
+ end
487
+ # fiber loop
488
+ begin
489
+ _fiber.transfer while true
490
+ rescue FiberError => e
491
+ fiber.transfer if fiber
492
+ end
493
+ else
494
+ # other elements
495
+ choose_concrete_expr(y, orig, [orig[i], list], fiber, i+1)
496
+ end
497
+ end
498
+ end
499
+
500
+ # Returns an array by converting from cons list.
501
+ def convert_cons_list_into_array(input)
502
+ input == [] ? [] : convert_cons_list_into_array(input[1]) << input.first
503
+ end
504
+ end
505
+
506
+ class OrExpr < Connective
507
+ UNIFICATIONS =
508
+ [ :unify_redundant_feature,
509
+ :summarize_and,
510
+ :foreground_preferred_feature,
511
+ :unify_by_possible_feature,
512
+ :neutralize
513
+ ]
514
+
515
+ module UnificationMethod
516
+ def unify_redundant_feature(elt)
517
+ # Γ | Γ -> Γ
518
+ # Δ | Δ -> Δ
519
+ return @elements.include?(elt)
520
+ end
521
+
522
+ def summarize_and(elt)
523
+ if elt.kind_of?(AndExpr)
524
+ if target = @elements.find {|e|
525
+ e.kind_of?(AndExpr) && not((e.elements & elt.elements).empty?)
526
+ }
527
+ # (Γ1 & Γ2) | (Γ1 & Γ3) -> Γ1 & (Γ2 | Γ3)
528
+ @elements.delete(target)
529
+ union = target.elements & elt.elements
530
+ union_expr = if union.length > 1
531
+ AndExpr.new(*union.to_a)
532
+ else
533
+ union.to_a.first
534
+ end
535
+ add(AndExpr.new(union_expr,
536
+ OrExpr.new(AndExpr.new(*(target.elements - union).to_a),
537
+ AndExpr.new(*(elt.elements - union).to_a))))
538
+ return true
539
+ else
540
+ # Γ1 | (Γ1 & Γ3) -> Γ1
541
+ # return not((@elements & elt.elements).empty?)
542
+ end
543
+ else
544
+ # (Γ1 & Γ2) | Γ1 -> Γ1
545
+ # if @elements.reject!{|e| e == elt }
546
+ # add(elt)
547
+ # return true
548
+ # end
549
+ end
550
+ return false
551
+ end
552
+
553
+ def foreground_preferred_feature(elt)
554
+ case elt
555
+ when PreferredExpr
556
+ # !X | ?X -> ?X
557
+ # ^X | ?X -> ?X
558
+ if @elements.reject! {|e|
559
+ e.symbol == elt.symbol &&
560
+ (e.kind_of?(RequisiteExpr) || e.kind_of?(BlockingExpr))
561
+ }
562
+ add(elt)
563
+ return true
564
+ end
565
+ when RequisiteExpr, BlockingExpr
566
+ # ?X | !X -> ?X
567
+ # ?X | ^X -> ?X
568
+ return @elements.any? {|e|
569
+ e.symbol == elt.symbol && e.kind_of?(PreferredExpr)
570
+ }
571
+ end
572
+ return false
573
+ end
574
+
575
+ def unify_by_possible_feature(elt)
576
+ case elt
577
+ when PossibleExpr
578
+ # !X | ^X -> ^X
579
+ if @elements.reject! {|e|
580
+ e.symbol == elt.symbol && e.kind_of?(RestrictiveExpr)
581
+ }
582
+ add(elt)
583
+ return true
584
+ end
585
+ when RestrictiveExpr
586
+ # ^X | !X -> ^X
587
+ return @elements.any? {|e|
588
+ e.symbol == elt.symbol && e.kind_of?(PossibleExpr)
589
+ }
590
+ end
591
+ return false
592
+ end
593
+
594
+ def neutralize(elt)
595
+ case elt
596
+ when BlockingExpr
597
+ # +X | -X -> *
598
+ if @elements.reject!{|e|
599
+ e.symbol == elt.symbol && e.kind_of?(RequisiteExpr)
600
+ }
601
+ add(EmptyFeature.new)
602
+ return true
603
+ end
604
+ when RequisiteExpr
605
+ # -X | +X -> *
606
+ if @elements.reject!{|e|
607
+ e.symbol == elt.symbol && e.kind_of?(BlockingExpr)
608
+ }
609
+ add(EmptyFeature.new)
610
+ return true
611
+ end
612
+ end
613
+ return false
614
+ end
615
+ end
616
+
617
+ include UnificationMethod
618
+
619
+ # Makes an expander for response test.
620
+ def expander
621
+ Enumerator.new do |y|
622
+ @elements.each do |elt|
623
+ elt.kind_of?(AndExpr) ? elt.expander.each {|e| y << e } : y << elt
624
+ end
625
+ end
626
+ end
627
+ end
628
+
629
+ class Sentence < Expr
630
+ ELIMINATIONS =
631
+ [ :eliminate_requisite_feature,
632
+ :eliminate_blocking_feature,
633
+ :eliminate_preferred_feature,
634
+ :eliminate_or_clause_including_empty_feature,
635
+ :eliminate_possible_feature
636
+ ]
637
+
638
+ module EliminationMethod
639
+ def eliminate_requisite_feature(provider, request)
640
+ # (^X & Γ <- +X & Δ) -> Γ & Δ
641
+ # (!X & Γ <- +X & Δ) -> Γ & Δ
642
+ request.elements.each do |r|
643
+ next unless r.kind_of?(RequisiteExpr)
644
+ provider.elements.each do |p|
645
+ next unless p.symbol == r.symbol
646
+ next unless p.kind_of?(PossibleExpr) || p.kind_of?(RestrictiveExpr)
647
+ # eliminate only if Γ dosen't include same symbol feature
648
+ next if provider.elements.any? {|e|
649
+ p.symbol == e.symbol && not(e.kind_of?(p.class))
650
+ }
651
+ # eliminate only if Δ dosen't include same symbol feature
652
+ next if request.elements.any? {|e|
653
+ r.symbol == e.symbol && not(e.kind_of?(r.class))
654
+ }
655
+ # eliminate
656
+ _provider = provider.clone.tap{|x| x.delete(p)}
657
+ _request = request.clone.tap{|x| x.delete(r)}
658
+ return true, _provider, _request
659
+ end
660
+ end
661
+ return false
662
+ end
663
+ module_function :eliminate_requisite_feature
664
+
665
+ def eliminate_blocking_feature(provider, request)
666
+ # (Γ <- -X & Δ) -> Γ & Δ
667
+ request.elements.each do |r|
668
+ next unless r.kind_of?(BlockingExpr)
669
+ # eliminate only if Γ dosen't include same symbol feature
670
+ next if request.elements.any? {|e|
671
+ r.symbol == e.symbol && not(e.kind_of?(r.class))
672
+ }
673
+ # eliminate only if Δ dosen't include same symbol feature
674
+ next if provider.elements.any? {|e|
675
+ r.symbol == e.symbol && not(e.kind_of?(p.class))
676
+ }
677
+ # eliminate
678
+ _request = request.clone.tap{|x| x.delete(r)}
679
+ return true, provider, _request
680
+ end
681
+ return false
682
+ end
683
+ module_function :eliminate_blocking_feature
684
+
685
+ def eliminate_preferred_feature(provider, request)
686
+ # (Γ <- ?X & Δ) -> (Γ <- Δ)
687
+ if request.elements.any? {|e| e.kind_of?(PreferredExpr)}
688
+ _request = request.clone.tap do |x|
689
+ x.elements.reject! {|e| e.kind_of?(PreferredExpr)}
690
+ end
691
+ return true, provider, _request
692
+ end
693
+ return false
694
+ end
695
+ module_function :eliminate_preferred_feature
696
+
697
+ def eliminate_or_clause_including_empty_feature(provider, request)
698
+ # ((* | Γ1) & Γ2 <- *) -> (Γ2 <- *)
699
+ return false unless request.empty?
700
+ provider.elements.each do |elt|
701
+ next unless elt.kind_of?(OrExpr)
702
+ next unless elt.elements.include?(EmptyFeature.new)
703
+ _provider = provider.clone.tap{|x| x.delete(elt)}
704
+ return true, _provider, request
705
+ end
706
+ return false
707
+ end
708
+ module_function :eliminate_or_clause_including_empty_feature
709
+
710
+ def eliminate_possible_feature(provider, request)
711
+ # (^X & Γ <- Δ) -> (Γ <- Δ)
712
+ provider.elements.each do |p|
713
+ next unless p.kind_of?(PossibleExpr)
714
+ # eliminate only if Γ dosen't include same symbol feature
715
+ next if provider.elements.any? {|e|
716
+ p.symbol == e.symbol && not(e.kind_of?(p.class))
717
+ }
718
+ # eliminate only if Δ dosen't include same symbol feature
719
+ next if request.elements.any? {|e|
720
+ p.symbol == e.symbol && not(e.kind_of?(p.class))
721
+ }
722
+ # eliminate
723
+ _provider = provider.clone.tap{|x| x.delete(p)}
724
+ return true, _provider, request
725
+ end
726
+ return false
727
+ end
728
+ module_function :eliminate_possible_feature
729
+ end
730
+
731
+ include EliminationMethod
732
+
733
+ def initialize(provider, request)
734
+ @provider = AndExpr.new(provider.simplify)
735
+ @request = AndExpr.new(request.simplify)
736
+ super()
737
+ end
738
+
739
+ # Return true if the provider expression can respond to the request.
740
+ def decide
741
+ result = false
742
+ begin
743
+ @provider.expander.each do |provider|
744
+ @request.expander.each do |request|
745
+ if match(provider, request)
746
+ result = true
747
+ raise StopIteration
748
+ end
749
+ end
750
+ end
751
+ rescue StopIteration
752
+ end
753
+ return result
754
+ end
755
+
756
+ private
757
+
758
+ def match(provider, request)
759
+ _provider, _request = provider, request
760
+ ELIMINATIONS.each do |elim|
761
+ result, new_provider, new_request = __send__(elim, provider, request)
762
+ if result
763
+ _provider = new_provider
764
+ _request = new_request
765
+ break
766
+ end
767
+ end
768
+ if _provider.simplify.empty? && _request.simplify.empty?
769
+ return true
770
+ else
771
+ if provider == _provider and request == _request
772
+ return false
773
+ else
774
+ return match(_provider, _request)
775
+ end
776
+ end
777
+ end
778
+ end
779
+ end
780
+
781
+ TypeFeature.instance_eval do
782
+ define_pione_method("==", [TypeFeature], TypeBoolean) do |rec, other|
783
+ PioneBoolean.new(rec == other)
784
+ end
785
+
786
+ define_pione_method("!=", [TypeFeature], TypeBoolean) do |rec, other|
787
+ PioneBoolean.not(rec.call_pione_method("==", other))
788
+ end
789
+
790
+ define_pione_method("as_string", [], TypeString) do |rec|
791
+ PioneString.new(rec.as_string)
792
+ end
793
+ end
794
+ end