redshift 1.3.15
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 +8 -0
- data/README +5 -0
- data/RELEASE-NOTES +455 -0
- data/TODO +431 -0
- data/bench/alg-state.rb +61 -0
- data/bench/bench +26 -0
- data/bench/bench.rb +10 -0
- data/bench/continuous.rb +76 -0
- data/bench/diff-bench +86 -0
- data/bench/discrete.rb +101 -0
- data/bench/euler.rb +50 -0
- data/bench/formula.rb +78 -0
- data/bench/half-strict.rb +103 -0
- data/bench/inertness.rb +116 -0
- data/bench/queue.rb +92 -0
- data/bench/run +66 -0
- data/bench/simple.rb +74 -0
- data/bench/strictness.rb +86 -0
- data/examples/ball-tkar.rb +72 -0
- data/examples/ball.rb +123 -0
- data/examples/collide.rb +70 -0
- data/examples/connect-parallel.rb +48 -0
- data/examples/connect.rb +109 -0
- data/examples/constants.rb +27 -0
- data/examples/delay.rb +80 -0
- data/examples/derivative.rb +77 -0
- data/examples/euler.rb +46 -0
- data/examples/external-lib.rb +33 -0
- data/examples/guard-debugger.rb +77 -0
- data/examples/lotka-volterra.rb +33 -0
- data/examples/persist-ball.rb +68 -0
- data/examples/pid.rb +87 -0
- data/examples/ports.rb +60 -0
- data/examples/queue.rb +56 -0
- data/examples/queue2.rb +98 -0
- data/examples/reset-with-event-val.rb +28 -0
- data/examples/scheduler.rb +104 -0
- data/examples/set-dest.rb +23 -0
- data/examples/simulink/README +1 -0
- data/examples/simulink/delay.mdl +827 -0
- data/examples/simulink/derivative.mdl +655 -0
- data/examples/step-discrete-profiler.rb +103 -0
- data/examples/subsystem.rb +109 -0
- data/examples/sync-deadlock.rb +32 -0
- data/examples/sync-queue.rb +91 -0
- data/examples/sync-retry.rb +20 -0
- data/examples/sync.rb +51 -0
- data/examples/thermostat.rb +53 -0
- data/examples/zeno.rb +53 -0
- data/lib/accessible-index.rb +47 -0
- data/lib/redshift.rb +1 -0
- data/lib/redshift/component.rb +412 -0
- data/lib/redshift/meta.rb +183 -0
- data/lib/redshift/mixins/zeno-debugger.rb +69 -0
- data/lib/redshift/port.rb +57 -0
- data/lib/redshift/queue.rb +104 -0
- data/lib/redshift/redshift.rb +111 -0
- data/lib/redshift/state.rb +31 -0
- data/lib/redshift/syntax.rb +558 -0
- data/lib/redshift/target/c.rb +37 -0
- data/lib/redshift/target/c/component-gen.rb +1303 -0
- data/lib/redshift/target/c/flow-gen.rb +325 -0
- data/lib/redshift/target/c/flow/algebraic.rb +85 -0
- data/lib/redshift/target/c/flow/buffer.rb +74 -0
- data/lib/redshift/target/c/flow/delay.rb +203 -0
- data/lib/redshift/target/c/flow/derivative.rb +101 -0
- data/lib/redshift/target/c/flow/euler.rb +67 -0
- data/lib/redshift/target/c/flow/expr.rb +113 -0
- data/lib/redshift/target/c/flow/rk4.rb +80 -0
- data/lib/redshift/target/c/library.rb +85 -0
- data/lib/redshift/target/c/world-gen.rb +1370 -0
- data/lib/redshift/target/spec.rb +34 -0
- data/lib/redshift/world.rb +300 -0
- data/rakefile +37 -0
- data/test/test.rb +52 -0
- data/test/test_buffer.rb +58 -0
- data/test/test_connect.rb +242 -0
- data/test/test_connect_parallel.rb +47 -0
- data/test/test_connect_strict.rb +135 -0
- data/test/test_constant.rb +74 -0
- data/test/test_delay.rb +145 -0
- data/test/test_derivative.rb +48 -0
- data/test/test_discrete.rb +592 -0
- data/test/test_discrete_isolated.rb +92 -0
- data/test/test_exit.rb +59 -0
- data/test/test_flow.rb +200 -0
- data/test/test_flow_link.rb +288 -0
- data/test/test_flow_sub.rb +100 -0
- data/test/test_flow_trans.rb +292 -0
- data/test/test_inherit.rb +127 -0
- data/test/test_inherit_event.rb +74 -0
- data/test/test_inherit_flow.rb +139 -0
- data/test/test_inherit_link.rb +65 -0
- data/test/test_inherit_setup.rb +56 -0
- data/test/test_inherit_state.rb +66 -0
- data/test/test_inherit_transition.rb +168 -0
- data/test/test_numerics.rb +34 -0
- data/test/test_queue.rb +90 -0
- data/test/test_queue_alone.rb +115 -0
- data/test/test_reset.rb +209 -0
- data/test/test_setup.rb +119 -0
- data/test/test_strict_continuity.rb +410 -0
- data/test/test_strict_reset_error.rb +30 -0
- data/test/test_strictness_error.rb +32 -0
- data/test/test_sync.rb +185 -0
- data/test/test_world.rb +328 -0
- metadata +204 -0
data/test/test_setup.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'redshift'
|
4
|
+
|
5
|
+
include RedShift
|
6
|
+
|
7
|
+
class SetupTestComponent < Component
|
8
|
+
attr_accessor :x
|
9
|
+
end
|
10
|
+
|
11
|
+
# setup and defaults should both be able to set @state
|
12
|
+
|
13
|
+
class Setup_1a < SetupTestComponent
|
14
|
+
state :A
|
15
|
+
start A # same as default { start A }
|
16
|
+
def assert_consistent test
|
17
|
+
test.assert_equal(A, state)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Setup_1b < SetupTestComponent
|
22
|
+
state :A
|
23
|
+
setup { start A }
|
24
|
+
def assert_consistent test
|
25
|
+
test.assert_equal(A, state)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# defaults happen before setup
|
30
|
+
|
31
|
+
class Setup_2 < SetupTestComponent
|
32
|
+
state :A, :B
|
33
|
+
default { start A }
|
34
|
+
setup { start B }
|
35
|
+
def assert_consistent test
|
36
|
+
test.assert_equal(B, state)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# create block happens after defaults, before setup
|
41
|
+
|
42
|
+
class Setup_3a < SetupTestComponent
|
43
|
+
defaults { self.x = 0 }
|
44
|
+
def assert_consistent test
|
45
|
+
test.assert_equal(1, x)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class Setup_3b < SetupTestComponent
|
50
|
+
setup { self.x = 2 }
|
51
|
+
def assert_consistent test
|
52
|
+
test.assert_equal(2, x)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# multiple setup and defaults blocks chain after each other
|
57
|
+
|
58
|
+
class Setup_4a < SetupTestComponent
|
59
|
+
attr_accessor :y, :z
|
60
|
+
defaults { self.y = 3 }
|
61
|
+
defaults { self.z = 4 }
|
62
|
+
def assert_consistent test
|
63
|
+
test.assert_equal([3,4], [y,z])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class Setup_4b < SetupTestComponent
|
68
|
+
attr_accessor :y, :z
|
69
|
+
setup { self.y = 3 }
|
70
|
+
setup { self.z = 4 }
|
71
|
+
def assert_consistent test
|
72
|
+
test.assert_equal([3,4], [y,z])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# defaults and setup can take a hash of var=>value, and constant and continuous
|
77
|
+
# can take var => value as well
|
78
|
+
|
79
|
+
class Setup_5 < SetupTestComponent
|
80
|
+
constant :k => 111, :k2 => 3
|
81
|
+
continuous :x => 222, :x2 => 4
|
82
|
+
setup :k => 1, :x => 2
|
83
|
+
def assert_consistent test
|
84
|
+
test.assert_equal(1, k)
|
85
|
+
test.assert_equal(2, x)
|
86
|
+
test.assert_equal(3, k2)
|
87
|
+
test.assert_equal(4, x2)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
#-----#
|
92
|
+
|
93
|
+
require 'test/unit'
|
94
|
+
|
95
|
+
class TestSetup < Test::Unit::TestCase
|
96
|
+
|
97
|
+
def setup
|
98
|
+
@world = World.new
|
99
|
+
@world.time_step = 0.1
|
100
|
+
end
|
101
|
+
|
102
|
+
def teardown
|
103
|
+
@world = nil
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_setup
|
107
|
+
testers = []
|
108
|
+
ObjectSpace.each_object(Class) do |cl|
|
109
|
+
if cl <= SetupTestComponent and
|
110
|
+
cl.instance_methods.include? "assert_consistent"
|
111
|
+
testers << @world.create(cl) { |tester| tester.x = 1 }
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
for t in testers
|
116
|
+
t.assert_consistent self
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,410 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'redshift'
|
4
|
+
|
5
|
+
include RedShift
|
6
|
+
|
7
|
+
# Tests strictly continuous and strictly constant variables. Tests strict
|
8
|
+
# link variables.
|
9
|
+
#
|
10
|
+
# - tests that guard optimization works: guards are eval-ed once per step
|
11
|
+
#
|
12
|
+
# - tests exceptions raised by assigning to strict vars
|
13
|
+
#
|
14
|
+
# - tests exception raised by a transition to a state that algebraically
|
15
|
+
# defines a variable in an inconsistent way
|
16
|
+
#
|
17
|
+
# [Note: exceptions caused by algebraically defining a strict var
|
18
|
+
# in terms of a non-strict var are caught at compile time. See
|
19
|
+
# test_strictness_error.rb. Similarly, a reset on a strict var can
|
20
|
+
# be caught at compile time. See test_strict_reset_error.rb.]
|
21
|
+
|
22
|
+
class SCWorld < World
|
23
|
+
def num_checks
|
24
|
+
@num_checks ||= Hash.new do |h,comp|
|
25
|
+
h[comp] = Hash.new do |h1,trans|
|
26
|
+
h1[trans] = 0
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def hook_eval_guard(comp, guard, enabled, trans, dest)
|
32
|
+
num_checks[comp][trans.name] += 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class TestComponent < Component
|
37
|
+
def finish(test); end
|
38
|
+
end
|
39
|
+
|
40
|
+
class C < Component
|
41
|
+
strictly_constant :y
|
42
|
+
default do
|
43
|
+
self.y = 1
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class A < TestComponent
|
48
|
+
strictly_continuous :x
|
49
|
+
strict_link :c => C
|
50
|
+
|
51
|
+
flow do
|
52
|
+
diff "x' = c.y"
|
53
|
+
end
|
54
|
+
|
55
|
+
setup do
|
56
|
+
self.c = create C
|
57
|
+
end
|
58
|
+
|
59
|
+
transition Enter => Exit do
|
60
|
+
name "t1"
|
61
|
+
guard " x > 0.50 "
|
62
|
+
end
|
63
|
+
|
64
|
+
transition Enter => Exit do
|
65
|
+
name "t2"
|
66
|
+
guard " x > 0.73 "
|
67
|
+
end
|
68
|
+
|
69
|
+
def assert_consistent(test)
|
70
|
+
case state
|
71
|
+
when Enter
|
72
|
+
# Should not check the guard more than once per step, or so.
|
73
|
+
num_checks = world.num_checks[self]
|
74
|
+
t1_count = num_checks["t1"]
|
75
|
+
t2_count = num_checks["t2"]
|
76
|
+
|
77
|
+
step_count = world.step_count
|
78
|
+
|
79
|
+
test.assert(t1_count <= step_count+2)
|
80
|
+
test.assert(t2_count <= step_count+2)
|
81
|
+
# This accounts for the fact that step_discrete is called an "extra"
|
82
|
+
# time at the start of one call to World#step or #evolve, plus an
|
83
|
+
# extra time by "run(0)" below.
|
84
|
+
|
85
|
+
when Exit
|
86
|
+
## we really only need to do these tests once...
|
87
|
+
old_x = x
|
88
|
+
old_c = c
|
89
|
+
old_c_y = c.y
|
90
|
+
|
91
|
+
test.assert_raises(RedShift::StrictnessError) do
|
92
|
+
self.x = x
|
93
|
+
end
|
94
|
+
|
95
|
+
test.assert_raises(RedShift::StrictnessError) do
|
96
|
+
self.c = c
|
97
|
+
end
|
98
|
+
|
99
|
+
test.assert_raises(RedShift::StrictnessError) do
|
100
|
+
c.y = c.y
|
101
|
+
end
|
102
|
+
|
103
|
+
# strictness has a backdoor...
|
104
|
+
begin
|
105
|
+
self.x = 123
|
106
|
+
rescue RedShift::StrictnessError
|
107
|
+
end
|
108
|
+
test.assert_equal(123, x)
|
109
|
+
|
110
|
+
begin
|
111
|
+
self.c = nil
|
112
|
+
rescue RedShift::StrictnessError
|
113
|
+
end
|
114
|
+
test.assert_equal(nil, c)
|
115
|
+
|
116
|
+
(self.x = old_x) rescue nil
|
117
|
+
(self.c = old_c) rescue nil
|
118
|
+
(c.y = old_c_y) rescue nil
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# This component exists to give the A instance a chance to make too many
|
124
|
+
# guard checks.
|
125
|
+
class B < TestComponent
|
126
|
+
state :S, :T, :U
|
127
|
+
setup do
|
128
|
+
start S
|
129
|
+
end
|
130
|
+
|
131
|
+
flow S do
|
132
|
+
diff "time' = 1"
|
133
|
+
end
|
134
|
+
|
135
|
+
transition S => T do
|
136
|
+
guard "time > 0"
|
137
|
+
reset :time => 0 # so we do it again next timestep
|
138
|
+
end
|
139
|
+
|
140
|
+
transition T => U
|
141
|
+
|
142
|
+
transition U => S do
|
143
|
+
action do
|
144
|
+
@awake = world.size - world.strict_sleep.size - world.inert.size
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def assert_consistent(test)
|
149
|
+
if @awake
|
150
|
+
test.assert_equal(1, @awake) # just the B
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
class D1 < Component
|
156
|
+
strictly_continuous :x
|
157
|
+
setup do
|
158
|
+
self.x = 1
|
159
|
+
end
|
160
|
+
|
161
|
+
state :Inconsistent
|
162
|
+
|
163
|
+
flow Inconsistent do
|
164
|
+
algebraic " x = 2 "
|
165
|
+
end
|
166
|
+
|
167
|
+
transition Enter => Inconsistent do
|
168
|
+
guard "x > 0"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
class D2 < Component
|
173
|
+
strictly_continuous :x
|
174
|
+
setup do
|
175
|
+
self.x = 1
|
176
|
+
end
|
177
|
+
|
178
|
+
state :Inconsistent
|
179
|
+
|
180
|
+
flow Inconsistent do
|
181
|
+
algebraic " x = 2 "
|
182
|
+
end
|
183
|
+
|
184
|
+
transition Enter => Inconsistent do
|
185
|
+
guard {x > 0}
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# test that lazily evaluated alg exprs get evaled correctly on demand
|
190
|
+
class Lazy < TestComponent
|
191
|
+
strictly_continuous :x, :y
|
192
|
+
# z is not strict, so that the second test below is meaningful
|
193
|
+
state :Test1, :Test2, :Test3
|
194
|
+
|
195
|
+
flow Test1, Test2 do
|
196
|
+
diff " x' = 1 "
|
197
|
+
alg " y = 2*x "
|
198
|
+
alg " z = y "
|
199
|
+
end
|
200
|
+
|
201
|
+
transition Test1 => Test2 do
|
202
|
+
guard "x >= 0.5"
|
203
|
+
action {@x = x; @test = y}
|
204
|
+
end
|
205
|
+
|
206
|
+
transition Test2 => Test3 do
|
207
|
+
guard "x >= 0.7"
|
208
|
+
action {@x = x; @test = z}
|
209
|
+
# indirect eval of y from z's alg expr is different from
|
210
|
+
# using the y reader method.
|
211
|
+
end
|
212
|
+
|
213
|
+
def assert_consistent(test)
|
214
|
+
case state
|
215
|
+
when Test1, Test2
|
216
|
+
test.assert_in_delta(2 * @x, @test, 1.0E-10)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
# test that a reset of a non-strict link doesn't get around the optimization
|
222
|
+
class NonStrictLink < TestComponent
|
223
|
+
link :c => C
|
224
|
+
state :Fail, :Pass, :Relink
|
225
|
+
setup do
|
226
|
+
self.c = create(C) {|c| c.y = -1}
|
227
|
+
end
|
228
|
+
transition Enter => Fail do
|
229
|
+
guard "c.y >= 0"
|
230
|
+
end
|
231
|
+
transition Enter => Relink do
|
232
|
+
guard "c.y < 0"
|
233
|
+
reset :c => proc {create(C) {|c| c.y = 1}} # try to fool the optimization!
|
234
|
+
end
|
235
|
+
transition Relink => Fail do
|
236
|
+
guard "c.y <= 0"
|
237
|
+
end
|
238
|
+
transition Relink => Pass do
|
239
|
+
guard "c.y > 0"
|
240
|
+
end
|
241
|
+
def assert_consistent(test)
|
242
|
+
test.flunk if state == Fail
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
# test that a strict link to a nonstrict var is not optimized
|
247
|
+
class StrictLinkToNonStrictVar < TestComponent
|
248
|
+
class NS < Component
|
249
|
+
constant :k
|
250
|
+
continuous :x
|
251
|
+
end
|
252
|
+
|
253
|
+
flow { diff "t'=1" }
|
254
|
+
|
255
|
+
strict_link :ns => NS
|
256
|
+
|
257
|
+
default {self.ns = create(NS)}
|
258
|
+
|
259
|
+
state :Pass
|
260
|
+
|
261
|
+
transition do
|
262
|
+
guard "ns.k == 0 && ns.x == 0"
|
263
|
+
action { ns.k = ns.x = 1 }
|
264
|
+
end
|
265
|
+
|
266
|
+
transition do
|
267
|
+
guard "ns.k == 1 && ns.x == 1"
|
268
|
+
action { ns.k = 0 }
|
269
|
+
end
|
270
|
+
|
271
|
+
transition Enter => Pass do
|
272
|
+
guard "ns.k == 0 && ns.x == 1"
|
273
|
+
end
|
274
|
+
|
275
|
+
def assert_consistent(test)
|
276
|
+
test.flunk if t > 0 and not state == Pass
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
# test that, if evaluation of a strict guard is deferred due to a transition
|
281
|
+
# then it is still evaluated.
|
282
|
+
class StrictGuardsEvaled < TestComponent
|
283
|
+
strictly_constant :k
|
284
|
+
constant :l
|
285
|
+
transition do
|
286
|
+
guard "l==0"
|
287
|
+
reset :l => 1
|
288
|
+
end
|
289
|
+
transition Enter => Exit do
|
290
|
+
guard "k<1"
|
291
|
+
end
|
292
|
+
def assert_consistent(test)
|
293
|
+
if l > 0
|
294
|
+
test.assert_equal(Exit, state)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
# test that, if evaluation of a strict guard is deferred due to a transition
|
300
|
+
# then it is still evaluated.
|
301
|
+
class StrictGuardsEvaled2 < TestComponent
|
302
|
+
strictly_constant :k
|
303
|
+
transition do
|
304
|
+
guard "k<1"
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
# Test that there is no memory of which strict guards have been "checked"
|
309
|
+
# after moving to a new state.
|
310
|
+
class StrictGuardsEvaled3 < TestComponent
|
311
|
+
state :S1, :S2
|
312
|
+
link :checker => :Checker
|
313
|
+
constant :i => 0
|
314
|
+
transition Enter => S1 do
|
315
|
+
reset :checker => proc {create(Checker) {|c| c.emitter = self}}
|
316
|
+
end
|
317
|
+
transition S1 => S2 do
|
318
|
+
guard "i > 5"
|
319
|
+
event :e
|
320
|
+
end
|
321
|
+
transition S1 => S1 do # give other comp time to check guards
|
322
|
+
reset :i => "i+1"
|
323
|
+
end
|
324
|
+
|
325
|
+
class Checker < Component
|
326
|
+
strictly_constant :x => 0, :y => 1
|
327
|
+
state :S1
|
328
|
+
link :emitter => StrictGuardsEvaled3
|
329
|
+
transition Enter => Exit do
|
330
|
+
guard "x > 0"
|
331
|
+
post {raise}
|
332
|
+
end
|
333
|
+
transition Enter => S1 do
|
334
|
+
sync :emitter => :e
|
335
|
+
end
|
336
|
+
transition S1 => Exit do
|
337
|
+
guard "y > 0"
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
def assert_consistent(test)
|
342
|
+
if self.state == S2
|
343
|
+
test.assert_equal(Exit, checker.state)
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
#-----#
|
349
|
+
|
350
|
+
require 'test/unit'
|
351
|
+
|
352
|
+
class TestStrictContinuity < Test::Unit::TestCase
|
353
|
+
|
354
|
+
def setup
|
355
|
+
@world = SCWorld.new
|
356
|
+
@world.time_step = 0.1
|
357
|
+
end
|
358
|
+
|
359
|
+
def teardown
|
360
|
+
@world = nil
|
361
|
+
end
|
362
|
+
|
363
|
+
def test_strict_continuity
|
364
|
+
testers = []
|
365
|
+
ObjectSpace.each_object(Class) do |cl|
|
366
|
+
if cl <= TestComponent and
|
367
|
+
cl.instance_methods.include? "assert_consistent"
|
368
|
+
testers << @world.create(cl)
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
testers.each { |t| t.assert_consistent self }
|
373
|
+
@world.run 0
|
374
|
+
# now we can check what happened after one discrete step, which
|
375
|
+
# is needed for StrictGuardsEvaled3.
|
376
|
+
testers.each { |t| t.assert_consistent self }
|
377
|
+
@world.run 10 do
|
378
|
+
testers.each { |t| t.assert_consistent self }
|
379
|
+
end
|
380
|
+
testers.each { |t| t.finish self }
|
381
|
+
|
382
|
+
a = testers.find {|t| t.class == A}
|
383
|
+
assert(a)
|
384
|
+
assert_equal(TestComponent::Exit, a.state)
|
385
|
+
|
386
|
+
b = testers.find {|t| t.class == B}
|
387
|
+
assert(b)
|
388
|
+
end
|
389
|
+
|
390
|
+
def test_algebraic_inconsistency1
|
391
|
+
d = @world.create(D1)
|
392
|
+
assert_raises(RedShift::StrictnessError) do
|
393
|
+
@world.run 10
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
def test_algebraic_inconsistency2
|
398
|
+
d = @world.create(D2)
|
399
|
+
assert_raises(RedShift::StrictnessError) do
|
400
|
+
@world.run 10
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
def test_StrictGuardsEvaled
|
405
|
+
c = @world.create(StrictGuardsEvaled2)
|
406
|
+
assert_raises(RedShift::ZenoError) do
|
407
|
+
@world.run 10
|
408
|
+
end
|
409
|
+
end
|
410
|
+
end
|