maroon 0.6.1 → 0.6.5

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 (52) hide show
  1. checksums.yaml +7 -0
  2. data/Examples/Dijkstra/CalculateShortestDistance.rb +16 -12
  3. data/Examples/Dijkstra/calculate_shortest_path.rb +47 -27
  4. data/Examples/Dijkstra/data.rb +41 -14
  5. data/Examples/Dijkstra/dijkstra.rb +4 -3
  6. data/Examples/MoneyTransfer.rb +61 -60
  7. data/Examples/greeter.rb +8 -7
  8. data/Examples/meter.rb +35 -29
  9. data/Gemfile +9 -4
  10. data/LICENSE.txt +21 -21
  11. data/README.md +13 -0
  12. data/Rakefile +41 -1
  13. data/Test/Generate/method_info_test.rb +12 -0
  14. data/Test/{Greeter_test.rb → Greeter_test_disabled.rb} +24 -20
  15. data/Test/ImmutableQueue_test.rb +18 -0
  16. data/Test/MethodInfo_test.rb +65 -0
  17. data/Test/alltests.rb +1 -0
  18. data/Test/{source_assertions.rb → assertions.rb} +15 -7
  19. data/Test/bind_test.rb +13 -0
  20. data/Test/expression_test.rb +105 -0
  21. data/Test/method_call_test.rb +83 -0
  22. data/Test/self_test.rb +46 -0
  23. data/Test/stack_test.rb +17 -0
  24. data/Test/test_helper.rb +14 -0
  25. data/base/ImmutableStack.rb +32 -0
  26. data/base/MethodDefinition.rb +124 -0
  27. data/base/bind_rewriter.rb +58 -0
  28. data/base/immutable_queue.rb +50 -0
  29. data/base/maroon_base.rb +267 -0
  30. data/base/method_call.rb +78 -0
  31. data/base/method_info.rb +86 -0
  32. data/base/self.rb +60 -0
  33. data/generated/build.rb +13 -0
  34. data/generated/interpretation_context.rb +29 -0
  35. data/lib/Bind.rb +65 -0
  36. data/lib/Context.rb +187 -0
  37. data/lib/ImmutableQueue.rb +50 -0
  38. data/lib/ImmutableStack.rb +38 -0
  39. data/lib/MethodCall.rb +91 -0
  40. data/lib/MethodDefinition.rb +114 -0
  41. data/lib/MethodInfo.rb +78 -0
  42. data/lib/Self.rb +71 -0
  43. data/lib/build.rb +14 -0
  44. data/lib/interpretation_context.rb +30 -0
  45. data/lib/maroon/contracts.rb +43 -0
  46. data/lib/maroon/kernel.rb +2 -0
  47. data/lib/maroon/version.rb +3 -3
  48. data/maroon.gemspec +26 -26
  49. metadata +49 -31
  50. data/lib/Source_cleaner.rb +0 -34
  51. data/lib/maroon.rb +0 -165
  52. data/lib/rewriter.rb +0 -185
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a2b4446ac84c36b68f710a04280f9488d116035c
4
+ data.tar.gz: 01322628719027b5cfc4b500f81063a23c326e5a
5
+ SHA512:
6
+ metadata.gz: 8a6644383356d9c8939dd1fa94c89d0e89baa05d867a1c7f2229c335972c04c164d4e6deacbe0632a679453c60858eb3447914817c8d9bc1e6fd7b1a741dd2ae
7
+ data.tar.gz: ae022ce8665b2c78f963112be9a0635306dc6c47d64110dbde15508bdd690ba975ab3f14d2f1711c94e694d99fba2a19fa9af33a987fa484097992a94a57828d
@@ -1,10 +1,14 @@
1
1
  Context::define :CalculateShortestDistance do
2
2
 
3
- role :tentative_distance_values do end
4
- role :path do end
3
+ role :tentative_distance_values do
4
+ end
5
+ role :path do
6
+ end
5
7
 
6
- role :current do end
7
- role :destination do end
8
+ role :current do
9
+ end
10
+ role :destination do
11
+ end
8
12
 
9
13
 
10
14
  role :map do
