nudge 0.0.1 → 0.0.2

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 CHANGED
@@ -1,4 +1,6 @@
1
1
  .hg*
2
+ pkg/*
3
+ nudge.gemspec
2
4
  *.pdf
3
5
  *.aux
4
6
  *.dvi
data/Rakefile CHANGED
@@ -5,16 +5,18 @@ begin
5
5
  Jeweler::Tasks.new do |gemspec|
6
6
  gemspec.name = "nudge"
7
7
  gemspec.summary = "Genetic Programming in the Nudge language"
8
- gemspec.description = "It's way complicated"
8
+ gemspec.description = "DOES NOT WORK YET. The nudge gem will provide a simple framework for building, running and managing genetic programming experiments which automatically discover algorithms and equations to solve well-defined target problems. It depends on CouchDB and Ruby 1.9+"
9
9
  gemspec.email = "bill@vagueinnovation.com"
10
10
  gemspec.homepage = "http://github.com/Vaguery/PragGP"
11
11
  gemspec.authors = ["Bill Tozier", "Trek Glowacki"]
12
12
 
13
- gemspec.add_dependency('couchrest')
14
- gemspec.add_dependency('sinatra')
15
- gemspec.add_dependency('treetop')
16
- gemspec.add_dependency('polyglot')
17
- gemspec.add_dependency('active_support')
13
+ gemspec.required_ruby_version = '>= 1.9.1'
14
+
15
+ gemspec.add_dependency('couchrest', '>= 0.33')
16
+ gemspec.add_dependency('sinatra', '>= 0.9.4')
17
+ gemspec.add_dependency('treetop', '>= 1.4.3')
18
+ gemspec.add_dependency('polyglot', '>= 0.2.9')
19
+ gemspec.add_dependency('activesupport', '>= 2.3.5')
18
20
  end
19
21
 
20
22
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
@@ -0,0 +1,23 @@
1
+ NUDGECODE:
2
+
3
+ block {
4
+ literal «1»
5
+ literal «2»
6
+ block {
7
+ sample «3»
8
+ sample «4»
9
+ }
10
+ }
11
+
12
+ # local values:
13
+ «1» float: 9.128
14
+ «2» code: block {literal code «5» block {sample bool «6»}}
15
+ «3» image: file:///881727183.jpg
16
+ «4» int: 881
17
+ «5» code: block { do int_add do int_multiply }
18
+ «6» bool: false
19
+
20
+ # local values can include references to other local values, but can never backtrack
21
+ # syntax check: are all local values assigned?
22
+ # syntax check: are all local values strings?
23
+ # semantic check: are there no backward-references?
@@ -0,0 +1,5 @@
1
+ Description:
2
+
3
+
4
+ Usage:
5
+
@@ -0,0 +1,73 @@
1
+ class NudgeGenerator < RubiGen::Base
2
+
3
+ DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
4
+ Config::CONFIG['ruby_install_name'])
5
+
6
+ default_options :author => nil
7
+
8
+ attr_reader :name
9
+
10
+ def initialize(runtime_args, runtime_options = {})
11
+ super
12
+ usage if args.empty?
13
+ @destination_root = File.expand_path(args.shift)
14
+ @name = base_name
15
+ extract_options
16
+ end
17
+
18
+ def manifest
19
+ record do |m|
20
+ # Ensure appropriate folder(s) exists
21
+ m.directory ''
22
+ BASEDIRS.each { |path| m.directory path }
23
+
24
+ # Create stubs
25
+ # m.template "template.rb", "some_file_after_erb.rb"
26
+ # m.template_copy_each ["template.rb", "template2.rb"]
27
+ # m.file "file", "some_file_copied"
28
+
29
+ m.file "activate.rb", "activate.rb"
30
+
31
+ # m.file_copy_each ["path/to/file", "path/to/file2"]
32
+
33
+ m.dependency "install_rubigen_scripts", [destination_root, 'nudge'],
34
+ :shebang => options[:shebang], :collision => :force
35
+ end
36
+ end
37
+
38
+ protected
39
+ def banner
40
+ <<-EOS
41
+ Creates a ...
42
+
43
+ USAGE: #{spec.name} name
44
+ EOS
45
+ end
46
+
47
+ def add_options!(opts)
48
+ opts.separator ''
49
+ opts.separator 'Options:'
50
+ # For each option below, place the default
51
+ # at the top of the file next to "default_options"
52
+ # opts.on("-a", "--author=\"Your Name\"", String,
53
+ # "Some comment about this option",
54
+ # "Default: none") { |o| options[:author] = o }
55
+ opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
56
+ end
57
+
58
+ def extract_options
59
+ # for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
60
+ # Templates can access these value via the attr_reader-generated methods, but not the
61
+ # raw instance variable value.
62
+ # @author = options[:author]
63
+ end
64
+
65
+ # Installation skeleton. Intermediate directories are automatically
66
+ # created so don't sweat their absence here.
67
+ BASEDIRS = %w(
68
+ config
69
+ experiment
70
+ spec
71
+ tmp
72
+ )
73
+ end
File without changes
data/bin/nudge ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'rubigen'
5
+
6
+ if %w(-v --version).include? ARGV.first
7
+ require 'nudge/version'
8
+ puts "#{File.basename($0)} #{Nudge::VERSION}"
9
+ exit(0)
10
+ end
11
+
12
+ require 'rubigen/scripts/generate'
13
+ source = RubiGen::PathSource.new(:application,
14
+ File.join(File.dirname(__FILE__), "../app_generators"))
15
+ RubiGen::Base.reset_sources
16
+ RubiGen::Base.append_sources source
17
+ RubiGen::Scripts::Generate.new.run(ARGV, :generator => 'nudge')
@@ -101,15 +101,18 @@ module Nudge
101
101
  def enable(item)
102
102
  if item.superclass == Instruction
103
103
  @instructions_library[item] = item.new(self)
104
- elsif item.superclass == NudgeType
104
+ elsif item.include? NudgeType
105
105
  @types |= [item]
106
106
  end
107
107
  end
108
108
 
109
109
  def active?(item)
110
+ puts "#{item.inspect} is the item"
110
111
  if item.superclass == Instruction
111
112
  @instructions_library.include?(item)
112
- elsif item.superclass == NudgeType
113
+ elsif item.include? NudgeType
114
+ puts "#{@types} is the type list"
115
+
113
116
  @types.include?(item)
114
117
  end
115
118
  end
@@ -160,7 +163,7 @@ module Nudge
160
163
  def disable(item)
161
164
  if item.superclass == Instruction
162
165
  @instructions_library.delete(item)
163
- elsif item.superclass == NudgeType
166
+ elsif item.include? NudgeType
164
167
  @types.delete(item)
165
168
  end
166
169
  end
@@ -82,7 +82,7 @@ module Nudge
82
82
  def randomize(context)
83
83
  raise(ArgumentError,"Random code cannot be created") if context.types == [CodeType]
84
84
  newType = context.types.sample
85
- @type = newType.to_s.slice(0..-5).downcase
85
+ @type = newType.to_nudgecode
86
86
  if newType != CodeType
87
87
  @value = newType.any_value
88
88
  else
@@ -123,7 +123,7 @@ module Nudge
123
123
 
124
124
  def randomize(context)
125
125
  newType = context.types.sample
126
- @type = newType.to_s.slice(0..-5).downcase
126
+ @type = newType.to_nudgecode
127
127
  if newType != CodeType
128
128
  @value = newType.any_value
129
129
  else
@@ -1,108 +1,111 @@
1
1
  # coding: utf-8
2
-
3
- class CodeType < NudgeType
4
- @@defaultPoints = 20
2
+ module NudgeType
5
3
 
6
- def self.random_skeleton(points=@@defaultPoints, blocks=points/10)
7
- blocks = [0,[points,blocks].min].max
4
+ class CodeType
5
+ include TypeBehaviors
6
+ @@defaultPoints = 20
7
+
8
+ def self.random_skeleton(points=@@defaultPoints, blocks=points/10)
9
+ blocks = [0,[points,blocks].min].max
8
10
 
9
- if points > 1
10
- skel = ["block {"]
11
- (points-2).times {skel << "*"}
12
- skel << "*}"
13
- front = 0
14
- (blocks-1).times do
15
- until skel[front].include?("*") do
16
- a,b = rand(points), rand(points)
17
- front,back = [a,b].min, [a,b].max
11
+ if points > 1
12
+ skel = ["block {"]
13
+ (points-2).times {skel << "*"}
14
+ skel << "*}"
15
+ front = 0
16
+ (blocks-1).times do
17
+ until skel[front].include?("*") do
18
+ a,b = rand(points), rand(points)
19
+ front,back = [a,b].min, [a,b].max
20
+ end
21
+ skel[front] = skel[front].sub(/\*/," block {")
22
+ skel[back] = skel[back] + "}"
18
23
  end
