maroon 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -6
  3. data/Rakefile +3 -3
  4. data/Test/Context_test.rb +16 -16
  5. data/{Examples/Dijkstra → Test/Examples}/CalculateShortestDistance.rb +11 -13
  6. data/Test/Examples/MoneyTransfer_test.rb +76 -0
  7. data/{Examples/Dijkstra → Test/Examples}/calculate_shortest_path.rb +77 -89
  8. data/{Examples/Dijkstra → Test/Examples}/data.rb +0 -0
  9. data/{Examples/Dijkstra/dijkstra.rb → Test/Examples/dijkstra_test.rb} +34 -24
  10. data/Test/Examples/greeter_test.rb +48 -0
  11. data/{Examples/meter.rb → Test/Examples/meter_test.rb} +44 -30
  12. data/Test/abstract_syntax_tree_test.rb +17 -26
  13. data/Test/alltests.rb +1 -1
  14. data/Test/test_helper.rb +2 -0
  15. data/base/AbstractSyntaxTree.rb +24 -3
  16. data/base/ImmutableStack.rb +1 -1
  17. data/base/dependency_graph.rb +94 -0
  18. data/base/immutable_queue.rb +1 -1
  19. data/base/maroon_base.rb +50 -11
  20. data/base/transfomer.rb +196 -197
  21. data/generated/Tokens.rb +64 -2
  22. data/generated/build.rb +1 -3
  23. data/generated/maroon/kernel.rb +7 -0
  24. data/lib/AbstractSyntaxTree.rb +120 -0
  25. data/lib/AstRewritter.rb +53 -58
  26. data/lib/Context.rb +104 -126
  27. data/lib/DependencyGraph.rb +76 -0
  28. data/lib/ImmutableQueue.rb +28 -39
  29. data/lib/ImmutableStack.rb +20 -34
  30. data/lib/Tokens.rb +64 -2
  31. data/lib/Transformer.rb +125 -165
  32. data/lib/build.rb +2 -4
  33. data/lib/maroon/kernel.rb +1 -1
  34. data/lib/maroon/version.rb +1 -1
  35. metadata +13 -11
  36. data/Examples/MoneyTransfer.rb +0 -62
  37. data/Examples/greeter.rb +0 -46
  38. data/Test/Greeter_test_disabled.rb +0 -203
  39. data/lib/Production.rb +0 -149
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8869041ee066afcbfc382e5679bdacbfef33401d
4
- data.tar.gz: 30910b3f6b2a216c99bc8b204d52fe6b735a7c01
3
+ metadata.gz: f663cc4db7c5aafc0525f99404cdeb2afe53f17b
4
+ data.tar.gz: b52e10404b2bcaafcc8fea74744d134235901aef
5
5
  SHA512:
6
- metadata.gz: 91a7a468e03ddb94d1549f138d52df08cf819bd85d4942064d867e0bcf6540911fc2882d33b3a33f92188479af5404deed83d730785db4466e52ac87cba895f4
7
- data.tar.gz: ad2cc204002f1f19c07cfb8f596648bb78dd2541d4de4c27565e48e355a1aa476d0a3c16fcffe26647921a31356a546552d6967e308a723a39bc6984017c109a
6
+ metadata.gz: 0d01a342d33a30bea615cc7584868963db58b5637f7adbb82168dd0bcbaa5d7c67f335b1e9f6822215d20a82a61234978e3a9572b58784adf9f1a253c48cdfa9
7
+ data.tar.gz: 84b7561a6183480bf571a5f7027be75cde74274c11752b9f9975fb418992b97f962ca288a730f591edba16f88ba744504dae2ff27f8f8cfb57559afad885ceb2
data/README.md CHANGED
@@ -22,7 +22,7 @@ See the examples for detailed information on how to use maroon.
22
22
 
23
23
  Essentially you can define a context by using
24
24
 
25
- Context::define :context_name do
25
+ Context.define :context_name do
26
26
  role :role_name do
27
27
  print_self do |x| #notice no symbol
28
28
  p "#{role_name} #use role_name to refer to the role of said name
@@ -34,7 +34,7 @@ end
34
34
 
35
35
  If you're using Bundler, run `bundle install` to setup your environment.
36
36
 
37
- Run `rake test` or just `rake` to make the tests run.
37
+ Run `rake default` or just `rake` to make the tests run.
38
38
 