@@ -44,14 +48,14 @@ Context::define :CalculateShortestDistance do
44
48
  @path = CalculateShortestPath.new(current, destination, map).path
45
49
  retval = 0
46
50
  previous_node = nil
47
- path.reverse_each {|node|
48
- if previous_node.nil?
49
- retval = 0
50
- else
51
- retval += map.distance_between previous_node, node
52
- end
53
- previous_node = node
54
- }
51
+ path.reverse_each { |node|
52
+ if previous_node.nil?
53
+ retval = 0
54
+ else
55
+ retval += map.distance_between previous_node, node
56
+ end
57
+ previous_node = node
58
+ }
55
59
  retval
56
60
  end
57
61
 
@@ -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 Dijstra's algorithm
5
+ # southeast city. Use Dijkstra's algorithm
6
6
  #
7
7
 
8
8
 
@@ -15,7 +15,6 @@
15
15
  #
16
16
 
17
17
 
18
-
19
18
  # There are eight roles in the algorithm:
20
19
  #
21
20
  # pathTo, which is the interface to whatever accumulates the path
@@ -39,7 +38,7 @@
39
38
  #
40
39
  # Map is a DCI role. The role in this example is played by an
41
40
  # object representing a particular Manhattan geometry
42
- ctx,source = Context::define :CalculateShortestPath do
41
+ ctx, source = Context::define :CalculateShortestPath do
43
42
  role :distance_labeled_graph_node do
44
43
  # Access to roles and other Context data
45
44
  tentative_distance_values do
@@ -58,17 +57,17 @@
58
57
  role :map do
59
58
  distance_between do |a, b|
60
59
  dist = @map.distances[Edge.new(a, b)]
61
- # p "distance between #{a.name} and #{b.name} is #{dist}"
60
+ # p "distance between #{a.name} and #{b.name} is #{dist}"
62
61
  dist
63
62
  end
64
63
  next_down_the_street_from do |x|
65
64
  n = east_neighbor_of x
66
- # p "next down the street from #{x.name} is #{n.name}"
65
+ # p "next down the street from #{x.name} is #{n.name}"
67
66
  n
68
67
  end
69
68
  next_along_the_avenue_from do |x|
70
69
  n = south_neighbor_of x
71
- # p "next along the avenue from #{x.name} is #{n.name}"
70
+ # p "next along the avenue from #{x.name} is #{n.name}"
72
71
  n
73
72
  end
74
73
  origin do
@@ -79,11 +78,11 @@
79
78
  selection = nil