19
- skel[front] = skel[front].sub(/\*/," block {")
20
- skel[back] = skel[back] + "}"
21
- end
22
- skel = skel.join
23
- else
24
- if blocks>0
25
- skel = "block {}"
24
+ skel = skel.join
26
25
  else
27
- skel = "*"
26
+ if blocks>0
27
+ skel = "block {}"
28
+ else
29
+ skel = "*"
30
+ end
28
31
  end
32
+ return skel
29
33
  end
30
- return skel
31
- end
32
34
 
33
35
 
34
- def self.any_type(types)
35
- raise(ArgumentError,"no available NudgeTypes") if types.empty?
36
- return types.sample
37
- end
36
+ def self.any_type(types)
37
+ raise(ArgumentError,"no available NudgeTypes") if types.empty?
38
+ return types.sample
39
+ end
38
40
 
39
41
 
40
- def self.any_instruction(instructions)
41
- raise(ArgumentError,"no available Instructions") if instructions.empty?
42
- return instructions.sample
43
- end
42
+ def self.any_instruction(instructions)
43
+ raise(ArgumentError,"no available Instructions") if instructions.empty?
44
+ return instructions.sample
45
+ end
44
46
 
45
47
 
46
- def self.any_reference(references)
47
- raise(ArgumentError,"no available references") if references.empty?
48
- return references.sample
49
- end
48
+ def self.any_reference(references)
49
+ raise(ArgumentError,"no available references") if references.empty?
50
+ return references.sample
51
+ end
50
52
 