39
39
 
40
40
  ## Contributing
@@ -47,10 +47,30 @@ Run `rake test` or just `rake` to make the tests run.
47
47
  6. Push to the branch (`git push origin my-new-feature`)
48
48
  7. Create new Pull Request
49
49
 
50
+ All changes should be done to the code in the base folder or the test folder.
51
+ The code in the base folder is the implementation of maroon. When the default rake task is executed code will be generated
52
+ in the 'generated' folder. The code in generated will be used when running the tests.
53
+ If all tests pass
54
+ 1. Copy the generated files from 'generated' to 'lib'
55
+ 2. Rerun the the default rake task
56
+ 3. If all tests pass copy the generated file from 'generated' to 'lib'
57
+ 4. commit and create a pull request
58
+
59
+ There's a rake task (build_lib) that will do the above if you are courageous enough to potentially loose your changes.
50
60
 
51
61
  Known bugs
52
- There are a few known bugs. The two major once are that #{...} syntax in strings can't beused. This is due to
53
- limitaion/bug in the current version of sourcify.
54
- If declaring several role methods for the same role sourcify might get confused and return the same sexp for
55
- multiple of them. The work around is to use do...end for the role ans {|| } for the role methods
62
+ 1. There are a few known bugs. The two major once are that double quotes can't be used. This is due to
63
+ limitation/bug in the current version of sourcify.
64
+ 2. Using 'self' in a role method points to the context itself where it should be the role player
65
+
66
+
56
67
 
68
+ Short description of the flow
69
+ The class named Context (defined in maroon_base.rb) will read and parse the block passed to the Context.define method
70
+ When the parsing is complete each method will be represented by an AST (using S-expressions). The transformer context
71
+ will take over from this point. In time it runs through the definition of all roles (including there methods) and interactions.
72
+ For each method it will use the AstRewritter context to rewrite the methods (e.g. call the correct method on the context
73
+ object when a role method is called). The AstRewritter is build on another context namely the AbstractSyntaxTree that is used to represent
74
+ and semantics to the abstract syntax tree (S-expressions) that represents each method.
75
+ When all methods have been rewritten the transformer will either write the corresponding class definition to file (if so specified)
76
+ or create a class in memory.
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require 'rake/testtask'
3
3
 
4
4
  Rake::TestTask.new do |t|
5
5
  t.libs << 'test'
6
- t.test_files = FileList['test/*_test.rb']
6
+ t.test_files = FileList['test/alltests.rb']
7
7
  t.verbose = true
8
8
  end
9
9
 
@@ -12,8 +12,8 @@ task :generate do |t|
12
12
  require_relative './lib/Context'
13
13
  require_relative './lib/maroon/kernel'
14
14
  require_relative './lib/build' #use the one in lib. That should be the stable one
15
- Context::generate_files_in(:generated) #generate files not just in memory classes
16
- `git ls-files ./base/`.split($/).grep(%r{(.)*.rb}).select {|f|p f; require_relative("#{f}")}
15
+ Context::generate_files_in=:generated #generate files not just in memory classes
16
+ `git ls-files ./base/`.split($/).grep(%r{(.)*.rb}).select {|f| require_relative("#{f}")}
17
17
  end
18
18
 
19
19
  #execute as with command line to make memory spaces independent
@@ -11,7 +11,7 @@ class ContextTest < Test::Unit::TestCase
11
11
  name = :MyContextRoleMethodCall
12
12
  role_name = :rol
13
13
 
14
- c=Context::define name do
14
+ Context.define name do
15
15
  role role_name do
16
16
  def rolem(x, y)
17
17
  x+y
@@ -26,20 +26,20 @@ class ContextTest < Test::Unit::TestCase
26
26
  assert_equal(7, MyContextRoleMethodCall.new.add(3, 4))
27
27
  end
28
28
 
29
- def xtest_simple
29
+ def test_simple
30
30
  name = :MyContextSimple
31
31
  role_name = :r
32
- Context::define name do
32
+ Context.define name do
33
33
  role role_name do
34
34
  end
35
35
  end
36
36
  assert(Kernel::const_defined? name)
37
37
  end
38
38
 
39
- def xtest_bind
39
+ def test_bind
40
40
  name = :MyContextBind
41
41
 
42
- c= Context::define name do
42
+ c= Context.define name do
43
43
  role :role_name do