80
79
  @unvisited.each_key {
81
80
  |intersection|
82
- bind :intersection=>:distance_labeled_graph_node
81
+ bind :intersection => :distance_labeled_graph_node
83
82
  if @unvisited[intersection]
84
83
  tentative_distance = intersection.tentative_distance
85
84
  if tentative_distance < min
86
- # p "min distance is updated from #{min} to #{tentative_distance}"
85
+ # p "min distance is updated from #{min} to #{tentative_distance}"
87
86
  min = tentative_distance
88
87
  selection = intersection
89
88
  end
@@ -106,12 +105,16 @@
106
105
  unvisited_neighbors do
107
106
  retval = Array.new
108
107
  if @south_neighbor != nil
109
- if unvisited[@south_neighbor] then retval << @south_neighbor end
108
+ if unvisited[@south_neighbor] then
109
+ retval << @south_neighbor
110
+ end
110
111
  end
111
112
  if @east_neighbor != nil
112
- if unvisited[@east_neighbor] then retval << @east_neighbor end
113
+ if unvisited[@east_neighbor] then
114
+ retval << @east_neighbor
115
+ end
113
116
  end
114
- # p "unvisited neighbors #{retval}"
117
+ # p "unvisited neighbors #{retval}"
115
118
  retval
116
119
  end
117
120
  tentative_distance do
@@ -119,7 +122,8 @@
119
122
  @tentative_distance_values[current]
120
123
  end
121
124
  end
122
- role :unvisited do end
125
+ role :unvisited do
126
+ end
123
127
 
124
128
 
125
129
  # This module serves to provide the methods both for the
@@ -131,11 +135,11 @@
131
135
  raise "self can't be nil" unless @neighbor_node
132
136
 
133
137
  if x < neighbor_node.tentative_distance
134
- # p "updated tentative distance from #{neighbor_node.tentative_distance} to #{x}"
138
+ # p "updated tentative distance from #{neighbor_node.tentative_distance} to #{x}"
135
139
  neighbor_node.set_tentative_distance_to x
136
140
  :distance_was_udated
137
141
  else
138
- # p "left tentative distance at #{neighbor_node.tentative_distance} instead of #{x}"
142
+ # p "left tentative distance at #{neighbor_node.tentative_distance} instead of #{x}"
139
143
  :distance_was_not_udated
140
144
  end
141
145
  end
@@ -151,7 +155,7 @@
151
155
  tentative_distance_values[@neighbor_node] = x
152
156
  end
153
157
  end
154
- # This is the method that starts the work. Called from initialize.
158
+ # This is the method that starts the work. Called from initialize.
155
159
 
156
160
  execute do |path_vector, unvisited_hash, pathto_hash, tentative_distance_values_hash|
157
161
  do_inits(path_vector, unvisited_hash, pathto_hash,
@@ -161,7 +165,7 @@
161
165
  # Calculate tentative distances of unvisited neighbors
162
166
 
163
167
  unvisited_neighbors = current.unvisited_neighbors
164
- # p "#{unvisited_neighbors}"
168
+ # p "#{unvisited_neighbors}"
165
169
  if unvisited_neighbors != nil
166
170
  unvisited_neighbors.each {
167
171
  |neighbor|
@@ -173,9 +177,9 @@
173
177
  net_distance = tentative_distance + distance_between
174
178
 
175
179
  if neighbor.relable_node_as(net_distance) == :distance_was_udated
176
- # p "set path"
180
+ # p "set path"
177
181
  pathTo[neighbor] = @current
178
- # p "path #{@pathTo}"
182
+ # p "path #{@pathTo}"
179
183
  end
180
184
  }
181
185
  end
@@ -218,7 +222,7 @@
218
222
  # These initializations are directly from the description of the algorithm
219
223
  map.nodes.each { |node| @unvisited[node] = true }
220
224
  @unvisited.delete(map.origin)
221
- map.nodes.each { |node| bind :node=>:distance_labeled_graph_node; node.set_tentative_distance_to(infinity) }
225
+ map.nodes.each { |node| bind :node => :distance_labeled_graph_node; node.set_tentative_distance_to(infinity) }
222
226
  tentative_distance_values[map.origin] = 0
223
227
 
224
228
  # The path array is kept in the outermost context and serves to store the
@@ -244,6 +248,7 @@
244
248
  @pathTo = pathto_hash
245
249
  end
246
250
  end
251
+
247
252
  # Since path_vector isn't set up, this is the first iteration of the recursion
248
253
 
249
254
  @tentative_distance_values = Hash.new
@@ -257,11 +262,11 @@
257
262
  # These initializations are directly from the description of the algorithm
258
263
  map.nodes.each { |node| @unvisited[node] = true }
259
264
  @unvisited.delete(map.origin)
260
- # p "map #{map.nodes}"
265
+ # p "map #{map.nodes}"
261
266
  map.nodes.each { |node|
262
267
  bind :node => :distance_labeled_graph_node;
263
268
  node.set_tentative_distance_to(infinity)
264
- # p "initialized node #{node.name}"
269
+ # p "initialized node #{node.name}"
265
270
  }
266
271
  tentative_distance_values[map.origin] = 0
267
272
 
@@ -297,12 +302,26 @@ class CalculateShortestPath
297
302
  def pathTo
298
303
  @pathTo
299
304
  end
300
- def east_neighbor; @east_neighbor end
301
- def south_neighbor; @south_neighbor end
302
- def path; @path end
303
305
 
304
- def destination; @destination end
305
- def tentative_distance_values; @tentative_distance_values end
306
+ def east_neighbor;
307
+ @east_neighbor
308
+ end
309
+
310
+ def south_neighbor;
311
+ @south_neighbor
312
+ end
313
+
314
+ def path;
315
+ @path
316
+ end
317
+
318
+ def destination;
319
+ @destination
320
+ end
321
+
322
+ def tentative_distance_values;
323
+ @tentative_distance_values
324
+ end
306
325
 
307
326
  # This is a shortcut to information that really belongs in the Map.
308
327
  # To keep roles stateless, we hold the Map's unvisited structure in the
@@ -333,6 +352,7 @@ class CalculateShortestPath
333
352
 
334
353
  execute(path_vector, unvisited_hash, pathto_hash, tentative_distance_values_hash)
335
354
  end
355
+
336
356
  def each
337
357
  path.each { |node| yield node }
338
358
  end
@@ -350,5 +370,5 @@ class CalculateShortestPath
350
370
  end
351
371
  end
352
372
 
353
- File.open('CalculateShortestPath_generated.rb', 'w') {|f| f.write(source) }
373
+ File.open('CalculateShortestPath_generated.rb', 'w') { |f| f.write(source) }
354
374
 
@@ -1,10 +1,17 @@
1
- def infinity; (2**(0.size * 8 -2) -1) end
1
+ def infinity;
2
+ (2**(0.size * 8 -2) -1)
3
+ end
4
+
2
5
  # Data classes
3
6
  Edge = Struct.new(:from, :to)
4
7
 
5
8
  class Node
6
9
  attr_reader :name
7
- def initialize(n); @name = n end
10
+
11
+ def initialize(n)
12
+ ; @name = n
13
+ end
14
+
8
15
  def eql? (another_node)
9
16
  # Nodes are == equal if they have the same name. This is explicitly
10
17
  # defined here to call out the importance of the differnce between
@@ -14,7 +21,6 @@ class Node
14
21
  end
15
22
 
16
23
 
17
-
18
24
  #
19
25
  # --- Geometry is the interface to the data class that has all
20
26
  # --- the information about the map. This is kind of silly in Ruby
@@ -25,14 +31,16 @@ class ManhattanGeometry
25
31
  @distances = Hash.new
26
32
  end
27
33
 
28
- def nodes; @nodes end
34
+ def nodes;
35
+ @nodes
36
+ end
37
+
29
38
  def distances
30
39
  @distances
31
40
  end
32
41
  end
33
42
 
34
43
 
35
-
36
44
  #
37
45
  # --- Here are some test data
38
46
  #
@@ -49,7 +57,6 @@ class Geometry_1 < ManhattanGeometry
49
57
  nodes << Node.new(names[(i*3)+j])
50
58
  }
51
59
  }