51
53
 
52
- def self.roulette_wheel(references, instructions, types)
53
- basis = Hash["reference", references.length,
54
- "instruction", instructions.length,
55
- "sample", types.length]
56
- sum = basis.values.inject(:+)
57
- spin = rand(sum)
58
- basis.each do |result,weight|
59
- return result if spin <= weight && weight > 0
60
- spin -= weight
54
+ def self.roulette_wheel(references, instructions, types)
55
+ basis = Hash["reference", references.length,
56
+ "instruction", instructions.length,
57
+ "sample", types.length]
58
+ sum = basis.values.inject(:+)
59
+ spin = rand(sum)
60
+ basis.each do |result,weight|
61
+ return result if spin <= weight && weight > 0
62
+ spin -= weight
63
+ end
64
+ raise "A problem occurred when executing CodeType#roulette_wheel"
61
65
  end
62
- raise "A problem occurred when executing CodeType#roulette_wheel"
63
- end
64
66
 
65
67
 
66
- def self.random_value(context, params = {})
67
- points = params[:points] || @@defaultPoints
68
- blocks = params[:blocks] || points/10
69
- skeleton = params[:skeleton] || self.random_skeleton(points, blocks)
70
- instructions = params[:instructions] || context.instructions
71
- references = params[:references] || context.references
72
- types = params[:types] || context.types
68
+ def self.random_value(context, params = {})
69
+ points = params[:points] || @@defaultPoints
70
+ blocks = params[:blocks] || points/10
71
+ skeleton = params[:skeleton] || self.random_skeleton(points, blocks)
72
+ instructions = params[:instructions] || context.instructions
73
+ references = params[:references] || context.references
74
+ types = params[:types] || context.types
73
75
 
