Dear Gethin,
Thank you very much for your response, I really appreciate the time you
took to respond!
You're right, my module was not counting the requests that were before
mine in the queue.
Following your description I came up with this module:
// Request arrives when there are J-1 requests in the queue, so needs
// to wait for J srv_x actions to be served. 0 < J <= Capacity
#for i=1:Cap#
module Processing#i#
processing#i# : bool init false;
count_#i# : [0 .. #i#] init #i#;
//// Clients drive these actions
/// Other request arrivals - ignore them.
[req1] (waiting!=#i#-1) -> 1 : true;
/// My arrival - start stopwatch.
[req1] (waiting =#i#-1) -> 1 : (processing#i#'=true) &
(count_#i#'=#i#);
//// Service providers drive these actions
#for j=1:s#
/// There's no processing for me - ignore.
[srv#j#] !(processing#i#) -> 1 : true;
/// There are still earlier requests waiting service - waiting.
[srv#j#] (processing#i#) & (count_#i# != 1) -> 1 :
(count_#i#'=max(0,count_#i#-1));
/// I am being served now - stop stopwatch.
[srv#j#] (processing#i#) & (count_#i# = 1) -> 1 :
(processing#i#'=false) & (count_#i#'=#i#);
#end#
endmodule
#end#
So there are K modules - one for each slot of the waiting queue (getting
the same result if I use just one of them and vary J externally).
When there are J-1 requests in the queue, a request sets signal
processingJ to true and count_J to J.
Then, while processingJ is true, each srv action reduces count_J.
I unset processingJ when count_J is equal to 1, since this is the
service of my request.
The property I'm then calculating is this one:
// Attempt at a generic Avg Resp. Time.
( 0.0 #for i=1:Cap# + ( (S=? [ (waiting=#i#) ]) * filter(avg,
R{"time"}=? [ S ], (processing#i#)) ) #end# )
So I add all the average times the system stays at a state where
processingJ is true, weighted by the probability there are J requests in
the queue.
For the case I'm testing (s=10,Cap=10,srvRate=11), the correct result is
0.090909091 for different values of the input rate (reqRate=50:10:100) -
the results I'm getting are far from that though... :-(
reqRate,Result
50,0.9893081518715127
60,0.9956181135207659
70,0.9981678841506308
80,0.9992120073301123
90,0.9996492594680785
100,0.9998378983125484
I'm at a loss as to where this is going wrong.
I don't understand why the numbers differ when the reqRate changes (they
should be the same), nor why they look like they're about (Cap+1) times
greater than the correct result.
Wonder whether I'm again doing something silly here... :-/
Commands used:
Capacity=10
srvRate=11
reqRateMin=50
reqRateMax=100
reqRateStp=10
servers=10
res=results
test -d ${res} || mkdir ${res}
prismpp ${model}.prism.pp ${servers} ${Capacity} >
${res}/${model}-${servers}.prism
prismpp properties-MMcK.props.pp ${servers} ${Capacity} >
${res}/properties.props
prop=4
prism \
-pgs \
-maxiters 10000 \
${res}/${model}-${servers}.prism \
${res}/properties.props \
-prop ${prop} \
-const
srvRate=${srvRate},reqRate=${reqRateMin}:${reqRateStp}:${reqRateMax} \
-exportresults ${res}/results.txt \
2>&1 \
| tee
${res}/${model}-${servers}-${prop}.log \
| egrep '(Error|^Model constants:|^Result)'
tr '\t' , < ${res}/results.txt > ${res}/${model}-${servers}-${prop}.csv
Best,
Christos
On 22/11/2017 15:17, Gethin Norman wrote:
> Christos,
>
> I am not sure I have followed what you have done but it does not look like you are tracking a single customer. What I was proposing was to calculate the waiting time for each possible arrival position in the queue through separate models and then average the results (based on the probability that the customer arrives at that position in the queue). I cannot see how it can be combined into a single module.
>
> For example, consider the case where customer arrives into the kth position in the queue. This will be the initial state for the corresponding model, so in the queue module you would need to set “waiting” to take k as its initial value. In addition to keep tack of this customers position add the module to record the time to respond:
>
> module Timing
>
> position : [0..k] init k;
>
> #for j=1:c#
> [srv#j#] (position>0) -> 1 : (position’=position-1);
> [srv#j#] (position=0) -> 1 : true; // just to prevent deadlocks in the model
>
> #end#
>
> endmodule
>
> Essentially, he customer moves up the queue as customers ahead in the queue are served and then when it reaches position 1 it is then served moving to position=0.
>
> The property of interest is (from the initial state) the expected time to reach a state where position=0 (this is the time for the customer to move through the queue and get served, i.e. the waiting and serving time).
>
> You would need to compute this for all possible values of k and then average based on the long run probability of arriving into the kth position into the queue.
>
> Does this make sense?
>
> thanks
>
> Gethin
>> <MMcK-right.prism.pp><properties.props.pp><expected-avg-resp-time.csv><MMcK-right-10-3.csv><MMcK-right-20-3.csv>