52
-
53
60
 
54
61
 
55
62
  # Aliases to help set up the grid. Grid is of Manhattan form:
@@ -114,11 +121,21 @@ class Geometry_1 < ManhattanGeometry
114
121
  @next_along_the_avenue_from.freeze
115
122
  end
116
123
 
117
- def east_neighbor_of(a); @next_down_the_street_from[a] end
118
- def south_neighbor_of(a); @next_along_the_avenue_from[a] end
124
+ def east_neighbor_of(a)
125
+ ; @next_down_the_street_from[a]
126
+ end
119
127
 
120
- def root; @node_a end
121
- def destination; @node_i end
128
+ def south_neighbor_of(a)
129
+ ; @next_along_the_avenue_from[a]
130
+ end
131
+
132
+ def root;
133
+ @node_a
134
+ end
135
+
136
+ def destination;
137
+ @node_i
138
+ end
122
139
  end
123
140
 
124
141
 
@@ -201,10 +218,20 @@ class ManhattanGeometry2 < ManhattanGeometry
201
218
  @next_along_the_avenue_from.freeze
202
219
  end
203
220
 
204
- def east_neighbor_of(a); @next_down_the_street_from[a] end
205
- def south_neighbor_of(a); @next_along_the_avenue_from[a] end
221
+ def east_neighbor_of(a)
222
+ ; @next_down_the_street_from[a]
223
+ end
224
+
225
+ def south_neighbor_of(a)
226
+ ; @next_along_the_avenue_from[a]
227
+ end
206
228
 
207
- def root; @node_a end
208
- def destination; @node_k end
229
+ def root;
230
+ @node_a
231
+ end
232
+
233
+ def destination;
234
+ @node_k
235
+ end
209
236
  end
210
237
 
@@ -57,7 +57,6 @@ require './Examples/Dijkstra/Calculate_Shortest_Path.rb'
57
57
  # design
