ESBify 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/ESBify.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ESBify/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ESBify"
7
+ s.version = ESBify::VERSION
8
+ s.authors = ["Jakub Hampl"]
9
+ s.email = ["honitom@seznam.cz"]
10
+ s.homepage = "https://github.com/gampleman/esbify"
11
+ s.summary = %q{Generates proper XML files for the ESB framework from a DSL.}
12
+ s.description = %q{Generates proper XML files for the ESB framework from a DSL.}
13
+
14
+ s.rubyforge_project = "ESBify"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "rake"
23
+ s.add_runtime_dependency "builder"
24
+ s.add_runtime_dependency "erubis"
25
+ end
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ESBify.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,107 @@
1
+ # ESBify
2
+
3
+ ESBify is a simple DSL for creating the necessary XML files for the ESB framework.
4
+
5
+ ## Instalation ##
6
+
7
+ $ gem install esbify
8
+
9
+ should do the trick provided you have a recent enough installation of Ruby. Run
10
+
11
+ $ esbify -h
12
+
13
+ to list basic usage.
14
+
15
+ ## Syntax
16
+
17
+ !expectations
18
+
19
+ name: may_not_have_bangs
20
+ condition: played(P1, duel, P2) | responded(P1, bang, P2, duel) | played(P1, indians, P2)
21
+ phi: requires_bang_response(P2)
22
+ test_plus: lost_life(P2)
23
+ test_minus: played(P2, bang, P3) | responded(P2, bang, P3, _)
24
+ rho_plus:
25
+ + has_no_bangs
26
+ rho_minus:
27
+ - has_no_bangs
28
+
29
+ ----------
30
+
31
+ name: has_no_bangs
32
+ condition: requires_bang_response℗ | has_no_bangs(P)
33
+ phi: has_no_bangs_phi(P)
34
+ test_minus: draw(P, X)
35
+ rho_minus:
36
+ - has_no_bangs
37
+
38
+
39
+ # comment
40
+
41
+ !behaviors
42
+
43
+ name: JI plans
44
+ jason: has_no_bangs(P)
45
+ action: card_expectation(P, bang, 0)
46
+
47
+
48
+
49
+ ### Headers
50
+
51
+ `!expectation`, `!behavior`, `!strategy`
52
+
53
+ Are possible headers saying that the following code will be of that particular type.
54
+
55
+ ### Expectations
56
+
57
+ ### Behaviors
58
+
59
+ `name` is an identifier and isn't particularly useful. When omitted, a random number will be used.
60
+
61
+ `ctl` is a [computation tree logic](http://en.wikipedia.org/wiki/Computation_tree_logic).
62
+
63
+ The syntax of CTL formulas recognized by NUSMV is as follows:
64
+
65
+ `ctl_expr` =
66
+
67
+
68
+ `simple_expr` | a simple boolean expression
69
+ --------------- | -------
70
+ `( ctl_expr )` |
71
+ `! ctl_expr` | logical not
72
+ `ctl_expr & ctl_expr` | logical and
73
+ `ctl_expr xor ctl_expr` | logical exclusive or
74
+ `ctl_expr xnor ctl_expr` | logical NOT exclusive or
75
+ `ctl_expr -> ctl_expr` | logical implies
76
+ `ctl_expr <-> ctl_expr` | logical equivalence
77
+ `EG ctl_expr` | exists globally
78
+ `EX ctl_expr` | exists next state
79
+ `EF ctl_expr` | exists finally
80
+ `AG ctl_expr` | forall globally
81
+ `AX ctl_expr` | for all next state
82
+ `AF ctl_expr` | for all finally
83
+ `E [ ctl_expr U ctl_expr ]` | exists until
84
+ `A [ ctl_expr U ctl_expr ]` | forall until
85
+
86
+ - `EX p` is true in a state s if there exists a state s′ such that a transition goes from s to s′
87
+ and p is true in s′.
88
+ - AX p is true in a states iff or all states s′ wherethereisatransitionfromstos′,pistrue
89
+ in s′.
90
+ - EF p is true in a state s0 if there exists a series of transitions s0 → s1, s1 → s2, ...,
91
+ sn−1 →sn suchthatpistrueinsn.
92
+ - AF pistrueinastates0 ifforallseriesoftransitionss0 → s1,s1 → s2,...,sn−1 → sn
93
+ p is true in sn.
94
+ - EG p is true in a state s0 if there exists an infinite series of transitions s0 → s1, s1 → s2,
95
+ ... such that p is true in every si.
96
+ - AG pistrueinastates0 ifforallinfiniteseriesoftransitionss0 →s1,s1 →s2,... p
97
+ is true in every si.
98
+ - E[p U q] is true in a state s0 if there exists a series of transitions s0 → s1, s1 → s2,
99
+ ..., sn−1 → sn such that p is true in every state from s0 to sn−1 and q is true in state sn.
100
+ - A[p U q]istrueinastates0 ifforallseriesoftransitionss0 → s1,s1 → s2,...,
101
+ sn−1 → sn p is true in every state from s0 to sn−1 and q is true in state sn. A CTL formula is true if it is true in all initial states.
102
+
103
+ ---
104
+
105
+ `jason` is a logic inside the ASL agent.
106
+
107
+ Both `ctl` and `jason` need to be true to execute `action`, which is a ASL belief that will be added to the agent's belief base.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/esbify ADDED
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env ruby
2
+ require "optparse"
3
+ require File.dirname(__FILE__) + "/../lib/ESBify"
4
+
5
+
6
+
7
+ options = {stdout: false, expectations: "./Expectations.xml", behaviors: "./Behaviours.xml", filter: /.*/, only: %w[expectations behaviors strategies], context: {}}
8
+ OptionParser.new do |opts|
9
+ opts.banner = "Usage: esbify [options] FILES..."
10
+
11
+ opts.on("-e", "--expectations FILE", "Output Expectations to FILE") do |v|
12
+ options[:expectations] = v
13
+ end
14
+
15
+ opts.on("-b", "--behaviors FILE", "Output Behaviours to FILE") do |v|
16
+ options[:behaviors] = v
17
+ end
18
+
19
+ opts.on("--[no-]stdout", "Print to STDOUT") do |v|
20
+ options[:stdout] = v
21
+ end
22
+
23
+ opts.on("-f", "--filter REGEXP", "When printing out expectations, only print those matching this regexp.") do |v|
24
+ options[:filter] = Regexp.new(v)
25
+ end
26
+
27
+ opts.on("--only expectations,behaviors,strategies", Array, "Only generate these files") do |v|
28
+ raise ArgumentError unless v.all?{|o| %w[expectations behaviors strategies].include?(o)}
29
+ options[:only] = v
30
+ end
31
+
32
+ opts.on("--context HASH_OR_PATH", "A path to a ruby class or a hash of values that will be passed to ERB", "The ruby class should have a underscored filename and CamelCased classname. ") do |v|
33
+ if v =~ /\:|=>/
34
+ options[:context] = eval(v, binding)
35
+ else
36
+ require v
37
+ name = v.gsub(/(_|^)./){|a| a.chars.to_a.last.upcase}
38
+ const = Object.const_defined?(name) ? Object.const_get(name) : Object.const_missing(name)
39
+ options[:context] = const.new
40
+ end
41
+ end
42
+
43
+ opts.on_tail("-h", "--help [README]", "Call -h with README to view the readme file") do |t|
44
+ if t == "README"
45
+ puts File.read(File.dirname(__FILE__) + "/../README.md")
46
+ else
47
+ puts opts
48
+ end
49
+ exit
50
+ end
51
+
52
+ opts.on_tail("-v", "--version", "Show version") do
53
+ puts ESBify::VERSION
54
+ exit
55
+ end
56
+
57
+ end.parse!
58
+
59
+ parser = ESBify::Parser.new options[:context]
60
+
61
+ ARGV.each do |f|
62
+ parser.parse_file! f
63
+ end
64
+
65
+ if options[:stdout]
66
+ puts parser.expectations if options[:only].include?("expectations")
67
+ puts parser.behaviors if options[:only].include?("behaviors")
68
+ else
69
+ File.open(options[:expectations], "w") {|f| f << parser.expectations } if options[:only].include?("expectations")
70
+ File.open(options[:behaviors], "w") {|f| f << parser.behaviors } if options[:only].include?("behaviors")
71
+ end
72
+
73
+ puts parser.expectation.names.grep(options[:filter]).join(",")
@@ -0,0 +1,27 @@
1
+ require "builder"
2
+ class ESBify::Base
3
+ def initialize
4
+ @data = []
5
+ end
6
+
7
+ def defaults
8
+
9
+ end
10
+
11
+ def <<(sects)
12
+ @data += sects.map do |sect|
13
+ defaults.merge(sect)
14
+ end
15
+ end
16
+
17
+ def to_xml_partial
18
+ b = Builder::XmlMarkup.new indent: 2, margin: 1
19
+ @data.each do |sect|
20
+ xml_section(b, sect)
21
+ end
22
+ #puts b.inspect
23
+ "\n" + b.target!
24
+ end
25
+
26
+
27
+ end
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + "/base"
2
+
3
+ class ESBify::Behavior < ::ESBify::Base
4
+
5
+ def defaults
6
+ {
7
+ "name" => rand(1000),
8
+ "ctl" => "",
9
+ "jason" => "",
10
+ "action" => "",
11
+ }
12
+ end
13
+
14
+
15
+ def xml_section(b, sect)
16
+ b.behaviour name: sect["name"] do |b|
17
+ b.condition do |b|
18
+ b.ctl sect["ctl"]
19
+ b.jason sect["jason"]
20
+ end
21
+ b.action sect["action"]
22
+ end
23
+ end
24
+
25
+
26
+ def to_xml
27
+ b = Builder::XmlMarkup.new indent: 2
28
+ b.instruct!
29
+ b.declare! :DOCTYPE, :BehaviourSet, :SYSTEM, "esb-ji-jason/behaviours.dtd"
30
+ b.BehaviourSet do |b|
31
+ b << to_xml_partial
32
+ end # ExpectationSet
33
+ end
34
+
35
+ end
36
+
@@ -0,0 +1,79 @@
1
+ require File.dirname(__FILE__) + "/base"
2
+ module ESBify
3
+ class Expectation < ::ESBify::Base
4
+ attr_reader :names
5
+
6
+ def defaults
7
+ {
8
+ "agent" => "self",
9
+ "name" => rand(1000),
10
+ "condition" => "true",
11
+ "phi" => "",
12
+ "test_plus" => "",
13
+ "test_minus" => "",
14
+ "rho_plus" => {
15
+ "addSet" => [],
16
+ "remSet" => []
17
+ },
18
+ "rho_minus" => {
19
+ "addSet" => [],
20
+ "remSet" => []
21
+ }
22
+ }
23
+ end
24
+
25
+ def <<(sects)
26
+ @names ||= []
27
+ @data += sects.map do |sect|
28
+ sect["rho_plus"] = parse_mods(sect["rho_plus"]) if sect["rho_plus"]
29
+ sect["rho_minus"] = parse_mods(sect["rho_minus"]) if sect["rho_minus"]
30
+ @names << sect["name"] if sect["name"]
31
+ defaults.merge(sect)
32
+ end
33
+ end
34
+
35
+ def parse_mods(str)
36
+ add_set = []
37
+ rem_set = []
38
+ str.scan(/^\s*(\+|\-)\s*(.+)\s*$/).each do |sym, str|
39
+ if sym == "+"
40
+ add_set << str
41
+ else
42
+ rem_set << str
43
+ end
44
+ end
45
+ {"addSet" => add_set, "remSet" => rem_set}
46
+ end
47
+
48
+ def to_xml
49
+ b = Builder::XmlMarkup.new indent: 2
50
+ b.instruct!
51
+ b.declare! :DOCTYPE, :ExpectationSet, :SYSTEM, "esb-ji-jason/ExpectationSet.dtd"
52
+ b.ExpectationSet do |b|
53
+ b << to_xml_partial
54
+ end # ExpectationSet
55
+ end
56
+
57
+ def xml_section(b, sect)
58
+ b.tag! "expectation" do |b|
59
+ sect.each do |k,v|
60
+ if v.is_a?(Array) || v.is_a?(Hash)
61
+ b.tag! k do |b|
62
+ b.tag! "addSet" do |b|
63
+ v["addSet"].each {|el| b.name(el) }
64
+ end
65
+ b.tag! "remSet" do |b|
66
+ v["remSet"].each {|el| b.name(el) }
67
+ end
68
+ end
69
+ else
70
+ b.tag! k, v
71
+ end
72
+ end
73
+ end # base
74
+ end
75
+
76
+
77
+ end
78
+
79
+ end
@@ -0,0 +1,69 @@
1
+ require 'erubis'
2
+ require File.dirname(__FILE__) + "/expectation"
3
+ require File.dirname(__FILE__) + "/behavior"
4
+ #require "./behavior"
5
+ #require "./strategy"
6
+
7
+ class ESBify::Parser
8
+
9
+ attr_reader :expectation
10
+
11
+ def initialize(context = {})
12
+ @expectation = ::ESBify::Expectation.new
13
+ @behavior = ::ESBify::Behavior.new
14
+ #@strategy = ::ESBify::Strategy.new
15
+
16
+ @context = context
17
+ end
18
+
19
+
20
+ def expectations
21
+ @expectation.to_xml
22
+ end
23
+
24
+ def behaviors
25
+ @behavior.to_xml
26
+ end
27
+
28
+ def strategies
29
+ @strategy.to_xml
30
+ end
31
+
32
+ def parse_file!(path)
33
+ parse! File.read(path)
34
+ end
35
+
36
+ def parse!(str)
37
+ # Remove comments
38
+ str = str.split("\n").map{|l| l.split('#').first }.join("\n")
39
+ str = Erubis::Eruby.new(str).evaluate(@context)
40
+ str.split(/\!(?=(?:expectation|behaviou?r|strateg(?:y|ie))s?\n)/).each do |section|
41
+ next if section =~ /\A\s*\z/m
42
+ m = section.match /\A(expectation|behaviou?r|strateg(?:y|ie))s?/
43
+ txt = str.split("\n")
44
+ txt.shift
45
+ txt.join("\n")
46
+ sect = parse_section(section)
47
+ case m[1]
48
+ when /expectations?/
49
+ @expectation << sect
50
+ when /behaviou?rs?/
51
+ @behavior << sect
52
+ when /strateg(?:y|ie)s?/
53
+ @strategy << sect
54
+ else
55
+ raise ArgumentError
56
+ end
57
+ end
58
+
59
+ end
60
+
61
+
62
+ def parse_section(str)
63
+ segs = str.split(/\s*\n---+\s*\n\s*/m)
64
+ segs.map do |seg|
65
+ ms = seg.scan /(?:^|\n)([\w_]+)\s*\:\s*(.+?)(?=(?:\n[\w_]+\s*\:|\z))/m
66
+ Hash[*ms.flatten.map(&:strip)]
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,35 @@
1
+ require File.dirname(__FILE__) + "/base"
2
+
3
+ class ESBify::Strategy < ::ESBify::Base
4
+
5
+ # TODO: There can be more then one transstatement per element, use lists for this
6
+
7
+ def defaults
8
+ {
9
+ "main" => "",
10
+ "expectation" => ""
11
+ }
12
+ end
13
+
14
+
15
+ def xml_section(b, sect)
16
+ b.main do |b|
17
+ b.transStatement sect["main"]
18
+ end
19
+ b.expectation do |b|
20
+ b.transStatement sect["expectation"]
21
+ end
22
+ end
23
+
24
+
25
+ def to_xml
26
+ b = Builder::XmlMarkup.new indent: 2
27
+ b.instruct!
28
+ b.declare! :DOCTYPE, :BehaviourSet, :SYSTEM, "esb-ji-jason/behaviours.dtd"
29
+ b.strategy do |b|
30
+ b << to_xml_partial
31
+ end
32
+ end
33
+
34
+ end
35
+
@@ -0,0 +1,3 @@
1
+ module ESBify
2
+ VERSION = "0.0.1"
3
+ end
data/lib/ESBify.rb ADDED
@@ -0,0 +1,6 @@
1
+ require File.dirname(__FILE__) + "/ESBify/version"
2
+
3
+ module ESBify
4
+ # Your code goes here...
5
+ end
6
+ require File.dirname(__FILE__) + "/ESBify/parser"
data/test.esb ADDED
@@ -0,0 +1,9 @@
1
+ !expectation
2
+ name: test
3
+
4
+ ---
5
+
6
+ condition: played(1) & played(2)
7
+ ----
8
+ name: has_no_bangs
9
+ condition: requires_bang_response(P) | has_no_bangs(P)
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ESBify
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jakub Hampl
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-02 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: &70235824010600 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70235824010600
25
+ - !ruby/object:Gem::Dependency
26
+ name: builder
27
+ requirement: &70235824010160 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70235824010160
36
+ - !ruby/object:Gem::Dependency
37
+ name: erubis
38
+ requirement: &70235824009740 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70235824009740
47
+ description: Generates proper XML files for the ESB framework from a DSL.
48
+ email:
49
+ - honitom@seznam.cz
50
+ executables:
51
+ - esbify
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - ESBify.gemspec
57
+ - Gemfile
58
+ - README.md
59
+ - Rakefile
60
+ - bin/esbify
61
+ - lib/ESBify.rb
62
+ - lib/ESBify/base.rb
63
+ - lib/ESBify/behavior.rb
64
+ - lib/ESBify/expectation.rb
65
+ - lib/ESBify/parser.rb
66
+ - lib/ESBify/strategy.rb
67
+ - lib/ESBify/version.rb
68
+ - test.esb
69
+ homepage: https://github.com/gampleman/esbify
70
+ licenses: []
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ segments:
82
+ - 0
83
+ hash: -1658457591522309798
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ segments:
91
+ - 0
92
+ hash: -1658457591522309798
93
+ requirements: []
94
+ rubyforge_project: ESBify
95
+ rubygems_version: 1.8.6
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: Generates proper XML files for the ESB framework from a DSL.
99
+ test_files: []