44
44
  def sum
45
45
  @sum += role_name
@@ -58,10 +58,10 @@ class ContextTest < Test::Unit::TestCase
58
58
  assert_equal(3, MyContextBind.new.inter)
59
59
  end
60
60
 
61
- def xtest_role_method
61
+ def test_role_method
62
62
  name = :MyContext
63
63
  role_name = :rol
64
- Context::define name do
64
+ Context.define name do
65
65
  role role_name do
66
66
  def rolem
67
67
  0+1
@@ -71,10 +71,10 @@ class ContextTest < Test::Unit::TestCase
71
71
  assert_equal(1, MyContext.new.send(:self_rol_rolem))
72
72
  end
73
73
 
74
- def xtest_role_method_args
74
+ def test_role_method_args
75
75
  name = :MyContextArgs
76
76
  role_name = :rol
77
- Context::define name do
77
+ Context.define name do
78
78
  role role_name do
79
79
  def rolem(x, y)
80
80
  x+y
@@ -84,10 +84,10 @@ class ContextTest < Test::Unit::TestCase
84
84
  assert_equal(7, MyContextArgs.new.send(:self_rol_rolem, 3, 4))
85
85
  end
86
86
 
87
- def xtest_role_method_splat
87
+ def test_role_method_splat
88
88
  name = :MyContextSplat
89
89
  role_name = :rol
90
- Context::define name do
90
+ Context.define name do
91
91
  role role_name do
92
92
  def rolem(x, *args)
93
93
  x+(args[0])
@@ -97,10 +97,10 @@ class ContextTest < Test::Unit::TestCase
97
97
  assert_equal(7, MyContextSplat.new.send(:self_rol_rolem, 3, 4))
98
98
  end
99
99
 
100
- def xtest_role_method_block
100
+ def test_role_method_block
101
101
  name = :MyContextBlock
102
102
  role_name = :rol
103
- c= Context::define name do
103
+ c= Context.define name do
104
104
  role :num do
105
105
  def next
106
106
  num + 3
@@ -118,13 +118,13 @@ class ContextTest < Test::Unit::TestCase
118
118
  end
119
119
  end
120
120
  end
121
- assert_equal(9, MyContextBlock.new.send(:self_rol_rolem, 3, 4) { |x, res| res + x })
121
+ assert_equal(13, MyContextBlock.new.send(:self_rol_rolem, 3, 4) { |x, res| res + x })
122
122
  end
123
123
 
124
- def xtest_class_method_block
124
+ def test_class_method_block
125
125
  name = :MyContextClass
126
126
  role_name = :rol
127
- Context::define name do
127
+ Context.define name do
128
128
  role :dummy do end
129
129
  role role_name do
130
130
  def rolem(*args, &b)
@@ -1,4 +1,5 @@
1
- Context::define :CalculateShortestDistance do
1
+
2
+ context :CalculateShortestDistance do
2
3
 
3
4
  role :tentative_distance_values do
4
5
  end
@@ -12,40 +13,40 @@ Context::define :CalculateShortestDistance do
12
13
 
13
14
 
14
15
  role :map do
15
- distance_between do |a, b|
16
+ def distance_between(a, b)
16
17
  map.distances[Edge.new(a, b)]
17
18
  end
18
19
 
19
20
  # These two functions presume always travelling
20
21
  # in a southern or easterly direction
21
- next_down_the_street_from do |x|
22
+ def next_down_the_street_from(x)
22
23
  map.east_neighbor_of x
23
24
  end
24
25
 
25
- next_along_the_avenue_from do |x|
26
+ def next_along_the_avenue_from(x)
26
27
  map.south_neighbor_of x
27
28
  end
28
29
  end
29
30
 
30
31
  role :current do
31
- tentative_distance do
32
+ def tentative_distance
32
33
  tentative_distance_values[current]
33
34
  end
34
- set_tentative_distance_to do |x|
35
+ def set_tentative_distance_to(x)
35
36
  tentative_distance_values[current] = x
36
37
  end
37
38
  end
38
39
 
39
40
 
40
- rebind do |origin_node, geometries|
41
+ def rebind(origin_node, geometries)
41
42
  @current = origin_node
42
43
  @destination = geometries.destination
43
44
  @map = geometries
44
45
  end
45
46
 