58
58
 
59
59
 
60
-
61
60
  # --- Main Program: test driver
62
61
  #
63
62
  geometries = Geometry_1.new
@@ -74,11 +73,13 @@ path = CalculateShortestPath.new(geometries.root, geometries.destination, geomet
74
73
  print 'Path is: '
75
74
  last_node = nil
76
75
  path.each do |node|
77
- if last_node != nil; print " - #{geometries.distances[Edge.new(node, last_node)]} - " end
76
+ if last_node != nil;
77
+ print " - #{geometries.distances[Edge.new(node, last_node)]} - "
78
+ end
78
79
  print "#{node.name}"
79
80
  last_node = node
80
81
  end
81
82
  print "\n"
82
83
 
83
84
  geometries = ManhattanGeometry2.new
84
- puts "distance is #{CalculateShortestDistance.new(geometries.root, geometries).distance }"
85
+ puts "distance is #{CalculateShortestDistance.new(geometries.root, geometries).distance }"
@@ -1,61 +1,62 @@
1
- require './lib/maroon.rb'
2
-
3
- Context::define :MoneyTransfer do
4
- role :source do
5
- withdraw do |amount|
6
- source.movement(amount)
7
- source.log "withdrawal #{amount}"
8
- end
9
- log do |message|
10
- p "#{@source} source #{message}"
11
- end
12
- end
13
-
14
- role :destination do
15
- deposit do |amount|
16
- @destination.movement(amount)
17
- @destination.log "deposit #{amount}"
18
- end
19
- logger do |message|
20
- p "#{@source} destination #{message}"
21
- end
22
- end
23
-
24
- role :amount do end
25
-
26
- transfer do
27
- source.withdraw -amount
28
- destination.deposit amount
29
- end
30
- end
31
-
32
- class MoneyTransfer
33
- def initialize(source, destination, amount)
34
- @source = source
35
- @destination = destination
36
- @amount = amount
37
- end
38
- end
39
- class Account
40
- def initialize (amount, id)
41
- @balance = amount
42
- @account_id = id
43
- end
44
-
45
- def movement(amount)
46
- log "Amount #{amount}"
47
- @balance+=amount
48
- end
49
-
50
- def log(message)
51
- (p s = "instance #{message}")
52
- end
53
-
54
- def to_s
55
- "balance of #{@account_id}: #{@balance}"
56
- end
57
- end
58
-
59
- account = Account.new 1000, "source"
60
- ctx = MoneyTransfer.new account, account, 100
1
+ require './lib/maroon.rb'
2
+
3
+ Context::define :MoneyTransfer do
4
+ role :source do
5
+ withdraw do |amount|
6
+ source.movement(amount)
7
+ source.log "withdrawal #{amount}"
8
+ end
9
+ log do |message|
10
+ p "#{@source} source #{message}"
11
+ end
12
+ end
13
+
14
+ role :destination do
15
+ deposit do |amount|
16
+ @destination.movement(amount)
17
+ @destination.log "deposit #{amount}"
18
+ end
19
+ logger do |message|
20
+ p "#{@source} destination #{message}"
21
+ end
22
+ end
23
+
24
+ role :amount do
25
+ end
26
+
27
+ transfer do
28
+ source.withdraw -amount
29
+ destination.deposit amount
30
+ end
31
+ end
32
+
33
+ class MoneyTransfer
34
+ def initialize(source, destination, amount)
35
+ @source = source
36
+ @destination = destination
37
+ @amount = amount
38
+ end
39
+ end
40
+ class Account
41
+ def initialize (amount, id)
42
+ @balance = amount
43
+ @account_id = id
44
+ end
45
+
46
+ def movement(amount)
47
+ log "Amount #{amount}"
48
+ @balance+=amount
49
+ end
50
+
51
+ def log(message)
52
+ (p s = "instance #{message}")
53
+ end
54
+
55
+ def to_s
56
+ "balance of #{@account_id}: #{@balance}"
57
+ end
58
+ end
59
+
60
+ account = Account.new 1000, "source"
61
+ ctx = MoneyTransfer.new account, account, 100
61
62
  ctx.transfer