pione 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.s3cfg +42 -0
- data/.travis.yml +18 -4
- data/.yardopts +1 -0
- data/Gemfile +3 -0
- data/History.txt +14 -0
- data/Procfile +7 -0
- data/Rakefile +25 -0
- data/bin/pione-interactive +6 -0
- data/bin/{pione-compiler → pione-notification-listener} +1 -1
- data/bin/{pione-broker → pione-task-worker-broker} +1 -1
- data/doc/man/pione-list-param.md +36 -0
- data/example/ActionError/ActionError.pione +9 -0
- data/example/ActionError/pione-package.json +15 -0
- data/example/CountChar/CountChar.pione +1 -1
- data/example/ScoreAggregation/ScoreAggregation.pione +1 -1
- data/example/Touch/pione-package.json +15 -0
- data/lib/pione.rb +12 -0
- data/lib/pione/agent.rb +3 -3
- data/lib/pione/agent/basic-agent.rb +10 -4
- data/lib/pione/agent/input-generator.rb +3 -3
- data/lib/pione/agent/{process-manager.rb → job-manager.rb} +10 -7
- data/lib/pione/agent/job-terminator.rb +2 -2
- data/lib/pione/agent/logger.rb +3 -3
- data/lib/pione/agent/messenger.rb +20 -9
- data/lib/pione/agent/notification-listener.rb +88 -0
- data/lib/pione/agent/task-worker-broker.rb +84 -0
- data/lib/pione/agent/task-worker.rb +3 -2
- data/lib/pione/agent/tuple-space-client.rb +1 -0
- data/lib/pione/agent/tuple-space-provider.rb +17 -35
- data/lib/pione/command.rb +33 -15
- data/lib/pione/command/action.rb +105 -0
- data/lib/pione/command/basic-command.rb +34 -376
- data/lib/pione/command/command-exception.rb +12 -11
- data/lib/pione/command/common.rb +198 -0
- data/lib/pione/command/option.rb +159 -204
- data/lib/pione/command/pione-action-exec.rb +85 -0
- data/lib/pione/command/pione-action-list.rb +43 -19
- data/lib/pione/command/pione-action-print.rb +79 -0
- data/lib/pione/command/pione-action.rb +8 -67
- data/lib/pione/command/pione-clean.rb +88 -68
- data/lib/pione/command/pione-client.rb +475 -332
- data/lib/pione/command/pione-command.rb +14 -31
- data/lib/pione/command/pione-compile.rb +90 -0
- data/lib/pione/command/pione-config-get.rb +53 -0
- data/lib/pione/command/pione-config-list.rb +64 -0
- data/lib/pione/command/pione-config-set.rb +59 -0
- data/lib/pione/command/pione-config-unset.rb +50 -0
- data/lib/pione/command/pione-config.rb +61 -0
- data/lib/pione/command/pione-diagnosis-notification.rb +235 -0
- data/lib/pione/command/pione-diagnosis.rb +21 -0
- data/lib/pione/command/pione-interactive.rb +188 -0
- data/lib/pione/command/pione-lang-check-syntax.rb +163 -0
- data/lib/pione/command/pione-lang-interactive.rb +146 -0
- data/lib/pione/command/pione-lang.rb +22 -0
- data/lib/pione/command/pione-log-format.rb +163 -0
- data/lib/pione/command/pione-log-list-id.rb +48 -0
- data/lib/pione/command/pione-log.rb +19 -101
- data/lib/pione/command/pione-notification-listener.rb +95 -0
- data/lib/pione/command/pione-package-add.rb +137 -0
- data/lib/pione/command/pione-package-build.rb +122 -0
- data/lib/pione/command/pione-package-show.rb +96 -0
- data/lib/pione/command/pione-package-update.rb +59 -0
- data/lib/pione/command/pione-package.rb +11 -139
- data/lib/pione/command/pione-task-worker-broker.rb +88 -0
- data/lib/pione/command/pione-task-worker.rb +148 -98
- data/lib/pione/command/pione-tuple-space-provider.rb +62 -54
- data/lib/pione/command/pione-tuple-space-viewer.rb +105 -83
- data/lib/pione/command/pione-val.rb +39 -39
- data/lib/pione/command/spawner.rb +34 -27
- data/lib/pione/front.rb +4 -2
- data/lib/pione/front/basic-front.rb +86 -23
- data/lib/pione/front/client-front.rb +2 -2
- data/lib/pione/front/diagnosis-notification-front.rb +40 -0
- data/lib/pione/front/front-exception.rb +7 -1
- data/lib/pione/front/notification-listener-front.rb +36 -0
- data/lib/pione/front/notification-recipient-interface.rb +19 -0
- data/lib/pione/front/relay-front.rb +4 -4
- data/lib/pione/front/task-worker-broker-front.rb +19 -0
- data/lib/pione/front/task-worker-front.rb +2 -2
- data/lib/pione/front/tuple-space-provider-front.rb +3 -2
- data/lib/pione/global.rb +3 -1
- data/lib/pione/global/client-variable.rb +1 -1
- data/lib/pione/global/config.rb +63 -7
- data/lib/pione/global/diagnosis-variable.rb +26 -0
- data/lib/pione/global/item.rb +28 -5
- data/lib/pione/global/log-variable.rb +6 -5
- data/lib/pione/global/network-variable.rb +75 -4
- data/lib/pione/global/path-variable.rb +1 -1
- data/lib/pione/global/system-variable.rb +12 -12
- data/lib/pione/global/task-worker-broker-variable.rb +43 -0
- data/lib/pione/global/tuple-space-notifier-variable.rb +3 -55
- data/lib/pione/lang/boolean.rb +4 -0
- data/lib/pione/lang/data-expr.rb +1 -1
- data/lib/pione/lang/integer.rb +1 -1
- data/lib/pione/lang/string.rb +4 -0
- data/lib/pione/lang/type.rb +1 -1
- data/lib/pione/location.rb +1 -0
- data/lib/pione/location/data-location.rb +41 -13
- data/lib/pione/location/dropbox-location.rb +175 -56
- data/lib/pione/location/ftp-location.rb +4 -1
- data/lib/pione/location/http-location.rb +5 -3
- data/lib/pione/location/https-location.rb +4 -2
- data/lib/pione/location/local-location.rb +6 -3
- data/lib/pione/location/location-exception.rb +12 -0
- data/lib/pione/location/notification-scheme.rb +46 -0
- data/lib/pione/log.rb +8 -7
- data/lib/pione/log/debug.rb +9 -9
- data/lib/pione/log/domain-log.rb +6 -1
- data/lib/pione/log/message-log-receiver.rb +32 -0
- data/lib/pione/log/system-log.rb +62 -141
- data/lib/pione/model.rb +7 -0
- data/lib/pione/model/notification-listener-model.rb +29 -0
- data/lib/pione/model/task-worker-broker-model.rb +129 -0
- data/lib/pione/notification.rb +13 -0
- data/lib/pione/notification/address.rb +104 -0
- data/lib/pione/notification/exception.rb +10 -0
- data/lib/pione/notification/message.rb +109 -0
- data/lib/pione/notification/receiver.rb +90 -0
- data/lib/pione/notification/recipient.rb +68 -0
- data/lib/pione/notification/task-worker-broker-recipient.rb +85 -0
- data/lib/pione/notification/transmitter.rb +84 -0
- data/lib/pione/pnml.rb +35 -0
- data/lib/pione/pnml/annotation-extractor.rb +47 -0
- data/lib/pione/pnml/compiler.rb +176 -0
- data/lib/pione/pnml/input-merge-complement.rb +78 -0
- data/lib/pione/pnml/input-parallelization-complement.rb +75 -0
- data/lib/pione/pnml/input-reduction.rb +80 -0
- data/lib/pione/pnml/invalid-arc-elimination.rb +41 -0
- data/lib/pione/pnml/io-expansion.rb +88 -0
- data/lib/pione/pnml/isolated-element-elimination.rb +32 -0
- data/lib/pione/pnml/net-rewriter.rb +44 -0
- data/lib/pione/pnml/output-decomposition-complement.rb +77 -0
- data/lib/pione/pnml/output-reduction.rb +86 -0
- data/lib/pione/pnml/output-synchronization-complement.rb +77 -0
- data/lib/pione/pnml/pione-model.rb +417 -0
- data/lib/pione/pnml/pnml-exception.rb +23 -0
- data/lib/pione/pnml/pnml-model.rb +368 -0
- data/lib/pione/pnml/reader.rb +51 -0
- data/lib/pione/rule-engine/action-handler.rb +8 -6
- data/lib/pione/rule-engine/basic-handler.rb +5 -5
- data/lib/pione/rule-engine/engine-exception.rb +7 -6
- data/lib/pione/rule-engine/flow-handler.rb +27 -18
- data/lib/pione/system.rb +3 -1
- data/lib/pione/system/domain-dump.rb +34 -0
- data/lib/pione/system/file-cache.rb +92 -13
- data/lib/pione/system/init.rb +3 -0
- data/lib/pione/system/normalizer.rb +40 -0
- data/lib/pione/system/status.rb +5 -5
- data/lib/pione/system/system-exception.rb +14 -1
- data/lib/pione/task-worker-broker.rb +7 -0
- data/lib/pione/task-worker-broker/basic-provider.rb +20 -0
- data/lib/pione/task-worker-broker/easy-provider.rb +65 -0
- data/lib/pione/test-helper.rb +27 -0
- data/lib/pione/test-helper/command-helper.rb +9 -101
- data/lib/pione/tuple-space/basic-tuple.rb +1 -1
- data/lib/pione/tuple-space/tuple-definition.yml +4 -6
- data/lib/pione/tuple-space/tuple-space-interface.rb +3 -45
- data/lib/pione/tuple-space/tuple-space-server.rb +45 -0
- data/lib/pione/util.rb +1 -2
- data/lib/pione/util/boolean-value.rb +62 -0
- data/lib/pione/util/completion.rb +111 -0
- data/lib/pione/util/evaluatable.rb +13 -27
- data/lib/pione/util/package-parameters-list.rb +15 -27
- data/lib/pione/util/zip.rb +8 -3
- data/lib/pione/version.rb +1 -1
- data/lib/rootage.rb +20 -0
- data/lib/rootage/action.rb +114 -0
- data/lib/rootage/argument.rb +46 -0
- data/lib/rootage/command.rb +218 -0
- data/lib/rootage/core.rb +532 -0
- data/lib/rootage/exception.rb +107 -0
- data/lib/rootage/help.rb +148 -0
- data/lib/rootage/help.txt.erb +31 -0
- data/lib/rootage/log.rb +226 -0
- data/lib/rootage/normalizer.rb +184 -0
- data/lib/rootage/option.rb +152 -0
- data/lib/rootage/scenario-test-result.erb +39 -0
- data/lib/rootage/scenario.rb +362 -0
- data/lib/rootage/test-helper.rb +115 -0
- data/man/pione-list-param.1 +44 -0
- data/misc/clock.rb +9 -0
- data/misc/machine-info.sh +21 -0
- data/misc/pione-completion.bash +238 -0
- data/misc/pione-completion.erb +53 -0
- data/misc/pione-completion.zsh +238 -0
- data/misc/pione.god +22 -0
- data/misc/ui.xml +23 -0
- data/pione.gemspec +3 -1
- data/test/agent/spec_basic-agent.rb +1 -1
- data/test/agent/spec_input-generator.rb +2 -2
- data/test/agent/spec_messenger.rb +6 -9
- data/test/agent/spec_notification-listener.rb +80 -0
- data/test/agent/{spec_broker.rb → spec_task-worker-broker.rb} +13 -10
- data/test/agent/spec_tuple-space-provider.rb +10 -6
- data/test/command/command-behavior.rb +3 -11
- data/test/command/data/pione-list-param/AdvancedParameters.pione +12 -0
- data/test/command/data/pione-list-param/BasicParameters.pione +12 -0
- data/test/command/spec_pione-action-exec.rb +16 -0
- data/test/command/spec_pione-action-list.rb +15 -10
- data/test/command/spec_pione-action-print.rb +14 -0
- data/test/command/spec_pione-action.rb +6 -19
- data/test/command/spec_pione-clean.rb +29 -46
- data/test/command/spec_pione-client.rb +29 -36
- data/test/command/spec_pione-command.rb +6 -6
- data/test/command/{spec_pione-compiler.rb → spec_pione-compile.rb} +11 -13
- data/test/command/spec_pione-config-get.rb +47 -0
- data/test/command/spec_pione-config-list.rb +42 -0
- data/test/command/spec_pione-config-set.rb +38 -0
- data/test/command/spec_pione-config-unset.rb +44 -0
- data/test/command/spec_pione-config.rb +11 -0
- data/test/command/spec_pione-diagnosis-notification.rb +23 -0
- data/test/command/spec_pione-diagnosis.rb +11 -0
- data/test/command/spec_pione-lang-check-syntax.rb +12 -0
- data/test/command/spec_pione-lang.rb +11 -0
- data/test/command/spec_pione-log-format.rb +29 -0
- data/test/command/spec_pione-log-list-id.rb +17 -0
- data/test/command/spec_pione-log.rb +6 -20
- data/test/command/spec_pione-package-add.rb +55 -0
- data/test/command/spec_pione-package-build.rb +57 -0
- data/test/command/spec_pione-package-show.rb +72 -0
- data/test/command/{spec_pione-update-package-info.rb → spec_pione-package-update.rb} +12 -13
- data/test/command/spec_pione-package.rb +4 -104
- data/test/command/spec_pione-val.rb +10 -7
- data/test/global/spec_config.rb +50 -0
- data/test/global/spec_item.rb +1 -1
- data/test/literate-action/data/HelloWorld.md +1 -1
- data/test/location/location-behavior.rb +1 -1
- data/test/location/spec_dropbox-location.rb +39 -0
- data/test/location/spec_notification-scheme.rb +37 -0
- data/test/log/spec_debug.rb +5 -4
- data/test/log/spec_message-log-receiver.rb +13 -0
- data/test/log/spec_message-log.rb +6 -9
- data/test/log/spec_system-log.rb +5 -3
- data/test/notification/spec_address.rb +229 -0
- data/test/notification/spec_message.rb +30 -0
- data/test/notification/spec_receiver.rb +36 -0
- data/test/notification/spec_transmitter.rb +37 -0
- data/test/pnml/data/ConditionalBranchIf.pnml +270 -0
- data/test/pnml/data/ConditionalBranchIfElse.pnml +309 -0
- data/test/pnml/data/IOExpansionComplex.pnml +363 -0
- data/test/pnml/data/IOExpansionSimple.pnml +140 -0
- data/test/pnml/data/InputMergeComplementComplex.pnml +381 -0
- data/test/pnml/data/InputMergeComplementSimple.pnml +248 -0
- data/test/pnml/data/InputParallelizationComplementComplex.pnml +433 -0
- data/test/pnml/data/InputParallelizationComplementSimple.pnml +288 -0
- data/test/pnml/data/InputReductionComplex.pnml +192 -0
- data/test/pnml/data/InputReductionLong.pnml +344 -0
- data/test/pnml/data/InputReductionSimple.pnml +140 -0
- data/test/pnml/data/IsolatedElementElimination.pnml +171 -0
- data/test/pnml/data/OutputDecompositionComplementComplex.pnml +381 -0
- data/test/pnml/data/OutputDecompositionComplementSimple.pnml +242 -0
- data/test/pnml/data/OutputReductionComplex.pnml +186 -0
- data/test/pnml/data/OutputReductionLong.pnml +344 -0
- data/test/pnml/data/OutputReductionSimple.pnml +140 -0
- data/test/pnml/data/OutputSynchronizationComplementComplex.pnml +498 -0
- data/test/pnml/data/OutputSynchronizationComplementSimple.pnml +347 -0
- data/test/pnml/data/SampleNet.pnml +238 -0
- data/test/pnml/spec_input-merge-complement.rb +40 -0
- data/test/pnml/spec_input-parallelization-complement.rb +50 -0
- data/test/pnml/spec_input-reduction.rb +113 -0
- data/test/pnml/spec_invalid-arc-elimination.rb +33 -0
- data/test/pnml/spec_io-expansion.rb +126 -0
- data/test/pnml/spec_isolated-element-elimination.rb +25 -0
- data/test/pnml/spec_output-decomposition-complement.rb +40 -0
- data/test/pnml/spec_output-reduction.rb +114 -0
- data/test/pnml/spec_output-synchronization-complement.rb +62 -0
- data/test/pnml/spec_pione-element.rb +144 -0
- data/test/pnml/spec_pnml-element.rb +373 -0
- data/test/pnml/spec_reader.rb +16 -0
- data/test/rootage/spec_argument.rb +18 -0
- data/test/rootage/spec_command.rb +239 -0
- data/test/rootage/spec_core.rb +198 -0
- data/test/rootage/spec_scenario.rb +149 -0
- data/test/system/{spec_domain-info.rb → spec_domain-dump.rb} +6 -6
- data/test/system/spec_file-cache.rb +6 -9
- data/test/tuple-space/spec_finished-tuple.rb +1 -1
- data/test/util/{spec_package-parameters-list_1.pione → data/package-parameters-list/Param1.pione} +0 -0
- data/test/util/{spec_package-parameters-list_2.pione → data/package-parameters-list/Param2.pione} +0 -0
- data/test/util/{spec_package-parameters-list_3.pione → data/package-parameters-list/Param3.pione} +0 -0
- data/test/util/{spec_package-parameters-list_4.pione → data/package-parameters-list/Param4.pione} +0 -0
- data/test/util/spec_boolean-value.rb +32 -0
- data/test/util/spec_completion.rb +22 -0
- data/test/util/spec_package-parameters-list.rb +39 -52
- data/test/util/spec_zip.rb +28 -1
- metadata +288 -47
- data/bin/pione-tuple-space-receiver +0 -5
- data/lib/pione/agent/broker.rb +0 -304
- data/lib/pione/agent/tuple-space-receiver.rb +0 -137
- data/lib/pione/command/pione-broker.rb +0 -104
- data/lib/pione/command/pione-compiler.rb +0 -57
- data/lib/pione/command/pione-relay-account-db.rb +0 -141
- data/lib/pione/command/pione-relay-client-db.rb +0 -118
- data/lib/pione/command/pione-relay.rb +0 -59
- data/lib/pione/command/pione-syntax-checker.rb +0 -214
- data/lib/pione/command/pione-tuple-space-receiver.rb +0 -111
- data/lib/pione/command/pione-update-package-info.rb +0 -53
- data/lib/pione/front/broker-front.rb +0 -22
- data/lib/pione/front/tuple-space-receiver-front.rb +0 -11
- data/lib/pione/global/broker-variable.rb +0 -33
- data/lib/pione/system/domain-info.rb +0 -25
- data/lib/pione/util/pnml-compiler.rb +0 -168
- data/test/agent/spec_tuple-space-receiver.rb +0 -47
- data/test/util/spec_pnml-compiler.rb +0 -32
@@ -0,0 +1,77 @@
|
|
1
|
+
module Pione
|
2
|
+
module PNML
|
3
|
+
# `OutputDecompositionComplement` is a net transformational rule. This rule
|
4
|
+
# complements name of source place that forms output decomposition
|
5
|
+
# pattern. For example, the net likes following
|
6
|
+
#
|
7
|
+
# +--> empty transition --> 'p1'
|
8
|
+
# |
|
9
|
+
# empty place --+--> empty transition --> 'p2'
|
10
|
+
# |
|
11
|
+
# +--> empty transition --> 'p3'
|
12
|
+
#
|
13
|
+
# is rewritten as th following.
|
14
|
+
#
|
15
|
+
# +--> empty transition --> 'p1'
|
16
|
+
# |
|
17
|
+
# 'p1' or 'p2' or 'p3' --+--> empty transition --> 'p2'
|
18
|
+
# |
|
19
|
+
# +--> empty transition --> 'p3'
|
20
|
+
#
|
21
|
+
module OutputDecompositionComplement
|
22
|
+
# Find subjects(source place and component places) of this rule from
|
23
|
+
# net. The conditions are followings:
|
24
|
+
#
|
25
|
+
# - There is an empty source place.
|
26
|
+
# - There are more than 2 target transitions. All traget transitions are
|
27
|
+
# empty, and each target transition has only one output named place.
|
28
|
+
# - There are arcs that connect the source and targets.
|
29
|
+
#
|
30
|
+
# @param net [PNML::Net]
|
31
|
+
# rewriting target net
|
32
|
+
# @return [Array]
|
33
|
+
# source place and component places
|
34
|
+
def self.find_subjects(net)
|
35
|
+
net.places.each do |place|
|
36
|
+
# source place should be empty
|
37
|
+
next unless place.empty_name?
|
38
|
+
|
39
|
+
# there should be more than 2 target transitions
|
40
|
+
transitions = net.find_all_transitions_by_source_id(place.id)
|
41
|
+
next unless transitions.size > 1
|
42
|
+
next unless transitions.all? {|transition| transition.empty_name?}
|
43
|
+
|
44
|
+
# each transition has only one output named place
|
45
|
+
component_places = []
|
46
|
+
next unless transitions.all? do |transition|
|
47
|
+
_places = net.find_all_places_by_source_id(transition.id)
|
48
|
+
component_places.concat(_places)
|
49
|
+
_places.size == 1 and not(_places.first.empty_name?)
|
50
|
+
end
|
51
|
+
|
52
|
+
return [place, component_places]
|
53
|
+
end
|
54
|
+
|
55
|
+
return nil
|
56
|
+
end
|
57
|
+
|
58
|
+
# Rewrite source place's name as disjunction of component place's name.
|
59
|
+
#
|
60
|
+
# @param net [PNML::Net]
|
61
|
+
# rewriting target net
|
62
|
+
# @param subjects [Array]
|
63
|
+
# source place and component places
|
64
|
+
# @return [void]
|
65
|
+
def self.rewrite(net, subjects)
|
66
|
+
place, component_places = subjects
|
67
|
+
|
68
|
+
# component places' names
|
69
|
+
names = component_places.map do |component_place|
|
70
|
+
Perspective.normalize_data_name(component_place.name)
|
71
|
+
end
|
72
|
+
|
73
|
+
place.name = "%s%s" % [Perspective.modifier(place.name), names.sort.join(" or ")]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Pione
|
2
|
+
module PNML
|
3
|
+
# `OutputReduction` is a net rewriting rule. This rule removes unnecessary
|
4
|
+
# output nodes of transitions. For example, the net likes the following
|
5
|
+
#
|
6
|
+
# A --> empty place --> empty transition --> place --> B
|
7
|
+
#
|
8
|
+
# is rewritten as the following.
|
9
|
+
#
|
10
|
+
# A -> place -> B
|
11
|
+
#
|
12
|
+
module OutputReduction
|
13
|
+
# Return subjects(source place, target transition, and the arc) if the net
|
14
|
+
# satisfies output reduction's condtions. The conditions are followings:
|
15
|
+
#
|
16
|
+
# - There is an empty source place. It is an output of named transition.
|
17
|
+
# - There is an empty target transition.
|
18
|
+
# - There is an arc that connects the source and the target.
|
19
|
+
#
|
20
|
+
# @param net [PNML::Net]
|
21
|
+
# rewriting target net
|
22
|
+
# @return [Array]
|
23
|
+
# source place, target transition, and the arc
|
24
|
+
def self.find_subjects(net)
|
25
|
+
net.places.each do |place|
|
26
|
+
# source place should be empty
|
27
|
+
next unless Perspective.empty?(place)
|
28
|
+
|
29
|
+
# source place should be an output of named transition
|
30
|
+
next if net.find_all_transitions_by_target_id(place.id).map do |transition|
|
31
|
+
Perspective.named?(transition)
|
32
|
+
end.empty?
|
33
|
+
|
34
|
+
transitions = net.find_all_transitions_by_source_id(place.id)
|
35
|
+
|
36
|
+
# only one transition
|
37
|
+
if transitions.size == 1
|
38
|
+
transition = transitions.first
|
39
|
+
|
40
|
+
# the transtion is connected to only one place at source side
|
41
|
+
if net.find_all_places_by_target_id(transition.id).size == 1
|
42
|
+
# target transition should be empty
|
43
|
+
next unless Perspective.empty?(transition)
|
44
|
+
|
45
|
+
return [place, transition, net.find_arc(place.id, transition.id)]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
return nil
|
51
|
+
end
|
52
|
+
|
53
|
+
# Rewrite the net with subjects by the following way.
|
54
|
+
#
|
55
|
+
# - Remove the subject place.
|
56
|
+
# - Remove the subject transition.
|
57
|
+
# - Remove the subject and related arcs.
|
58
|
+
# - Connect discontinuous nodes by new arcs.
|
59
|
+
#
|
60
|
+
# @param net [PNML::Net]
|
61
|
+
# rewriting target net
|
62
|
+
# @return [void]
|
63
|
+
def self.rewrite(net, subjects)
|
64
|
+
place, transition, arc = subjects
|
65
|
+
|
66
|
+
# remove subjects from the net
|
67
|
+
net.places.delete(place)
|
68
|
+
net.transitions.delete(transition)
|
69
|
+
net.arcs.delete(arc)
|
70
|
+
|
71
|
+
# remove related arcs
|
72
|
+
input_arcs = net.find_all_arcs_by_target_id(place.id)
|
73
|
+
input_arcs.each {|arc| net.arcs.delete(arc)}
|
74
|
+
output_arcs = net.find_all_arcs_by_source_id(transition.id)
|
75
|
+
output_arcs.each {|arc| net.arcs.delete(arc)}
|
76
|
+
|
77
|
+
# append new arcs
|
78
|
+
input_arcs.each do |input_arc|
|
79
|
+
output_arcs.each do |output_arc|
|
80
|
+
net.arcs << Arc.new(net, net.generate_id, input_arc.source_id, output_arc.target_id)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Pione
|
2
|
+
module PNML
|
3
|
+
# `OutputSynchronizationComplement` is a net rewriting rule. This rule
|
4
|
+
# complements names of source places that forms output synchronization
|
5
|
+
# pattern. For example, the net like the following
|
6
|
+
#
|
7
|
+
# A --> empty place --+
|
8
|
+
# |
|
9
|
+
# B --> empty place --+--> empty transition --> '*.p1'
|
10
|
+
# |
|
11
|
+
# C --> empty place --+
|
12
|
+
#
|
13
|
+
# is written as the following.
|
14
|
+
#
|
15
|
+
# A --> '*.p1' --+
|
16
|
+
# |
|
17
|
+
# B --> '*.p1' --+--> empty transition --> '*.p1'
|
18
|
+
# |
|
19
|
+
# C --> '*.p1' --+
|
20
|
+
#
|
21
|
+
module OutputSynchronizationComplement
|
22
|
+
# Find subjects(source places and synchronized place) of this rule from
|
23
|
+
# the net. The conditions are followings:
|
24
|
+
#
|
25
|
+
# - There are more than 2 source places.
|
26
|
+
# - There is an empty target transition. It has only one output named
|
27
|
+
# place.
|
28
|
+
# - There are arcs that connect sources and the target.
|
29
|
+
#
|
30
|
+
# @param net [PNML::Net]
|
31
|
+
# rewriting target net
|
32
|
+
# @return [Array]
|
33
|
+
# source places and synchronized place
|
34
|
+
def self.find_subjects(net)
|
35
|
+
net.transitions.each do |transition|
|
36
|
+
# target transition should be empty
|
37
|
+
next unless transition.empty_name?
|
38
|
+
|
39
|
+
# the transition should have only one output place
|
40
|
+
synchronized_places = net.find_all_places_by_source_id(transition.id).select do |place|
|
41
|
+
Perspective.file?(place)
|
42
|
+
end
|
43
|
+
next unless synchronized_places.size == 1
|
44
|
+
|
45
|
+
# collect source places
|
46
|
+
source_places = net.find_all_places_by_target_id(transition.id)
|
47
|
+
next unless source_places.size > 1
|
48
|
+
next unless source_places.any? {|place| place.empty_name?}
|
49
|
+
|
50
|
+
# return subjects
|
51
|
+
return [source_places, synchronized_places.first]
|
52
|
+
end
|
53
|
+
|
54
|
+
return nil
|
55
|
+
end
|
56
|
+
|
57
|
+
# Rewrite names of empty source places same as the name of synchronized place.
|
58
|
+
#
|
59
|
+
# @param net [PNML::Net]
|
60
|
+
# rewriting target net
|
61
|
+
# @param subjects [Array]
|
62
|
+
# source places and synchronized place
|
63
|
+
# @return [void]
|
64
|
+
def self.rewrite(net, subjects)
|
65
|
+
source_places, synchronized_place = subjects
|
66
|
+
|
67
|
+
# rewrite names of empty source places
|
68
|
+
source_places.each do |place|
|
69
|
+
# rewrite name only if it is empty
|
70
|
+
if place.empty_name?
|
71
|
+
place.name = synchronized_place.name
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,417 @@
|
|
1
|
+
module Pione
|
2
|
+
module PNML
|
3
|
+
# `Perspective` is a meta class for PIONE's concepts overlayed in PNML.
|
4
|
+
class Perspective
|
5
|
+
# Eliminate comments from the string. This implementation is temporary, we
|
6
|
+
# should fix this.
|
7
|
+
def self.eliminate_comment(str)
|
8
|
+
# FIXME
|
9
|
+
str.sub(/#.*$/, "")
|
10
|
+
end
|
11
|
+
|
12
|
+
# Return true if the node is empty in PIONE model.
|
13
|
+
#
|
14
|
+
# @return [Boolean]
|
15
|
+
# true if the node is empty
|
16
|
+
def self.empty?(node)
|
17
|
+
# node should be a place or transition
|
18
|
+
return false unless node.is_a?(Place) or node.is_a?(Transition)
|
19
|
+
|
20
|
+
return true if node.name.nil?
|
21
|
+
return true if /^[<>]?\s*$/.match(eliminate_comment(node.name.strip))
|
22
|
+
end
|
23
|
+
|
24
|
+
# Return true if the node is named in PIONE model.
|
25
|
+
#
|
26
|
+
# @return [Boolean]
|
27
|
+
# true if the node is named
|
28
|
+
def self.named?(node)
|
29
|
+
not(empty?(node))
|
30
|
+
end
|
31
|
+
|
32
|
+
# Return true if the node is a file in PIONE model.
|
33
|
+
#
|
34
|
+
# @return [Boolean]
|
35
|
+
# true if the node is a file
|
36
|
+
def self.file?(node)
|
37
|
+
# files should be represented as a place
|
38
|
+
return false unless node.is_a?(Place)
|
39
|
+
return false if node.name.nil?
|
40
|
+
|
41
|
+
# normalize
|
42
|
+
name = node.name.strip
|
43
|
+
if name.size > 0 and "<>".include?(name[0])
|
44
|
+
name = name.sub(/[<>]/, "")
|
45
|
+
end
|
46
|
+
|
47
|
+
# test
|
48
|
+
return (name.size > 0 and name[0] == "'")
|
49
|
+
end
|
50
|
+
|
51
|
+
# Return true if the node is a ticket in PIONE model.
|
52
|
+
#
|
53
|
+
# @return [Boolean]
|
54
|
+
# true if the node is a ticket
|
55
|
+
def self.ticket?(node)
|
56
|
+
# tickets should be represented as a place
|
57
|
+
return false unless node.is_a?(Place)
|
58
|
+
|
59
|
+
# try parsing as a ticket expression
|
60
|
+
Lang::Parser.ticket_expr.parse(node.name)
|
61
|
+
|
62
|
+
# the node is a ticket
|
63
|
+
return true
|
64
|
+
rescue Parslet::ParseFailed => e
|
65
|
+
# the node is not a ticket
|
66
|
+
return false
|
67
|
+
end
|
68
|
+
|
69
|
+
# Return true if the node is a parameter in PIONE model.
|
70
|
+
#
|
71
|
+
# @return [Boolean]
|
72
|
+
# true if the node is a parameter
|
73
|
+
def self.param?(node)
|
74
|
+
# parameter node should be represented as a place
|
75
|
+
return false unless node.is_a?(Place)
|
76
|
+
|
77
|
+
# parameter node should be parsed as param sentence
|
78
|
+
begin
|
79
|
+
Lang::DocumentParser.new.param_sentence.parse(name)
|
80
|
+
return true
|
81
|
+
rescue
|
82
|
+
return false
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Return true if the node is a rule.
|
87
|
+
#
|
88
|
+
# @param node [PNML::Node]
|
89
|
+
# the node
|
90
|
+
# @return [Boolean]
|
91
|
+
# true if the node is a rule.
|
92
|
+
def self.rule?(node)
|
93
|
+
return false unless node.is_a?(Transition)
|
94
|
+
return false unless not(node.name.nil?)
|
95
|
+
|
96
|
+
name = node.name.strip
|
97
|
+
|
98
|
+
# keywords
|
99
|
+
if ["if", "else", "then"].include?(name)
|
100
|
+
return false
|
101
|
+
end
|
102
|
+
|
103
|
+
return name.size > 0
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.normalize_data_name(name)
|
107
|
+
return nil if name.nil?
|
108
|
+
|
109
|
+
name = name.strip
|
110
|
+
name = remove_comment(name)
|
111
|
+
if name.size > 0 and name[0] == "<" or name[0] == ">"
|
112
|
+
name[1..-1].strip
|
113
|
+
else
|
114
|
+
name
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.compact(name)
|
119
|
+
remove_comment(name)
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.remove_comment(name)
|
123
|
+
name.sub(/#\s*$/, "").strip
|
124
|
+
end
|
125
|
+
|
126
|
+
# Return true if the node is a net's input.
|
127
|
+
#
|
128
|
+
# @param node [PNML::Node]
|
129
|
+
# the node
|
130
|
+
# @return [Boolean]
|
131
|
+
# true if the node is a net's input.
|
132
|
+
def self.net_input?(node)
|
133
|
+
node.name and compact(node.name)[0] == "<"
|
134
|
+
end
|
135
|
+
|
136
|
+
# Return true if the node is a net's output.
|
137
|
+
#
|
138
|
+
# @param node [PNML::Node]
|
139
|
+
# the node
|
140
|
+
# @return [Boolean]
|
141
|
+
# true if the node is a net's output.
|
142
|
+
def self.net_output?(node)
|
143
|
+
node.name and compact(node.name)[0] == ">"
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.modifier(name)
|
147
|
+
if name.size > 0 and name.strip[0] == "<"
|
148
|
+
return "<"
|
149
|
+
end
|
150
|
+
if name.size > 0 and name.strip[0] == ">"
|
151
|
+
return ">"
|
152
|
+
end
|
153
|
+
return ""
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
# Return an indented version of the string. Indentation size is calculated
|
159
|
+
# by the optional argument `:level`. If the level is zero, return the
|
160
|
+
# string as is.
|
161
|
+
#
|
162
|
+
# @param option [Hash]
|
163
|
+
# @option option [Integer] :level
|
164
|
+
# indentation level, this should be non-negative integer
|
165
|
+
def indent(str, option)
|
166
|
+
str.lines.map do |line|
|
167
|
+
(" " * (option[:level] || 0)) + line
|
168
|
+
end.join
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# `ConstituentRule` is a class represents PIONE's constituent rule.
|
173
|
+
class ConstituentRule < Perspective
|
174
|
+
attr_reader :type
|
175
|
+
attr_reader :name
|
176
|
+
attr_reader :params
|
177
|
+
|
178
|
+
# @param type [Symbol]
|
179
|
+
# rule type of either `:input` or `:output`
|
180
|
+
# @param name [String]
|
181
|
+
# rule name
|
182
|
+
def initialize(type, name)
|
183
|
+
@type = type
|
184
|
+
@name = name
|
185
|
+
@params = []
|
186
|
+
end
|
187
|
+
|
188
|
+
# Return a declaration of constituent rule.
|
189
|
+
#
|
190
|
+
# @return [String]
|
191
|
+
# a declaration string for PIONE's constituent rule
|
192
|
+
def as_declaration(option={})
|
193
|
+
indent("rule %s" % textize_rule_expr, option)
|
194
|
+
end
|
195
|
+
|
196
|
+
def as_rule_definition
|
197
|
+
RuleDefinition.new()
|
198
|
+
end
|
199
|
+
|
200
|
+
private
|
201
|
+
|
202
|
+
# Return a string form of PIONE's rule expression.
|
203
|
+
def textize_rule_expr
|
204
|
+
[@name, textize_params].compact.join(" ")
|
205
|
+
end
|
206
|
+
|
207
|
+
# Return a string form of PIONE's parameter set.
|
208
|
+
def textize_params
|
209
|
+
unless @params.empty?
|
210
|
+
"{%s}" % [@params.map{|param| "%s: $%s" % [param.name, param.name]}.join(", ")]
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
# `DataCondition` is a class represents PIONE's input and output data condition.
|
216
|
+
class DataCondition < Perspective
|
217
|
+
attr_reader :data_expr
|
218
|
+
attr_accessor :input_distribution
|
219
|
+
attr_accessor :output_distribution
|
220
|
+
attr_accessor :input_priority
|
221
|
+
attr_accessor :output_priority
|
222
|
+
attr_accessor :input_nonexistable
|
223
|
+
attr_accessor :output_nonexistable
|
224
|
+
attr_accessor :output_for_this_flow
|
225
|
+
|
226
|
+
# @param data_expr [String]
|
227
|
+
# data expression as a PIONE's expression string
|
228
|
+
# @param attr [Hash]
|
229
|
+
# various attributes for the data expression
|
230
|
+
# @option attr [Symbol] :input_distribution
|
231
|
+
# input distribution type of either `:each` or `:all`
|
232
|
+
# @option attr [Symbol] :output_distribution
|
233
|
+
# output distribution type of either `:each` or `:all`
|
234
|
+
# @option attr [Integer] :input_priority
|
235
|
+
# priority of this input condition
|
236
|
+
# @option attr [Integer] :output_priority
|
237
|
+
# priority of this output condition
|
238
|
+
# @option attr [Boolean] :output_for_this_flow
|
239
|
+
# flag for this flow's output
|
240
|
+
def initialize(data_expr, attr={})
|
241
|
+
@data_expr = data_expr
|
242
|
+
@input_distribution = attr[:input_distribution]
|
243
|
+
@output_distribution = attr[:output_distribution]
|
244
|
+
@input_priority = attr[:input_priority] || 1
|
245
|
+
@output_priority = attr[:output_priority] || 1
|
246
|
+
@input_nonexistable = attr[:input_nonexistable]
|
247
|
+
@output_nonexistable = attr[:output_nonexistable]
|
248
|
+
@output_for_this_flow = attr[:output_for_this_flow]
|
249
|
+
end
|
250
|
+
|
251
|
+
# Return a declaration string of the data expression as input condition.
|
252
|
+
def as_input_declaration(option={})
|
253
|
+
indent("input %s" % textize_data_expr(:input), option)
|
254
|
+
end
|
255
|
+
|
256
|
+
# Return a declaration string of the data expression as output condition.
|
257
|
+
def as_output_declaration(option={})
|
258
|
+
indent("output %s" % textize_data_expr(:output), option)
|
259
|
+
end
|
260
|
+
|
261
|
+
private
|
262
|
+
|
263
|
+
def textize_data_expr(type)
|
264
|
+
data_expr = "%s" % @data_expr
|
265
|
+
if (type == :input and @input_nonexistable) or (type == :output and @output_nonexistable)
|
266
|
+
data_expr = data_expr + " or null"
|
267
|
+
end
|
268
|
+
if type == :input and @input_distribution
|
269
|
+
data_expr = "(%s).%s" % [data_expr, @input_distribution]
|
270
|
+
end
|
271
|
+
if type == :output and @output_distribution
|
272
|
+
data_expr = "(%s).%s" % [data_expr, @output_distribution]
|
273
|
+
end
|
274
|
+
return data_expr
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
# `Param` is a class represents PIONE's paramter declaration.
|
279
|
+
class Param < Perspective
|
280
|
+
attr_reader :name
|
281
|
+
attr_reader :default_expr
|
282
|
+
|
283
|
+
# @param name [String]
|
284
|
+
# parameter name, note that this name doesn't include heading `$`
|
285
|
+
# @param default expr [String]
|
286
|
+
# default value expression
|
287
|
+
def initialize(name, default_expr)
|
288
|
+
@name = name
|
289
|
+
@default_expr = default_expr
|
290
|
+
end
|
291
|
+
|
292
|
+
def as_declaration(option={})
|
293
|
+
indent("param $%s := %s" % [@name, @default_expr], option)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
# ConditionalBranch is a class represents PIONE's conditional branch
|
298
|
+
# declaration.
|
299
|
+
class ConditionalBranch < Perspective
|
300
|
+
attr_reader :condition
|
301
|
+
attr_reader :table
|
302
|
+
|
303
|
+
def initialize(type, condition)
|
304
|
+
@type = type
|
305
|
+
@condition = condition
|
306
|
+
@table = Hash.new {|h,k| h[k] = []}
|
307
|
+
end
|
308
|
+
|
309
|
+
def as_declaration(option={})
|
310
|
+
case @type
|
311
|
+
when :"if"
|
312
|
+
branch_then = @table[:then].map do |rule|
|
313
|
+
" rule %s" % Perspective.normalize_data_name(rule.name)
|
314
|
+
end.join("\n")
|
315
|
+
|
316
|
+
if @table[:else].empty?
|
317
|
+
indent(Util::Indentation.cut(TEMPLATE_IF) % [@condition, branch_then], option)
|
318
|
+
else
|
319
|
+
branch_else = @table[:else].map do |rule|
|
320
|
+
" rule %s" % Perspective.normalize_data_name(rule.name)
|
321
|
+
end.join("\n")
|
322
|
+
indent(Util::Indentation.cut(TEMPLATE_IF_ELSE) % [@condition, branch_then, branch_else], option)
|
323
|
+
end
|
324
|
+
when :"case"
|
325
|
+
branches = @table.each_with_object([]) do |(val, rules), list|
|
326
|
+
list << ((val == :else) ? "else" : "when %s" % val)
|
327
|
+
list.concat(rules.map{|rule| " rule %s" % rule.name})
|
328
|
+
end.join("\n")
|
329
|
+
indent(Util::Indentation.cut(TEMPLATE_CASE) % [@condition, branches], option)
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
TEMPLATE_IF = <<-TXT
|
334
|
+
if %s
|
335
|
+
%s
|
336
|
+
end
|
337
|
+
TXT
|
338
|
+
|
339
|
+
TEMPLATE_IF_ELSE = <<-TXT
|
340
|
+
if %s
|
341
|
+
%s
|
342
|
+
else
|
343
|
+
%s
|
344
|
+
end
|
345
|
+
TXT
|
346
|
+
|
347
|
+
TEMPLATE_CASE = <<-TXT
|
348
|
+
case %s
|
349
|
+
%s
|
350
|
+
end
|
351
|
+
TXT
|
352
|
+
end
|
353
|
+
|
354
|
+
class RuleDefinition < Perspective
|
355
|
+
attr_accessor :name
|
356
|
+
attr_accessor :inputs
|
357
|
+
attr_accessor :outputs
|
358
|
+
attr_accessor :params
|
359
|
+
attr_accessor :conditions
|
360
|
+
attr_accessor :flow_elements
|
361
|
+
|
362
|
+
def initialize(name, option={})
|
363
|
+
@name = name
|
364
|
+
@inputs = option[:inputs] || []
|
365
|
+
@outputs = option[:outputs] || []
|
366
|
+
@params = option[:params] || []
|
367
|
+
@conditions = option[:conditions] || []
|
368
|
+
@flow_elements = option[:flow_elements] || []
|
369
|
+
end
|
370
|
+
|
371
|
+
def textize
|
372
|
+
if flow_elements.empty?
|
373
|
+
template = Util::Indentation.cut(ACTION_RULE_TEMPLATE)
|
374
|
+
else
|
375
|
+
template = Util::Indentation.cut(FLOW_RULE_TEMPLATE)
|
376
|
+
end
|
377
|
+
ERB.new(template, nil, "-").result(binding)
|
378
|
+
end
|
379
|
+
|
380
|
+
FLOW_RULE_TEMPLATE = <<-RULE
|
381
|
+
Rule <%= @name %>
|
382
|
+
<%- @inputs.each do |input| -%>
|
383
|
+
input <%= input %>
|
384
|
+
<%- end -%>
|
385
|
+
<%- @outputs.each do |output| -%>
|
386
|
+
output <%= output %>
|
387
|
+
<%- end -%>
|
388
|
+
<%- @params.each do |param| -%>
|
389
|
+
<%= param.as_declaration %>
|
390
|
+
<%- end -%>
|
391
|
+
Flow
|
392
|
+
<%- @flow_elements.each do |element| -%>
|
393
|
+
<%- if element.is_a?(RuleDefinition) -%>
|
394
|
+
rule <%= element.name %>
|
395
|
+
<%- else -%>
|
396
|
+
<%= element.as_declaration(level: 1) %>
|
397
|
+
<%- end -%>
|
398
|
+
<%- end -%>
|
399
|
+
End
|
400
|
+
RULE
|
401
|
+
|
402
|
+
ACTION_RULE_TEMPLATE = <<-RULE
|
403
|
+
Rule <%= @name %>
|
404
|
+
<%- @inputs.each do |input| -%>
|
405
|
+
input <%= input %>
|
406
|
+
<%- end -%>
|
407
|
+
<%- @outputs.each do |output| -%>
|
408
|
+
output (<%= output %>).touch
|
409
|
+
<%- end -%>
|
410
|
+
<%- @params.each do |param| -%>
|
411
|
+
<%= param.as_declaration %>
|
412
|
+
<%- end -%>
|
413
|
+
End
|
414
|
+
RULE
|
415
|
+
end
|
416
|
+
end
|
417
|
+
end
|