maroon 0.7.1 → 0.8.0

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.
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