74
- while skeleton.include?("*") do
75
- case self.roulette_wheel(references,instructions,types)
76
- when "instruction"
77
- newPoint = " do " + self.any_instruction(instructions).to_nudgecode
78
- when "reference"
79
- newPoint = " ref " + self.any_reference(references)
80
- when "sample"
81
- theType = any_type(types)
82
- if theType == CodeType
83
- if types != [CodeType]
84
- theType = self.any_type(types - [CodeType])
85
- else
86
- raise ArgumentError, "Random code cannot be created"
76
+ while skeleton.include?("*") do
77
+ case self.roulette_wheel(references,instructions,types)
78
+ when "instruction"
79
+ newPoint = " do " + self.any_instruction(instructions).to_nudgecode
80
+ when "reference"
81
+ newPoint = " ref " + self.any_reference(references)
82
+ when "sample"
83
+ theType = any_type(types)
84
+ if theType == CodeType
85
+ if types != [CodeType]
86
+ theType = self.any_type(types - [CodeType])
87
+ else
88
+ raise ArgumentError, "Random code cannot be created"
89
+ end
87
90
  end
91
+ newPoint = " sample " + theType.to_nudgecode + " (" + theType.any_value.to_s + ")"
92
+ else
93
+ raise ArgumentError, "Nothing to make random code from"
88
94
  end
89
- newPoint = " sample " + theType.to_nudgecode + " (" + theType.any_value.to_s + ")"
90
- else
91
- raise ArgumentError, "Nothing to make random code from"
95
+ skeleton = skeleton.sub(/\*/, newPoint)
96
+ skeleton = skeleton.sub(/\n/,'')
92
97
  end
93
- skeleton = skeleton.sub(/\*/, newPoint)
94
- skeleton = skeleton.sub(/\n/,'')
98
+ skeleton
95
99
  end
96
- skeleton
97
- end
98
100
 
99
101
 
100
102
 
101
- def self.from_s(string_value)
102
- return string_value.sub(/\(/,"«").sub(/\)/,"»")
103
- end
103
+ def self.from_s(string_value)
104
+ return string_value.sub(/\(/,"«").sub(/\)/,"»")
105
+ end
104
106
 
105
- def self.any_value(context)
106
- self.random_value(context)
107
+ def self.any_value(context)
108
+ self.random_value(context)
109
+ end
107
110
  end
108
111
  end
@@ -1,102 +1,115 @@
1
1
  # coding: utf-8
2
2
 
3
- class NudgeType
4
- require 'singleton'
5
- include Singleton
6
-
7
- @@all_types = []
8
-
9
- def self.inherited(subclass)
10
- @@all_types << subclass
11
- super
12
- end
3
+ module NudgeType
13
4
 
14
5
  def self.all_types
15
- @@all_types
6
+ @all_types ||= []
16
7
  end
17
8
 
18
9
  def self.push_types
19
10
  [IntType, BoolType, FloatType]
20
11
  end
21
12
 
22
- def self.to_nudgecode
23
- self.to_s.slice(0..-5).downcase
24
- end
25
-
26
- def self.from_s
27
- raise "Your subclass of NudgeType should provide a method for parsing string values in code"
28
- end
29
- end
30
-
13
+ module TypeBehaviors
14
+ def self.extended(subclass)
15
+ NudgeType.all_types << subclass
16
+ end
17
+
18
+ def to_nudgecode
19
+ self.to_s.demodulize.slice(0..-5).downcase.intern
20
+ end
31
21
 
22
+ def from_s(some_string)
23
+ raise "This class must implement #{self.inspect}.from_s"
24
+ end
32
25
 
26
+ def any_value
27
+ raise "This class must implement #{self.inspect}.any_value"
28
+ end
33
29
 
34
- class IntType < NudgeType
35
- @defaultLowest = -100
36
- @defaultHighest = 100
37
-
38
- def self.defaultLowest
39
- @defaultLowest
30
+ def random_value(params)
31
+ raise "This class must implement #{self.inspect}.random_value"
32
+ end
40
33
  end
41
34
 
42
- def self.defaultHighest
43
- @defaultHighest
35
+ class BasicType
36
+ def self.inherited(subclass)
37
+ subclass.extend TypeBehaviors
38
+ end
44
39
  end
45
40
 
