ESBify 0.0.1

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 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: []