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.
- data/.gitignore +14 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +94 -0
- data/Rakefile +118 -0
- data/bin/pione-broker +5 -0
- data/bin/pione-clean +5 -0
- data/bin/pione-client +5 -0
- data/bin/pione-eval +111 -0
- data/bin/pione-relay +5 -0
- data/bin/pione-relay-account-db +5 -0
- data/bin/pione-relay-client-db +5 -0
- data/bin/pione-search-log +30 -0
- data/bin/pione-syntax-checker +5 -0
- data/bin/pione-task-worker +5 -0
- data/bin/pione-tuple-space-provider +5 -0
- data/bin/pione-tuple-space-receiver +5 -0
- data/bin/pione-tuple-space-viewer +5 -0
- data/demo/demo.rb +311 -0
- data/demo/public/base.css +94 -0
- data/demo/public/demo.js +107 -0
- data/demo/public/index.html +91 -0
- data/demo/public/jquery-1.8.3.min.js +2 -0
- data/example/CountChar/CountChar.pione +64 -0
- data/example/CountChar/misc/CountChar.rb +22 -0
- data/example/CountChar/text/aidokushono_insho.txt +32 -0
- data/example/CountChar/text/aikokuka_shokan.txt +108 -0
- data/example/CountChar/text/carlyle_hakubutsukan.txt +58 -0
- data/example/CountChar/text/dark_minister.txt +2440 -0
- data/example/CountChar/text/kaikano_otto.txt +61 -0
- data/example/CountChar/text/kaikon.txt +30 -0
- data/example/CountChar/text/nagashimano_shi.txt +45 -0
- data/example/CountChar/text/saikachibuchi.txt +80 -0
- data/example/CountChar/text/saikonihonno_josei.txt +91 -0
- data/example/CountChar/text/taishojugonenno_bundan.txt +21 -0
- data/example/FeatureExample/FeatureExample.pione +7 -0
- data/example/Fib/Fib.pione +56 -0
- data/example/Fib/FibBC.pione +56 -0
- data/example/HelloWorld/HelloWorld.pione +5 -0
- data/example/LucasNumber/LucasNumber.pione +64 -0
- data/example/MakePair/MakePair.pione +14 -0
- data/example/MakePair/data/1.i +0 -0
- data/example/MakePair/data/2.i +0 -0
- data/example/MakePair/data/3.i +0 -0
- data/example/MakePair/data/4.i +0 -0
- data/example/MakePair/data/5.i +0 -0
- data/example/SieveOfEratosthenes/SieveOfEratosthenes.pione +61 -0
- data/example/SingleParticlesWithRef/Makefile +289 -0
- data/example/SingleParticlesWithRef/SingleParticlesWithRef.Makefile +153 -0
- data/example/SingleParticlesWithRef/SingleParticlesWithRef.pione +116 -0
- data/example/SingleParticlesWithRef/SingleParticlesWithRefFull.pione +400 -0
- data/example/SingleParticlesWithRef/data/121p-shift-0-0-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-0-120-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-0-180-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-0-240-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-0-300-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-0-60-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-120-0-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-120-120-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-120-180-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-120-240-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-120-300-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-120-60-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-180-0-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-180-120-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-180-180-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-180-240-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-180-300-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-180-60-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-240-0-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-240-120-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-240-180-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-240-240-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-240-300-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-240-60-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-300-0-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-300-120-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-300-180-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-300-240-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-300-300-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-300-60-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-60-0-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-60-120-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-60-180-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-60-240-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-60-300-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-60-60-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-0-0-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-0-120-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-0-180-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-0-240-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-0-300-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-0-60-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-120-0-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-120-120-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-120-180-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-120-240-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-120-300-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-120-60-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-180-0-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-180-120-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-180-180-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-180-240-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-180-300-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-180-60-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-240-0-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-240-120-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-240-180-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-240-240-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-240-300-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-240-60-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-300-0-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-300-120-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-300-180-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-300-240-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-300-300-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-300-60-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-60-0-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-60-120-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-60-180-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-60-240-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-60-300-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift-noise-60-60-0.roi +0 -0
- data/example/SingleParticlesWithRef/data/121p-shift.pdb +3381 -0
- data/example/SingleParticlesWithRef/data/all.ref2d +0 -0
- data/example/SingleParticlesWithRef/data/all.ref3d +0 -0
- data/example/Sum/Sum.pione +52 -0
- data/example/SyntaxError/call_rule_error.pione +6 -0
- data/example/SyntaxError/feature_line_error.pione +7 -0
- data/example/SyntaxError/flow_block_error.pione +5 -0
- data/example/SyntaxError/input_line_error.pione +6 -0
- data/example/SyntaxError/invalid_rule_name.pione +6 -0
- data/example/SyntaxError/param_line_error.pione +7 -0
- data/example/SyntaxError/variable-binding-error.pione +11 -0
- data/lib/pione.rb +241 -0
- data/lib/pione/agent/basic-agent.rb +333 -0
- data/lib/pione/agent/broker.rb +274 -0
- data/lib/pione/agent/command-listener.rb +47 -0
- data/lib/pione/agent/input-generator.rb +194 -0
- data/lib/pione/agent/logger.rb +65 -0
- data/lib/pione/agent/process-manager.rb +38 -0
- data/lib/pione/agent/rule-provider.rb +64 -0
- data/lib/pione/agent/task-worker.rb +274 -0
- data/lib/pione/agent/trivial-routine-worker.rb +28 -0
- data/lib/pione/agent/tuple-space-client.rb +146 -0
- data/lib/pione/agent/tuple-space-server-client-life-checker.rb +29 -0
- data/lib/pione/command-option/basic-option.rb +42 -0
- data/lib/pione/command-option/child-process-option.rb +17 -0
- data/lib/pione/command-option/common-option.rb +29 -0
- data/lib/pione/command-option/daemon-option.rb +12 -0
- data/lib/pione/command-option/presence-notifier-option.rb +15 -0
- data/lib/pione/command-option/task-worker-owner-option.rb +17 -0
- data/lib/pione/command-option/tuple-space-provider-option.rb +26 -0
- data/lib/pione/command-option/tuple-space-provider-owner-option.rb +16 -0
- data/lib/pione/command-option/tuple-space-receiver-option.rb +12 -0
- data/lib/pione/command/basic-command.rb +126 -0
- data/lib/pione/command/child-process.rb +43 -0
- data/lib/pione/command/daemon-process.rb +18 -0
- data/lib/pione/command/front-owner-command.rb +37 -0
- data/lib/pione/command/pione-broker.rb +53 -0
- data/lib/pione/command/pione-clean.rb +16 -0
- data/lib/pione/command/pione-client.rb +273 -0
- data/lib/pione/command/pione-relay-account-db.rb +85 -0
- data/lib/pione/command/pione-relay-client-db.rb +80 -0
- data/lib/pione/command/pione-relay.rb +47 -0
- data/lib/pione/command/pione-syntax-checker.rb +103 -0
- data/lib/pione/command/pione-task-worker.rb +123 -0
- data/lib/pione/command/pione-tuple-space-provider.rb +87 -0
- data/lib/pione/command/pione-tuple-space-receiver.rb +55 -0
- data/lib/pione/command/pione-tuple-space-viewer.rb +151 -0
- data/lib/pione/command/tuple-space-provider-owner.rb +6 -0
- data/lib/pione/front/basic-front.rb +64 -0
- data/lib/pione/front/broker-front.rb +30 -0
- data/lib/pione/front/client-front.rb +28 -0
- data/lib/pione/front/relay-front.rb +19 -0
- data/lib/pione/front/task-worker-front.rb +16 -0
- data/lib/pione/front/task-worker-owner.rb +42 -0
- data/lib/pione/front/tuple-space-provider-front.rb +22 -0
- data/lib/pione/front/tuple-space-provider-owner.rb +11 -0
- data/lib/pione/front/tuple-space-receiver-front.rb +18 -0
- data/lib/pione/model/assignment.rb +89 -0
- data/lib/pione/model/basic-model.rb +395 -0
- data/lib/pione/model/binary-operator.rb +80 -0
- data/lib/pione/model/block.rb +233 -0
- data/lib/pione/model/boolean.rb +138 -0
- data/lib/pione/model/call-rule.rb +69 -0
- data/lib/pione/model/data-expr.rb +360 -0
- data/lib/pione/model/feature-expr.rb +794 -0
- data/lib/pione/model/float.rb +107 -0
- data/lib/pione/model/integer.rb +140 -0
- data/lib/pione/model/list.rb +104 -0
- data/lib/pione/model/message.rb +80 -0
- data/lib/pione/model/package.rb +48 -0
- data/lib/pione/model/parameters.rb +282 -0
- data/lib/pione/model/rule-expr.rb +120 -0
- data/lib/pione/model/rule-io.rb +166 -0
- data/lib/pione/model/rule.rb +294 -0
- data/lib/pione/model/string.rb +111 -0
- data/lib/pione/model/undefined-value.rb +24 -0
- data/lib/pione/model/variable-table.rb +315 -0
- data/lib/pione/model/variable.rb +87 -0
- data/lib/pione/parser/block-parser.rb +83 -0
- data/lib/pione/parser/common-parser.rb +145 -0
- data/lib/pione/parser/document-parser.rb +58 -0
- data/lib/pione/parser/error-message.yml +4 -0
- data/lib/pione/parser/expr-parser.rb +266 -0
- data/lib/pione/parser/feature-expr-parser.rb +105 -0
- data/lib/pione/parser/flow-element-parser.rb +181 -0
- data/lib/pione/parser/literal-parser.rb +182 -0
- data/lib/pione/parser/rule-definition-parser.rb +163 -0
- data/lib/pione/parser/syntax-error.rb +61 -0
- data/lib/pione/patch/array-patch.rb +3 -0
- data/lib/pione/patch/drb-patch.rb +467 -0
- data/lib/pione/patch/monitor-patch.rb +16 -0
- data/lib/pione/patch/rinda-patch.rb +759 -0
- data/lib/pione/patch/uri-patch.rb +66 -0
- data/lib/pione/relay/receiver-socket.rb +69 -0
- data/lib/pione/relay/relay-account-db.rb +55 -0
- data/lib/pione/relay/relay-client-db.rb +53 -0
- data/lib/pione/relay/relay-socket.rb +215 -0
- data/lib/pione/relay/trampoline.rb +22 -0
- data/lib/pione/relay/transmitter-socket.rb +167 -0
- data/lib/pione/resource/basic-resource.rb +92 -0
- data/lib/pione/resource/dropbox-resource.rb +106 -0
- data/lib/pione/resource/ftp.rb +84 -0
- data/lib/pione/resource/local.rb +113 -0
- data/lib/pione/rule-handler/action-handler.rb +184 -0
- data/lib/pione/rule-handler/basic-handler.rb +217 -0
- data/lib/pione/rule-handler/flow-handler.rb +339 -0
- data/lib/pione/rule-handler/root-handler.rb +23 -0
- data/lib/pione/rule-handler/system-handler.rb +13 -0
- data/lib/pione/system/common.rb +22 -0
- data/lib/pione/system/config.rb +20 -0
- data/lib/pione/system/document.rb +81 -0
- data/lib/pione/system/file-cache.rb +150 -0
- data/lib/pione/system/global.rb +346 -0
- data/lib/pione/system/identifier.rb +61 -0
- data/lib/pione/system/init.rb +16 -0
- data/lib/pione/system/object.rb +35 -0
- data/lib/pione/transformer/block-transformer.rb +23 -0
- data/lib/pione/transformer/document-transformer.rb +36 -0
- data/lib/pione/transformer/expr-transformer.rb +89 -0
- data/lib/pione/transformer/feature-expr-transformer.rb +56 -0
- data/lib/pione/transformer/flow-element-transformer.rb +66 -0
- data/lib/pione/transformer/literal-transformer.rb +76 -0
- data/lib/pione/transformer/rule-definition-transformer.rb +62 -0
- data/lib/pione/transformer/transformer-module.rb +37 -0
- data/lib/pione/tuple-space/data-finder.rb +165 -0
- data/lib/pione/tuple-space/presence-notifier.rb +83 -0
- data/lib/pione/tuple-space/relay.rb +9 -0
- data/lib/pione/tuple-space/tuple-space-provider.rb +85 -0
- data/lib/pione/tuple-space/tuple-space-receiver.rb +140 -0
- data/lib/pione/tuple-space/tuple-space-server-interface.rb +60 -0
- data/lib/pione/tuple-space/tuple-space-server.rb +156 -0
- data/lib/pione/tuple-space/update-criteria.rb +96 -0
- data/lib/pione/tuple/agent-tuple.rb +10 -0
- data/lib/pione/tuple/attribute-tuple.rb +7 -0
- data/lib/pione/tuple/base-uri-tuple.rb +9 -0
- data/lib/pione/tuple/basic-tuple.rb +317 -0
- data/lib/pione/tuple/bye-tuple.rb +9 -0
- data/lib/pione/tuple/command-tuple.rb +9 -0
- data/lib/pione/tuple/data-tuple.rb +18 -0
- data/lib/pione/tuple/dry-run-tuple.rb +8 -0
- data/lib/pione/tuple/exception-tuple.rb +11 -0
- data/lib/pione/tuple/finished-tuple.rb +17 -0
- data/lib/pione/tuple/foreground-tuple.rb +7 -0
- data/lib/pione/tuple/log-tuple.rb +14 -0
- data/lib/pione/tuple/process-info-tuple.rb +9 -0
- data/lib/pione/tuple/request-rule-tuple.rb +9 -0
- data/lib/pione/tuple/rule-tuple.rb +10 -0
- data/lib/pione/tuple/shift-tuple.rb +13 -0
- data/lib/pione/tuple/task-tuple.rb +36 -0
- data/lib/pione/tuple/task-worker-resource-tuple.rb +9 -0
- data/lib/pione/tuple/working-tuple.rb +13 -0
- data/lib/pione/uri-scheme/basic-scheme.rb +40 -0
- data/lib/pione/uri-scheme/broadcast-scheme.rb +11 -0
- data/lib/pione/uri-scheme/dropbox-scheme.rb +9 -0
- data/lib/pione/uri-scheme/local-scheme.rb +28 -0
- data/lib/pione/util/error-report.rb +12 -0
- data/lib/pione/util/log.rb +79 -0
- data/lib/pione/util/message.rb +155 -0
- data/lib/pione/util/misc.rb +73 -0
- data/lib/pione/util/terminal.rb +78 -0
- data/lib/pione/util/waiter-table.rb +53 -0
- data/lib/pione/version.rb +3 -0
- data/misc/env.sh +2 -0
- data/misc/test-drb-stop-service.rb +34 -0
- data/misc/test-ensure-and-thread-kill.rb +40 -0
- data/misc/test-many-waiters-client.rb +56 -0
- data/misc/test-many-waiters-server.rb +14 -0
- data/misc/write_and_take_test.png +0 -0
- data/misc/write_and_take_test.rb +36 -0
- data/pione.gemspec +49 -0
- data/test/agent/spec_basic-agent.rb +170 -0
- data/test/agent/spec_broker.rb +36 -0
- data/test/agent/spec_command-listener.rb +30 -0
- data/test/agent/spec_input-generator.rb +123 -0
- data/test/agent/spec_logger.rb +71 -0
- data/test/agent/spec_rule-provider.rb +65 -0
- data/test/agent/spec_task-worker.rb +307 -0
- data/test/agent/spec_tuple-space-client.rb +30 -0
- data/test/model/spec_assignment.rb +51 -0
- data/test/model/spec_binary-operator.rb +39 -0
- data/test/model/spec_block.rb +154 -0
- data/test/model/spec_boolean.rb +115 -0
- data/test/model/spec_call-rule.rb +23 -0
- data/test/model/spec_data-expr.rb +312 -0
- data/test/model/spec_feature-expr.rb +359 -0
- data/test/model/spec_feature-expr.yml +16 -0
- data/test/model/spec_float.rb +141 -0
- data/test/model/spec_integer.rb +141 -0
- data/test/model/spec_list.rb +26 -0
- data/test/model/spec_message.rb +42 -0
- data/test/model/spec_package.rb +15 -0
- data/test/model/spec_parameters.rb +148 -0
- data/test/model/spec_rule-expr.rb +66 -0
- data/test/model/spec_rule-io.rb +32 -0
- data/test/model/spec_rule.rb +158 -0
- data/test/model/spec_string.rb +106 -0
- data/test/model/spec_variable-table.rb +117 -0
- data/test/model/spec_variable.rb +84 -0
- data/test/parser/spec_block-parser.rb +5 -0
- data/test/parser/spec_block-parser.yml +85 -0
- data/test/parser/spec_common-parser.rb +281 -0
- data/test/parser/spec_expr-parser.rb +6 -0
- data/test/parser/spec_expr-parser.yml +82 -0
- data/test/parser/spec_feature-expr-parser.rb +32 -0
- data/test/parser/spec_feature-expr-parser.yml +25 -0
- data/test/parser/spec_flow-element-parser.rb +5 -0
- data/test/parser/spec_flow-element-parser.yml +180 -0
- data/test/parser/spec_literal-parser.rb +5 -0
- data/test/parser/spec_literal-parser.yml +123 -0
- data/test/parser/spec_rule-definition-parser.rb +5 -0
- data/test/parser/spec_rule-definition-parser.yml +93 -0
- data/test/patch/spec_rinda-patch.rb +32 -0
- data/test/patch/spec_uri-patch.rb +23 -0
- data/test/rule-handler/spec_action-handler.rb +135 -0
- data/test/rule-handler/spec_flow-handler.rb +127 -0
- data/test/spec_common.rb +14 -0
- data/test/spec_data-finder.rb +88 -0
- data/test/spec_data-finder.yml +115 -0
- data/test/spec_document.rb +76 -0
- data/test/spec_identifier.rb +29 -0
- data/test/spec_log.rb +52 -0
- data/test/spec_object.rb +20 -0
- data/test/spec_resource.rb +73 -0
- data/test/spec_update-criteria.rb +83 -0
- data/test/test-util.rb +223 -0
- data/test/transformer/spec_block-transformer.rb +26 -0
- data/test/transformer/spec_expr-transformer.rb +106 -0
- data/test/transformer/spec_feature-expr-transformer.rb +21 -0
- data/test/transformer/spec_flow-element-transformer.rb +154 -0
- data/test/transformer/spec_literal-transformer.rb +58 -0
- data/test/transformer/spec_rule-definition-transformer.rb +168 -0
- data/test/tuple-space/spec_tuple-space-provider.rb +36 -0
- data/test/tuple-space/spec_tuple-space-receiver.rb +32 -0
- data/test/tuple-space/spec_tuple-space-server.rb +49 -0
- data/test/tuple/spec_basic-tuple.rb +87 -0
- data/test/tuple/spec_data-tuple.rb +85 -0
- data/test/tuple/spec_finished-tuple.rb +61 -0
- data/test/tuple/spec_task-tuple.rb +127 -0
- data/test/tuple/spec_working-tuple.rb +58 -0
- data/test/uri-scheme/spec_broadcast-scheme.rb +40 -0
- data/test/uri-scheme/spec_dropbox-scheme.rb +31 -0
- data/test/uri-scheme/spec_local-scheme.rb +69 -0
- 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
|