redshift 1.3.15
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,77 @@
|
|
1
|
+
# Numerical differentiation.
|
2
|
+
|
3
|
+
# Compare with simulink/derivative.mdl -- note that redshift is more accurate
|
4
|
+
# because the derivative flow operates at all integrator steps, not just at
|
5
|
+
# the simulation timesteps.
|
6
|
+
|
7
|
+
require 'redshift'
|
8
|
+
include RedShift
|
9
|
+
|
10
|
+
class C < Component
|
11
|
+
flow do
|
12
|
+
diff " t' = 1 "
|
13
|
+
|
14
|
+
alg " u = sin(t) "
|
15
|
+
alg " sdu = cos(t) " # symbolic derivative
|
16
|
+
derive " ndu = u' ",# numerical derivative (can be (<expr>)' )
|
17
|
+
:feedback => false
|
18
|
+
diff " nindu' = ndu " # numerical integral of ndu
|
19
|
+
diff " niu' = u " # numerical integral of u
|
20
|
+
derive " ndniu = niu' ",# numerical derivative of niu
|
21
|
+
:feedback => false
|
22
|
+
|
23
|
+
alg " err = sdu - ndu "
|
24
|
+
# This error is small.
|
25
|
+
|
26
|
+
alg " e_ndni = ndniu - u "
|
27
|
+
alg " e_nind = nindu - u "
|
28
|
+
# The error is very small when numerically differentiating a signal that
|
29
|
+
# has been numerically integrated (e_ndni), but the error is worse
|
30
|
+
# for the integral of a differentiated signal (e_nind).
|
31
|
+
end
|
32
|
+
|
33
|
+
# Some alternative examples:
|
34
|
+
# alg " u = pow(t, 4) - 17*pow(t,3) + 102*pow(t,2) - 1300*t "
|
35
|
+
# alg " sdu = 4*pow(t, 3) - 3*17*pow(t,2) + 2*102*t - 1300 "
|
36
|
+
#
|
37
|
+
# continuous :u => 1, :nindu => 1, :ndniu =>1
|
38
|
+
# diff " u' = 0.02*u "
|
39
|
+
# alg " sdu = 0.02*exp(0.02*u) "
|
40
|
+
end
|
41
|
+
|
42
|
+
world = World.new
|
43
|
+
c = world.create(C)
|
44
|
+
|
45
|
+
u, sdu, ndu, nindu, err, e_ndni, e_nind = [], [], [], [], [], [], []
|
46
|
+
gather = proc do
|
47
|
+
time = c.t
|
48
|
+
u << [time, c.u]
|
49
|
+
sdu << [time, c.sdu]
|
50
|
+
ndu << [time, c.ndu]
|
51
|
+
nindu << [time, c.nindu]
|
52
|
+
err << [time, c.err]
|
53
|
+
e_ndni << [time, c.e_ndni]
|
54
|
+
e_nind << [time, c.e_nind]
|
55
|
+
end
|
56
|
+
|
57
|
+
gather.call
|
58
|
+
world.evolve 10 do
|
59
|
+
gather.call
|
60
|
+
end
|
61
|
+
|
62
|
+
require 'sci/plot'
|
63
|
+
include Plot::PlotUtils
|
64
|
+
|
65
|
+
gnuplot do |plot|
|
66
|
+
plot.command %{set title "Numerical differentiation"}
|
67
|
+
plot.command %{set xlabel "time"}
|
68
|
+
plot.add u, %{title "u" with lines}
|
69
|
+
plot.add sdu, %{title "sdu" with lines}
|
70
|
+
plot.add ndu, %{title "ndu" with lines}
|
71
|
+
plot.add nindu, %{title "nindu" with lines}
|
72
|
+
plot.add err, %{title "err" with lines}
|
73
|
+
plot.add e_ndni, %{title "e_ndni" with lines}
|
74
|
+
plot.add e_nind, %{title "e_nind" with lines}
|
75
|
+
end
|
76
|
+
|
77
|
+
sleep 1 if /mswin32|mingw32/ =~ RUBY_PLATFORM
|
data/examples/euler.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'redshift'
|
2
|
+
|
3
|
+
include RedShift
|
4
|
+
|
5
|
+
class Flow_Euler < Component
|
6
|
+
flow do
|
7
|
+
euler "x' = 1"
|
8
|
+
euler "y_euler' = x" # y is a worse approx of z, due to Euler
|
9
|
+
diff " y_rk4' = x"
|
10
|
+
alg " y_true = 0.5 * pow(x,2)" # the true value
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
world = World.new
|
15
|
+
c = world.create(Flow_Euler)
|
16
|
+
|
17
|
+
|
18
|
+
x, y_euler, y_rk4, y_true, rk4_err, euler_err = [], [], [], [], [], []
|
19
|
+
gather = proc do
|
20
|
+
time = world.clock
|
21
|
+
x << [time, c.x]
|
22
|
+
y_euler << [time, c.y_euler]
|
23
|
+
y_rk4 << [time, c.y_rk4]
|
24
|
+
y_true << [time, c.y_true]
|
25
|
+
rk4_err << [time, (c.y_rk4 - c.y_true).abs]
|
26
|
+
euler_err << [time, (c.y_euler - c.y_true).abs]
|
27
|
+
end
|
28
|
+
|
29
|
+
gather.call
|
30
|
+
world.evolve 10 do
|
31
|
+
gather.call
|
32
|
+
end
|
33
|
+
|
34
|
+
require 'sci/plot'
|
35
|
+
include Plot::PlotUtils
|
36
|
+
|
37
|
+
gnuplot do |plot|
|
38
|
+
plot.command %{set title "Euler Integration"}
|
39
|
+
plot.command %{set xlabel "time"}
|
40
|
+
plot.add x, %{title "x" with lines}
|
41
|
+
plot.add y_true, %{title "y_true" with lp}
|
42
|
+
plot.add y_rk4, %{title "y_rk4" with lp}
|
43
|
+
plot.add y_euler, %{title "y_euler" with lp}
|
44
|
+
plot.add rk4_err, %{title "rk4_err" with lp}
|
45
|
+
plot.add euler_err, %{title "euler_err" with lp}
|
46
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Example of using an external C lib with redshift. Note that
|
2
|
+
# <math.h> is included and -lm is linked by default.
|
3
|
+
|
4
|
+
require 'redshift'
|
5
|
+
|
6
|
+
RedShift.with_library do |library|
|
7
|
+
library.include_file.include "<gsl/gsl_sf_gamma.h>"
|
8
|
+
library.include_file.include "<gsl/gsl_math.h>"
|
9
|
+
library.include_file.include "<gsl/gsl_const_mksa.h>"
|
10
|
+
library.link_with "-lgsl"
|
11
|
+
library.declare_external_constant "GSL_CONST_MKSA_MASS_ELECTRON"
|
12
|
+
|
13
|
+
# If you need custom cflags, you can put them here:
|
14
|
+
# $CFLAGS = "-fPIC -O2 -march=i686 -msse2 -mfpmath=sse"
|
15
|
+
end
|
16
|
+
|
17
|
+
class C < RedShift::Component
|
18
|
+
continuous :x, :y
|
19
|
+
|
20
|
+
flow do
|
21
|
+
diff " y' = 2 + GSL_CONST_MKSA_MASS_ELECTRON "
|
22
|
+
end
|
23
|
+
|
24
|
+
transition Enter => Exit do
|
25
|
+
guard " gsl_fcmp(y, 1.0, 0.01) == 0 "
|
26
|
+
reset :x => "gsl_sf_taylorcoeff(3, 2)"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
w = RedShift::World.new
|
31
|
+
c = w.create C
|
32
|
+
w.evolve 1
|
33
|
+
p c.x, c.y
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'redshift'
|
2
|
+
|
3
|
+
include RedShift
|
4
|
+
|
5
|
+
# This example is a simple debugger for stepping through guards. It's not
|
6
|
+
# intended to be useful as a debugger, but to show how hook methods can be
|
7
|
+
# used to develop debuggers.
|
8
|
+
#
|
9
|
+
# See examples/step-discrete-hook.rb for more examples of hook methods.
|
10
|
+
#
|
11
|
+
# See mixins/debugger.rb and examples/debugger.rb for a more useful debugger.
|
12
|
+
|
13
|
+
class DebuggingWorld < World
|
14
|
+
def hook_eval_guard(comp, guard, enabled, trans, dest)
|
15
|
+
puts "%-30p %-30p %-8s %6d" %
|
16
|
+
[comp, guard, enabled ? "enabled" : nil, discrete_step]
|
17
|
+
if enabled and dest != comp.state
|
18
|
+
puts "%-30s %-30s %-s" % [nil, nil, "#{comp.state} => #{dest}"]
|
19
|
+
end
|
20
|
+
puts "press <enter> to continue"
|
21
|
+
gets
|
22
|
+
end
|
23
|
+
|
24
|
+
def hook_begin
|
25
|
+
puts "-"*60
|
26
|
+
puts "Begin discrete update in #{inspect}"
|
27
|
+
puts "press <enter> to continue, ^C at any time to stop"
|
28
|
+
puts "%-30s %-30s %-8s %6s" %
|
29
|
+
%w(component guard status step)
|
30
|
+
gets
|
31
|
+
end
|
32
|
+
|
33
|
+
def hook_end
|
34
|
+
puts "End discrete update in #{inspect}"
|
35
|
+
puts "press <enter> to continue"
|
36
|
+
gets
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class Thing < Component
|
41
|
+
state :A, :B
|
42
|
+
start A
|
43
|
+
|
44
|
+
continuous :x
|
45
|
+
flow A do
|
46
|
+
diff "x' = 1"
|
47
|
+
end
|
48
|
+
|
49
|
+
transition A => B do
|
50
|
+
guard "x > 2"
|
51
|
+
end
|
52
|
+
|
53
|
+
transition B => A do
|
54
|
+
guard "x < 1e-10"
|
55
|
+
reset :x => 0
|
56
|
+
end
|
57
|
+
|
58
|
+
transition B => B do
|
59
|
+
guard "x >= 1e-10"
|
60
|
+
reset :x => "x-1"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
w = DebuggingWorld.new
|
65
|
+
|
66
|
+
w.create(Thing) do |th|
|
67
|
+
th.name = 1
|
68
|
+
th.x = 0.5
|
69
|
+
end
|
70
|
+
|
71
|
+
w.create(Thing) do |th|
|
72
|
+
th.name = 2
|
73
|
+
th.x = 5
|
74
|
+
th.start Thing::B
|
75
|
+
end
|
76
|
+
|
77
|
+
w.evolve 100
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'redshift'
|
2
|
+
|
3
|
+
class Population < RedShift::Component
|
4
|
+
flow do
|
5
|
+
diff " rabbits' = 0.3*rabbits - 0.02 * rabbits * foxes "
|
6
|
+
diff " foxes' = 0.01*foxes*rabbits - 0.5 * foxes "
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
world = RedShift::World.new do |w|
|
11
|
+
w.time_step = 0.05
|
12
|
+
end
|
13
|
+
|
14
|
+
pop = world.create Population
|
15
|
+
pop.foxes = 2
|
16
|
+
pop.rabbits = 100
|
17
|
+
|
18
|
+
data = []
|
19
|
+
world.evolve 100 do |w|
|
20
|
+
data << [w.clock, pop.foxes, pop.rabbits]
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'sci/plot'
|
24
|
+
include Plot::PlotUtils
|
25
|
+
|
26
|
+
gnuplot do |plot|
|
27
|
+
plot.command %{set title "Lotla-Volterra"}
|
28
|
+
plot.command %{set xlabel "time"}
|
29
|
+
plot.add data, %{using 1:2 title "foxes" with lines}
|
30
|
+
plot.add data, %{using 1:3 title "rabbits" with lines}
|
31
|
+
end
|
32
|
+
|
33
|
+
sleep 1 if /mswin32|mingw32/ =~ RUBY_PLATFORM
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'redshift'
|
2
|
+
require 'plot/plot'
|
3
|
+
require 'nr/random'
|
4
|
+
|
5
|
+
include RedShift
|
6
|
+
include NR::Random
|
7
|
+
include Math
|
8
|
+
|
9
|
+
|
10
|
+
class Ball < Component
|
11
|
+
|
12
|
+
flow {
|
13
|
+
euler " x' = @vx "
|
14
|
+
euler " y' = @vy "
|
15
|
+
}
|
16
|
+
|
17
|
+
defaults {
|
18
|
+
@x = 0
|
19
|
+
@y = 0
|
20
|
+
}
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
world = World.open "ball.world"
|
25
|
+
|
26
|
+
unless world
|
27
|
+
|
28
|
+
world = World.new {time_step 0.01}
|
29
|
+
|
30
|
+
seq = UniformSequence.new :min => 0, :max => 2*PI
|
31
|
+
|
32
|
+
5.times do
|
33
|
+
world.create(Ball) {
|
34
|
+
angle = seq.next
|
35
|
+
@vx = cos angle
|
36
|
+
@vy = sin angle
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
balls = world.select { |c| c.type == Ball }
|
43
|
+
|
44
|
+
data = {}
|
45
|
+
for b in balls
|
46
|
+
data[b] = [[b.x, b.y]]
|
47
|
+
end
|
48
|
+
|
49
|
+
50.times do
|
50
|
+
world.run
|
51
|
+
for b in balls
|
52
|
+
data[b] << [b.x, b.y]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
Plot.new ('gnuplot') {
|
57
|
+
|
58
|
+
command 'set xrange [ -2 : 2 ]; set yrange [ -2 : 2 ]'
|
59
|
+
|
60
|
+
for b in balls
|
61
|
+
add data[b], "title \"#{balls.index(b)}\" with lines"
|
62
|
+
end
|
63
|
+
|
64
|
+
show
|
65
|
+
pause 5
|
66
|
+
}
|
67
|
+
|
68
|
+
world.save "ball.world"
|
data/examples/pid.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# PID control example
|
2
|
+
# See http://en.wikipedia.org/wiki/PID_control.
|
3
|
+
|
4
|
+
require 'redshift'
|
5
|
+
include RedShift
|
6
|
+
|
7
|
+
srand(12345)
|
8
|
+
|
9
|
+
# Variable with discrete and continuous perturbation.
|
10
|
+
class Plant < Component
|
11
|
+
continuous :x => 0, :t => 1
|
12
|
+
|
13
|
+
link :control => :Control # fwd ref to undefined class Control
|
14
|
+
|
15
|
+
flow do
|
16
|
+
diff " x' = control.output + sin(t) "
|
17
|
+
diff " t' = -1 "
|
18
|
+
end
|
19
|
+
|
20
|
+
transition do
|
21
|
+
guard "t <= 0"
|
22
|
+
action do
|
23
|
+
self.t += rand * 20
|
24
|
+
self.x += (rand - 0.5) * 10
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Tries to bring x back to the set_point.
|
30
|
+
class Control < Component
|
31
|
+
continuous :set_point => 2.0
|
32
|
+
continuous :p_out, :i_out, :d_out, :output
|
33
|
+
|
34
|
+
# Gains
|
35
|
+
constant :k_p => 1.0,
|
36
|
+
:k_i => 1.0,
|
37
|
+
:k_d => 1.0
|
38
|
+
|
39
|
+
link :plant => Plant
|
40
|
+
|
41
|
+
flow do
|
42
|
+
algebraic " error = set_point - plant.x "
|
43
|
+
algebraic " p_out = k_p * error "
|
44
|
+
differential " i_out' = k_i * error "
|
45
|
+
algebraic " d_out = k_d * (- sin(plant.t)) "
|
46
|
+
# since in plant we have x' = control.output + sin(t)
|
47
|
+
# and we can algebraically remove the "output" term.
|
48
|
+
# this is a special case that doesn't need numerical differentiation
|
49
|
+
algebraic " output = p_out + i_out + d_out "
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
world = World.new
|
54
|
+
plant = world.create Plant
|
55
|
+
control = world.create Control
|
56
|
+
control.plant = plant
|
57
|
+
plant.control = control
|
58
|
+
|
59
|
+
x, p_out, i_out, d_out, output = [], [], [], [], []
|
60
|
+
gather = proc do
|
61
|
+
time = world.clock
|
62
|
+
x << [time, plant.x]
|
63
|
+
p_out << [time, control.p_out]
|
64
|
+
i_out << [time, control.i_out]
|
65
|
+
d_out << [time, control.d_out]
|
66
|
+
output << [time, control.output]
|
67
|
+
end
|
68
|
+
|
69
|
+
gather.call
|
70
|
+
world.evolve 1000 do
|
71
|
+
gather.call
|
72
|
+
end
|
73
|
+
|
74
|
+
require 'sci/plot'
|
75
|
+
include Plot::PlotUtils
|
76
|
+
|
77
|
+
gnuplot do |plot|
|
78
|
+
plot.command %{set title "PID control"}
|
79
|
+
plot.command %{set xlabel "time"}
|
80
|
+
plot.add x, %{title "x" with lines}
|
81
|
+
plot.add p_out, %{title "p_out" with lines}
|
82
|
+
plot.add i_out, %{title "i_out" with lines}
|
83
|
+
plot.add d_out, %{title "d_out" with lines}
|
84
|
+
plot.add output, %{title "output" with lines}
|
85
|
+
end
|
86
|
+
|
87
|
+
sleep 1 if /mswin32|mingw32/ =~ RUBY_PLATFORM
|
data/examples/ports.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# Shows how to use the port abstraction to refer to ports independently of the
|
2
|
+
# components (and classes) they are attached to.
|
3
|
+
|
4
|
+
require 'redshift'
|
5
|
+
include RedShift
|
6
|
+
|
7
|
+
class I < Component
|
8
|
+
flow do
|
9
|
+
diff " x' = -x "
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class A < Component
|
14
|
+
flow do
|
15
|
+
diff " t' = 1 "
|
16
|
+
alg " x = cos(t) "
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class K < Component
|
21
|
+
constant :x => 5.678
|
22
|
+
end
|
23
|
+
|
24
|
+
class W < Component
|
25
|
+
input :x
|
26
|
+
setup do
|
27
|
+
port(:x) << create(I).port(:x)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class L < Component
|
32
|
+
link :i => I
|
33
|
+
setup do
|
34
|
+
self.i = create(I)
|
35
|
+
end
|
36
|
+
flow do
|
37
|
+
alg " x = i.x "
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Tester < Component
|
42
|
+
input :x
|
43
|
+
end
|
44
|
+
|
45
|
+
w = World.new
|
46
|
+
|
47
|
+
comps = [I, A, K, W, L].map {|cl| w.create(cl)}
|
48
|
+
ports = comps.map {|comp| comp.port(:x)}
|
49
|
+
values = ports.map {|port| port.value}
|
50
|
+
|
51
|
+
p values # ==> [0.0, 1.0, 5.678, 0.0, 0.0]
|
52
|
+
|
53
|
+
tester = w.create(Tester)
|
54
|
+
values = ports.map do |port|
|
55
|
+
tester.port(:x) << port
|
56
|
+
tester.x
|
57
|
+
end
|
58
|
+
|
59
|
+
p values # same as above
|
60
|
+
|