46
- def self.random_value(params={})
47
- bottom = params[:randomIntegerLowerBound] || @defaultLowest
48
- top = params[:randomIntegerUpperBound] || @defaultHighest
49
- lowest, highest = [bottom,top].min, [bottom,top].max
50
- rand(highest-lowest).to_i + lowest
51
- end
52
-
53
- def self.from_s(string_value)
54
- return string_value.to_i
55
- end
56
-
57
- def self.any_value
58
- self.random_value
59
- end
60
- end
41
+ class IntType < Fixnum
42
+ extend TypeBehaviors
43
+ @defaultLowest = -100
44
+ @defaultHighest = 100
61
45
 
46
+ def self.defaultLowest
47
+ @defaultLowest
48
+ end
62
49
 
50
+ def self.defaultHighest
51
+ @defaultHighest
52
+ end
63
53
 
54
+ def self.random_value(params={})
55
+ bottom = params[:randomIntegerLowerBound] || @defaultLowest
56
+ top = params[:randomIntegerUpperBound] || @defaultHighest
57
+ lowest, highest = [bottom,top].min, [bottom,top].max
58
+ rand(highest-lowest).to_i + lowest
59
+ end
64
60
 
65
- class BoolType < NudgeType
66
- def self.random_value(params = {})
67
- p = params[:randomBooleanTruthProb] || 0.5
68
- rand() < p
69
- end
70
-
71
- def self.from_s(string_value)
72
- return string_value.downcase == "true"
73
- end
74
-
75
- def self.any_value
76
- self.random_value
61
+ def self.from_s(string_value)
62
+ return string_value.to_i
63
+ end
64
+
65
+ def self.any_value
66
+ self.random_value
67
+ end
77
68
  end
78
- end
79
69
 
80
70
 
81
71
 
82
72
 
83
- class FloatType < NudgeType
84
- @defaultLowest = -1000.0
85
- @defaultHighest = 1000.0
86
-
87
- def self.random_value(params = {})
88
- bottom = params[:randomFloatLowerBound] || @defaultLowest
89
- top = params[:randomFloatUpperBound] || @defaultHighest
90
- bottom, top = [bottom,top].min, [bottom,top].max
91
- range = top - bottom
92
- (rand*range) + bottom
93
- end
94
-
95
- def self.from_s(string_value)
96
- return string_value.to_f
73
+ class BoolType
74
+ extend TypeBehaviors
75
+
76
+ def self.random_value(params = {})
77
+ p = params[:randomBooleanTruthProb] || 0.5
78
+ rand() < p
79
+ end
80
+
81
+ def self.from_s(string_value)
82
+ string_value.downcase == "true" ? true : false
83
+ end
84
+
85
+ def self.any_value
86
+ self.random_value
87
+ end
97
88
  end
98
-
99
- def self.any_value
100
- self.random_value
89
+
90
+
91
+
92
+
93
+ class FloatType < Float
94
+ extend TypeBehaviors
95
+
96
+ @defaultLowest = -1000.0
97
+ @defaultHighest = 1000.0
98
+
99
+ def self.random_value(params = {})
100
+ bottom = params[:randomFloatLowerBound] || @defaultLowest
101
+ top = params[:randomFloatUpperBound] || @defaultHighest
102
+ bottom, top = [bottom,top].min, [bottom,top].max
103
+ range = top - bottom
104
+ (rand*range) + bottom
105
+ end
106
+
107
+ def self.from_s(string_value)
108
+ return string_value.to_f
109
+ end
110
+
111
+ def self.any_value
112
+ self.random_value
113
+ end
101
114
  end
102
- end
115
+ end
data/lib/nudge.rb CHANGED
@@ -35,4 +35,6 @@ require 'search/operators/basic_operators'
35
35
  require 'search/operators/samplers_and_selectors'
36
36
  require 'search/operators/evaluators'
37
37
  require 'search/stations/station'
38
- require 'search/experiments/experiment'
38
+ require 'search/experiments/experiment'
39
+
40
+ include NudgeType
@@ -28,9 +28,7 @@ module Nudge
28
28
  attr_reader :id
29
29
 
30
30
  def initialize(listing)
31
- @helperParser =
32
-
33
- @genome = listing
31
+ @helperParser = @genome = listing
34
32
  raise(ArgumentError, "Nudge program cannot be parsed") if Individual.helperParser.parse(genome) == nil
35
33
  @program = Individual.helperParser.parse(genome).to_points
36
34
  @scores = Hash.new