46
- distance do
47
- current.set_tentative_distance_to 0
48
- @path = CalculateShortestPath.new(current, destination, map).path
47
+ def distance
48
+ current.set_tentative_distance_to(0)
49
+ @path = CalculateShortestPath.new(current, destination, map,nil,nil,nil,nil).path
49
50
  retval = 0
50
51
  previous_node = nil
51
52
  path.reverse_each { |node|
@@ -59,9 +60,6 @@ Context::define :CalculateShortestDistance do
59
60
  retval
60
61
  end
61
62
 
62
- end
63
-
64
- class CalculateShortestDistance
65
63
  def initialize(origin_node, geometries)
66
64
  rebind(origin_node, geometries)
67
65
  @tentative_distance_values = Hash.new
@@ -0,0 +1,76 @@
1
+ require 'test/unit'
2
+ require_relative '../test_helper'
3
+
4
+ Context.define :MoneyTransfer do
5
+ def initialize(source, destination, amount)
6
+ @source = source
7
+ @destination = destination
8
+ @amount = amount
9
+ @log = []
10
+ end
11
+
12
+ role :source do
13
+ def withdraw(amount)
14
+ source.movement(amount)
15
+ source.log 'withdrawal ' + amount.to_s
16
+ end
17
+ def log(message)
18
+ @log << (@source.to_s + ' source ' + message)
19
+ end
20
+ end
21
+
22
+ role :destination do
23
+ def deposit(amount)
24
+ @destination.movement(amount)
25
+ @destination.log 'deposit ' + amount.to_s
26
+ end
27
+ def logger(message)
28
+ @log << @destination.to_s + ' destination ' + message
29
+ end
30
+ end
31
+
32
+ role :amount do
33
+ end
34
+
35
+ def transfer
36
+ source.withdraw -amount
37
+ destination.deposit amount
38
+ end
39
+ end
40
+
41
+ class Account
42
+ def initialize (amount, id)
43
+ @balance = amount
44
+ @account_id = id
45
+ @log = []
46
+ end
47
+
48
+ def movement(amount)
49
+ log "Amount #{amount}"
50
+ @balance+=amount
51
+ end
52
+
53
+ def log(message)
54
+ @log << message
55
+ end
56
+
57
+ def balance
58
+ @balance
59
+ end
60
+
61
+ def to_s
62
+ "balance of #{@account_id}: #{@balance}"
63
+ end
64
+ end
65
+
66
+
67
+ class MoneyTransferTest < Test::Unit::TestCase
68
+ def test_transfer
69
+ source = Account.new 1000, "source"
70
+ destination = Account.new 0, "destination"
71
+ ctx = MoneyTransfer.new source, destination, 100
72
+ ctx.transfer
73
+ assert_equal(900,source.balance)
74
+ assert_equal(100,destination.balance)
75
+ end
76
+ end
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Consider street corners on a Manhattan grid. We want to find the
4
4
  # minimal path from the most northeast city to the most
5
- # southeast city. Use Dijkstra's algorithm
5
+ # southeast city. Use DijkstraTest's algorithm
6
6
  #
7
7
 
8
8
 
@@ -29,80 +29,91 @@
29
29
  #
30
30
  # The algorithm is straight from Wikipedia:
31
31
  #
32
- # http://en.wikipedia.org/wiki/Dijkstra's_algorithm
32
+ # http://en.wikipedia.org/wiki/DijkstraTest's_algorithm
33
33
  #
34
34
  # and reads directly from the distance method, below
35
35
 
36
36
 
37
- # "Map" as in cartography rather than Computer Science...
37
+ # Map as in cartography rather than Computer Science...
38
38
  #
39
39
  # Map is a DCI role. The role in this example is played by an
40
40
  # object representing a particular Manhattan geometry
41
- ctx, source = Context::define :CalculateShortestPath do
41
+ #Context::generate_files_in('.')
42
+ c = context :CalculateShortestPath do
43
+ # public initialize. It's overloaded so that the public version doesn't
44
+ # have to pass a lot of crap; the initialize method takes care of
45
+ # setting up internal data structures on the first invocation. On
46
+ # recursion we override the defaults
47
+
48
+ def initialize(origin_node, target_node, geometries,
49
+ path_vector, unvisited_hash, pathto_hash,
50
+ tentative_distance_values_hash)
51
+ @destination = target_node
52
+
53
+ rebind(origin_node, geometries)
54
+
55
+ execute(path_vector, unvisited_hash, pathto_hash, tentative_distance_values_hash)
56
+ end
57
+
58
+
42
59
  role :distance_labeled_graph_node do
43
60
  # Access to roles and other Context data
44
- tentative_distance_values do
61
+ def tentative_distance_values
45
62
  tentative_distance_values
46
63
  end
47
64
  # Role Methods
48
- tentative_distance do
65
+ def tentative_distance
49
66
  tentative_distance_values[@distance_labeled_graph_node]
50
67
  end
51
- set_tentative_distance_to do |x|
68
+ def set_tentative_distance_to(x)
52
69
  tentative_distance_values[@distance_labeled_graph_node] = x
53
70
  end
54
71
  end
55
72
 
56
73
  # These are handles to to the roles
57
74
  role :map do
58
- distance_between do |a, b|
59
- dist = @map.distances[Edge.new(a, b)]
60
- # p "distance between #{a.name} and #{b.name} is #{dist}"
61
- dist
75
+ def distance_between(a, b)
76
+ @map.distances[Edge.new(a, b)]
62
77
  end
63
- next_down_the_street_from do |x|
64
- n = east_neighbor_of x
65
- # p "next down the street from #{x.name} is #{n.name}"
66
- n
78
+ def next_down_the_street_from(x)
79
+ east_neighbor_of x
67
80
  end
68
- next_along_the_avenue_from do |x|
69
- n = south_neighbor_of x
70
- # p "next along the avenue from #{x.name} is #{n.name}"
71
- n
81
+ def next_along_the_avenue_from(x)
82
+ south_neighbor_of x
72
83
  end
73
- origin do
84
+ def origin
74
85
  map.root
75
86
  end
76
- nearest_unvisited_node_to_target do
87
+ def nearest_unvisited_node_to_target
77
88
  min = infinity
78
89
  selection = nil
79
90
  @unvisited.each_key {
80
91
  |intersection|
81
92
  bind :intersection => :distance_labeled_graph_node
82
- if @unvisited[intersection]
83
- tentative_distance = intersection.tentative_distance
93
+ if @unvisited[distance_labeled_graph_node]
94
+ tentative_distance = distance_labeled_graph_node.tentative_distance
84
95
  if tentative_distance < min
85
- # p "min distance is updated from #{min} to #{tentative_distance}"
96
+
86
97
  min = tentative_distance
87
- selection = intersection
98
+ selection = distance_labeled_graph_node
88
99
  end
89
100
  end
90
101
  }
91
102
  selection
92
103
  end
93
- unvisited do
104
+ def unvisited
94
105
  @unvisited
95
106
  end
96
107
  end
97
108
 
98
109
  role :current do
99
110
  # Access to roles and other Context data
100
- unvisited do
111
+ def unvisited
101
112
  map.unvisited
102
113
  end
103
114
 
104
115
  # Role Methods
105
- unvisited_neighbors do
116
+ def unvisited_neighbors
106
117
  retval = Array.new
107
118
  if @south_neighbor != nil
108
119
  if unvisited[@south_neighbor] then
@@ -114,11 +125,10 @@ ctx, source = Context::define :CalculateShortestPath do
114
125
  retval << @east_neighbor
115
126
  end
116
127
  end
117
- # p "unvisited neighbors #{retval}"
128
+
118
129
  retval
119
130
  end
120
- tentative_distance do
121
- raise "key (#{current}) not found in #{@tentative_distance_values}" unless @tentative_distance_values && (@tentative_distance_values.has_key? current)
131
+ def tentative_distance
122
132
  @tentative_distance_values[current]
123
133
  end
124
134
  end
@@ -130,34 +140,32 @@ ctx, source = Context::define :CalculateShortestPath do
130
140
  # east_neighbor and south_neighbor roles
131
141
 
132
142
  role :neighbor_node do
133
- relable_node_as do |x|
134
- raise "Argument can't be nil" unless x
135
- raise "self can't be nil" unless @neighbor_node
143
+ def relable_node_as(x)
144
+ raise 'Argument cannot be nil' unless x
145
+ raise 'self cannot be nil' unless @neighbor_node
136
146
 
137
147
  if x < neighbor_node.tentative_distance
138
- # p "updated tentative distance from #{neighbor_node.tentative_distance} to #{x}"
139
148
  neighbor_node.set_tentative_distance_to x
140
149
  :distance_was_udated
141
150
  else
142
- # p "left tentative distance at #{neighbor_node.tentative_distance} instead of #{x}"
143
151
  :distance_was_not_udated
144
152
  end
145
153
  end
146
154
 
147
155
  # Role Methods
148
- tentative_distance do
149
- raise "self can't be nil" unless @neighbor_node
156
+ def tentative_distance
157
+ raise 'self cannot be nil' unless @neighbor_node
150
158
  tentative_distance_values[@neighbor_node]
151
159
  end
152
- set_tentative_distance_to do |x|
153
- raise "Argument can't be nil" unless x
154
- raise "self can't be nil" unless @neighbor_node
160
+ def set_tentative_distance_to(x)
161
+ raise 'Argument cannot be nil' unless x
162
+ raise 'self cannot be nil' unless @neighbor_node
155
163
  tentative_distance_values[@neighbor_node] = x
156
164
  end
157
165
  end
158
166
  # This is the method that starts the work. Called from initialize.
159
167
 
160
- execute do |path_vector, unvisited_hash, pathto_hash, tentative_distance_values_hash|
168
+ def execute (path_vector, unvisited_hash, pathto_hash, tentative_distance_values_hash)
161
169
  do_inits(path_vector, unvisited_hash, pathto_hash,
162
170
  tentative_distance_values_hash)
163
171
 
@@ -165,21 +173,19 @@ ctx, source = Context::define :CalculateShortestPath do
165
173
  # Calculate tentative distances of unvisited neighbors
166
174
 
167
175
  unvisited_neighbors = current.unvisited_neighbors
168
- # p "#{unvisited_neighbors}"
176
+
169
177
  if unvisited_neighbors != nil
170
178
  unvisited_neighbors.each {
171
179
  |neighbor|
172
180
  bind :neighbor => :neighbor_node
173
181
  tentative_distance = current.tentative_distance
174
- raise "tentative distance can't be nil" if tentative_distance == nil
182
+ raise 'tentative distance cannot be nil' if tentative_distance == nil
175
183
  distance_between = map.distance_between(current, neighbor)
176
- raise "distance between can't be nil" if distance_between == nil
184
+ raise 'distance between cannot be nil' if distance_between == nil
177
185
  net_distance = tentative_distance + distance_between
178
186
 
179
- if neighbor.relable_node_as(net_distance) == :distance_was_udated
180
- # p "set path"
187
+ if neighbor_node.relable_node_as(net_distance) == :distance_was_udated
181
188
  pathTo[neighbor] = @current
182
- # p "path #{@pathTo}"
183
189
  end
184
190
  }
185
191
  end
@@ -200,7 +206,7 @@ ctx, source = Context::define :CalculateShortestPath do
200
206
  end
201
207
  end
202
208
 
203
- do_inits do |path_vector, unvisited_hash, pathto_hash, tentative_distance_values_hash|
209
+ def do_inits(path_vector, unvisited_hash, pathto_hash, tentative_distance_values_hash)
204
210
 
205
211
  # The conditional switches between the first and subsequent instances of the
206
212
  # recursion (the algorithm is recursive in graph contexts)
@@ -213,8 +219,8 @@ ctx, source = Context::define :CalculateShortestPath do
213
219
  # Since path_vector isn't set up, this is the first iteration of the recursion
214
220
  @tentative_distance_values = Hash.new
215
221
 
216
- # This is the fundamental data structure for Dijkstra's algorithm, called
217
- # "Q" in the Wikipedia description. It is a boolean hash that maps a
222
+ # This is the fundamental data structure for DijkstraTest's algorithm, called
223
+ # Q in the Wikipedia description. It is a boolean hash that maps a
218
224
  # node onto false or true according to whether it has been visited
219
225
 
220
226
  @unvisited = Hash.new
@@ -222,13 +228,13 @@ ctx, source = Context::define :CalculateShortestPath do
222
228
  # These initializations are directly from the description of the algorithm
223
229
  map.nodes.each { |node| @unvisited[node] = true }
224
230
  @unvisited.delete(map.origin)
225
- map.nodes.each { |node| bind :node => :distance_labeled_graph_node; node.set_tentative_distance_to(infinity) }
231
+ map.nodes.each { |node| bind :node => :distance_labeled_graph_node; distance_labeled_graph_node.set_tentative_distance_to(infinity) }
226
232
  tentative_distance_values[map.origin] = 0
227
233
 
228
234
  # The path array is kept in the outermost context and serves to store the
229
235
  # return path. Each recurring context may add something to the array along
230
236
  # the way. However, because of the nature of the algorithm, individual
231
- # Context instances don't deliver "partial paths" as partial answers.
237
+ # Context instances don't deliver partial paths as partial answers.
232
238
  @path = Array.new
233
239
 
234
240
  # The pathTo map is a local associative array that remembers the
@@ -253,8 +259,8 @@ ctx, source = Context::define :CalculateShortestPath do
253
259
 
254
260
  @tentative_distance_values = Hash.new
255
261
 
256
- # This is the fundamental data structure for Dijkstra's algorithm, called
257
- # "Q" in the Wikipedia description. It is a boolean hash that maps a
262
+ # This is the fundamental data structure for DijkstraTest's algorithm, called
263
+ # Q in the Wikipedia description. It is a boolean hash that maps a
258
264
  # node onto false or true according to whether it has been visited
259
265
 
260
266
  @unvisited = Hash.new
@@ -262,11 +268,10 @@ ctx, source = Context::define :CalculateShortestPath do
262
268
  # These initializations are directly from the description of the algorithm
263
269
  map.nodes.each { |node| @unvisited[node] = true }
264
270
  @unvisited.delete(map.origin)
265
- # p "map #{map.nodes}"
271
+
266
272
  map.nodes.each { |node|
267
- bind :node => :distance_labeled_graph_node;
268
- node.set_tentative_distance_to(infinity)
269
- # p "initialized node #{node.name}"
273
+ bind :node => :distance_labeled_graph_node
274
+ distance_labeled_graph_node.set_tentative_distance_to(infinity)
270
275
  }
271
276
  tentative_distance_values[map.origin] = 0
272
277
 
@@ -274,7 +279,7 @@ ctx, source = Context::define :CalculateShortestPath do
274
279
  # The path array is kept in the outermost context and serves to store the
275
280
  # return path. Each recurring context may add something to the array along
276
281
  # the way. However, because of the nature of the algorithm, individual
277
- # Context instances don't deliver "partial paths" as partial answers.
282
+ # Context instances don't deliver partial paths as partial answers.
278
283
 
279
284
  @path = Array.new
280
285
 
@@ -295,9 +300,18 @@ ctx, source = Context::define :CalculateShortestPath do
295
300
  @pathTo = pathto_hash
296
301
  end
297
302
  end
298
- end
299
303
 
300
- class CalculateShortestPath
304
+
305
+ def each
306
+ path.each { |node| yield node }
307
+ end
308
+
309
+
310
+ def path
311
+ @path
312
+ end
313
+
314
+ private
301
315
 
302
316
  def pathTo
303
317
  @pathTo
@@ -311,10 +325,6 @@ class CalculateShortestPath
311
325
  @south_neighbor
312
326
  end
313
327
 
314
- def path;
315
- @path
316
- end
317
-
318
328
  def destination;
319
329
  @destination
320
330
  end
@@ -337,27 +347,6 @@ class CalculateShortestPath
337
347
  @south_neighbor = map.south_neighbor_of(origin_node)
338
348
  end
339
349
 
340
-
341
- # public initialize. It's overloaded so that the public version doesn't
342
- # have to pass a lot of crap; the initialize method takes care of
343
- # setting up internal data structures on the first invocation. On
344
- # recursion we override the defaults
345
-
346
- def initialize(origin_node, target_node, geometries,
347
- path_vector = nil, unvisited_hash = nil, pathto_hash = nil,
348
- tentative_distance_values_hash = nil)
349
- @destination = target_node
350
-
351
- rebind(origin_node, geometries)
352
-
353
- execute(path_vector, unvisited_hash, pathto_hash, tentative_distance_values_hash)
354
- end
355
-
356
- def each
357
- path.each { |node| yield node }
358
- end
359
-
360
-
361
350
  # This method does a simple traversal of the data structures (following pathTo)
362
351
  # to build the directed traversal vector for the minimum path
363
352
 
@@ -370,5 +359,4 @@ class CalculateShortestPath
370
359
  end
371
360
  end
372
361
 
373
- File.open('CalculateShortestPath_generated.rb', 'w') { |f| f.write(source) }
374
-
362
+ p c