redshift 1.3.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/.gitignore +8 -0
  2. data/README +5 -0
  3. data/RELEASE-NOTES +455 -0
  4. data/TODO +431 -0
  5. data/bench/alg-state.rb +61 -0
  6. data/bench/bench +26 -0
  7. data/bench/bench.rb +10 -0
  8. data/bench/continuous.rb +76 -0
  9. data/bench/diff-bench +86 -0
  10. data/bench/discrete.rb +101 -0
  11. data/bench/euler.rb +50 -0
  12. data/bench/formula.rb +78 -0
  13. data/bench/half-strict.rb +103 -0
  14. data/bench/inertness.rb +116 -0
  15. data/bench/queue.rb +92 -0
  16. data/bench/run +66 -0
  17. data/bench/simple.rb +74 -0
  18. data/bench/strictness.rb +86 -0
  19. data/examples/ball-tkar.rb +72 -0
  20. data/examples/ball.rb +123 -0
  21. data/examples/collide.rb +70 -0
  22. data/examples/connect-parallel.rb +48 -0
  23. data/examples/connect.rb +109 -0
  24. data/examples/constants.rb +27 -0
  25. data/examples/delay.rb +80 -0
  26. data/examples/derivative.rb +77 -0
  27. data/examples/euler.rb +46 -0
  28. data/examples/external-lib.rb +33 -0
  29. data/examples/guard-debugger.rb +77 -0
  30. data/examples/lotka-volterra.rb +33 -0
  31. data/examples/persist-ball.rb +68 -0
  32. data/examples/pid.rb +87 -0
  33. data/examples/ports.rb +60 -0
  34. data/examples/queue.rb +56 -0
  35. data/examples/queue2.rb +98 -0
  36. data/examples/reset-with-event-val.rb +28 -0
  37. data/examples/scheduler.rb +104 -0
  38. data/examples/set-dest.rb +23 -0
  39. data/examples/simulink/README +1 -0
  40. data/examples/simulink/delay.mdl +827 -0
  41. data/examples/simulink/derivative.mdl +655 -0
  42. data/examples/step-discrete-profiler.rb +103 -0
  43. data/examples/subsystem.rb +109 -0
  44. data/examples/sync-deadlock.rb +32 -0
  45. data/examples/sync-queue.rb +91 -0
  46. data/examples/sync-retry.rb +20 -0
  47. data/examples/sync.rb +51 -0
  48. data/examples/thermostat.rb +53 -0
  49. data/examples/zeno.rb +53 -0
  50. data/lib/accessible-index.rb +47 -0
  51. data/lib/redshift.rb +1 -0
  52. data/lib/redshift/component.rb +412 -0
  53. data/lib/redshift/meta.rb +183 -0
  54. data/lib/redshift/mixins/zeno-debugger.rb +69 -0
  55. data/lib/redshift/port.rb +57 -0
  56. data/lib/redshift/queue.rb +104 -0
  57. data/lib/redshift/redshift.rb +111 -0
  58. data/lib/redshift/state.rb +31 -0
  59. data/lib/redshift/syntax.rb +558 -0
  60. data/lib/redshift/target/c.rb +37 -0
  61. data/lib/redshift/target/c/component-gen.rb +1303 -0
  62. data/lib/redshift/target/c/flow-gen.rb +325 -0
  63. data/lib/redshift/target/c/flow/algebraic.rb +85 -0
  64. data/lib/redshift/target/c/flow/buffer.rb +74 -0
  65. data/lib/redshift/target/c/flow/delay.rb +203 -0
  66. data/lib/redshift/target/c/flow/derivative.rb +101 -0
  67. data/lib/redshift/target/c/flow/euler.rb +67 -0
  68. data/lib/redshift/target/c/flow/expr.rb +113 -0
  69. data/lib/redshift/target/c/flow/rk4.rb +80 -0
  70. data/lib/redshift/target/c/library.rb +85 -0
  71. data/lib/redshift/target/c/world-gen.rb +1370 -0
  72. data/lib/redshift/target/spec.rb +34 -0
  73. data/lib/redshift/world.rb +300 -0
  74. data/rakefile +37 -0
  75. data/test/test.rb +52 -0
  76. data/test/test_buffer.rb +58 -0
  77. data/test/test_connect.rb +242 -0
  78. data/test/test_connect_parallel.rb +47 -0
  79. data/test/test_connect_strict.rb +135 -0
  80. data/test/test_constant.rb +74 -0
  81. data/test/test_delay.rb +145 -0
  82. data/test/test_derivative.rb +48 -0
  83. data/test/test_discrete.rb +592 -0
  84. data/test/test_discrete_isolated.rb +92 -0
  85. data/test/test_exit.rb +59 -0
  86. data/test/test_flow.rb +200 -0
  87. data/test/test_flow_link.rb +288 -0
  88. data/test/test_flow_sub.rb +100 -0
  89. data/test/test_flow_trans.rb +292 -0
  90. data/test/test_inherit.rb +127 -0
  91. data/test/test_inherit_event.rb +74 -0
  92. data/test/test_inherit_flow.rb +139 -0
  93. data/test/test_inherit_link.rb +65 -0
  94. data/test/test_inherit_setup.rb +56 -0
  95. data/test/test_inherit_state.rb +66 -0
  96. data/test/test_inherit_transition.rb +168 -0
  97. data/test/test_numerics.rb +34 -0
  98. data/test/test_queue.rb +90 -0
  99. data/test/test_queue_alone.rb +115 -0
  100. data/test/test_reset.rb +209 -0
  101. data/test/test_setup.rb +119 -0
  102. data/test/test_strict_continuity.rb +410 -0
  103. data/test/test_strict_reset_error.rb +30 -0
  104. data/test/test_strictness_error.rb +32 -0
  105. data/test/test_sync.rb +185 -0
  106. data/test/test_world.rb +328 -0
  107. metadata +204 -0
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'mathn' # Use rationals for 1/2 etc.
4
+
5
+ require 'test/unit'
6
+
7
+ require 'redshift'
8
+
9
+ include RedShift
10
+
11
+ class Timer < Component
12
+ attr_accessor :x
13
+ flow { diff " x' = 1 " }
14
+ end
15
+
16
+ class TestNumerics < Test::Unit::TestCase
17
+
18
+ def setup
19
+ @world = World.new
20
+ @world.time_step = 0.1
21
+ end
22
+
23
+ def teardown
24
+ @world = nil
25
+ end
26
+
27
+ def test_rational
28
+ c = @world.create(Timer) { |timer| timer.x = 1/2}
29
+ @world.run 100
30
+ assert_in_delta(10.5, c.x, 0.000001)
31
+ end
32
+ end
33
+
34
+ ## should test NaN, Inf, precision, etc.
@@ -0,0 +1,90 @@
1
+ require 'redshift'
2
+ require 'test/unit'
3
+
4
+ class TestQueue < Test::Unit::TestCase
5
+ class Receiver < RedShift::Component
6
+ queue :q
7
+ transition Enter => Exit do
8
+ wait :q
9
+ end
10
+ end
11
+
12
+ class Sender < RedShift::Component
13
+ link :receiver => RedShift::Component
14
+ flow {diff "t'=1"}
15
+ transition Enter => Exit do
16
+ guard "t>1"
17
+ action do
18
+ receiver.q << "hello"
19
+ end
20
+ end
21
+ end
22
+
23
+ def setup
24
+ @world = RedShift::World.new
25
+ @s = @world.create(Sender)
26
+ @r = @world.create(Receiver)
27
+ @s.receiver = @r
28
+ end
29
+
30
+ def test_msg_received
31
+ @world.evolve 0.9
32
+ assert_equal(RedShift::Component::Enter, @r.state)
33
+ assert(@world.queue_sleep[@r])
34
+ @world.evolve 0.2
35
+ assert_equal(RedShift::Component::Exit, @r.state)
36
+ assert_equal("hello", @r.q.pop)
37
+ end
38
+ end
39
+
40
+ class TestQueueAndStrict < Test::Unit::TestCase
41
+ class Receiver < RedShift::Component
42
+ queue :q
43
+ strictly_continuous :x
44
+ transition Enter => Exit do
45
+ guard "x>0"
46
+ end
47
+ transition Enter => Exit do
48
+ wait :q
49
+ end
50
+ end
51
+
52
+ class Sender < RedShift::Component
53
+ link :receiver => RedShift::Component
54
+ flow {diff "t'=1"}
55
+ state :S1
56
+ transition Enter => S1 do
57
+ guard "t>1"
58
+ # this transition gives receiver a chance to go into strict sleep,
59
+ # if that bug exists in redshift
60
+ end
61
+ transition S1 => Exit do
62
+ action do
63
+ receiver.q << "hello"
64
+ end
65
+ end
66
+ end
67
+
68
+ def setup
69
+ @world = RedShift::World.new
70
+ @s = @world.create(Sender)
71
+ @r = @world.create(Receiver)
72
+ @s.receiver = @r
73
+ end
74
+
75
+ def test_msg_received
76
+ @world.evolve 0.9
77
+ assert_equal(RedShift::Component::Enter, @r.state)
78
+ while @r.state == RedShift::Component::Enter do
79
+ # Can't be in queue sleep because of the x>0 guard.
80
+ assert(!@world.queue_sleep[@r])
81
+ @world.run 1
82
+ end
83
+
84
+ # in 1 step, @r should *both* receive the message and exit,
85
+ # which shows that it did not go into strict sleep after the first
86
+ # pass thru discrete update
87
+ assert_equal(RedShift::Component::Exit, @r.state)
88
+ assert_equal("hello", @r.q.pop)
89
+ end
90
+ end
@@ -0,0 +1,115 @@
1
+ require 'redshift/queue'
2
+ require 'test/unit'
3
+
4
+ # Test queue class outside of simulation using mocked World and
5
+ # Component classes.
6
+ class TestQueueAlone < Test::Unit::TestCase
7
+ class World
8
+ attr_accessor :step_count, :discrete_step
9
+ end
10
+ class Component
11
+ attr_accessor :world, :awake
12
+ def inc_queue_ready_count
13
+ @awake = true
14
+ end
15
+ def dec_queue_ready_count
16
+ end
17
+ end
18
+
19
+ def setup
20
+ @w = World.new
21
+ @w.step_count = 0
22
+ @w.discrete_step = 0
23
+ @c = Component.new
24
+ @c.world = @w
25
+ @q = RedShift::Queue.new @c
26
+ end
27
+
28
+ def test_fifo
29
+ 3.times do |i|
30
+ @q.push i
31
+ @w.discrete_step += 1
32
+ end
33
+
34
+ a = []
35
+ 3.times do
36
+ a << @q.pop
37
+ end
38
+
39
+ assert_equal([0,1,2], a)
40
+ end
41
+
42
+ def test_unpop
43
+ @q.push 1
44
+ x = @q.pop
45
+ @q.unpop x
46
+ assert_equal(x, @q.pop)
47
+ end
48
+
49
+ def test_simultaneous_entries
50
+ @w.step_count = 123
51
+ @w.discrete_step = 42
52
+ a = [1,2,3]
53
+ a.each do |x|
54
+ @q.push x
55
+ end
56
+
57
+ head = @q.pop
58
+ assert_equal(a, head)
59
+ @q.unpop head
60
+
61
+ @w.discrete_step += 1
62
+ @q.push "some stuff"
63
+ assert_equal(a, @q.pop)
64
+ end
65
+
66
+ def test_unpop_partial
67
+ @w.step_count = 123
68
+ @w.discrete_step = 42
69
+ a = [1,2,3]
70
+ a.each do |x|
71
+ @q.push x
72
+ end
73
+
74
+ head = @q.pop
75
+ head.shift
76
+ @q.unpop head
77
+
78
+ head = @q.pop
79
+ assert_equal([2,3], head)
80
+ assert_equal(RedShift::SimultaneousQueueEntries, head.class)
81
+ head.shift
82
+ @q.unpop head
83
+
84
+ head = @q.pop
85
+ assert_equal(3, head)
86
+ end
87
+
88
+ def test_wake
89
+ @c.awake = false
90
+ @q.push 1
91
+ assert_equal(true, @c.awake)
92
+ end
93
+
94
+ def test_match_empty_queue
95
+ assert_equal(false, @q.head_matches(Object))
96
+ end
97
+
98
+ def test_match_one_entry
99
+ @q.push("foo")
100
+ assert(@q.head_matches( ))
101
+ assert(@q.head_matches( /o/ ))
102
+ assert(@q.head_matches( String, /o/, proc {|x| x.kind_of?(String)} ))
103
+
104
+ assert_equal(false, @q.head_matches( /z/ ))
105
+ assert_equal(false, @q.head_matches( Symbol ))
106
+ assert_equal(false, @q.head_matches( proc {false} ))
107
+ end
108
+
109
+ def test_match_simultaneous_entries
110
+ @q.push "foo"
111
+ @q.push "bar"
112
+ assert(@q.head_matches( /foo/ ))
113
+ assert(@q.head_matches( /bar/ ))
114
+ end
115
+ end
@@ -0,0 +1,209 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'redshift'
4
+
5
+ include RedShift
6
+
7
+ # Tests resets in transitions.
8
+
9
+ class A < Component
10
+ constant :k1, :k2
11
+
12
+ continuous :x
13
+ continuous :y
14
+
15
+ link :other => A
16
+
17
+ state :S1, :S2
18
+
19
+ transition Enter => S1 do
20
+ reset :y => 1 # literal value (float or int)
21
+ end
22
+
23
+ transition S1 => S2 do
24
+ reset :x => "other.x", # expr value
25
+ :y => proc {10-y}, # proc value
26
+ :k1 => "y",
27
+ :k2 => proc {42}
28
+ end
29
+
30
+ transition S2 => Exit
31
+ end
32
+
33
+ class B < Component
34
+ state :S1, :S2
35
+
36
+ start S1
37
+
38
+ flow S1 do
39
+ alg " x = 1 "
40
+ end
41
+ flow S2 do
42
+ alg " x = 2 "
43
+ end
44
+
45
+ transition S1 => S2 do
46
+ reset :x => 3
47
+ end
48
+ end
49
+
50
+ class C < Component
51
+ constant :k, :kk
52
+ state :S
53
+ transition Enter => S do
54
+ reset :k => "kk"
55
+ end
56
+ end
57
+
58
+ class ResetVarToNonFloat < Component
59
+ continuous :var
60
+ state :S
61
+ transition Enter => S do
62
+ reset :var => proc {nil}
63
+ end
64
+ end
65
+
66
+ class ResetLink < Component
67
+ link :lnk => C
68
+ state :S
69
+ transition Enter => S do
70
+ reset :lnk => proc {create(C) {|c| c.kk = 1.337}}
71
+ end
72
+ end
73
+
74
+ class ResetLinkToNil < Component
75
+ link :lnk => C
76
+ state :S
77
+ transition Enter => S do
78
+ reset :lnk => proc {nil}
79
+ end
80
+ end
81
+
82
+ class ResetLinkToLiteralNil < Component
83
+ link :lnk => C
84
+ state :S
85
+ transition Enter => S do
86
+ reset :lnk => nil
87
+ end
88
+ end
89
+
90
+ class ResetLinkToWrongType < Component
91
+ link :lnk => C
92
+ state :S
93
+ transition Enter => S do
94
+ reset :lnk => proc {create(A)}
95
+ end
96
+ end
97
+
98
+ class Emitter < Component
99
+ transition Enter => Exit do
100
+ event :e => 42.0
101
+ end
102
+ end
103
+
104
+ class Receiver < Component
105
+ link :c => Emitter
106
+ constant :result
107
+ transition Enter => Exit do
108
+ sync :c => :e
109
+ event :e => 0.42
110
+ reset :result => "e + c.e"
111
+ end
112
+ end
113
+
114
+ require 'test/unit'
115
+
116
+ class TestReset < Test::Unit::TestCase
117
+
118
+ def setup
119
+ @world = World.new
120
+ @world.time_step = 0.1
121
+ end
122
+
123
+ def teardown
124
+ @world = nil
125
+ end
126
+
127
+ def test_reset
128
+ a1 = @world.create(A)
129
+ a2 = @world.create(A)
130
+
131
+ a1.other = a2
132
+ a2.other = a1
133
+
134
+ a1.x = v1 = 5
135
+ a2.x = v2 = 1.23
136
+
137
+ @world.run 1
138
+
139
+ assert_equal(v2, a1.x)
140
+ assert_equal(v1, a2.x)
141
+
142
+ assert_equal(9, a1.y)
143
+ assert_equal(9, a2.y)
144
+
145
+ assert_equal(1, a1.k1)
146
+ assert_equal(42, a1.k2)
147
+ end
148
+
149
+ def test_reset_algebraic_flow_error
150
+ b = @world.create(B)
151
+
152
+ assert_equal(B::S1, b.state)
153
+ assert_equal(1, b.x)
154
+
155
+ @world.run 1
156
+
157
+ assert_equal(B::S2, b.state)
158
+ assert_equal(2, b.x)
159
+ end
160
+
161
+ # This is to test the expansion of the reset value cache.
162
+ def test_many_constant_resets
163
+ ## need to get the limit as a const
164
+ n = World::CV_CACHE_SIZE + 10
165
+ cs = (0..n).map {|i| @world.create(C) {|c| c.kk = i}}
166
+ @world.run 1
167
+ cs.each do |c|
168
+ assert_equal(c.kk, c.k)
169
+ end
170
+ end
171
+
172
+ def test_reset_var_to_wrong_type
173
+ rl = @world.create(ResetVarToNonFloat)
174
+ assert_raises(VarTypeError) {@world.run 1}
175
+ end
176
+
177
+ def test_reset_link
178
+ rl = @world.create(ResetLink)
179
+ assert_equal(nil, rl.lnk)
180
+ @world.run 1
181
+ assert_equal(C, rl.lnk.class)
182
+ assert_equal(1.337, rl.lnk.k)
183
+ end
184
+
185
+ def test_reset_link_to_nil
186
+ rl = @world.create(ResetLinkToNil)
187
+ assert_equal(nil, rl.lnk)
188
+ @world.run 1
189
+ assert_equal(nil, rl.lnk)
190
+ end
191
+
192
+ def test_reset_link_to_literal_nil
193
+ rl = @world.create(ResetLinkToLiteralNil)
194
+ assert_equal(nil, rl.lnk)
195
+ @world.run 1
196
+ assert_equal(nil, rl.lnk)
197
+ end
198
+
199
+ def test_reset_link_to_wrong_type
200
+ rl = @world.create(ResetLinkToWrongType)
201
+ assert_raises(LinkTypeError) {@world.run 1}
202
+ end
203
+
204
+ def test_reset_using_event_val
205
+ r = @world.create(Receiver) {|r| r.c = r.create(Emitter)}
206
+ @world.run 1
207
+ assert_equal(42.42, r.result)
208
+ end
209
+ end