------------------------------------------ ------------------------------------------ ----- 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")