sfp 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *.gem
data/LICENSE ADDED
@@ -0,0 +1,30 @@
1
+ BSD LICENSE
2
+
3
+ Copyright (c) 2013, Herry
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+
26
+ The views and conclusions contained in the software and documentation are those
27
+ of the authors and should not be interpreted as representing official policies,
28
+ either expressed or implied, of the FreeBSD Project.
29
+
30
+ The solver binaries are under GPL License from http://fast-downward.org.
data/README.md ADDED
@@ -0,0 +1,200 @@
1
+ SFP Parser and Planner for Ruby
2
+ ===============================
3
+ - Author: Herry (herry13@gmail.com)
4
+ - Last update: 20 April 2013
5
+ - Version: 1.0.1
6
+ - License: [BSD License](https://github.com/herry13/sfp-ruby/blob/master/LICENSE)
7
+
8
+ A Ruby gem that provides a Ruby interface to parse SFP language. It also provides
9
+ a Ruby interface for a solver to generate a workflow for a planning task written
10
+ in SFP language.
11
+
12
+
13
+ To install
14
+ ----------
15
+
16
+ $ gem install sfp
17
+
18
+
19
+ Requirements
20
+ ------------
21
+ - Rubygems
22
+ - antlr3
23
+ - json
24
+
25
+
26
+ To use as a solver to solve a planning task
27
+ -------------------------------------------
28
+ - parse a SFP file, then print the output in JSON
29
+
30
+ $ sfp -p <sfp-file>
31
+
32
+ - solve a planning task, then print the workflow in JSON
33
+
34
+ $ sfp <sfp-file>
35
+
36
+ The planning task must be written in [SFP language](https://github.com/herry13/nuri/wiki/SFP-language).
37
+
38
+
39
+ To use as Ruby library
40
+ ----------------------
41
+ - include file **main.sfp** in your codes:
42
+
43
+ require 'sfp'
44
+
45
+ - to parse an SFP file, create a Sfp::Parser object, and then pass the content of the file:
46
+
47
+ # Determine the home directory of your SFP file.
48
+ home_dir = File.expand_path(File.dirname("my_file.sfp"))
49
+
50
+ # Create Sfp::Parser object; pass the home and root directory so the parser
51
+ # can find the included files.
52
+ parser = Sfp::Parser.new({:home_dir => home_dir, :root_dir => '/'})
53
+
54
+ # Parse the file.
55
+ parser.parse(File.read("my_file.sfp"))
56
+
57
+ # Get the result in Hash data structure
58
+ result = parser.root
59
+
60
+ - to solve a planning task, create a Sfp::Planner object, and then pass the file's path:
61
+
62
+ # Create Sfp::Planner object.
63
+ planner = Sfp::Planner.new
64
+
65
+ # Solve a planning task written in "my_file.sfp", then print
66
+ # the result in JSON.
67
+ puts planner.solve({:file => "my_file.sfp", :json => true})
68
+
69
+
70
+ Example
71
+ -------
72
+ - Create file **types.sfp** with content:
73
+
74
+ class Service {
75
+ running is false
76
+ procedure start {
77
+ conditions {
78
+ this.running is false
79
+ }
80
+ effects {
81
+ this.running is true
82
+ }
83
+ }
84
+ procedure stop {
85
+ conditions {
86
+ this.running is true
87
+ }
88
+ effects {
89
+ this.running is false
90
+ }
91
+ }
92
+ }
93
+ class Client {
94
+ refer isref Service
95
+ procedure redirect(s isref Service) {
96
+ conditions { }
97
+ effects {
98
+ this.refer is s
99
+ }
100
+ }
101
+ }
102
+
103
+ In this file, we have two classes that model our domain. First, class
104
+ **Service** with an attribute **running*, procedure **start** that
105
+ changes **running**'s value from **false** to *true*, and procedure
106
+ **stop** that changes **running**'s value from **true** to **false**.
107
+
108
+ We also have class **Client** with an attribute **refer**, which is
109
+ a reference to an instance of **Service**. There is a procedure
110
+ **redirect** that changes the value of **refer** with any instance if
111
+ **Service**.
112
+
113
+ - Create file **task.sfp** with content:
114
+
115
+ include "types.sfp"
116
+
117
+ initial state {
118
+ a isa Service {
119
+ running is true
120
+ }
121
+
122
+ b isa Service // with "running" is false
123
+
124
+ pc isa Client {
125
+ refer is a
126
+ }
127
+ }
128
+
129
+ goal constraint {
130
+ pc.refer is b
131
+ a.running is false
132
+ }
133
+
134
+ global constraint {
135
+ pc.refer.running is true
136
+ }
137
+
138
+ In this file, we specify a task where in the initial state of our domain,
139
+ we have two services **a** and **b**, and a client **pc**. **a** is
140
+ running, **b** is stopped, and **pc** is referring to **a**. We want to
141
+ generate a workflow that achieves goal: **pc** is referring to **b**
142
+ and **a** is stopped, and preserves global constraint: **pc** is always
143
+ referring to a running service.
144
+
145
+ - To generate the workflow, we invoke **sfp** command with argument
146
+ the path of the task file:
147
+
148
+ $ sfp task.sfp
149
+
150
+ Which will generate a workflow in JSON
151
+
152
+ {
153
+ "type": "sequential",
154
+ "workflow": [
155
+ {
156
+ "name": "$.b.start",
157
+ "parameters": {
158
+ },
159
+ "condition": {
160
+ "$.b.running": false
161
+ },
162
+ "effect": {
163
+ "$.b.running": true
164
+ }
165
+ },
166
+ {
167
+ "name": "$.pc.redirect",
168
+ "parameters": {
169
+ "$.s": "$.b"
170
+ },
171
+ "condition": {
172
+ },
173
+ "effect": {
174
+ "$.pc.refer": "$.b"
175
+ }
176
+ },
177
+ {
178
+ "name": "$.a.stop",
179
+ "parameters": {
180
+ },
181
+ "condition": {
182
+ "$.a.running": true
183
+ },
184
+ "effect": {
185
+ "$.a.running": false
186
+ }
187
+ }
188
+ ],
189
+ "version": "1",
190
+ "total": 3
191
+ }
192
+
193
+ This workflow is sequential that has 3 procedures. If you executes
194
+ the workflow in given order, it will achieves the goal state as well
195
+ as perserves the global constraints during the changes.
196
+
197
+ [Nuri](https://github.com/herry13/nuri) is a configuration tools that
198
+ binds these procedures with particular shell commands in order to
199
+ implement the required configuration changes based on the goal and
200
+ global constraints given by the user.
data/bin/sfp ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ libdir = File.expand_path(File.dirname(__FILE__))
4
+ require "#{libdir}/../lib/sfp"
5
+
6
+ # application mode
7
+ if ARGV.length > 1 and ARGV[0] == '-p'
8
+ home_dir = File.expand_path(File.dirname(ARGV[1]))
9
+ parser = Sfp::Parser.new({:home_dir => home_dir})
10
+ parser.parse(File.read(ARGV[1]))
11
+ puts parser.to_json({:pretty => true})
12
+ elsif ARGV.length > 0
13
+ planner = Sfp::Planner.new
14
+ #puts planner.solve_file(ARGV[0], true)
15
+ puts planner.solve({:file => ARGV[0], :pretty_json => true})
16
+ else
17
+ puts "Usage: #{$0} [options] <sfp-file>
18
+
19
+ options:
20
+ <none> parse file and solve the planning task
21
+ -p parse file and print it in JSON format
22
+
23
+ "
24
+ end
Binary file
Binary file
Binary file
Binary file