------------------------------------------
------------------------------------------
----- A System Matrix Implementation -----
----- using Sparse Matrix Methods, -----
----- and Energy Flow Processing -----
----- -----
----- By John Ringland -----
----- 2004/11/22 -----
------------------------------------------
------------------------------------------
-- this file uses sparse matrix energy flow methods
-- to implement an ergodic pure metric sysWrapped SMN framework
with trace
include ergodicSysMSMN.e
---------------------------------
---------------------------------
----- Test Model of a -----
----- Drink Machine system -----
---------------------------------
---------------------------------
-- The previous model drink machine (ergodicSysMSMN_DrinkMachine00.ex) had the problem that
-- its outputs disapeared if one didn't take them immediately,
-- Not very good for slow movers...
-- So that has been fixed in this model
-- 1 2 3 4 5 6 7 8 9 10 11 12 13
-- -------------------------------------------------------
--1 chosen | 0 1 0 1 0 0 0 0 0 0 0 0 1
-- |
--2 available | F2 0 0 F23 1 0 0 1 0 0 0 0 0 0
-- |
--3 drink reservoir | F3 F31 0 1 0 0 0 0 0 0 1 0 0 0
-- |
--4 drink prices | 0 0 0 0 0 0 0 0 0 0 0 0 0
-- |
--5 change calc | F51 0 0 0 0 0 1 0 0 0 0 0 0
-- |
--6 coin adder | 0 0 0 0 F65 0 0 0 0 0 0 F612 0
-- |
--7 coin total | F7 0 0 0 0 0 1 1 0 0 0 0 0 0
-- |
--8 coin reservoir | F8 0 0 0 0 F85 0 0 0 0 0 0 1 0
-- |
--9 change shute | F9 0 0 0 0 0 0 0 1 1 0 0 0 0
-- |
--10 drink shute |F10 0 0 1 0 0 0 0 0 0 1 0 0 0
-- |
--11 lights | 0 1 0 0 0 0 0 0 0 0 0 0 0
-- |
--12 coin slot | 0 0 0 0 0 0 0 0 0 0 0 0 0
-- |
--13 buttons | 0 0 0 0 0 0 0 0 0 0 0 0 0
-- |
-- used when printing out the system state vector
sequence sv_names
sv_names = {"chosen","available","drink reservoir","drink prices","change calc",
"coin adder","coin total","coin reservoir","change shute","drink shute","lights",
"coin slot","buttons"}
-- F(2,3) takes the state of the drink_reservoir and extracts its inventory
function F23_(sequence in) --{inventory, dispensed_drink}
return in[1] -- inventory
end function
integer F23
F23 = routine_id("F23_")
-- F(3,1) extracts the button_id from chosen's input and sends this to drink_reservoir
function F31_(sequence in) --{availability vector, drink prices list, button id}
return in[3] -- button_id if it is available
end function
integer F31
F31 = routine_id("F31_")
-- F(5,1) extracts the price that corresponds to drink_id from drink_prices and sends to change_calc
function F51_(sequence in) --{availability_vector, drink_prices:{price,..}, button_id}
integer button_id
button_id = in[3]
if button_id and in[1][button_id] then
return in[2][button_id] -- price that corresponds to button_id=drink_id only if available
end if
return 0
end function
integer F51
F51 = routine_id("F51_")
-- F(6,5) if change_calc's input (price) is non-zero then reset=1
function F65_(sequence in) --{price, coin_total}
return in[1] != 0 -- price!=0
end function
integer F65
F65 = routine_id("F65_")
-- F(6,12) for the coin in the slot it determines the value of the coin
function F612_(sequence in) --{value} where a coin is a sequence containing value coin:{value}
return in[1] -- value
end function
integer F612
F612 = routine_id("F612_")
-- F(8,5) calculates the difference between price and coin_total to determine required change
function F85_(sequence in) --{price, coin_total}
integer price
price = in[1]
if price then
return in[2] - price -- coin_total-price
end if
return 0
end function
integer F85
F85 = routine_id("F85_")
-- F2 takes drink_prices, drink inventory and coin_total and produces an availability vector
function F2_(sequence in) --{ inventory, drink_prices:{price,..}, coin_total}
sequence vect, price, inv
integer len, total
len = length(in[1])
vect = repeat(0, len)
inv = in[1]
price = in[2]
total = in[3]
for i = 1 to len do
if inv[i][2] and price[i]<= total then
vect[i] = 1
end if
end for
return vect -- {0,1,1,0} for example if the second and third drinks are available
end function
integer F2
F2 = routine_id("F2_")
-- F3 takes a drink_id and its previous state and subtracts one from its inventory then outputs this tally plus any required drinks
function F3_(sequence in) --{drink_id, {inventory, dispensed_drink}, drink_dispensed}
sequence inv, dispensed_drink
integer drink_id
drink_id = in[1]
inv = in[2][1]
if drink_id then
inv[drink_id][2] -= 1
return {inv,inv[drink_id][1]} -- {inventory, dispensed_drink}
end if
if not equal(in[3],"none") then -- if drink_dispensed
dispensed_drink = "none"
else
dispensed_drink = in[2][2]
end if
return {inv,dispensed_drink}
end function
integer F3
F3 = routine_id("F3_")
-- F7 takes {{the reset bool and any new coin values} and the previous total} and
-- determines a new total
function F7_(sequence in) --{{reset, new_value}, coin_total}
if in[1][1] then
return in[1][2] -- new_value if reset=1
else
return in[1][2]+in[2] -- new_value + coin_total if reset=0
end if
end function
integer F7
F7 = routine_id("F7_")
sequence coin_tally, values
values = { 5, 10, 20, 50, 100, 200}
coin_tally = {100, 100, 100, 100, 100, 100}
-- F8 takes a change_value and an input coin, it adds the coin to its internal tally
-- and subtracts the change from its internal tally and outputs the requested change coins.
function F8_(sequence in) --{change_value, new_coin}
integer val, chng, coin
sequence output
coin = in[2][1]
if coin then
val = find(in[2][1], values)
coin_tally[val] += 1
end if
chng = in[1]
output = {}
if chng then
while chng do
if chng - 200 >= 0 then
if values[6] then
chng -= 200
coin_tally[6] -= 1
output = output & {{200}}
end if
elsif chng - 100 >= 0 then
if values[5] then
chng -= 100
coin_tally[5] -= 1
output = output & {{100}}
end if
elsif chng - 50 >= 0 then
if values[4] then
chng -= 50
coin_tally[4] -= 1
output = output & {{50}}
end if
elsif chng - 20 >= 0 then
if values[3] then
chng -= 20
coin_tally[3] -= 1
output = output & {{20}}
end if
elsif chng - 10 >= 0 then
if values[2] then
chng -= 10
coin_tally[2] -= 1
output = output & {{10}}
end if
elsif chng - 5 >= 0 then
if values[1] then
chng -= 5
coin_tally[1] -= 1
output = output & {{5}}
end if
else
exit
end if
end while
end if
return output -- {change_coins} where change coins is a sequence of coins of particular denominations.
end function
integer F8
F8 = routine_id("F8_")
-- F9 takes the output of the coin_reservoir and the shute_state and manages the shute_state
function F9_(sequence in) --{{coin,...}, shute_state}
sequence shute, chng
chng = in[1]
shute = in[2]
if length(shute) then
return shute
end if
return chng
end function
integer F9
F9 = routine_id("F9_")
-- F10 takes the state of the drink_reservoir and the shute_state and manages the shute_state
function F10_(sequence in) --{{inventory, dispensed_drink}, shute_state}
sequence shute
shute = in[2]
if equal(shute,"none") then
return in[1][2] -- dispensed_drink
end if
return shute
end function
integer F10
F10 = routine_id("F10_")
-- Assembling all the model components...
sequence st, sm, sv, model, cUpdate, result
-- constructing the singular transform vector
st = {-1,F2,F3,-1,-1,-1,F7,F8,F9,F10,-1,-1,-1}
-- constructing the Metric System Matrix element by element
sm = sparse_SM(13,13)
sm = set_SM(sm, {1,2}, 1)
sm = set_SM(sm, {1,4}, 1)
sm = set_SM(sm, {1,13}, 1)
sm = set_SM(sm, {2,3}, {{F23},1})
sm = set_SM(sm, {2,4}, 1)
sm = set_SM(sm, {2,7}, 1)
sm = set_SM(sm, {3,1}, {1,{F31}})
sm = set_SM(sm, {3,3}, 1)
sm = set_SM(sm, {3,10}, 1)
sm = set_SM(sm, {5,1}, {1,{F51}})
sm = set_SM(sm, {5,7}, 1)
sm = set_SM(sm, {6,5}, {1,{F65}})
sm = set_SM(sm, {6,12}, {{F612},1})
sm = set_SM(sm, {7,6}, 1)
sm = set_SM(sm, {7,7}, 1)
sm = set_SM(sm, {8,5}, {1,{F85}})
sm = set_SM(sm, {8,12}, 1)
sm = set_SM(sm, {9,8}, 1)
sm = set_SM(sm, {9,9}, 1)
sm = set_SM(sm, {10,3}, 1)
sm = set_SM(sm, {10,10}, 1)
sm = set_SM(sm, {11,2}, 1)
sequence inv, prices
-- 100 each of four types of drinks
inv = {{"cola",100},{"lemonade",100},{"juice",100},{"water",100}}
-- prices in cents for the four drink types
prices = {120,120,100,80}
-- constructing the final State Vector
sv = {{{0,0,0,0},prices,0},{0,0,0,0},{inv,"none"},prices,{0,0},{0,0,0},0,{},{},"none",0,{100},0}
-- flagging the initial inputs for processing by the energy flow algorithm
cUpdate = {12}
-- combining all of the above into a single system model
model = {st,sm,sv,cUpdate}
puts(1,"\n\nDrink Machine System\n\n")
puts(1,"initial model\n")
? model
puts(1,"\nWe have inserted a one dollar coin in the coin_slot\n")
puts(1,"\n\nfirst iteration\n")
result = step_Model(model, 1)
print_sv(result[model_][SV_], sv_names)
puts(1,"\n# Coin Tally #####\n")
? coin_tally
puts(1,"# Update List #####\n")
? result[model_][CU_]
puts(1,"\nIt is now registered in coin_tally and in the coin adders new_value\n")
puts(1,"\n\nNow setting coin slot = {0} for no coin\n")
result[model_][SV_][12] = {0}
result[model_][CU_] = result[model_][CU_] & {12}
print_sv(result[model_][SV_], sv_names)
puts(1,"\n# Coin Tally #####\n")
? coin_tally
puts(1,"# Update List #####\n")
? result[model_][CU_]
puts(1,"\n\nsecond iteration\n")
result = step_Model(result[model_], 1)
print_sv(result[model_][SV_], sv_names)
puts(1,"\n# Coin Tally #####\n")
? coin_tally
puts(1,"# Update List #####\n")
? result[model_][CU_]
puts(1,"\nIt is now registered in coin_total\n")
puts(1,"\n\nthird iteration\n")
result = step_Model(result[model_], 1)
print_sv(result[model_][SV_], sv_names)
puts(1,"\n# Coin Tally #####\n")
? coin_tally
puts(1,"# Update List #####\n")
? result[model_][CU_]
puts(1,"\nNow the availability vector has been created, coin_total has been registered\n")
puts(1,"by change_calc and the new zero coin_value has been registered by coin_adder\n")
puts(1,"\n\nfourth iteration\n")
result = step_Model(result[model_], 1)
print_sv(result[model_][SV_], sv_names)
puts(1,"\n# Coin Tally #####\n")
? coin_tally
puts(1,"# Update List #####\n")
? result[model_][CU_]
puts(1,"\nThe new availability vector has been registered by chosen and the lights have\n")
puts(1,"come on for juice and water.\n")
puts(1,"\n\nfifth iteration\n")
result = step_Model(result[model_], 1)
print_sv(result[model_][SV_], sv_names)
puts(1,"\n# Coin Tally #####\n")
? coin_tally
puts(1,"# Update List #####\n")
? result[model_][CU_]
puts(1,"\nNow it has reached a steady state and is waiting for more input\n")
puts(1,"\n\nSo now we can choose some water by pressing the fourth button.\n")
result[model_][SV_][13] = 4
result[model_][CU_] = result[model_][CU_] & {13}
print_sv(result[model_][SV_], sv_names)
puts(1,"\n# Coin Tally #####\n")
? coin_tally
puts(1,"# Update List #####\n")
? result[model_][CU_]
puts(1,"\n\nsixth iteration\n")
result = step_Model(result[model_], 1)
puts(1,"\nI now take the finger off the button\n")
result[model_][SV_][13] = 0
result[model_][CU_] = result[model_][CU_] & {13}
print_sv(result[model_][SV_], sv_names)
puts(1,"\n# Coin Tally #####\n")
? coin_tally
puts(1,"# Update List #####\n")
? result[model_][CU_]
puts(1,"\nThe button press has been registered by chosen\n")
puts(1,"\n\nseventh iteration\n")
result = step_Model(result[model_], 1)
print_sv(result[model_][SV_], sv_names)
puts(1,"\n# Coin Tally #####\n")
? coin_tally
puts(1,"# Update List #####\n")
? result[model_][CU_]
puts(1,"\nA water has been dispensed by drink_reservoir, the price has been registered\n")
puts(1,"by change_calc and the button release has been registered by chosen\n")
puts(1,"\n\neighth iteration\n")
result = step_Model(result[model_], 1)
print_sv(result[model_][SV_], sv_names)
puts(1,"\n# Coin Tally #####\n")
? coin_tally
puts(1,"# Update List #####\n")
? result[model_][CU_]
puts(1,"\nA reset has been registered by coin_adder, the change has been dispensed\n")
puts(1,"by the coin_reservoir and a water is now present in the drink shute\n")
puts(1,"\n\nninth iteration\n")
result = step_Model(result[model_], 1)
print_sv(result[model_][SV_], sv_names)
puts(1,"\n# Coin Tally #####\n")
? coin_tally
puts(1,"# Update List #####\n")
? result[model_][CU_]
puts(1,"\nThe drink_reservoir has finished dispensing the drink, the price has been cleared\n")
puts(1,"from change_calc, the coin_total has been reset to zero and the change is now\n")
puts(1,"present in the change shute\n")
puts(1,"\n\ntenth iteration\n")
result = step_Model(result[model_], 1)
print_sv(result[model_][SV_], sv_names)
puts(1,"\n# Coin Tally #####\n")
? coin_tally
puts(1,"# Update List #####\n")
? result[model_][CU_]
puts(1,"\nThe availability vector has gone dormant (no money so none available), the reset\n")
puts(1,"coin_total has been registered by change_calc, the reset coin_total has been registered\n")
puts(1,"by coin_adder and the coin_reservoir has finished dispensing the change\n")
puts(1,"\n\neleventh iteration\n")
result = step_Model(result[model_], 1)
print_sv(result[model_][SV_], sv_names)
puts(1,"\n# Coin Tally #####\n")
? coin_tally
puts(1,"# Update List #####\n")
? result[model_][CU_]
puts(1,"\nThe Null availability vector has been registered\n")
puts(1,"by chosen and the lights have turned off\n")
puts(1,"\n\ntwelfth iteration\n")
result = step_Model(result[model_], 1)
print_sv(result[model_][SV_], sv_names)
puts(1,"\n# Coin Tally #####\n")
? coin_tally
puts(1,"# Update List #####\n")
? result[model_][CU_]
puts(1,"\nThe Drink Machine is now in a dormant state waiting for input,\n")
puts(1,"there is one less water in the inventory, one extra dollar coin\n")
puts(1,"and one less 20c coin in the coin_tally, one water in the drink shute\n")
puts(1,"and one 20c coin in the change shute.\n")
www.Anandavala.info