From b4ad182911add83f9c9c29f3e14c98de81e0fe94 Mon Sep 17 00:00:00 2001 From: TimQu Date: Sun, 12 Jun 2016 14:30:40 +0200 Subject: [PATCH] reorganized prism benchmark files a little Former-commit-id: d1b882bacd666d7bdb1af8a663ac081fcb284624 --- .../mdp/consensus/consensus2_3_2.nm | 88 +++ .../mdp/consensus/consensus2_4_2.nm | 114 ++++ .../mdp/consensus/consensus2_5_2.nm | 140 +++++ .../mdp/consensus/consensus3_3_2.nm | 100 ++++ .../mdp/consensus/consensus3_4_2.nm | 131 +++++ .../mdp/consensus/consensus3_5_2.nm | 162 ++++++ .../mdp/consensus/consensus_multi.pctl.1 | 27 - .../{ => origFiles}/consensus2_multi3.nm | 0 .../{ => origFiles}/consensus2_multi4.nm | 0 .../{ => origFiles}/consensus2_multi5.nm | 0 .../{ => origFiles}/consensus3_multi3.nm | 0 .../{ => origFiles}/consensus3_multi4.nm | 0 .../{ => origFiles}/consensus3_multi5.nm | 0 .../{ => origFiles}/consensus_multi.pctl | 0 examples/multi-objective/mdp/dpm/dpm100.nm | 160 ++++++ examples/multi-objective/mdp/dpm/dpm200.nm | 160 ++++++ examples/multi-objective/mdp/dpm/dpm300.nm | 160 ++++++ .../mdp/dpm/origFiles/power-timed.nm | 160 ++++++ .../mdp/dpm/origFiles/power-timed.pctl | 11 + .../scheduler/{ => origFiles}/scheduler.pctl | 0 .../{ => origFiles}/scheduler_prob2_K.nm | 0 .../mdp/scheduler/scheduler05.nm | 95 ++++ .../mdp/scheduler/scheduler25.nm | 95 ++++ .../mdp/scheduler/scheduler50.nm | 95 ++++ .../{ => origFiles}/MDP_a2_r3_t2_full_exp.nm | 0 .../team/origFiles/MDP_a3_r3_t2_full_exp.nm | 287 ++++++++++ .../team/origFiles/MDP_a4_r3_t2_full_exp.nm | 364 ++++++++++++ .../{ => origFiles}/MDP_a5_r3_t2_full_exp.nm | 0 .../mdp/team/{ => origFiles}/team.pctl | 0 .../multi-objective/mdp/team/team2obj_3.nm | 287 ++++++++++ .../multi-objective/mdp/team/team2obj_4.nm | 364 ++++++++++++ .../multi-objective/mdp/team/team2obj_5.nm | 531 ++++++++++++++++++ .../multi-objective/mdp/team/team3obj_3.nm | 287 ++++++++++ .../multi-objective/mdp/team/team3obj_4.nm | 364 ++++++++++++ .../multi-objective/mdp/team/team3obj_5.nm | 531 ++++++++++++++++++ .../origFiles/zeroconf_host_multi2_time.nm | 169 ++++++ .../origFiles/zeroconf_host_multi4_time.nm | 174 ++++++ .../origFiles/zeroconf_host_multi_time.pctl | 13 + .../mdp/zeroconf-tb/zeroconf-tb2_14.nm | 169 ++++++ .../mdp/zeroconf-tb/zeroconf-tb4_10.nm | 174 ++++++ .../mdp/zeroconf-tb/zeroconf-tb4_14.nm | 174 ++++++ .../{ => origFiles}/zeroconf_host_multi.pctl | 0 .../{ => origFiles}/zeroconf_host_multi2.nm | 0 .../{ => origFiles}/zeroconf_host_multi4.nm | 0 .../{ => origFiles}/zeroconf_host_multi6.nm | 0 .../{ => origFiles}/zeroconf_host_multi8.nm | 0 .../multi-objective/mdp/zeroconf/zeroconf4.nm | 153 +++++ .../multi-objective/mdp/zeroconf/zeroconf6.nm | 157 ++++++ .../multi-objective/mdp/zeroconf/zeroconf8.nm | 161 ++++++ 49 files changed, 6030 insertions(+), 27 deletions(-) create mode 100644 examples/multi-objective/mdp/consensus/consensus2_3_2.nm create mode 100644 examples/multi-objective/mdp/consensus/consensus2_4_2.nm create mode 100644 examples/multi-objective/mdp/consensus/consensus2_5_2.nm create mode 100644 examples/multi-objective/mdp/consensus/consensus3_3_2.nm create mode 100644 examples/multi-objective/mdp/consensus/consensus3_4_2.nm create mode 100644 examples/multi-objective/mdp/consensus/consensus3_5_2.nm delete mode 100644 examples/multi-objective/mdp/consensus/consensus_multi.pctl.1 rename examples/multi-objective/mdp/consensus/{ => origFiles}/consensus2_multi3.nm (100%) rename examples/multi-objective/mdp/consensus/{ => origFiles}/consensus2_multi4.nm (100%) rename examples/multi-objective/mdp/consensus/{ => origFiles}/consensus2_multi5.nm (100%) rename examples/multi-objective/mdp/consensus/{ => origFiles}/consensus3_multi3.nm (100%) rename examples/multi-objective/mdp/consensus/{ => origFiles}/consensus3_multi4.nm (100%) rename examples/multi-objective/mdp/consensus/{ => origFiles}/consensus3_multi5.nm (100%) rename examples/multi-objective/mdp/consensus/{ => origFiles}/consensus_multi.pctl (100%) create mode 100644 examples/multi-objective/mdp/dpm/dpm100.nm create mode 100644 examples/multi-objective/mdp/dpm/dpm200.nm create mode 100644 examples/multi-objective/mdp/dpm/dpm300.nm create mode 100644 examples/multi-objective/mdp/dpm/origFiles/power-timed.nm create mode 100644 examples/multi-objective/mdp/dpm/origFiles/power-timed.pctl rename examples/multi-objective/mdp/scheduler/{ => origFiles}/scheduler.pctl (100%) rename examples/multi-objective/mdp/scheduler/{ => origFiles}/scheduler_prob2_K.nm (100%) create mode 100644 examples/multi-objective/mdp/scheduler/scheduler05.nm create mode 100644 examples/multi-objective/mdp/scheduler/scheduler25.nm create mode 100644 examples/multi-objective/mdp/scheduler/scheduler50.nm rename examples/multi-objective/mdp/team/{ => origFiles}/MDP_a2_r3_t2_full_exp.nm (100%) create mode 100644 examples/multi-objective/mdp/team/origFiles/MDP_a3_r3_t2_full_exp.nm create mode 100644 examples/multi-objective/mdp/team/origFiles/MDP_a4_r3_t2_full_exp.nm rename examples/multi-objective/mdp/team/{ => origFiles}/MDP_a5_r3_t2_full_exp.nm (100%) rename examples/multi-objective/mdp/team/{ => origFiles}/team.pctl (100%) create mode 100644 examples/multi-objective/mdp/team/team2obj_3.nm create mode 100644 examples/multi-objective/mdp/team/team2obj_4.nm create mode 100644 examples/multi-objective/mdp/team/team2obj_5.nm create mode 100644 examples/multi-objective/mdp/team/team3obj_3.nm create mode 100644 examples/multi-objective/mdp/team/team3obj_4.nm create mode 100644 examples/multi-objective/mdp/team/team3obj_5.nm create mode 100644 examples/multi-objective/mdp/zeroconf-tb/origFiles/zeroconf_host_multi2_time.nm create mode 100644 examples/multi-objective/mdp/zeroconf-tb/origFiles/zeroconf_host_multi4_time.nm create mode 100644 examples/multi-objective/mdp/zeroconf-tb/origFiles/zeroconf_host_multi_time.pctl create mode 100644 examples/multi-objective/mdp/zeroconf-tb/zeroconf-tb2_14.nm create mode 100644 examples/multi-objective/mdp/zeroconf-tb/zeroconf-tb4_10.nm create mode 100644 examples/multi-objective/mdp/zeroconf-tb/zeroconf-tb4_14.nm rename examples/multi-objective/mdp/zeroconf/{ => origFiles}/zeroconf_host_multi.pctl (100%) rename examples/multi-objective/mdp/zeroconf/{ => origFiles}/zeroconf_host_multi2.nm (100%) rename examples/multi-objective/mdp/zeroconf/{ => origFiles}/zeroconf_host_multi4.nm (100%) rename examples/multi-objective/mdp/zeroconf/{ => origFiles}/zeroconf_host_multi6.nm (100%) rename examples/multi-objective/mdp/zeroconf/{ => origFiles}/zeroconf_host_multi8.nm (100%) create mode 100644 examples/multi-objective/mdp/zeroconf/zeroconf4.nm create mode 100644 examples/multi-objective/mdp/zeroconf/zeroconf6.nm create mode 100644 examples/multi-objective/mdp/zeroconf/zeroconf8.nm diff --git a/examples/multi-objective/mdp/consensus/consensus2_3_2.nm b/examples/multi-objective/mdp/consensus/consensus2_3_2.nm new file mode 100644 index 000000000..8b602a4d7 --- /dev/null +++ b/examples/multi-objective/mdp/consensus/consensus2_3_2.nm @@ -0,0 +1,88 @@ +// model of randomised consensus + +mdp + +const int N = 2; // num processes +const int MAX = 3; // num rounds (R) +const int K = 2; // Parameter for coins + +// need to turn these into local copies later so the reading phase is complete? +formula leaders_agree1 = (p1=1 | r1 (p1'=1) & (r1'=1); + [] s1=0 & r1=0 -> (p1'=2) & (r1'=1); + + // read registers (currently does nothing because read vs from other processes + [] s1=0 & r1>0 & r1<=MAX -> (s1'=1); + // maxke a decision + [] s1=1 & decide1 -> (s1'=4) & (p1'=1); + [] s1=1 & decide2 -> (s1'=4) & (p1'=2); + [] s1=1 & r1 (s1'=0) & (p1'=1) & (r1'=r1+1); + [] s1=1 & r1 (s1'=0) & (p1'=2) & (r1'=r1+1); + [] s1=1 & r1 (s1'=2) & (p1'=0); + [] s1=1 & r1=MAX & !(decide1 | decide2) -> (s1'=5); // run out of rounds so error + // enter the coin procotol for the current round + [coin1_s1_start] s1=2 & r1=1 -> (s1'=3); + [coin2_s1_start] s1=2 & r1=2 -> (s1'=3); + // get response from the coin protocol + [coin1_s1_p1] s1=3 & r1=1 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin1_s1_p2] s1=3 & r1=1 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + [coin2_s1_p1] s1=3 & r1=2 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin2_s1_p2] s1=3 & r1=2 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + // done so loop + [done] s1>=4 -> true; + +endmodule + +module process2 = process1[ s1=s2, + p1=p2,p2=p1, + r1=r2,r2=r1, + coin1_s1_start=coin1_s2_start,coin2_s1_start=coin2_s2_start, + coin1_s1_p1=coin1_s2_p1,coin2_s1_p1=coin2_s2_p1, + coin1_s1_p2=coin1_s2_p2,coin2_s1_p2=coin2_s2_p2 ] +endmodule + +module coin1_error + + c1 : [0..1]; // 1 is the error state + v1 : [0..2]; // value of the coin returned the first time + + // first returned value (any processes) + [coin1_s1_p1] v1=0 -> (v1'=1); + [coin1_s2_p1] v1=0 -> (v1'=1); + [coin1_s1_p2] v1=0 -> (v1'=2); + [coin1_s2_p2] v1=0 -> (v1'=2); + // later values returned + [coin1_s1_p1] v1=1 -> true; // good behaviour + [coin1_s2_p1] v1=1 -> true; // good behaviour + [coin1_s1_p2] v1=2 -> true; // good behaviour + [coin1_s2_p2] v1=2 -> true; // good behaviour + [coin1_s1_p1] v1=2 -> (c1'=1); // error + [coin1_s2_p1] v1=2 -> (c1'=1); // error + [coin1_s1_p2] v1=1 -> (c1'=1); // error + [coin1_s2_p2] v1=1 -> (c1'=1); // error + +endmodule + +// coins 2 and 3 are of no use as there are not enough rounds afterwards to decide + +// Labels +label "one_proc_err" = (s1=5 | s2=5); +label "one_coin_ok" = (c1=0); diff --git a/examples/multi-objective/mdp/consensus/consensus2_4_2.nm b/examples/multi-objective/mdp/consensus/consensus2_4_2.nm new file mode 100644 index 000000000..02724ba6e --- /dev/null +++ b/examples/multi-objective/mdp/consensus/consensus2_4_2.nm @@ -0,0 +1,114 @@ +// model of randomised consensus + +mdp + +const int N = 2; // num processes +const int MAX = 4; // num rounds (R) +const int K = 2; // Parameter for coins + +// need to turn these into local copies later so the reading phase is complete? +formula leaders_agree1 = (p1=1 | r1 (p1'=1) & (r1'=1); + [] s1=0 & r1=0 -> (p1'=2) & (r1'=1); + + // read registers (currently does nothing because read vs from other processes + [] s1=0 & r1>0 & r1<=MAX -> (s1'=1); + // maxke a decision + [] s1=1 & decide1 -> (s1'=4) & (p1'=1); + [] s1=1 & decide2 -> (s1'=4) & (p1'=2); + [] s1=1 & r1 (s1'=0) & (p1'=1) & (r1'=r1+1); + [] s1=1 & r1 (s1'=0) & (p1'=2) & (r1'=r1+1); + [] s1=1 & r1 (s1'=2) & (p1'=0); + [] s1=1 & r1=MAX & !(decide1 | decide2) -> (s1'=5); // run out of rounds so error + // enter the coin procotol for the current round + [coin1_s1_start] s1=2 & r1=1 -> (s1'=3); + [coin2_s1_start] s1=2 & r1=2 -> (s1'=3); + [coin3_s1_start] s1=2 & r1=3 -> (s1'=3); + // get response from the coin protocol + [coin1_s1_p1] s1=3 & r1=1 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin1_s1_p2] s1=3 & r1=1 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + [coin2_s1_p1] s1=3 & r1=2 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin2_s1_p2] s1=3 & r1=2 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + [coin3_s1_p1] s1=3 & r1=3 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin3_s1_p2] s1=3 & r1=3 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + // done so loop + [done] s1>=4 -> true; + +endmodule + +module process2 = process1[ s1=s2, + p1=p2,p2=p1, + r1=r2,r2=r1, + coin1_s1_start=coin1_s2_start,coin2_s1_start=coin2_s2_start,coin3_s1_start=coin3_s2_start, + coin1_s1_p1=coin1_s2_p1,coin2_s1_p1=coin2_s2_p1,coin3_s1_p1=coin3_s2_p1, + coin1_s1_p2=coin1_s2_p2,coin2_s1_p2=coin2_s2_p2,coin3_s1_p2=coin3_s2_p2 ] +endmodule + +module coin1_error + + c1 : [0..1]; // 1 is the error state + v1 : [0..2]; // value of the coin returned the first time + + // first returned value (any processes) + [coin1_s1_p1] v1=0 -> (v1'=1); + [coin1_s2_p1] v1=0 -> (v1'=1); + [coin1_s1_p2] v1=0 -> (v1'=2); + [coin1_s2_p2] v1=0 -> (v1'=2); + // later values returned + [coin1_s1_p1] v1=1 -> true; // good behaviour + [coin1_s2_p1] v1=1 -> true; // good behaviour + [coin1_s1_p2] v1=2 -> true; // good behaviour + [coin1_s2_p2] v1=2 -> true; // good behaviour + [coin1_s1_p1] v1=2 -> (c1'=1); // error + [coin1_s2_p1] v1=2 -> (c1'=1); // error + [coin1_s1_p2] v1=1 -> (c1'=1); // error + [coin1_s2_p2] v1=1 -> (c1'=1); // error + +endmodule + +// could do with renaming +module coin2_error + + c2 : [0..1]; // 1 is the error state + v2 : [0..2]; // value of the coin returned the first time + + // first returned value (any processes) + [coin2_s1_p1] v2=0 -> (v2'=1); + [coin2_s2_p1] v2=0 -> (v2'=1); + [coin2_s1_p2] v2=0 -> (v2'=2); + [coin2_s2_p2] v2=0 -> (v2'=2); + // later values returned + [coin2_s1_p1] v2=1 -> true; // good behaviour + [coin2_s2_p1] v2=1 -> true; // good behaviour + [coin2_s1_p2] v2=2 -> true; // good behaviour + [coin2_s2_p2] v2=2 -> true; // good behaviour + [coin2_s1_p1] v2=2 -> (c2'=1); // error + [coin2_s2_p1] v2=2 -> (c2'=1); // error + [coin2_s1_p2] v2=1 -> (c2'=1); // error + [coin2_s2_p2] v2=1 -> (c2'=1); // error + +endmodule + +// coin 3 is of no use because of number of rounds + +// Labels +label "one_proc_err" = (s1=5 | s2=5); +label "one_coin_ok" = (c1=0 | c2=0); diff --git a/examples/multi-objective/mdp/consensus/consensus2_5_2.nm b/examples/multi-objective/mdp/consensus/consensus2_5_2.nm new file mode 100644 index 000000000..288579d38 --- /dev/null +++ b/examples/multi-objective/mdp/consensus/consensus2_5_2.nm @@ -0,0 +1,140 @@ +// model of randomised consensus + +mdp + +const int N = 2; // num processes +const int MAX = 5; // num rounds (R) +const int K = 2; // Parameter for coins + +// need to turn these into local copies later so the reading phase is complete? +formula leaders_agree1 = (p1=1 | r1 (p1'=1) & (r1'=1); + [] s1=0 & r1=0 -> (p1'=2) & (r1'=1); + + // read registers (currently does nothing because read vs from other processes + [] s1=0 & r1>0 & r1<=MAX -> (s1'=1); + // maxke a decision + [] s1=1 & decide1 -> (s1'=4) & (p1'=1); + [] s1=1 & decide2 -> (s1'=4) & (p1'=2); + [] s1=1 & r1 (s1'=0) & (p1'=1) & (r1'=r1+1); + [] s1=1 & r1 (s1'=0) & (p1'=2) & (r1'=r1+1); + [] s1=1 & r1 (s1'=2) & (p1'=0); + [] s1=1 & r1=MAX & !(decide1 | decide2) -> (s1'=5); // run out of rounds so error + // enter the coin procotol for the current round + [coin1_s1_start] s1=2 & r1=1 -> (s1'=3); + [coin2_s1_start] s1=2 & r1=2 -> (s1'=3); + [coin3_s1_start] s1=2 & r1=3 -> (s1'=3); + [coin4_s1_start] s1=2 & r1=4 -> (s1'=3); + // get response from the coin protocol + [coin1_s1_p1] s1=3 & r1=1 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin1_s1_p2] s1=3 & r1=1 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + [coin2_s1_p1] s1=3 & r1=2 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin2_s1_p2] s1=3 & r1=2 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + [coin3_s1_p1] s1=3 & r1=3 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin3_s1_p2] s1=3 & r1=3 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + [coin4_s1_p1] s1=3 & r1=4 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin4_s1_p2] s1=3 & r1=4 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + // done so loop + [done] s1>=4 -> true; + +endmodule + +module process2 = process1[ s1=s2, + p1=p2,p2=p1, + r1=r2,r2=r1, + coin1_s1_start=coin1_s2_start,coin2_s1_start=coin2_s2_start,coin3_s1_start=coin3_s2_start,coin4_s1_start=coin4_s2_start, + coin1_s1_p1=coin1_s2_p1,coin2_s1_p1=coin2_s2_p1,coin3_s1_p1=coin3_s2_p1,coin4_s1_p1=coin4_s2_p1, + coin1_s1_p2=coin1_s2_p2,coin2_s1_p2=coin2_s2_p2,coin3_s1_p2=coin3_s2_p2,coin4_s1_p2=coin4_s2_p2 ] +endmodule + +module coin1_error + + c1 : [0..1]; // 1 is the error state + v1 : [0..2]; // value of the coin returned the first time + + // first returned value (any processes) + [coin1_s1_p1] v1=0 -> (v1'=1); + [coin1_s2_p1] v1=0 -> (v1'=1); + [coin1_s1_p2] v1=0 -> (v1'=2); + [coin1_s2_p2] v1=0 -> (v1'=2); + // later values returned + [coin1_s1_p1] v1=1 -> true; // good behaviour + [coin1_s2_p1] v1=1 -> true; // good behaviour + [coin1_s1_p2] v1=2 -> true; // good behaviour + [coin1_s2_p2] v1=2 -> true; // good behaviour + [coin1_s1_p1] v1=2 -> (c1'=1); // error + [coin1_s2_p1] v1=2 -> (c1'=1); // error + [coin1_s1_p2] v1=1 -> (c1'=1); // error + [coin1_s2_p2] v1=1 -> (c1'=1); // error + +endmodule + +// could do with renaming +module coin2_error + + c2 : [0..1]; // 1 is the error state + v2 : [0..2]; // value of the coin returned the first time + + // first returned value (any processes) + [coin2_s1_p1] v2=0 -> (v2'=1); + [coin2_s2_p1] v2=0 -> (v2'=1); + [coin2_s1_p2] v2=0 -> (v2'=2); + [coin2_s2_p2] v2=0 -> (v2'=2); + // later values returned + [coin2_s1_p1] v2=1 -> true; // good behaviour + [coin2_s2_p1] v2=1 -> true; // good behaviour + [coin2_s1_p2] v2=2 -> true; // good behaviour + [coin2_s2_p2] v2=2 -> true; // good behaviour + [coin2_s1_p1] v2=2 -> (c2'=1); // error + [coin2_s2_p1] v2=2 -> (c2'=1); // error + [coin2_s1_p2] v2=1 -> (c2'=1); // error + [coin2_s2_p2] v2=1 -> (c2'=1); // error + +endmodule + +// could do with renaming +module coin3_error + + c3 : [0..1]; // 1 is the error state + v3 : [0..2]; // value of the coin returned the first time + + // first returned value (any processes) + [coin3_s1_p1] v3=0 -> (v3'=1); + [coin3_s2_p1] v3=0 -> (v3'=1); + [coin3_s1_p2] v3=0 -> (v3'=2); + [coin3_s2_p2] v3=0 -> (v3'=2); + // later values returned + [coin3_s1_p1] v3=1 -> true; // good behaviour + [coin3_s2_p1] v3=1 -> true; // good behaviour + [coin3_s1_p2] v3=2 -> true; // good behaviour + [coin3_s2_p2] v3=2 -> true; // good behaviour + [coin3_s1_p1] v3=2 -> (c3'=1); // error + [coin3_s2_p1] v3=2 -> (c3'=1); // error + [coin3_s1_p2] v3=1 -> (c3'=1); // error + [coin3_s2_p2] v3=1 -> (c3'=1); // error + +endmodule + +// coin 4 is of no use because of number of rounds + +// Labels +label "one_proc_err" = (s1=5 | s2=5); +label "one_coin_ok" = (c1=0 | c2=0 | c3=0); diff --git a/examples/multi-objective/mdp/consensus/consensus3_3_2.nm b/examples/multi-objective/mdp/consensus/consensus3_3_2.nm new file mode 100644 index 000000000..a7f06fbdf --- /dev/null +++ b/examples/multi-objective/mdp/consensus/consensus3_3_2.nm @@ -0,0 +1,100 @@ +// model of randomised consensus + +mdp + +const int N = 3; // num processes +const int MAX = 3; // num rounds (R) +const int K = 2; // Parameter for coins + +// need to turn these into local copies later so the reading phase is complete? +formula leaders_agree1 = (p1=1 | r1 (p1'=1) & (r1'=1); + [] s1=0 & r1=0 -> (p1'=2) & (r1'=1); + + // read registers (currently does nothing because read vs from other processes + [] s1=0 & r1>0 & r1<=MAX -> (s1'=1); + // maxke a decision + [] s1=1 & decide1 -> (s1'=4) & (p1'=1); + [] s1=1 & decide2 -> (s1'=4) & (p1'=2); + [] s1=1 & r1 (s1'=0) & (p1'=1) & (r1'=r1+1); + [] s1=1 & r1 (s1'=0) & (p1'=2) & (r1'=r1+1); + [] s1=1 & r1 (s1'=2) & (p1'=0); + [] s1=1 & r1=MAX & !(decide1 | decide2) -> (s1'=5); // run out of rounds so error + // enter the coin procotol for the current round + [coin1_s1_start] s1=2 & r1=1 -> (s1'=3); + [coin2_s1_start] s1=2 & r1=2 -> (s1'=3); + // get response from the coin protocol + [coin1_s1_p1] s1=3 & r1=1 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin1_s1_p2] s1=3 & r1=1 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + [coin2_s1_p1] s1=3 & r1=2 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin2_s1_p2] s1=3 & r1=2 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + // done so loop + [done] s1>=4 -> true; + +endmodule + +module process2 = process1[ s1=s2, + p1=p2,p2=p3,p3=p1, + r1=r2,r2=r3,r3=r1, + coin1_s1_start=coin1_s2_start,coin2_s1_start=coin2_s2_start, + coin1_s1_p1=coin1_s2_p1,coin2_s1_p1=coin2_s2_p1, + coin1_s1_p2=coin1_s2_p2,coin2_s1_p2=coin2_s2_p2 ] +endmodule + +module process3 = process1[ s1=s3, + p1=p3,p2=p1,p3=p2, + r1=r3,r2=r1,r3=r2, + coin1_s1_start=coin1_s3_start,coin2_s1_start=coin2_s3_start, + coin1_s1_p1=coin1_s3_p1,coin2_s1_p1=coin2_s3_p1, + coin1_s1_p2=coin1_s3_p2,coin2_s1_p2=coin2_s3_p2 ] +endmodule + +module coin1_error + + c1 : [0..1]; // 1 is the error state + v1 : [0..2]; // value of the coin returned the first time + + // first returned value (any processes) + [coin1_s1_p1] v1=0 -> (v1'=1); + [coin1_s2_p1] v1=0 -> (v1'=1); + [coin1_s3_p1] v1=0 -> (v1'=1); + [coin1_s1_p2] v1=0 -> (v1'=2); + [coin1_s2_p2] v1=0 -> (v1'=2); + [coin1_s3_p2] v1=0 -> (v1'=2); + // later values returned + [coin1_s1_p1] v1=1 -> true; // good behaviour + [coin1_s2_p1] v1=1 -> true; // good behaviour + [coin1_s3_p1] v1=1 -> true; // good behaviour + [coin1_s1_p2] v1=2 -> true; // good behaviour + [coin1_s2_p2] v1=2 -> true; // good behaviour + [coin1_s3_p2] v1=2 -> true; // good behaviour + [coin1_s1_p1] v1=2 -> (c1'=1); // error + [coin1_s2_p1] v1=2 -> (c1'=1); // error + [coin1_s3_p1] v1=2 -> (c1'=1); // error + [coin1_s1_p2] v1=1 -> (c1'=1); // error + [coin1_s2_p2] v1=1 -> (c1'=1); // error + [coin1_s3_p2] v1=1 -> (c1'=1); // error + +endmodule + +// Labels +label "one_proc_err" = (s1=5 | s2=5 | s3=5); +label "one_coin_ok" = (c1=0); diff --git a/examples/multi-objective/mdp/consensus/consensus3_4_2.nm b/examples/multi-objective/mdp/consensus/consensus3_4_2.nm new file mode 100644 index 000000000..abfc0ed1e --- /dev/null +++ b/examples/multi-objective/mdp/consensus/consensus3_4_2.nm @@ -0,0 +1,131 @@ +// model of randomised consensus + +mdp + +const int N = 3; // num processes +const int MAX = 4; // num rounds (R) +const int K = 2; // Parameter for coins + +// need to turn these into local copies later so the reading phase is complete? +formula leaders_agree1 = (p1=1 | r1 (p1'=1) & (r1'=1); + [] s1=0 & r1=0 -> (p1'=2) & (r1'=1); + + // read registers (currently does nothing because read vs from other processes + [] s1=0 & r1>0 & r1<=MAX -> (s1'=1); + // maxke a decision + [] s1=1 & decide1 -> (s1'=4) & (p1'=1); + [] s1=1 & decide2 -> (s1'=4) & (p1'=2); + [] s1=1 & r1 (s1'=0) & (p1'=1) & (r1'=r1+1); + [] s1=1 & r1 (s1'=0) & (p1'=2) & (r1'=r1+1); + [] s1=1 & r1 (s1'=2) & (p1'=0); + [] s1=1 & r1=MAX & !(decide1 | decide2) -> (s1'=5); // run out of rounds so error + // enter the coin procotol for the current round + [coin1_s1_start] s1=2 & r1=1 -> (s1'=3); + [coin2_s1_start] s1=2 & r1=2 -> (s1'=3); + [coin3_s1_start] s1=2 & r1=3 -> (s1'=3); + // get response from the coin protocol + [coin1_s1_p1] s1=3 & r1=1 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin1_s1_p2] s1=3 & r1=1 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + [coin2_s1_p1] s1=3 & r1=2 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin2_s1_p2] s1=3 & r1=2 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + [coin3_s1_p1] s1=3 & r1=3 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin3_s1_p2] s1=3 & r1=3 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + // done so loop + [done] s1>=4 -> true; + +endmodule + +module process2 = process1[ s1=s2, + p1=p2,p2=p3,p3=p1, + r1=r2,r2=r3,r3=r1, + coin1_s1_start=coin1_s2_start,coin2_s1_start=coin2_s2_start,coin3_s1_start=coin3_s2_start, + coin1_s1_p1=coin1_s2_p1,coin2_s1_p1=coin2_s2_p1,coin3_s1_p1=coin3_s2_p1, + coin1_s1_p2=coin1_s2_p2,coin2_s1_p2=coin2_s2_p2,coin3_s1_p2=coin3_s2_p2 ] +endmodule + +module process3 = process1[ s1=s3, + p1=p3,p2=p1,p3=p2, + r1=r3,r2=r1,r3=r2, + coin1_s1_start=coin1_s3_start,coin2_s1_start=coin2_s3_start,coin3_s1_start=coin3_s3_start, + coin1_s1_p1=coin1_s3_p1,coin2_s1_p1=coin2_s3_p1,coin3_s1_p1=coin3_s3_p1, + coin1_s1_p2=coin1_s3_p2,coin2_s1_p2=coin2_s3_p2,coin3_s1_p2=coin3_s3_p2 ] +endmodule + +module coin1_error + + c1 : [0..1]; // 1 is the error state + v1 : [0..2]; // value of the coin returned the first time + + // first returned value (any processes) + [coin1_s1_p1] v1=0 -> (v1'=1); + [coin1_s2_p1] v1=0 -> (v1'=1); + [coin1_s3_p1] v1=0 -> (v1'=1); + [coin1_s1_p2] v1=0 -> (v1'=2); + [coin1_s2_p2] v1=0 -> (v1'=2); + [coin1_s3_p2] v1=0 -> (v1'=2); + // later values returned + [coin1_s1_p1] v1=1 -> true; // good behaviour + [coin1_s2_p1] v1=1 -> true; // good behaviour + [coin1_s3_p1] v1=1 -> true; // good behaviour + [coin1_s1_p2] v1=2 -> true; // good behaviour + [coin1_s2_p2] v1=2 -> true; // good behaviour + [coin1_s3_p2] v1=2 -> true; // good behaviour + [coin1_s1_p1] v1=2 -> (c1'=1); // error + [coin1_s2_p1] v1=2 -> (c1'=1); // error + [coin1_s3_p1] v1=2 -> (c1'=1); // error + [coin1_s1_p2] v1=1 -> (c1'=1); // error + [coin1_s2_p2] v1=1 -> (c1'=1); // error + [coin1_s3_p2] v1=1 -> (c1'=1); // error + +endmodule + +module coin2_error + + c2 : [0..1]; // 1 is the error state + v2 : [0..2]; // value of the coin returned the first time + + // first returned value (any processes) + [coin2_s1_p1] v2=0 -> (v2'=1); + [coin2_s2_p1] v2=0 -> (v2'=1); + [coin2_s3_p1] v2=0 -> (v2'=1); + [coin2_s1_p2] v2=0 -> (v2'=2); + [coin2_s2_p2] v2=0 -> (v2'=2); + [coin2_s3_p2] v2=0 -> (v2'=2); + // later values returned + [coin2_s1_p1] v2=1 -> true; // good behaviour + [coin2_s2_p1] v2=1 -> true; // good behaviour + [coin2_s3_p1] v2=1 -> true; // good behaviour + [coin2_s1_p2] v2=2 -> true; // good behaviour + [coin2_s2_p2] v2=2 -> true; // good behaviour + [coin2_s3_p2] v2=2 -> true; // good behaviour + [coin2_s1_p1] v2=2 -> (c2'=1); // error + [coin2_s2_p1] v2=2 -> (c2'=1); // error + [coin2_s3_p1] v2=2 -> (c2'=1); // error + [coin2_s1_p2] v2=1 -> (c2'=1); // error + [coin2_s2_p2] v2=1 -> (c2'=1); // error + [coin2_s3_p2] v2=1 -> (c2'=1); // error + +endmodule + +// Labels +label "one_proc_err" = (s1=5 | s2=5 | s3=5); +label "one_coin_ok" = (c1=0 | c2=0); diff --git a/examples/multi-objective/mdp/consensus/consensus3_5_2.nm b/examples/multi-objective/mdp/consensus/consensus3_5_2.nm new file mode 100644 index 000000000..cc9a7ebbf --- /dev/null +++ b/examples/multi-objective/mdp/consensus/consensus3_5_2.nm @@ -0,0 +1,162 @@ +// model of randomised consensus + +mdp + +const int N = 3; // num processes +const int MAX = 5; // num rounds (R) +const int K = 2; // Parameter for coins + +// need to turn these into local copies later so the reading phase is complete? +formula leaders_agree1 = (p1=1 | r1 (p1'=1) & (r1'=1); + [] s1=0 & r1=0 -> (p1'=2) & (r1'=1); + + // read registers (currently does nothing because read vs from other processes + [] s1=0 & r1>0 & r1<=MAX -> (s1'=1); + // maxke a decision + [] s1=1 & decide1 -> (s1'=4) & (p1'=1); + [] s1=1 & decide2 -> (s1'=4) & (p1'=2); + [] s1=1 & r1 (s1'=0) & (p1'=1) & (r1'=r1+1); + [] s1=1 & r1 (s1'=0) & (p1'=2) & (r1'=r1+1); + [] s1=1 & r1 (s1'=2) & (p1'=0); + [] s1=1 & r1=MAX & !(decide1 | decide2) -> (s1'=5); // run out of rounds so error + // enter the coin procotol for the current round + [coin1_s1_start] s1=2 & r1=1 -> (s1'=3); + [coin2_s1_start] s1=2 & r1=2 -> (s1'=3); + [coin3_s1_start] s1=2 & r1=3 -> (s1'=3); + [coin4_s1_start] s1=2 & r1=4 -> (s1'=3); + // get response from the coin protocol + [coin1_s1_p1] s1=3 & r1=1 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin1_s1_p2] s1=3 & r1=1 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + [coin2_s1_p1] s1=3 & r1=2 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin2_s1_p2] s1=3 & r1=2 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + [coin3_s1_p1] s1=3 & r1=3 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin3_s1_p2] s1=3 & r1=3 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + [coin4_s1_p1] s1=3 & r1=4 -> (s1'=0) & (p1'=1) & (r1'=r1+1); + [coin4_s1_p2] s1=3 & r1=4 -> (s1'=0) & (p1'=2) & (r1'=r1+1); + // done so loop + [done] s1>=4 -> true; + +endmodule + +module process2 = process1[ s1=s2, + p1=p2,p2=p3,p3=p1, + r1=r2,r2=r3,r3=r1, + coin1_s1_start=coin1_s2_start,coin2_s1_start=coin2_s2_start,coin3_s1_start=coin3_s2_start,coin4_s1_start=coin4_s2_start, + coin1_s1_p1=coin1_s2_p1,coin2_s1_p1=coin2_s2_p1,coin3_s1_p1=coin3_s2_p1,coin4_s1_p1=coin4_s2_p1, + coin1_s1_p2=coin1_s2_p2,coin2_s1_p2=coin2_s2_p2,coin3_s1_p2=coin3_s2_p2,coin4_s1_p2=coin4_s2_p2 ] +endmodule + +module process3 = process1[ s1=s3, + p1=p3,p2=p1,p3=p2, + r1=r3,r2=r1,r3=r2, + coin1_s1_start=coin1_s3_start,coin2_s1_start=coin2_s3_start,coin3_s1_start=coin3_s3_start,coin4_s1_start=coin4_s3_start, + coin1_s1_p1=coin1_s3_p1,coin2_s1_p1=coin2_s3_p1,coin3_s1_p1=coin3_s3_p1,coin4_s1_p1=coin4_s3_p1, + coin1_s1_p2=coin1_s3_p2,coin2_s1_p2=coin2_s3_p2,coin3_s1_p2=coin3_s3_p2,coin4_s1_p2=coin4_s3_p2 ] +endmodule + +module coin1_error + + c1 : [0..1]; // 1 is the error state + v1 : [0..2]; // value of the coin returned the first time + + // first returned value (any processes) + [coin1_s1_p1] v1=0 -> (v1'=1); + [coin1_s2_p1] v1=0 -> (v1'=1); + [coin1_s3_p1] v1=0 -> (v1'=1); + [coin1_s1_p2] v1=0 -> (v1'=2); + [coin1_s2_p2] v1=0 -> (v1'=2); + [coin1_s3_p2] v1=0 -> (v1'=2); + // later values returned + [coin1_s1_p1] v1=1 -> true; // good behaviour + [coin1_s2_p1] v1=1 -> true; // good behaviour + [coin1_s3_p1] v1=1 -> true; // good behaviour + [coin1_s1_p2] v1=2 -> true; // good behaviour + [coin1_s2_p2] v1=2 -> true; // good behaviour + [coin1_s3_p2] v1=2 -> true; // good behaviour + [coin1_s1_p1] v1=2 -> (c1'=1); // error + [coin1_s2_p1] v1=2 -> (c1'=1); // error + [coin1_s3_p1] v1=2 -> (c1'=1); // error + [coin1_s1_p2] v1=1 -> (c1'=1); // error + [coin1_s2_p2] v1=1 -> (c1'=1); // error + [coin1_s3_p2] v1=1 -> (c1'=1); // error + +endmodule + +module coin2_error + + c2 : [0..1]; // 1 is the error state + v2 : [0..2]; // value of the coin returned the first time + + // first returned value (any processes) + [coin2_s1_p1] v2=0 -> (v2'=1); + [coin2_s2_p1] v2=0 -> (v2'=1); + [coin2_s3_p1] v2=0 -> (v2'=1); + [coin2_s1_p2] v2=0 -> (v2'=2); + [coin2_s2_p2] v2=0 -> (v2'=2); + [coin2_s3_p2] v2=0 -> (v2'=2); + // later values returned + [coin2_s1_p1] v2=1 -> true; // good behaviour + [coin2_s2_p1] v2=1 -> true; // good behaviour + [coin2_s3_p1] v2=1 -> true; // good behaviour + [coin2_s1_p2] v2=2 -> true; // good behaviour + [coin2_s2_p2] v2=2 -> true; // good behaviour + [coin2_s3_p2] v2=2 -> true; // good behaviour + [coin2_s1_p1] v2=2 -> (c2'=1); // error + [coin2_s2_p1] v2=2 -> (c2'=1); // error + [coin2_s3_p1] v2=2 -> (c2'=1); // error + [coin2_s1_p2] v2=1 -> (c2'=1); // error + [coin2_s2_p2] v2=1 -> (c2'=1); // error + [coin2_s3_p2] v2=1 -> (c2'=1); // error + +endmodule + +module coin3_error + + c3 : [0..1]; // 1 is the error state + v3 : [0..2]; // value of the coin returned the first time + + // first returned value (any processes) + [coin3_s1_p1] v3=0 -> (v3'=1); + [coin3_s2_p1] v3=0 -> (v3'=1); + [coin3_s3_p1] v3=0 -> (v3'=1); + [coin3_s1_p2] v3=0 -> (v3'=2); + [coin3_s2_p2] v3=0 -> (v3'=2); + [coin3_s3_p2] v3=0 -> (v3'=2); + // later values returned + [coin3_s1_p1] v3=1 -> true; // good behaviour + [coin3_s2_p1] v3=1 -> true; // good behaviour + [coin3_s3_p1] v3=1 -> true; // good behaviour + [coin3_s1_p2] v3=2 -> true; // good behaviour + [coin3_s2_p2] v3=2 -> true; // good behaviour + [coin3_s3_p2] v3=2 -> true; // good behaviour + [coin3_s1_p1] v3=2 -> (c3'=1); // error + [coin3_s2_p1] v3=2 -> (c3'=1); // error + [coin3_s3_p1] v3=2 -> (c3'=1); // error + [coin3_s1_p2] v3=1 -> (c3'=1); // error + [coin3_s2_p2] v3=1 -> (c3'=1); // error + [coin3_s3_p2] v3=1 -> (c3'=1); // error + +endmodule + +// Labels +label "one_proc_err" = (s1=5 | s2=5 | s3=5); +label "one_coin_ok" = (c1=0 | c2=0 | c3=0); diff --git a/examples/multi-objective/mdp/consensus/consensus_multi.pctl.1 b/examples/multi-objective/mdp/consensus/consensus_multi.pctl.1 deleted file mode 100644 index 7a5f12b31..000000000 --- a/examples/multi-objective/mdp/consensus/consensus_multi.pctl.1 +++ /dev/null @@ -1,27 +0,0 @@ -// Parameter K for coins -const int K; - -// Max probability of component (coins) violating assumption property (checked separately) -const double p_coin_fail = -N=2 ? ( - K=2 ? 0.10833260973166493 : - K=12 ? 0.04164301267240658 : - K=20 ? 0.01249126244810821 : -0 ) : -N=3 ? ( - K=2 ? 0.22908875545788154 : - K=4 ? 0.12450138796380239 : - K=8 ? 0.06248479880890645 : - K=12 ? 0.04164365757451993 : - K=16 ? 0.031218839562495382 : - K=20 ? 0.024960596483605935 : -0 ) : 0; - -// Probability bound for assumption, derived from above -const double p_one_coin_ok = 1 - pow(p_coin_fail, MAX-2); - -// Assume-guarantee check via multi-objective (using ASYM rule) -"num_ag": multi(Pmax=? [ F "one_proc_err" ], P>=p_one_coin_ok [ G "one_coin_ok" ]) - -// Pareto query for assume-guarantee check -"pareto": multi(Pmax=? [ F "one_proc_err" ], Pmax=? [ G "one_coin_ok" ]) diff --git a/examples/multi-objective/mdp/consensus/consensus2_multi3.nm b/examples/multi-objective/mdp/consensus/origFiles/consensus2_multi3.nm similarity index 100% rename from examples/multi-objective/mdp/consensus/consensus2_multi3.nm rename to examples/multi-objective/mdp/consensus/origFiles/consensus2_multi3.nm diff --git a/examples/multi-objective/mdp/consensus/consensus2_multi4.nm b/examples/multi-objective/mdp/consensus/origFiles/consensus2_multi4.nm similarity index 100% rename from examples/multi-objective/mdp/consensus/consensus2_multi4.nm rename to examples/multi-objective/mdp/consensus/origFiles/consensus2_multi4.nm diff --git a/examples/multi-objective/mdp/consensus/consensus2_multi5.nm b/examples/multi-objective/mdp/consensus/origFiles/consensus2_multi5.nm similarity index 100% rename from examples/multi-objective/mdp/consensus/consensus2_multi5.nm rename to examples/multi-objective/mdp/consensus/origFiles/consensus2_multi5.nm diff --git a/examples/multi-objective/mdp/consensus/consensus3_multi3.nm b/examples/multi-objective/mdp/consensus/origFiles/consensus3_multi3.nm similarity index 100% rename from examples/multi-objective/mdp/consensus/consensus3_multi3.nm rename to examples/multi-objective/mdp/consensus/origFiles/consensus3_multi3.nm diff --git a/examples/multi-objective/mdp/consensus/consensus3_multi4.nm b/examples/multi-objective/mdp/consensus/origFiles/consensus3_multi4.nm similarity index 100% rename from examples/multi-objective/mdp/consensus/consensus3_multi4.nm rename to examples/multi-objective/mdp/consensus/origFiles/consensus3_multi4.nm diff --git a/examples/multi-objective/mdp/consensus/consensus3_multi5.nm b/examples/multi-objective/mdp/consensus/origFiles/consensus3_multi5.nm similarity index 100% rename from examples/multi-objective/mdp/consensus/consensus3_multi5.nm rename to examples/multi-objective/mdp/consensus/origFiles/consensus3_multi5.nm diff --git a/examples/multi-objective/mdp/consensus/consensus_multi.pctl b/examples/multi-objective/mdp/consensus/origFiles/consensus_multi.pctl similarity index 100% rename from examples/multi-objective/mdp/consensus/consensus_multi.pctl rename to examples/multi-objective/mdp/consensus/origFiles/consensus_multi.pctl diff --git a/examples/multi-objective/mdp/dpm/dpm100.nm b/examples/multi-objective/mdp/dpm/dpm100.nm new file mode 100644 index 000000000..0862cfb73 --- /dev/null +++ b/examples/multi-objective/mdp/dpm/dpm100.nm @@ -0,0 +1,160 @@ +// power manager example +mdp + +const int QMAX =2; // max queue size + +// to model the pm making a choice and then a move being made we need +// two clock ticks for each transition +// first the pm decides tick1 and then the system moves tick2 + +module timer + + c : [0..1]; + + [tick1] c=0 -> (c'=1); + [tick2] c=1 -> (c'=0); + +endmodule + +//------------------------------------------------------------------------- + +// POWER MANAGER +module PM + + pm : [0..4] init 4; + // 0 - go to active + // 1 - go to idle + // 2 - go to idlelp + // 3 - go to stby + // 4 - go to sleep + + [tick1] true -> (pm'=0); + [tick1] true -> (pm'=1); + [tick1] true -> (pm'=2); + [tick1] true -> (pm'=3); + [tick1] true -> (pm'=4); + +endmodule + + +//------------------------------------------------------------------------- + +// SERVICE REQUESTER +module SR + + sr : [0..1] init 0; + // 0 idle + // 1 1req + + [tick2] sr=0 -> 0.898: (sr'=0) + 0.102: (sr'=1); + [tick2] sr=1 -> 0.454: (sr'=0) + 0.546: (sr'=1); + +endmodule + +//------------------------------------------------------------------------- + +// SERVICE PROVIDER + +module SP + + sp : [0..10] init 9; + // 0 active + // 1 idle + // 2 active_idlelp + // 3 idlelp + // 4 idlelp_active + // 5 active_stby + // 6 stby + // 7 stby_active + // 8 active_sleep + // 9 sleep + // 10 sleep_active + + // states where PM has no control (transient states) + [tick2] sp=2 -> 0.75 : (sp'=2) + 0.25 : (sp'=3); // active_idlelp + [tick2] sp=4 -> 0.25 : (sp'=0) + 0.75 : (sp'=4); // idlelp_active + [tick2] sp=5 -> 0.995 : (sp'=5) + 0.005 : (sp'=6); // active_stby + [tick2] sp=7 -> 0.005 : (sp'=0) + 0.995 : (sp'=7); // stby_active + [tick2] sp=8 -> 0.9983 : (sp'=8) + 0.0017 : (sp'=9); // active_sleep + [tick2] sp=10 -> 0.0017 : (sp'=0) + 0.9983 : (sp'=10); // sleep_active + + // states where PM has control + // goto_active + [tick2] sp=0 & pm=0 -> (sp'=0); // active + [tick2] sp=1 & pm=0 -> (sp'=0); // idle + [tick2] sp=3 & pm=0 -> (sp'=4); // idlelp + [tick2] sp=6 & pm=0 -> (sp'=7); // stby + [tick2] sp=9 & pm=0 -> (sp'=10); // sleep + // goto_idle + [tick2] sp=0 & pm=1 -> (sp'=1); // active + [tick2] sp=1 & pm=1 -> (sp'=1); // idle + [tick2] sp=3 & pm=1 -> (sp'=3); // idlelp + [tick2] sp=6 & pm=1 -> (sp'=6); // stby + [tick2] sp=9 & pm=1 -> (sp'=9); // sleep + // goto_idlelp + [tick2] sp=0 & pm=2 -> (sp'=2); // active + [tick2] sp=1 & pm=2 -> (sp'=2); // idle + [tick2] sp=3 & pm=2 -> (sp'=3); // idlelp + [tick2] sp=6 & pm=2 -> (sp'=6); // stby + [tick2] sp=9 & pm=2 -> (sp'=9); // sleep + // goto_stby + [tick2] sp=0 & pm=3 -> (sp'=5); // active + [tick2] sp=1 & pm=3 -> (sp'=5); // idle + [tick2] sp=3 & pm=3 -> (sp'=5); // idlelp + [tick2] sp=6 & pm=3 -> (sp'=6); // stby + [tick2] sp=9 & pm=3 -> (sp'=9); // sleep + // goto_sleep + [tick2] sp=0 & pm=4 -> (sp'=8); // active + [tick2] sp=1 & pm=4 -> (sp'=8); // idle + [tick2] sp=3 & pm=4 -> (sp'=8); // idlelp + [tick2] sp=6 & pm=4 -> (sp'=8); // stby + [tick2] sp=9 & pm=4 -> (sp'=9); // sleep + +endmodule + + +//------------------------------------------------------------------------- + +// SQ +module SQ + + q : [0..QMAX] init 0; + + // serve if busy + [tick2] sr=0 & sp=0 -> (q'=max(q-1,0)); + [tick2] sr=1 & sp=0 -> (q'=q); + + // otherwise do nothing + [tick2] sr=0 & sp>0 -> (q'=q); + [tick2] sr=1 & sp>0 -> (q'=min(q+1,QMAX)); + +endmodule + +//------------------------------------------------------------------------- +//rewards "time" +// [tick2] bat=1 : 1; +//endrewards + +rewards "power" + [tick2] sp=0 & c=1 : 2.5; + [tick2] sp=1 & c=1 : 1.5; + [tick2] sp=2 & c=1 : 2.5; + [tick2] sp=3 & c=1 : 0.8; + [tick2] sp=4 & c=1 : 2.5; + [tick2] sp=5 & c=1 : 2.5; + [tick2] sp=6 & c=1 : 0.3; + [tick2] sp=7 & c=1 : 2.5; + [tick2] sp=8 & c=1 : 2.5; + [tick2] sp=9 & c=1 : 0.1; + [tick2] sp=10 & c=1 : 2.5; +endrewards + +// is an instantaneous property but I suppose we can look at average size +// i.e. divide by the expected number of time steps +rewards "queue" + [tick2] c=1 : q; +endrewards + +rewards "lost" + [tick2] sr=1 & sp>0 & q=2 : 1; +endrewards diff --git a/examples/multi-objective/mdp/dpm/dpm200.nm b/examples/multi-objective/mdp/dpm/dpm200.nm new file mode 100644 index 000000000..0862cfb73 --- /dev/null +++ b/examples/multi-objective/mdp/dpm/dpm200.nm @@ -0,0 +1,160 @@ +// power manager example +mdp + +const int QMAX =2; // max queue size + +// to model the pm making a choice and then a move being made we need +// two clock ticks for each transition +// first the pm decides tick1 and then the system moves tick2 + +module timer + + c : [0..1]; + + [tick1] c=0 -> (c'=1); + [tick2] c=1 -> (c'=0); + +endmodule + +//------------------------------------------------------------------------- + +// POWER MANAGER +module PM + + pm : [0..4] init 4; + // 0 - go to active + // 1 - go to idle + // 2 - go to idlelp + // 3 - go to stby + // 4 - go to sleep + + [tick1] true -> (pm'=0); + [tick1] true -> (pm'=1); + [tick1] true -> (pm'=2); + [tick1] true -> (pm'=3); + [tick1] true -> (pm'=4); + +endmodule + + +//------------------------------------------------------------------------- + +// SERVICE REQUESTER +module SR + + sr : [0..1] init 0; + // 0 idle + // 1 1req + + [tick2] sr=0 -> 0.898: (sr'=0) + 0.102: (sr'=1); + [tick2] sr=1 -> 0.454: (sr'=0) + 0.546: (sr'=1); + +endmodule + +//------------------------------------------------------------------------- + +// SERVICE PROVIDER + +module SP + + sp : [0..10] init 9; + // 0 active + // 1 idle + // 2 active_idlelp + // 3 idlelp + // 4 idlelp_active + // 5 active_stby + // 6 stby + // 7 stby_active + // 8 active_sleep + // 9 sleep + // 10 sleep_active + + // states where PM has no control (transient states) + [tick2] sp=2 -> 0.75 : (sp'=2) + 0.25 : (sp'=3); // active_idlelp + [tick2] sp=4 -> 0.25 : (sp'=0) + 0.75 : (sp'=4); // idlelp_active + [tick2] sp=5 -> 0.995 : (sp'=5) + 0.005 : (sp'=6); // active_stby + [tick2] sp=7 -> 0.005 : (sp'=0) + 0.995 : (sp'=7); // stby_active + [tick2] sp=8 -> 0.9983 : (sp'=8) + 0.0017 : (sp'=9); // active_sleep + [tick2] sp=10 -> 0.0017 : (sp'=0) + 0.9983 : (sp'=10); // sleep_active + + // states where PM has control + // goto_active + [tick2] sp=0 & pm=0 -> (sp'=0); // active + [tick2] sp=1 & pm=0 -> (sp'=0); // idle + [tick2] sp=3 & pm=0 -> (sp'=4); // idlelp + [tick2] sp=6 & pm=0 -> (sp'=7); // stby + [tick2] sp=9 & pm=0 -> (sp'=10); // sleep + // goto_idle + [tick2] sp=0 & pm=1 -> (sp'=1); // active + [tick2] sp=1 & pm=1 -> (sp'=1); // idle + [tick2] sp=3 & pm=1 -> (sp'=3); // idlelp + [tick2] sp=6 & pm=1 -> (sp'=6); // stby + [tick2] sp=9 & pm=1 -> (sp'=9); // sleep + // goto_idlelp + [tick2] sp=0 & pm=2 -> (sp'=2); // active + [tick2] sp=1 & pm=2 -> (sp'=2); // idle + [tick2] sp=3 & pm=2 -> (sp'=3); // idlelp + [tick2] sp=6 & pm=2 -> (sp'=6); // stby + [tick2] sp=9 & pm=2 -> (sp'=9); // sleep + // goto_stby + [tick2] sp=0 & pm=3 -> (sp'=5); // active + [tick2] sp=1 & pm=3 -> (sp'=5); // idle + [tick2] sp=3 & pm=3 -> (sp'=5); // idlelp + [tick2] sp=6 & pm=3 -> (sp'=6); // stby + [tick2] sp=9 & pm=3 -> (sp'=9); // sleep + // goto_sleep + [tick2] sp=0 & pm=4 -> (sp'=8); // active + [tick2] sp=1 & pm=4 -> (sp'=8); // idle + [tick2] sp=3 & pm=4 -> (sp'=8); // idlelp + [tick2] sp=6 & pm=4 -> (sp'=8); // stby + [tick2] sp=9 & pm=4 -> (sp'=9); // sleep + +endmodule + + +//------------------------------------------------------------------------- + +// SQ +module SQ + + q : [0..QMAX] init 0; + + // serve if busy + [tick2] sr=0 & sp=0 -> (q'=max(q-1,0)); + [tick2] sr=1 & sp=0 -> (q'=q); + + // otherwise do nothing + [tick2] sr=0 & sp>0 -> (q'=q); + [tick2] sr=1 & sp>0 -> (q'=min(q+1,QMAX)); + +endmodule + +//------------------------------------------------------------------------- +//rewards "time" +// [tick2] bat=1 : 1; +//endrewards + +rewards "power" + [tick2] sp=0 & c=1 : 2.5; + [tick2] sp=1 & c=1 : 1.5; + [tick2] sp=2 & c=1 : 2.5; + [tick2] sp=3 & c=1 : 0.8; + [tick2] sp=4 & c=1 : 2.5; + [tick2] sp=5 & c=1 : 2.5; + [tick2] sp=6 & c=1 : 0.3; + [tick2] sp=7 & c=1 : 2.5; + [tick2] sp=8 & c=1 : 2.5; + [tick2] sp=9 & c=1 : 0.1; + [tick2] sp=10 & c=1 : 2.5; +endrewards + +// is an instantaneous property but I suppose we can look at average size +// i.e. divide by the expected number of time steps +rewards "queue" + [tick2] c=1 : q; +endrewards + +rewards "lost" + [tick2] sr=1 & sp>0 & q=2 : 1; +endrewards diff --git a/examples/multi-objective/mdp/dpm/dpm300.nm b/examples/multi-objective/mdp/dpm/dpm300.nm new file mode 100644 index 000000000..3ac45e621 --- /dev/null +++ b/examples/multi-objective/mdp/dpm/dpm300.nm @@ -0,0 +1,160 @@ +// power manager example +mdp + +const int QMAX=2; // max queue size + +// to model the pm making a choice and then a move being made we need +// two clock ticks for each transition +// first the pm decides tick1 and then the system moves tick2 + +module timer + + c : [0..1]; + + [tick1] c=0 -> (c'=1); + [tick2] c=1 -> (c'=0); + +endmodule + +//------------------------------------------------------------------------- + +// POWER MANAGER +module PM + + pm : [0..4] init 4; + // 0 - go to active + // 1 - go to idle + // 2 - go to idlelp + // 3 - go to stby + // 4 - go to sleep + + [tick1] true -> (pm'=0); + [tick1] true -> (pm'=1); + [tick1] true -> (pm'=2); + [tick1] true -> (pm'=3); + [tick1] true -> (pm'=4); + +endmodule + + +//------------------------------------------------------------------------- + +// SERVICE REQUESTER +module SR + + sr : [0..1] init 0; + // 0 idle + // 1 1req + + [tick2] sr=0 -> 0.898: (sr'=0) + 0.102: (sr'=1); + [tick2] sr=1 -> 0.454: (sr'=0) + 0.546: (sr'=1); + +endmodule + +//------------------------------------------------------------------------- + +// SERVICE PROVIDER + +module SP + + sp : [0..10] init 9; + // 0 active + // 1 idle + // 2 active_idlelp + // 3 idlelp + // 4 idlelp_active + // 5 active_stby + // 6 stby + // 7 stby_active + // 8 active_sleep + // 9 sleep + // 10 sleep_active + + // states where PM has no control (transient states) + [tick2] sp=2 -> 0.75 : (sp'=2) + 0.25 : (sp'=3); // active_idlelp + [tick2] sp=4 -> 0.25 : (sp'=0) + 0.75 : (sp'=4); // idlelp_active + [tick2] sp=5 -> 0.995 : (sp'=5) + 0.005 : (sp'=6); // active_stby + [tick2] sp=7 -> 0.005 : (sp'=0) + 0.995 : (sp'=7); // stby_active + [tick2] sp=8 -> 0.9983 : (sp'=8) + 0.0017 : (sp'=9); // active_sleep + [tick2] sp=10 -> 0.0017 : (sp'=0) + 0.9983 : (sp'=10); // sleep_active + + // states where PM has control + // goto_active + [tick2] sp=0 & pm=0 -> (sp'=0); // active + [tick2] sp=1 & pm=0 -> (sp'=0); // idle + [tick2] sp=3 & pm=0 -> (sp'=4); // idlelp + [tick2] sp=6 & pm=0 -> (sp'=7); // stby + [tick2] sp=9 & pm=0 -> (sp'=10); // sleep + // goto_idle + [tick2] sp=0 & pm=1 -> (sp'=1); // active + [tick2] sp=1 & pm=1 -> (sp'=1); // idle + [tick2] sp=3 & pm=1 -> (sp'=3); // idlelp + [tick2] sp=6 & pm=1 -> (sp'=6); // stby + [tick2] sp=9 & pm=1 -> (sp'=9); // sleep + // goto_idlelp + [tick2] sp=0 & pm=2 -> (sp'=2); // active + [tick2] sp=1 & pm=2 -> (sp'=2); // idle + [tick2] sp=3 & pm=2 -> (sp'=3); // idlelp + [tick2] sp=6 & pm=2 -> (sp'=6); // stby + [tick2] sp=9 & pm=2 -> (sp'=9); // sleep + // goto_stby + [tick2] sp=0 & pm=3 -> (sp'=5); // active + [tick2] sp=1 & pm=3 -> (sp'=5); // idle + [tick2] sp=3 & pm=3 -> (sp'=5); // idlelp + [tick2] sp=6 & pm=3 -> (sp'=6); // stby + [tick2] sp=9 & pm=3 -> (sp'=9); // sleep + // goto_sleep + [tick2] sp=0 & pm=4 -> (sp'=8); // active + [tick2] sp=1 & pm=4 -> (sp'=8); // idle + [tick2] sp=3 & pm=4 -> (sp'=8); // idlelp + [tick2] sp=6 & pm=4 -> (sp'=8); // stby + [tick2] sp=9 & pm=4 -> (sp'=9); // sleep + +endmodule + + +//------------------------------------------------------------------------- + +// SQ +module SQ + + q : [0..QMAX] init 0; + + // serve if busy + [tick2] sr=0 & sp=0 -> (q'=max(q-1,0)); + [tick2] sr=1 & sp=0 -> (q'=q); + + // otherwise do nothing + [tick2] sr=0 & sp>0 -> (q'=q); + [tick2] sr=1 & sp>0 -> (q'=min(q+1,QMAX)); + +endmodule + +//------------------------------------------------------------------------- +//rewards "time" +// [tick2] bat=1 : 1; +//endrewards + +rewards "power" + [tick2] sp=0 & c=1 : 2.5; + [tick2] sp=1 & c=1 : 1.5; + [tick2] sp=2 & c=1 : 2.5; + [tick2] sp=3 & c=1 : 0.8; + [tick2] sp=4 & c=1 : 2.5; + [tick2] sp=5 & c=1 : 2.5; + [tick2] sp=6 & c=1 : 0.3; + [tick2] sp=7 & c=1 : 2.5; + [tick2] sp=8 & c=1 : 2.5; + [tick2] sp=9 & c=1 : 0.1; + [tick2] sp=10 & c=1 : 2.5; +endrewards + +// is an instantaneous property but I suppose we can look at average size +// i.e. divide by the expected number of time steps +rewards "queue" + [tick2] c=1 : q; +endrewards + +rewards "lost" + [tick2] sr=1 & sp>0 & q=2 : 1; +endrewards diff --git a/examples/multi-objective/mdp/dpm/origFiles/power-timed.nm b/examples/multi-objective/mdp/dpm/origFiles/power-timed.nm new file mode 100644 index 000000000..561742815 --- /dev/null +++ b/examples/multi-objective/mdp/dpm/origFiles/power-timed.nm @@ -0,0 +1,160 @@ +// power manager example +mdp + +const int QMAX; // max queue size + +// to model the pm making a choice and then a move being made we need +// two clock ticks for each transition +// first the pm decides tick1 and then the system moves tick2 + +module timer + + c : [0..1]; + + [tick1] c=0 -> (c'=1); + [tick2] c=1 -> (c'=0); + +endmodule + +//------------------------------------------------------------------------- + +// POWER MANAGER +module PM + + pm : [0..4] init 4; + // 0 - go to active + // 1 - go to idle + // 2 - go to idlelp + // 3 - go to stby + // 4 - go to sleep + + [tick1] true -> (pm'=0); + [tick1] true -> (pm'=1); + [tick1] true -> (pm'=2); + [tick1] true -> (pm'=3); + [tick1] true -> (pm'=4); + +endmodule + + +//------------------------------------------------------------------------- + +// SERVICE REQUESTER +module SR + + sr : [0..1] init 0; + // 0 idle + // 1 1req + + [tick2] sr=0 -> 0.898: (sr'=0) + 0.102: (sr'=1); + [tick2] sr=1 -> 0.454: (sr'=0) + 0.546: (sr'=1); + +endmodule + +//------------------------------------------------------------------------- + +// SERVICE PROVIDER + +module SP + + sp : [0..10] init 9; + // 0 active + // 1 idle + // 2 active_idlelp + // 3 idlelp + // 4 idlelp_active + // 5 active_stby + // 6 stby + // 7 stby_active + // 8 active_sleep + // 9 sleep + // 10 sleep_active + + // states where PM has no control (transient states) + [tick2] sp=2 -> 0.75 : (sp'=2) + 0.25 : (sp'=3); // active_idlelp + [tick2] sp=4 -> 0.25 : (sp'=0) + 0.75 : (sp'=4); // idlelp_active + [tick2] sp=5 -> 0.995 : (sp'=5) + 0.005 : (sp'=6); // active_stby + [tick2] sp=7 -> 0.005 : (sp'=0) + 0.995 : (sp'=7); // stby_active + [tick2] sp=8 -> 0.9983 : (sp'=8) + 0.0017 : (sp'=9); // active_sleep + [tick2] sp=10 -> 0.0017 : (sp'=0) + 0.9983 : (sp'=10); // sleep_active + + // states where PM has control + // goto_active + [tick2] sp=0 & pm=0 -> (sp'=0); // active + [tick2] sp=1 & pm=0 -> (sp'=0); // idle + [tick2] sp=3 & pm=0 -> (sp'=4); // idlelp + [tick2] sp=6 & pm=0 -> (sp'=7); // stby + [tick2] sp=9 & pm=0 -> (sp'=10); // sleep + // goto_idle + [tick2] sp=0 & pm=1 -> (sp'=1); // active + [tick2] sp=1 & pm=1 -> (sp'=1); // idle + [tick2] sp=3 & pm=1 -> (sp'=3); // idlelp + [tick2] sp=6 & pm=1 -> (sp'=6); // stby + [tick2] sp=9 & pm=1 -> (sp'=9); // sleep + // goto_idlelp + [tick2] sp=0 & pm=2 -> (sp'=2); // active + [tick2] sp=1 & pm=2 -> (sp'=2); // idle + [tick2] sp=3 & pm=2 -> (sp'=3); // idlelp + [tick2] sp=6 & pm=2 -> (sp'=6); // stby + [tick2] sp=9 & pm=2 -> (sp'=9); // sleep + // goto_stby + [tick2] sp=0 & pm=3 -> (sp'=5); // active + [tick2] sp=1 & pm=3 -> (sp'=5); // idle + [tick2] sp=3 & pm=3 -> (sp'=5); // idlelp + [tick2] sp=6 & pm=3 -> (sp'=6); // stby + [tick2] sp=9 & pm=3 -> (sp'=9); // sleep + // goto_sleep + [tick2] sp=0 & pm=4 -> (sp'=8); // active + [tick2] sp=1 & pm=4 -> (sp'=8); // idle + [tick2] sp=3 & pm=4 -> (sp'=8); // idlelp + [tick2] sp=6 & pm=4 -> (sp'=8); // stby + [tick2] sp=9 & pm=4 -> (sp'=9); // sleep + +endmodule + + +//------------------------------------------------------------------------- + +// SQ +module SQ + + q : [0..QMAX] init 0; + + // serve if busy + [tick2] sr=0 & sp=0 -> (q'=max(q-1,0)); + [tick2] sr=1 & sp=0 -> (q'=q); + + // otherwise do nothing + [tick2] sr=0 & sp>0 -> (q'=q); + [tick2] sr=1 & sp>0 -> (q'=min(q+1,QMAX)); + +endmodule + +//------------------------------------------------------------------------- +//rewards "time" +// [tick2] bat=1 : 1; +//endrewards + +rewards "power" + [tick2] sp=0 & c=1 : 2.5; + [tick2] sp=1 & c=1 : 1.5; + [tick2] sp=2 & c=1 : 2.5; + [tick2] sp=3 & c=1 : 0.8; + [tick2] sp=4 & c=1 : 2.5; + [tick2] sp=5 & c=1 : 2.5; + [tick2] sp=6 & c=1 : 0.3; + [tick2] sp=7 & c=1 : 2.5; + [tick2] sp=8 & c=1 : 2.5; + [tick2] sp=9 & c=1 : 0.1; + [tick2] sp=10 & c=1 : 2.5; +endrewards + +// is an instantaneous property but I suppose we can look at average size +// i.e. divide by the expected number of time steps +rewards "queue" + [tick2] c=1 : q; +endrewards + +rewards "lost" + [tick2] sr=1 & sp>0 & q=2 : 1; +endrewards diff --git a/examples/multi-objective/mdp/dpm/origFiles/power-timed.pctl b/examples/multi-objective/mdp/dpm/origFiles/power-timed.pctl new file mode 100644 index 000000000..153141e7c --- /dev/null +++ b/examples/multi-objective/mdp/dpm/origFiles/power-timed.pctl @@ -0,0 +1,11 @@ +// Average queue size +const double Q; + +// Time bound +const int k; + +// Minimum energy usage over k time-steps, such that average queue size remains below Q +"num_energy": multi(R{"power"}min=? [ C<=k ], R{"queue"}<=Q*k [ C<=k ]) + +// Pareto query: minimum energy usage vs minimum average queue size +"pareto": multi(R{"power"}min=? [ C<=k ], R{"queue"}min=? [ C<=k ]) diff --git a/examples/multi-objective/mdp/scheduler/scheduler.pctl b/examples/multi-objective/mdp/scheduler/origFiles/scheduler.pctl similarity index 100% rename from examples/multi-objective/mdp/scheduler/scheduler.pctl rename to examples/multi-objective/mdp/scheduler/origFiles/scheduler.pctl diff --git a/examples/multi-objective/mdp/scheduler/scheduler_prob2_K.nm b/examples/multi-objective/mdp/scheduler/origFiles/scheduler_prob2_K.nm similarity index 100% rename from examples/multi-objective/mdp/scheduler/scheduler_prob2_K.nm rename to examples/multi-objective/mdp/scheduler/origFiles/scheduler_prob2_K.nm diff --git a/examples/multi-objective/mdp/scheduler/scheduler05.nm b/examples/multi-objective/mdp/scheduler/scheduler05.nm new file mode 100644 index 000000000..00f4e9539 --- /dev/null +++ b/examples/multi-objective/mdp/scheduler/scheduler05.nm @@ -0,0 +1,95 @@ +mdp + +label "tasks_complete" = (task6=3); + +const int K=5; + +module scheduler + + task1 : [0..3]; + task2 : [0..3]; + task3 : [0..3]; + task4 : [0..3]; + task5 : [0..3]; + task6 : [0..3]; + + [p1_add] task1=0 -> (task1'=1); + [p2_add] task1=0 -> (task1'=2); + [p1_mult] task2=0 -> (task2'=1); + [p2_mult] task2=0 -> (task2'=2); + [p1_mult] task3=0&task1=3 -> (task3'=1); + [p2_mult] task3=0&task1=3 -> (task3'=2); + [p1_add] task4=0&task1=3&task2=3 -> (task4'=1); + [p2_add] task4=0&task1=3&task2=3 -> (task4'=2); + [p1_mult] task5=0&task3=3 -> (task5'=1); + [p2_mult] task5=0&task3=3 -> (task5'=2); + [p1_add] task6=0&task4=3&task5=3 -> (task6'=1); + [p2_add] task6=0&task4=3&task5=3 -> (task6'=2); + [p1_done] task1=1 -> (task1'=3); + [p1_done] task2=1 -> (task2'=3); + [p1_done] task3=1 -> (task3'=3); + [p1_done] task4=1 -> (task4'=3); + [p1_done] task5=1 -> (task5'=3); + [p1_done] task6=1 -> (task6'=3); + [p2_done] task1=2 -> (task1'=3); + [p2_done] task2=2 -> (task2'=3); + [p2_done] task3=2 -> (task3'=3); + [p2_done] task4=2 -> (task4'=3); + [p2_done] task5=2 -> (task5'=3); + [p2_done] task6=2 -> (task6'=3); + [time] true -> 1.0 : true; + +endmodule + +module P1 + + p1 : [0..3]; + c1 : [0..2]; + x1 : [0..4*K+1]; + + [p1_add] (p1=0) -> (p1'=1) & (x1'=0); + [] (p1=1)&(x1=1*K)&(c1=0) -> 1/3 : (p1'=3) & (x1'=0) & (c1'=0) + 2/3 : (c1'=1) & (x1'=0); + [] (p1=1)&(x1=1*K)&(c1=1) -> 1/2 : (p1'=3) & (x1'=0) & (c1'=0) + 1/2 : (c1'=2) & (x1'=0); + [p1_done] (p1=1)&(x1=1*K)&(c1=2) -> (p1'=0) & (x1'=0) & (c1'=0); + [p1_mult] (p1=0) -> (p1'=2) & (x1'=0); + [] (p1=2)&(x1=2*K)&(c1=0) -> 1/3 : (p1'=3) & (x1'=0) & (c1'=0) + 2/3 : (c1'=1) & (x1'=0); + [] (p1=2)&(x1=1*K)&(c1=1) -> 1/2 : (p1'=3) & (x1'=0) & (c1'=0) + 1/2 : (c1'=2) & (x1'=0); + [p1_done] (p1=2)&(x1=1*K)&(c1=2) -> (p1'=0) & (x1'=0) & (c1'=0); + [p1_done] (p1=3) -> (p1'=0); + [time] (p1=1=>x1+1<=1*K)&((p1=2&c1=0)=>x1+1<=2*K)&((p1=2&c1>0)=>x1+1<=1*K)&(p1=3=>x1+1<=0) -> 1.0 : (x1'=min(x1+1,4*K+1)); + +endmodule + +module P2 + + p2 : [0..3]; + c2 : [0..2]; + x2 : [0..6*K+1]; + + [p2_add] (p2=0) -> (p2'=1) & (x2'=0); + [] (p2=1)&(x2=4*K)&(c2=0) -> 1/3 : (p2'=3) & (x2'=0) & (c2'=0) + 2/3 : (c2'=1) & (x2'=0); + [] (p2=1)&(x2=1)&(c2=1) -> 1/2 : (p2'=3) & (x2'=0) & (c2'=0) + 1/2 : (c2'=2) & (x2'=0); + [p2_done] (p2=1)&(x2=1)&(c2=2) -> (p2'=0) & (x2'=0) & (c2'=0); + [p2_mult] (p2=0) -> (p2'=2) & (x2'=0); + [] (p2=2)&(x2=6*K)&(c2=0) -> 1/3 : (p2'=3) & (x2'=0) & (c2'=0) + 2/3 : (c2'=1) & (x2'=0); + [] (p2=2)&(x2=1)&(c2=1) -> 1/2 : (p2'=3) & (x2'=0) & (c2'=0) + 1/2 : (c2'=2) & (x2'=0); + [p2_done] (p2=2)&(x2=1)&(c2=2) -> (p2'=0) & (x2'=0) & (c2'=0); + [p2_done] (p2=3) -> (p2'=0); + [time] ((p2=1&c2=0)=>x2+1<=4*K)&((p2=1&c2>0)=>x2+1<=1)&((p2=2&c2=0)=>x2+1<=6*K)&((p2=2&c2>0)=>x2+1<=1)&(p2=3=>x2+1<=0) -> 1.0 : (x2'=min(x2+1,6*K+1)); + +endmodule + +rewards "time" + + [time] true : 1/K; + +endrewards + +rewards "energy" + + [time] p1=0 : 10/(1000*K); + [time] p1>0 : 90/(1000*K); + [time] p2=0 : 20/(1000*K); + [time] p2>0 : 30/(1000*K); + +endrewards diff --git a/examples/multi-objective/mdp/scheduler/scheduler25.nm b/examples/multi-objective/mdp/scheduler/scheduler25.nm new file mode 100644 index 000000000..2e75dfbdd --- /dev/null +++ b/examples/multi-objective/mdp/scheduler/scheduler25.nm @@ -0,0 +1,95 @@ +mdp + +label "tasks_complete" = (task6=3); + +const int K=25; + +module scheduler + + task1 : [0..3]; + task2 : [0..3]; + task3 : [0..3]; + task4 : [0..3]; + task5 : [0..3]; + task6 : [0..3]; + + [p1_add] task1=0 -> (task1'=1); + [p2_add] task1=0 -> (task1'=2); + [p1_mult] task2=0 -> (task2'=1); + [p2_mult] task2=0 -> (task2'=2); + [p1_mult] task3=0&task1=3 -> (task3'=1); + [p2_mult] task3=0&task1=3 -> (task3'=2); + [p1_add] task4=0&task1=3&task2=3 -> (task4'=1); + [p2_add] task4=0&task1=3&task2=3 -> (task4'=2); + [p1_mult] task5=0&task3=3 -> (task5'=1); + [p2_mult] task5=0&task3=3 -> (task5'=2); + [p1_add] task6=0&task4=3&task5=3 -> (task6'=1); + [p2_add] task6=0&task4=3&task5=3 -> (task6'=2); + [p1_done] task1=1 -> (task1'=3); + [p1_done] task2=1 -> (task2'=3); + [p1_done] task3=1 -> (task3'=3); + [p1_done] task4=1 -> (task4'=3); + [p1_done] task5=1 -> (task5'=3); + [p1_done] task6=1 -> (task6'=3); + [p2_done] task1=2 -> (task1'=3); + [p2_done] task2=2 -> (task2'=3); + [p2_done] task3=2 -> (task3'=3); + [p2_done] task4=2 -> (task4'=3); + [p2_done] task5=2 -> (task5'=3); + [p2_done] task6=2 -> (task6'=3); + [time] true -> 1.0 : true; + +endmodule + +module P1 + + p1 : [0..3]; + c1 : [0..2]; + x1 : [0..4*K+1]; + + [p1_add] (p1=0) -> (p1'=1) & (x1'=0); + [] (p1=1)&(x1=1*K)&(c1=0) -> 1/3 : (p1'=3) & (x1'=0) & (c1'=0) + 2/3 : (c1'=1) & (x1'=0); + [] (p1=1)&(x1=1*K)&(c1=1) -> 1/2 : (p1'=3) & (x1'=0) & (c1'=0) + 1/2 : (c1'=2) & (x1'=0); + [p1_done] (p1=1)&(x1=1*K)&(c1=2) -> (p1'=0) & (x1'=0) & (c1'=0); + [p1_mult] (p1=0) -> (p1'=2) & (x1'=0); + [] (p1=2)&(x1=2*K)&(c1=0) -> 1/3 : (p1'=3) & (x1'=0) & (c1'=0) + 2/3 : (c1'=1) & (x1'=0); + [] (p1=2)&(x1=1*K)&(c1=1) -> 1/2 : (p1'=3) & (x1'=0) & (c1'=0) + 1/2 : (c1'=2) & (x1'=0); + [p1_done] (p1=2)&(x1=1*K)&(c1=2) -> (p1'=0) & (x1'=0) & (c1'=0); + [p1_done] (p1=3) -> (p1'=0); + [time] (p1=1=>x1+1<=1*K)&((p1=2&c1=0)=>x1+1<=2*K)&((p1=2&c1>0)=>x1+1<=1*K)&(p1=3=>x1+1<=0) -> 1.0 : (x1'=min(x1+1,4*K+1)); + +endmodule + +module P2 + + p2 : [0..3]; + c2 : [0..2]; + x2 : [0..6*K+1]; + + [p2_add] (p2=0) -> (p2'=1) & (x2'=0); + [] (p2=1)&(x2=4*K)&(c2=0) -> 1/3 : (p2'=3) & (x2'=0) & (c2'=0) + 2/3 : (c2'=1) & (x2'=0); + [] (p2=1)&(x2=1)&(c2=1) -> 1/2 : (p2'=3) & (x2'=0) & (c2'=0) + 1/2 : (c2'=2) & (x2'=0); + [p2_done] (p2=1)&(x2=1)&(c2=2) -> (p2'=0) & (x2'=0) & (c2'=0); + [p2_mult] (p2=0) -> (p2'=2) & (x2'=0); + [] (p2=2)&(x2=6*K)&(c2=0) -> 1/3 : (p2'=3) & (x2'=0) & (c2'=0) + 2/3 : (c2'=1) & (x2'=0); + [] (p2=2)&(x2=1)&(c2=1) -> 1/2 : (p2'=3) & (x2'=0) & (c2'=0) + 1/2 : (c2'=2) & (x2'=0); + [p2_done] (p2=2)&(x2=1)&(c2=2) -> (p2'=0) & (x2'=0) & (c2'=0); + [p2_done] (p2=3) -> (p2'=0); + [time] ((p2=1&c2=0)=>x2+1<=4*K)&((p2=1&c2>0)=>x2+1<=1)&((p2=2&c2=0)=>x2+1<=6*K)&((p2=2&c2>0)=>x2+1<=1)&(p2=3=>x2+1<=0) -> 1.0 : (x2'=min(x2+1,6*K+1)); + +endmodule + +rewards "time" + + [time] true : 1/K; + +endrewards + +rewards "energy" + + [time] p1=0 : 10/(1000*K); + [time] p1>0 : 90/(1000*K); + [time] p2=0 : 20/(1000*K); + [time] p2>0 : 30/(1000*K); + +endrewards diff --git a/examples/multi-objective/mdp/scheduler/scheduler50.nm b/examples/multi-objective/mdp/scheduler/scheduler50.nm new file mode 100644 index 000000000..5e44a94fc --- /dev/null +++ b/examples/multi-objective/mdp/scheduler/scheduler50.nm @@ -0,0 +1,95 @@ +mdp + +label "tasks_complete" = (task6=3); + +const int K=50; + +module scheduler + + task1 : [0..3]; + task2 : [0..3]; + task3 : [0..3]; + task4 : [0..3]; + task5 : [0..3]; + task6 : [0..3]; + + [p1_add] task1=0 -> (task1'=1); + [p2_add] task1=0 -> (task1'=2); + [p1_mult] task2=0 -> (task2'=1); + [p2_mult] task2=0 -> (task2'=2); + [p1_mult] task3=0&task1=3 -> (task3'=1); + [p2_mult] task3=0&task1=3 -> (task3'=2); + [p1_add] task4=0&task1=3&task2=3 -> (task4'=1); + [p2_add] task4=0&task1=3&task2=3 -> (task4'=2); + [p1_mult] task5=0&task3=3 -> (task5'=1); + [p2_mult] task5=0&task3=3 -> (task5'=2); + [p1_add] task6=0&task4=3&task5=3 -> (task6'=1); + [p2_add] task6=0&task4=3&task5=3 -> (task6'=2); + [p1_done] task1=1 -> (task1'=3); + [p1_done] task2=1 -> (task2'=3); + [p1_done] task3=1 -> (task3'=3); + [p1_done] task4=1 -> (task4'=3); + [p1_done] task5=1 -> (task5'=3); + [p1_done] task6=1 -> (task6'=3); + [p2_done] task1=2 -> (task1'=3); + [p2_done] task2=2 -> (task2'=3); + [p2_done] task3=2 -> (task3'=3); + [p2_done] task4=2 -> (task4'=3); + [p2_done] task5=2 -> (task5'=3); + [p2_done] task6=2 -> (task6'=3); + [time] true -> 1.0 : true; + +endmodule + +module P1 + + p1 : [0..3]; + c1 : [0..2]; + x1 : [0..4*K+1]; + + [p1_add] (p1=0) -> (p1'=1) & (x1'=0); + [] (p1=1)&(x1=1*K)&(c1=0) -> 1/3 : (p1'=3) & (x1'=0) & (c1'=0) + 2/3 : (c1'=1) & (x1'=0); + [] (p1=1)&(x1=1*K)&(c1=1) -> 1/2 : (p1'=3) & (x1'=0) & (c1'=0) + 1/2 : (c1'=2) & (x1'=0); + [p1_done] (p1=1)&(x1=1*K)&(c1=2) -> (p1'=0) & (x1'=0) & (c1'=0); + [p1_mult] (p1=0) -> (p1'=2) & (x1'=0); + [] (p1=2)&(x1=2*K)&(c1=0) -> 1/3 : (p1'=3) & (x1'=0) & (c1'=0) + 2/3 : (c1'=1) & (x1'=0); + [] (p1=2)&(x1=1*K)&(c1=1) -> 1/2 : (p1'=3) & (x1'=0) & (c1'=0) + 1/2 : (c1'=2) & (x1'=0); + [p1_done] (p1=2)&(x1=1*K)&(c1=2) -> (p1'=0) & (x1'=0) & (c1'=0); + [p1_done] (p1=3) -> (p1'=0); + [time] (p1=1=>x1+1<=1*K)&((p1=2&c1=0)=>x1+1<=2*K)&((p1=2&c1>0)=>x1+1<=1*K)&(p1=3=>x1+1<=0) -> 1.0 : (x1'=min(x1+1,4*K+1)); + +endmodule + +module P2 + + p2 : [0..3]; + c2 : [0..2]; + x2 : [0..6*K+1]; + + [p2_add] (p2=0) -> (p2'=1) & (x2'=0); + [] (p2=1)&(x2=4*K)&(c2=0) -> 1/3 : (p2'=3) & (x2'=0) & (c2'=0) + 2/3 : (c2'=1) & (x2'=0); + [] (p2=1)&(x2=1)&(c2=1) -> 1/2 : (p2'=3) & (x2'=0) & (c2'=0) + 1/2 : (c2'=2) & (x2'=0); + [p2_done] (p2=1)&(x2=1)&(c2=2) -> (p2'=0) & (x2'=0) & (c2'=0); + [p2_mult] (p2=0) -> (p2'=2) & (x2'=0); + [] (p2=2)&(x2=6*K)&(c2=0) -> 1/3 : (p2'=3) & (x2'=0) & (c2'=0) + 2/3 : (c2'=1) & (x2'=0); + [] (p2=2)&(x2=1)&(c2=1) -> 1/2 : (p2'=3) & (x2'=0) & (c2'=0) + 1/2 : (c2'=2) & (x2'=0); + [p2_done] (p2=2)&(x2=1)&(c2=2) -> (p2'=0) & (x2'=0) & (c2'=0); + [p2_done] (p2=3) -> (p2'=0); + [time] ((p2=1&c2=0)=>x2+1<=4*K)&((p2=1&c2>0)=>x2+1<=1)&((p2=2&c2=0)=>x2+1<=6*K)&((p2=2&c2>0)=>x2+1<=1)&(p2=3=>x2+1<=0) -> 1.0 : (x2'=min(x2+1,6*K+1)); + +endmodule + +rewards "time" + + [time] true : 1/K; + +endrewards + +rewards "energy" + + [time] p1=0 : 10/(1000*K); + [time] p1>0 : 90/(1000*K); + [time] p2=0 : 20/(1000*K); + [time] p2>0 : 30/(1000*K); + +endrewards diff --git a/examples/multi-objective/mdp/team/MDP_a2_r3_t2_full_exp.nm b/examples/multi-objective/mdp/team/origFiles/MDP_a2_r3_t2_full_exp.nm similarity index 100% rename from examples/multi-objective/mdp/team/MDP_a2_r3_t2_full_exp.nm rename to examples/multi-objective/mdp/team/origFiles/MDP_a2_r3_t2_full_exp.nm diff --git a/examples/multi-objective/mdp/team/origFiles/MDP_a3_r3_t2_full_exp.nm b/examples/multi-objective/mdp/team/origFiles/MDP_a3_r3_t2_full_exp.nm new file mode 100644 index 000000000..8a754d922 --- /dev/null +++ b/examples/multi-objective/mdp/team/origFiles/MDP_a3_r3_t2_full_exp.nm @@ -0,0 +1,287 @@ +mdp + +// parameters +const int n_resources = 3; +const int n_tasks = 2; +const int n_sensors = 3; + + +// sensor resources +const int resource1=1; +const int resource2=2; +const int resource3=3; + +// network configuration +const int e12=1; +const int e13=1; + +const int e21=e12; +const int e23=1; + +const int e31=e13; +const int e32=e23; + + +module controller // schedules the algorithm + + // algorithm status + status : [0..6]; + + // task resource indicator variables + t1_r1 : [0..1]; + t1_r2 : [0..1]; + t1_r3 : [0..1]; + + t2_r1 : [0..1]; + t2_r2 : [0..1]; + t2_r3 : [0..1]; + + // schedule placeholders + turn1 : [0..n_sensors]; + turn2 : [0..n_sensors]; + turn3 : [0..n_sensors]; + + // selecting schedule uniformly at random + [] status=0 -> 1/6 : (turn1'=1) & (turn2'=2) & (turn3'=3) & (status'=1) + + 1/6 : (turn1'=1) & (turn2'=3) & (turn3'=2) & (status'=1) + + 1/6 : (turn1'=2) & (turn2'=1) & (turn3'=3) & (status'=1) + + 1/6 : (turn1'=2) & (turn2'=3) & (turn3'=1) & (status'=1) + + 1/6 : (turn1'=3) & (turn2'=1) & (turn3'=2) & (status'=1) + + 1/6 : (turn1'=3) & (turn2'=2) & (turn3'=1) & (status'=1); + + + // initialising non-empty tasks uniformly at random + [] status=1 -> 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2); + + // executing the schedule + + // 1st round + [str1] status=2 & turn1=1 -> (status'=2); + [fin1] status=2 & turn1=1 -> (status'=3); + [str2] status=2 & turn1=2 -> (status'=2); + [fin2] status=2 & turn1=2 -> (status'=3); + [str3] status=2 & turn1=3 -> (status'=2); + [fin3] status=2 & turn1=3 -> (status'=3); + + // 2nd round + [str1] status=3 & turn2=1 -> (status'=3); + [fin1] status=3 & turn2=1 -> (status'=4); + [str2] status=3 & turn2=2 -> (status'=3); + [fin2] status=3 & turn2=2 -> (status'=4); + [str3] status=3 & turn2=3 -> (status'=3); + [fin3] status=3 & turn2=3 -> (status'=4); + + // 3rd round + [str1] status=4 & turn3=1 -> (status'=4); + [fin1] status=4 & turn3=1 -> (status'=5); + [str2] status=4 & turn3=2 -> (status'=4); + [fin2] status=4 & turn3=2 -> (status'=5); + [str3] status=4 & turn3=3 -> (status'=4); + [fin3] status=4 & turn3=3 -> (status'=5); + + [] status=5 -> (status'=6); + + [] status=6 -> true; + +endmodule + +module sensor1 + + state1 : [0..1]; + + // team membership indicators + m1_t1 : [0..1]; + m1_t2 : [0..1]; + + // starting turn, selecting order of tasks + [str1] state1=0 -> (state1'=1); + + // if there is no team and has required skill - initiating the team + [] state1=1 & !committed & team_size_t1=0 & has_resource_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2=0 & has_resource_t2 -> (m1_t2'=1); + + // if team already exists and one of the neighbours is in it - joining the team + [] state1=1 & !committed & team_size_t1>0 & can_join_t1 & has_resource_t1 & !resource_filled_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2>0 & can_join_t2 & has_resource_t2 & !resource_filled_t2 -> (m1_t2'=1); + + [fin1] state1>0 -> (state1'=0); + +endmodule + +module sensor2 = sensor1 +[ + state1=state2, + + str1=str2, + fin1=fin2, + + m1_t1=m2_t1, + m1_t2=m2_t2, + + m2_t1=m1_t1, + m2_t2=m1_t2, + + resource1=resource2, + resource2=resource1, + + e12=e21, + e13=e23, + e14=e24, + e15=e25, + + e21=e12, + e23=e13, + e24=e14, + e25=e15 +] +endmodule + +module sensor3 = sensor1 +[ + state1=state3, + + str1=str3, + fin1=fin3, + + m1_t1=m3_t1, + m1_t2=m3_t2, + m3_t1=m1_t1, + m3_t2=m1_t2, + + resource1=resource3, + resource3=resource1, + + e12=e32, + e13=e31, + e14=e34, + e15=e35, + + e31=e13, + e32=e12, + e34=e14, + e35=e15 +] +endmodule + + + +// agent is committed to some team +formula committed = (m1_t1+m1_t2) > 0; + +// formulae to compute team sizes +formula team_size_t1 = m1_t1+m2_t1+m3_t1; +formula team_size_t2 = m1_t2+m2_t2+m3_t2; + +// formulae to check whether the agent can join the team +formula can_join_t1 = e12*m2_t1 + e13*m3_t1 > 0; +formula can_join_t2 = e12*m2_t2 + e13*m3_t2 > 0; + +// formulae to check whether agent has the resource required by the task +formula has_resource_t1 = ( (t1_r1=1&resource1=1) | (t1_r2=1&resource1=2) | (t1_r3=1&resource1=3) ); +formula has_resource_t2 = ( (t2_r1=1&resource1=1) | (t2_r2=1&resource1=2) | (t2_r3=1&resource1=3) ); + +// formulae to check whether the resource of an agent has been already filled in the team +formula resource_filled_t1 = (m2_t1=1 & resource1=resource2) | (m3_t1=1 & resource1=resource3); +formula resource_filled_t2 = (m2_t2=1 & resource1=resource2) | (m3_t2=1 & resource1=resource3); + +// formula to compute team initiation probability (assuming each agent has at least one connection) +formula IP = (e12*(1-((m2_t1+m2_t2)=0?0:1))+e13*(1-((m3_t1+m3_t2)=0?0:1))) / (e12+e13); + + + + +// labels and formulae for property specification +formula finished = (status=5); +label "end" = (status=6); + + +formula task1_completed = finished + & ((t1_r1=1)=>((m1_t1=1&resource1=1)|(m2_t1=1&resource2=1)|(m3_t1=1&resource3=1))) + & ((t1_r2=1)=>((m1_t1=1&resource1=2)|(m2_t1=1&resource2=2)|(m3_t1=1&resource3=2))) + & ((t1_r3=1)=>((m1_t1=1&resource1=3)|(m2_t1=1&resource2=3)|(m3_t1=1&resource3=3))); + +formula task2_completed = finished + & ((t2_r1=1)=>((m1_t2=1&resource1=1)|(m2_t2=1&resource2=1)|(m3_t2=1&resource3=1))) + & ((t2_r2=1)=>((m1_t2=1&resource1=2)|(m2_t2=1&resource2=2)|(m3_t2=1&resource3=2))) + & ((t2_r3=1)=>((m1_t2=1&resource1=3)|(m2_t2=1&resource2=3)|(m3_t2=1&resource3=3))); + + + +formula agent1_joins_successful_team = (task1_completed & m1_t1=1) | (task2_completed & m1_t2=1); +formula agent1_joins_successful_team_of_1 = (task1_completed & m1_t1=1 & team_size_t1=1) | (task2_completed & m1_t2=1 & team_size_t2=1); +formula agent1_joins_successful_team_of_2 = (task1_completed & m1_t1=1 & team_size_t1=2) | (task2_completed & m1_t2=1 & team_size_t2=2); +formula agent1_joins_successful_team_of_3 = (task1_completed & m1_t1=1 & team_size_t1=3) | (task2_completed & m1_t2=1 & team_size_t2=3); + +formula agent2_joins_successful_team = (task1_completed & m2_t1=1) | (task2_completed & m2_t2=1); +formula agent2_joins_successful_team_of_1 = (task1_completed & m2_t1=1 & team_size_t1=1) | (task2_completed & m2_t2=1 & team_size_t2=1); +formula agent2_joins_successful_team_of_2 = (task1_completed & m2_t1=1 & team_size_t1=2) | (task2_completed & m2_t2=1 & team_size_t2=2); +formula agent2_joins_successful_team_of_3 = (task1_completed & m2_t1=1 & team_size_t1=3) | (task2_completed & m2_t2=1 & team_size_t2=3); + +formula agent3_joins_successful_team = (task1_completed & m3_t1=1) | (task2_completed & m3_t2=1); +formula agent3_joins_successful_team_of_1 = (task1_completed & m3_t1=1 & team_size_t1=1) | (task2_completed & m3_t2=1 & team_size_t2=1); +formula agent3_joins_successful_team_of_2 = (task1_completed & m3_t1=1 & team_size_t1=2) | (task2_completed & m3_t2=1 & team_size_t2=2); +formula agent3_joins_successful_team_of_3 = (task1_completed & m3_t1=1 & team_size_t1=3) | (task2_completed & m3_t2=1 & team_size_t2=3); + +// rewards +rewards "w_1_total" + [] agent1_joins_successful_team : 1; + [] agent2_joins_successful_team : 1; + [] agent3_joins_successful_team : 1; +endrewards + +rewards "w_2_total" + [] task1_completed : 1; + [] task2_completed : 1; +endrewards + + + + diff --git a/examples/multi-objective/mdp/team/origFiles/MDP_a4_r3_t2_full_exp.nm b/examples/multi-objective/mdp/team/origFiles/MDP_a4_r3_t2_full_exp.nm new file mode 100644 index 000000000..bc9e536c2 --- /dev/null +++ b/examples/multi-objective/mdp/team/origFiles/MDP_a4_r3_t2_full_exp.nm @@ -0,0 +1,364 @@ +mdp + +// parameters +const int n_resources = 3; +const int n_tasks = 2; +const int n_sensors = 4; + + +// sensor resources +const int resource1=1; +const int resource2=2; +const int resource3=3; +const int resource4=1; + +// network configuration +const int e12=1; +const int e13=1; +const int e14=1; + +const int e21=e12; +const int e23=1; +const int e24=1; + +const int e31=e13; +const int e32=e23; +const int e34=1; + +const int e41=e14; +const int e42=e24; +const int e43=e34; + + +module controller // schedules the algorithm + + // algorithm status + status : [0..7]; + + // task resource indicator variables + t1_r1 : [0..1]; + t1_r2 : [0..1]; + t1_r3 : [0..1]; + + t2_r1 : [0..1]; + t2_r2 : [0..1]; + t2_r3 : [0..1]; + + // schedule placeholders + turn1 : [0..n_sensors]; + turn2 : [0..n_sensors]; + turn3 : [0..n_sensors]; + turn4 : [0..n_sensors]; + turn5 : [0..n_sensors]; + + // selecting schedule uniformly at random + [] status=0 -> 1/24 : (turn1'=1) & (turn2'=2) & (turn3'=3) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=1) & (turn2'=2) & (turn3'=4) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=1) & (turn2'=3) & (turn3'=2) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=1) & (turn2'=3) & (turn3'=4) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=1) & (turn2'=4) & (turn3'=2) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=1) & (turn2'=4) & (turn3'=3) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=1) & (turn3'=3) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=1) & (turn3'=4) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=3) & (turn3'=1) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=3) & (turn3'=4) & (turn4'=1) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=4) & (turn3'=1) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=4) & (turn3'=3) & (turn4'=1) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=1) & (turn3'=2) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=1) & (turn3'=4) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=2) & (turn3'=1) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=2) & (turn3'=4) & (turn4'=1) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=4) & (turn3'=1) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=4) & (turn3'=2) & (turn4'=1) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=1) & (turn3'=2) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=1) & (turn3'=3) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=2) & (turn3'=1) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=2) & (turn3'=3) & (turn4'=1) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=3) & (turn3'=1) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=3) & (turn3'=2) & (turn4'=1) & (status'=1); + + + // initialising non-empty tasks uniformly at random + [] status=1 -> 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2); + + // executing the schedule + + // 1st round + [str1] status=2 & turn1=1 -> (status'=2); + [fin1] status=2 & turn1=1 -> (status'=3); + [str2] status=2 & turn1=2 -> (status'=2); + [fin2] status=2 & turn1=2 -> (status'=3); + [str3] status=2 & turn1=3 -> (status'=2); + [fin3] status=2 & turn1=3 -> (status'=3); + [str4] status=2 & turn1=4 -> (status'=2); + [fin4] status=2 & turn1=4 -> (status'=3); + + // 2nd round + [str1] status=3 & turn2=1 -> (status'=3); + [fin1] status=3 & turn2=1 -> (status'=4); + [str2] status=3 & turn2=2 -> (status'=3); + [fin2] status=3 & turn2=2 -> (status'=4); + [str3] status=3 & turn2=3 -> (status'=3); + [fin3] status=3 & turn2=3 -> (status'=4); + [str4] status=3 & turn2=4 -> (status'=3); + [fin4] status=3 & turn2=4 -> (status'=4); + + // 3rd round + [str1] status=4 & turn3=1 -> (status'=4); + [fin1] status=4 & turn3=1 -> (status'=5); + [str2] status=4 & turn3=2 -> (status'=4); + [fin2] status=4 & turn3=2 -> (status'=5); + [str3] status=4 & turn3=3 -> (status'=4); + [fin3] status=4 & turn3=3 -> (status'=5); + [str4] status=4 & turn3=4 -> (status'=4); + [fin4] status=4 & turn3=4 -> (status'=5); + + // 4th round + [str1] status=5 & turn4=1 -> (status'=5); + [fin1] status=5 & turn4=1 -> (status'=6); + [str2] status=5 & turn4=2 -> (status'=5); + [fin2] status=5 & turn4=2 -> (status'=6); + [str3] status=5 & turn4=3 -> (status'=5); + [fin3] status=5 & turn4=3 -> (status'=6); + [str4] status=5 & turn4=4 -> (status'=5); + [fin4] status=5 & turn4=4 -> (status'=6); + + [] status=6 -> (status'=7); + + [] status=7 -> (status'=7); + +endmodule + +module sensor1 + + state1 : [0..1]; + + // team membership indicators + m1_t1 : [0..1]; + m1_t2 : [0..1]; + + // starting turn, selecting order of tasks + [str1] state1=0 -> (state1'=1); + + // if there is no team and has required skill - initiating the team + [] state1=1 & !committed & team_size_t1=0 & has_resource_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2=0 & has_resource_t2 -> (m1_t2'=1); + + // if team already exists and one of the neighbours is in it - joining the team + [] state1=1 & !committed & team_size_t1>0 & can_join_t1 & has_resource_t1 & !resource_filled_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2>0 & can_join_t2 & has_resource_t2 & !resource_filled_t2 -> (m1_t2'=1); + + [fin1] state1>0 -> (state1'=0); + +endmodule + +module sensor2 = sensor1 +[ + state1=state2, + + str1=str2, + fin1=fin2, + + m1_t1=m2_t1, + m1_t2=m2_t2, + + m2_t1=m1_t1, + m2_t2=m1_t2, + + resource1=resource2, + resource2=resource1, + + e12=e21, + e13=e23, + e14=e24, + e15=e25, + + e21=e12, + e23=e13, + e24=e14, + e25=e15 +] +endmodule + +module sensor3 = sensor1 +[ + state1=state3, + + str1=str3, + fin1=fin3, + + m1_t1=m3_t1, + m1_t2=m3_t2, + m3_t1=m1_t1, + m3_t2=m1_t2, + + resource1=resource3, + resource3=resource1, + + e12=e32, + e13=e31, + e14=e34, + e15=e35, + + e31=e13, + e32=e12, + e34=e14, + e35=e15 +] +endmodule + +module sensor4 = sensor1 +[ + state1=state4, + + str1=str4, + fin1=fin4, + + m1_t1=m4_t1, + m1_t2=m4_t2, + + m4_t1=m1_t1, + m4_t2=m1_t2, + + resource1=resource4, + resource4=resource1, + + e12=e42, + e13=e43, + e14=e41, + e15=e45, + + e41=e14, + e42=e12, + e43=e13, + e45=e15 +] +endmodule + + + +// agent is committed to some team +formula committed = (m1_t1+m1_t2) > 0; + +// formulae to compute team sizes +formula team_size_t1 = m1_t1+m2_t1+m3_t1+m4_t1; +formula team_size_t2 = m1_t2+m2_t2+m3_t2+m4_t2; + +// formulae to check whether the agent can join the team +formula can_join_t1 = e12*m2_t1 + e13*m3_t1 + e14*m4_t1 > 0; +formula can_join_t2 = e12*m2_t2 + e13*m3_t2 + e14*m4_t2 > 0; + +// formulae to check whether agent has the resource required by the task +formula has_resource_t1 = ( (t1_r1=1&resource1=1) | (t1_r2=1&resource1=2) | (t1_r3=1&resource1=3) ); +formula has_resource_t2 = ( (t2_r1=1&resource1=1) | (t2_r2=1&resource1=2) | (t2_r3=1&resource1=3) ); + +// formulae to check whether the resource of an agent has been already filled in the team +formula resource_filled_t1 = (m2_t1=1 & resource1=resource2) | (m3_t1=1 & resource1=resource3) | (m4_t1=1 & resource1=resource4); +formula resource_filled_t2 = (m2_t2=1 & resource1=resource2) | (m3_t2=1 & resource1=resource3) | (m4_t2=1 & resource1=resource4); + +// formula to compute team initiation probability (assuming each agent has at least one connection) +formula IP = (e12*(1-((m2_t1+m2_t2)=0?0:1))+e13*(1-((m3_t1+m3_t2)=0?0:1))+e14*(1-((m4_t1+m4_t2)=0?0:1))) / (e12+e13+e14); + + + + +// labels and formulae for property specification +formula finished = (status=6); +label "end" = (status=7); + + +formula agent1_joins_successful_team = (task1_completed & m1_t1=1) | (task2_completed & m1_t2=1); +formula agent1_joins_successful_team_of_1 = (task1_completed & m1_t1=1 & team_size_t1=1) | (task2_completed & m1_t2=1 & team_size_t2=1); +formula agent1_joins_successful_team_of_2 = (task1_completed & m1_t1=1 & team_size_t1=2) | (task2_completed & m1_t2=1 & team_size_t2=2); +formula agent1_joins_successful_team_of_3 = (task1_completed & m1_t1=1 & team_size_t1=3) | (task2_completed & m1_t2=1 & team_size_t2=3); + +formula agent2_joins_successful_team = (task1_completed & m2_t1=1) | (task2_completed & m2_t2=1); +formula agent2_joins_successful_team_of_1 = (task1_completed & m2_t1=1 & team_size_t1=1) | (task2_completed & m2_t2=1 & team_size_t2=1); +formula agent2_joins_successful_team_of_2 = (task1_completed & m2_t1=1 & team_size_t1=2) | (task2_completed & m2_t2=1 & team_size_t2=2); +formula agent2_joins_successful_team_of_3 = (task1_completed & m2_t1=1 & team_size_t1=3) | (task2_completed & m2_t2=1 & team_size_t2=3); + +formula agent3_joins_successful_team = (task1_completed & m3_t1=1) | (task2_completed & m3_t2=1); +formula agent3_joins_successful_team_of_1 = (task1_completed & m3_t1=1 & team_size_t1=1) | (task2_completed & m3_t2=1 & team_size_t2=1); +formula agent3_joins_successful_team_of_2 = (task1_completed & m3_t1=1 & team_size_t1=2) | (task2_completed & m3_t2=1 & team_size_t2=2); +formula agent3_joins_successful_team_of_3 = (task1_completed & m3_t1=1 & team_size_t1=3) | (task2_completed & m3_t2=1 & team_size_t2=3); + +formula agent4_joins_successful_team = (task1_completed & m4_t1=1) | (task2_completed & m4_t2=1); +formula agent4_joins_successful_team_of_1 = (task1_completed & m4_t1=1 & team_size_t1=1) | (task2_completed & m4_t2=1 & team_size_t2=1); +formula agent4_joins_successful_team_of_2 = (task1_completed & m4_t1=1 & team_size_t1=2) | (task2_completed & m4_t2=1 & team_size_t2=2); +formula agent4_joins_successful_team_of_3 = (task1_completed & m4_t1=1 & team_size_t1=3) | (task2_completed & m4_t2=1 & team_size_t2=3); + +formula task1_completed = finished + & ((t1_r1=1)=>((m1_t1=1&resource1=1)|(m2_t1=1&resource2=1)|(m3_t1=1&resource3=1)|(m4_t1=1&resource4=1))) + & ((t1_r2=1)=>((m1_t1=1&resource1=2)|(m2_t1=1&resource2=2)|(m3_t1=1&resource3=2)|(m4_t1=1&resource4=2))) + & ((t1_r3=1)=>((m1_t1=1&resource1=3)|(m2_t1=1&resource2=3)|(m3_t1=1&resource3=3)|(m4_t1=1&resource4=3))); + +formula task2_completed = finished + & ((t2_r1=1)=>((m1_t2=1&resource1=1)|(m2_t2=1&resource2=1)|(m3_t2=1&resource3=1)|(m4_t2=1&resource4=1))) + & ((t2_r2=1)=>((m1_t2=1&resource1=2)|(m2_t2=1&resource2=2)|(m3_t2=1&resource3=2)|(m4_t2=1&resource4=2))) + & ((t2_r3=1)=>((m1_t2=1&resource1=3)|(m2_t2=1&resource2=3)|(m3_t2=1&resource3=3)|(m4_t2=1&resource4=3))); + +// rewards +rewards "w_1_total" + [] agent1_joins_successful_team : 1; + [] agent2_joins_successful_team : 1; + [] agent3_joins_successful_team : 1; + [] agent4_joins_successful_team : 1; +endrewards + +rewards "w_2_total" + [] task1_completed : 1; + [] task2_completed : 1; +endrewards + + + + + diff --git a/examples/multi-objective/mdp/team/MDP_a5_r3_t2_full_exp.nm b/examples/multi-objective/mdp/team/origFiles/MDP_a5_r3_t2_full_exp.nm similarity index 100% rename from examples/multi-objective/mdp/team/MDP_a5_r3_t2_full_exp.nm rename to examples/multi-objective/mdp/team/origFiles/MDP_a5_r3_t2_full_exp.nm diff --git a/examples/multi-objective/mdp/team/team.pctl b/examples/multi-objective/mdp/team/origFiles/team.pctl similarity index 100% rename from examples/multi-objective/mdp/team/team.pctl rename to examples/multi-objective/mdp/team/origFiles/team.pctl diff --git a/examples/multi-objective/mdp/team/team2obj_3.nm b/examples/multi-objective/mdp/team/team2obj_3.nm new file mode 100644 index 000000000..8a754d922 --- /dev/null +++ b/examples/multi-objective/mdp/team/team2obj_3.nm @@ -0,0 +1,287 @@ +mdp + +// parameters +const int n_resources = 3; +const int n_tasks = 2; +const int n_sensors = 3; + + +// sensor resources +const int resource1=1; +const int resource2=2; +const int resource3=3; + +// network configuration +const int e12=1; +const int e13=1; + +const int e21=e12; +const int e23=1; + +const int e31=e13; +const int e32=e23; + + +module controller // schedules the algorithm + + // algorithm status + status : [0..6]; + + // task resource indicator variables + t1_r1 : [0..1]; + t1_r2 : [0..1]; + t1_r3 : [0..1]; + + t2_r1 : [0..1]; + t2_r2 : [0..1]; + t2_r3 : [0..1]; + + // schedule placeholders + turn1 : [0..n_sensors]; + turn2 : [0..n_sensors]; + turn3 : [0..n_sensors]; + + // selecting schedule uniformly at random + [] status=0 -> 1/6 : (turn1'=1) & (turn2'=2) & (turn3'=3) & (status'=1) + + 1/6 : (turn1'=1) & (turn2'=3) & (turn3'=2) & (status'=1) + + 1/6 : (turn1'=2) & (turn2'=1) & (turn3'=3) & (status'=1) + + 1/6 : (turn1'=2) & (turn2'=3) & (turn3'=1) & (status'=1) + + 1/6 : (turn1'=3) & (turn2'=1) & (turn3'=2) & (status'=1) + + 1/6 : (turn1'=3) & (turn2'=2) & (turn3'=1) & (status'=1); + + + // initialising non-empty tasks uniformly at random + [] status=1 -> 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2); + + // executing the schedule + + // 1st round + [str1] status=2 & turn1=1 -> (status'=2); + [fin1] status=2 & turn1=1 -> (status'=3); + [str2] status=2 & turn1=2 -> (status'=2); + [fin2] status=2 & turn1=2 -> (status'=3); + [str3] status=2 & turn1=3 -> (status'=2); + [fin3] status=2 & turn1=3 -> (status'=3); + + // 2nd round + [str1] status=3 & turn2=1 -> (status'=3); + [fin1] status=3 & turn2=1 -> (status'=4); + [str2] status=3 & turn2=2 -> (status'=3); + [fin2] status=3 & turn2=2 -> (status'=4); + [str3] status=3 & turn2=3 -> (status'=3); + [fin3] status=3 & turn2=3 -> (status'=4); + + // 3rd round + [str1] status=4 & turn3=1 -> (status'=4); + [fin1] status=4 & turn3=1 -> (status'=5); + [str2] status=4 & turn3=2 -> (status'=4); + [fin2] status=4 & turn3=2 -> (status'=5); + [str3] status=4 & turn3=3 -> (status'=4); + [fin3] status=4 & turn3=3 -> (status'=5); + + [] status=5 -> (status'=6); + + [] status=6 -> true; + +endmodule + +module sensor1 + + state1 : [0..1]; + + // team membership indicators + m1_t1 : [0..1]; + m1_t2 : [0..1]; + + // starting turn, selecting order of tasks + [str1] state1=0 -> (state1'=1); + + // if there is no team and has required skill - initiating the team + [] state1=1 & !committed & team_size_t1=0 & has_resource_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2=0 & has_resource_t2 -> (m1_t2'=1); + + // if team already exists and one of the neighbours is in it - joining the team + [] state1=1 & !committed & team_size_t1>0 & can_join_t1 & has_resource_t1 & !resource_filled_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2>0 & can_join_t2 & has_resource_t2 & !resource_filled_t2 -> (m1_t2'=1); + + [fin1] state1>0 -> (state1'=0); + +endmodule + +module sensor2 = sensor1 +[ + state1=state2, + + str1=str2, + fin1=fin2, + + m1_t1=m2_t1, + m1_t2=m2_t2, + + m2_t1=m1_t1, + m2_t2=m1_t2, + + resource1=resource2, + resource2=resource1, + + e12=e21, + e13=e23, + e14=e24, + e15=e25, + + e21=e12, + e23=e13, + e24=e14, + e25=e15 +] +endmodule + +module sensor3 = sensor1 +[ + state1=state3, + + str1=str3, + fin1=fin3, + + m1_t1=m3_t1, + m1_t2=m3_t2, + m3_t1=m1_t1, + m3_t2=m1_t2, + + resource1=resource3, + resource3=resource1, + + e12=e32, + e13=e31, + e14=e34, + e15=e35, + + e31=e13, + e32=e12, + e34=e14, + e35=e15 +] +endmodule + + + +// agent is committed to some team +formula committed = (m1_t1+m1_t2) > 0; + +// formulae to compute team sizes +formula team_size_t1 = m1_t1+m2_t1+m3_t1; +formula team_size_t2 = m1_t2+m2_t2+m3_t2; + +// formulae to check whether the agent can join the team +formula can_join_t1 = e12*m2_t1 + e13*m3_t1 > 0; +formula can_join_t2 = e12*m2_t2 + e13*m3_t2 > 0; + +// formulae to check whether agent has the resource required by the task +formula has_resource_t1 = ( (t1_r1=1&resource1=1) | (t1_r2=1&resource1=2) | (t1_r3=1&resource1=3) ); +formula has_resource_t2 = ( (t2_r1=1&resource1=1) | (t2_r2=1&resource1=2) | (t2_r3=1&resource1=3) ); + +// formulae to check whether the resource of an agent has been already filled in the team +formula resource_filled_t1 = (m2_t1=1 & resource1=resource2) | (m3_t1=1 & resource1=resource3); +formula resource_filled_t2 = (m2_t2=1 & resource1=resource2) | (m3_t2=1 & resource1=resource3); + +// formula to compute team initiation probability (assuming each agent has at least one connection) +formula IP = (e12*(1-((m2_t1+m2_t2)=0?0:1))+e13*(1-((m3_t1+m3_t2)=0?0:1))) / (e12+e13); + + + + +// labels and formulae for property specification +formula finished = (status=5); +label "end" = (status=6); + + +formula task1_completed = finished + & ((t1_r1=1)=>((m1_t1=1&resource1=1)|(m2_t1=1&resource2=1)|(m3_t1=1&resource3=1))) + & ((t1_r2=1)=>((m1_t1=1&resource1=2)|(m2_t1=1&resource2=2)|(m3_t1=1&resource3=2))) + & ((t1_r3=1)=>((m1_t1=1&resource1=3)|(m2_t1=1&resource2=3)|(m3_t1=1&resource3=3))); + +formula task2_completed = finished + & ((t2_r1=1)=>((m1_t2=1&resource1=1)|(m2_t2=1&resource2=1)|(m3_t2=1&resource3=1))) + & ((t2_r2=1)=>((m1_t2=1&resource1=2)|(m2_t2=1&resource2=2)|(m3_t2=1&resource3=2))) + & ((t2_r3=1)=>((m1_t2=1&resource1=3)|(m2_t2=1&resource2=3)|(m3_t2=1&resource3=3))); + + + +formula agent1_joins_successful_team = (task1_completed & m1_t1=1) | (task2_completed & m1_t2=1); +formula agent1_joins_successful_team_of_1 = (task1_completed & m1_t1=1 & team_size_t1=1) | (task2_completed & m1_t2=1 & team_size_t2=1); +formula agent1_joins_successful_team_of_2 = (task1_completed & m1_t1=1 & team_size_t1=2) | (task2_completed & m1_t2=1 & team_size_t2=2); +formula agent1_joins_successful_team_of_3 = (task1_completed & m1_t1=1 & team_size_t1=3) | (task2_completed & m1_t2=1 & team_size_t2=3); + +formula agent2_joins_successful_team = (task1_completed & m2_t1=1) | (task2_completed & m2_t2=1); +formula agent2_joins_successful_team_of_1 = (task1_completed & m2_t1=1 & team_size_t1=1) | (task2_completed & m2_t2=1 & team_size_t2=1); +formula agent2_joins_successful_team_of_2 = (task1_completed & m2_t1=1 & team_size_t1=2) | (task2_completed & m2_t2=1 & team_size_t2=2); +formula agent2_joins_successful_team_of_3 = (task1_completed & m2_t1=1 & team_size_t1=3) | (task2_completed & m2_t2=1 & team_size_t2=3); + +formula agent3_joins_successful_team = (task1_completed & m3_t1=1) | (task2_completed & m3_t2=1); +formula agent3_joins_successful_team_of_1 = (task1_completed & m3_t1=1 & team_size_t1=1) | (task2_completed & m3_t2=1 & team_size_t2=1); +formula agent3_joins_successful_team_of_2 = (task1_completed & m3_t1=1 & team_size_t1=2) | (task2_completed & m3_t2=1 & team_size_t2=2); +formula agent3_joins_successful_team_of_3 = (task1_completed & m3_t1=1 & team_size_t1=3) | (task2_completed & m3_t2=1 & team_size_t2=3); + +// rewards +rewards "w_1_total" + [] agent1_joins_successful_team : 1; + [] agent2_joins_successful_team : 1; + [] agent3_joins_successful_team : 1; +endrewards + +rewards "w_2_total" + [] task1_completed : 1; + [] task2_completed : 1; +endrewards + + + + diff --git a/examples/multi-objective/mdp/team/team2obj_4.nm b/examples/multi-objective/mdp/team/team2obj_4.nm new file mode 100644 index 000000000..bc9e536c2 --- /dev/null +++ b/examples/multi-objective/mdp/team/team2obj_4.nm @@ -0,0 +1,364 @@ +mdp + +// parameters +const int n_resources = 3; +const int n_tasks = 2; +const int n_sensors = 4; + + +// sensor resources +const int resource1=1; +const int resource2=2; +const int resource3=3; +const int resource4=1; + +// network configuration +const int e12=1; +const int e13=1; +const int e14=1; + +const int e21=e12; +const int e23=1; +const int e24=1; + +const int e31=e13; +const int e32=e23; +const int e34=1; + +const int e41=e14; +const int e42=e24; +const int e43=e34; + + +module controller // schedules the algorithm + + // algorithm status + status : [0..7]; + + // task resource indicator variables + t1_r1 : [0..1]; + t1_r2 : [0..1]; + t1_r3 : [0..1]; + + t2_r1 : [0..1]; + t2_r2 : [0..1]; + t2_r3 : [0..1]; + + // schedule placeholders + turn1 : [0..n_sensors]; + turn2 : [0..n_sensors]; + turn3 : [0..n_sensors]; + turn4 : [0..n_sensors]; + turn5 : [0..n_sensors]; + + // selecting schedule uniformly at random + [] status=0 -> 1/24 : (turn1'=1) & (turn2'=2) & (turn3'=3) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=1) & (turn2'=2) & (turn3'=4) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=1) & (turn2'=3) & (turn3'=2) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=1) & (turn2'=3) & (turn3'=4) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=1) & (turn2'=4) & (turn3'=2) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=1) & (turn2'=4) & (turn3'=3) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=1) & (turn3'=3) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=1) & (turn3'=4) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=3) & (turn3'=1) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=3) & (turn3'=4) & (turn4'=1) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=4) & (turn3'=1) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=4) & (turn3'=3) & (turn4'=1) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=1) & (turn3'=2) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=1) & (turn3'=4) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=2) & (turn3'=1) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=2) & (turn3'=4) & (turn4'=1) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=4) & (turn3'=1) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=4) & (turn3'=2) & (turn4'=1) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=1) & (turn3'=2) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=1) & (turn3'=3) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=2) & (turn3'=1) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=2) & (turn3'=3) & (turn4'=1) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=3) & (turn3'=1) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=3) & (turn3'=2) & (turn4'=1) & (status'=1); + + + // initialising non-empty tasks uniformly at random + [] status=1 -> 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2); + + // executing the schedule + + // 1st round + [str1] status=2 & turn1=1 -> (status'=2); + [fin1] status=2 & turn1=1 -> (status'=3); + [str2] status=2 & turn1=2 -> (status'=2); + [fin2] status=2 & turn1=2 -> (status'=3); + [str3] status=2 & turn1=3 -> (status'=2); + [fin3] status=2 & turn1=3 -> (status'=3); + [str4] status=2 & turn1=4 -> (status'=2); + [fin4] status=2 & turn1=4 -> (status'=3); + + // 2nd round + [str1] status=3 & turn2=1 -> (status'=3); + [fin1] status=3 & turn2=1 -> (status'=4); + [str2] status=3 & turn2=2 -> (status'=3); + [fin2] status=3 & turn2=2 -> (status'=4); + [str3] status=3 & turn2=3 -> (status'=3); + [fin3] status=3 & turn2=3 -> (status'=4); + [str4] status=3 & turn2=4 -> (status'=3); + [fin4] status=3 & turn2=4 -> (status'=4); + + // 3rd round + [str1] status=4 & turn3=1 -> (status'=4); + [fin1] status=4 & turn3=1 -> (status'=5); + [str2] status=4 & turn3=2 -> (status'=4); + [fin2] status=4 & turn3=2 -> (status'=5); + [str3] status=4 & turn3=3 -> (status'=4); + [fin3] status=4 & turn3=3 -> (status'=5); + [str4] status=4 & turn3=4 -> (status'=4); + [fin4] status=4 & turn3=4 -> (status'=5); + + // 4th round + [str1] status=5 & turn4=1 -> (status'=5); + [fin1] status=5 & turn4=1 -> (status'=6); + [str2] status=5 & turn4=2 -> (status'=5); + [fin2] status=5 & turn4=2 -> (status'=6); + [str3] status=5 & turn4=3 -> (status'=5); + [fin3] status=5 & turn4=3 -> (status'=6); + [str4] status=5 & turn4=4 -> (status'=5); + [fin4] status=5 & turn4=4 -> (status'=6); + + [] status=6 -> (status'=7); + + [] status=7 -> (status'=7); + +endmodule + +module sensor1 + + state1 : [0..1]; + + // team membership indicators + m1_t1 : [0..1]; + m1_t2 : [0..1]; + + // starting turn, selecting order of tasks + [str1] state1=0 -> (state1'=1); + + // if there is no team and has required skill - initiating the team + [] state1=1 & !committed & team_size_t1=0 & has_resource_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2=0 & has_resource_t2 -> (m1_t2'=1); + + // if team already exists and one of the neighbours is in it - joining the team + [] state1=1 & !committed & team_size_t1>0 & can_join_t1 & has_resource_t1 & !resource_filled_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2>0 & can_join_t2 & has_resource_t2 & !resource_filled_t2 -> (m1_t2'=1); + + [fin1] state1>0 -> (state1'=0); + +endmodule + +module sensor2 = sensor1 +[ + state1=state2, + + str1=str2, + fin1=fin2, + + m1_t1=m2_t1, + m1_t2=m2_t2, + + m2_t1=m1_t1, + m2_t2=m1_t2, + + resource1=resource2, + resource2=resource1, + + e12=e21, + e13=e23, + e14=e24, + e15=e25, + + e21=e12, + e23=e13, + e24=e14, + e25=e15 +] +endmodule + +module sensor3 = sensor1 +[ + state1=state3, + + str1=str3, + fin1=fin3, + + m1_t1=m3_t1, + m1_t2=m3_t2, + m3_t1=m1_t1, + m3_t2=m1_t2, + + resource1=resource3, + resource3=resource1, + + e12=e32, + e13=e31, + e14=e34, + e15=e35, + + e31=e13, + e32=e12, + e34=e14, + e35=e15 +] +endmodule + +module sensor4 = sensor1 +[ + state1=state4, + + str1=str4, + fin1=fin4, + + m1_t1=m4_t1, + m1_t2=m4_t2, + + m4_t1=m1_t1, + m4_t2=m1_t2, + + resource1=resource4, + resource4=resource1, + + e12=e42, + e13=e43, + e14=e41, + e15=e45, + + e41=e14, + e42=e12, + e43=e13, + e45=e15 +] +endmodule + + + +// agent is committed to some team +formula committed = (m1_t1+m1_t2) > 0; + +// formulae to compute team sizes +formula team_size_t1 = m1_t1+m2_t1+m3_t1+m4_t1; +formula team_size_t2 = m1_t2+m2_t2+m3_t2+m4_t2; + +// formulae to check whether the agent can join the team +formula can_join_t1 = e12*m2_t1 + e13*m3_t1 + e14*m4_t1 > 0; +formula can_join_t2 = e12*m2_t2 + e13*m3_t2 + e14*m4_t2 > 0; + +// formulae to check whether agent has the resource required by the task +formula has_resource_t1 = ( (t1_r1=1&resource1=1) | (t1_r2=1&resource1=2) | (t1_r3=1&resource1=3) ); +formula has_resource_t2 = ( (t2_r1=1&resource1=1) | (t2_r2=1&resource1=2) | (t2_r3=1&resource1=3) ); + +// formulae to check whether the resource of an agent has been already filled in the team +formula resource_filled_t1 = (m2_t1=1 & resource1=resource2) | (m3_t1=1 & resource1=resource3) | (m4_t1=1 & resource1=resource4); +formula resource_filled_t2 = (m2_t2=1 & resource1=resource2) | (m3_t2=1 & resource1=resource3) | (m4_t2=1 & resource1=resource4); + +// formula to compute team initiation probability (assuming each agent has at least one connection) +formula IP = (e12*(1-((m2_t1+m2_t2)=0?0:1))+e13*(1-((m3_t1+m3_t2)=0?0:1))+e14*(1-((m4_t1+m4_t2)=0?0:1))) / (e12+e13+e14); + + + + +// labels and formulae for property specification +formula finished = (status=6); +label "end" = (status=7); + + +formula agent1_joins_successful_team = (task1_completed & m1_t1=1) | (task2_completed & m1_t2=1); +formula agent1_joins_successful_team_of_1 = (task1_completed & m1_t1=1 & team_size_t1=1) | (task2_completed & m1_t2=1 & team_size_t2=1); +formula agent1_joins_successful_team_of_2 = (task1_completed & m1_t1=1 & team_size_t1=2) | (task2_completed & m1_t2=1 & team_size_t2=2); +formula agent1_joins_successful_team_of_3 = (task1_completed & m1_t1=1 & team_size_t1=3) | (task2_completed & m1_t2=1 & team_size_t2=3); + +formula agent2_joins_successful_team = (task1_completed & m2_t1=1) | (task2_completed & m2_t2=1); +formula agent2_joins_successful_team_of_1 = (task1_completed & m2_t1=1 & team_size_t1=1) | (task2_completed & m2_t2=1 & team_size_t2=1); +formula agent2_joins_successful_team_of_2 = (task1_completed & m2_t1=1 & team_size_t1=2) | (task2_completed & m2_t2=1 & team_size_t2=2); +formula agent2_joins_successful_team_of_3 = (task1_completed & m2_t1=1 & team_size_t1=3) | (task2_completed & m2_t2=1 & team_size_t2=3); + +formula agent3_joins_successful_team = (task1_completed & m3_t1=1) | (task2_completed & m3_t2=1); +formula agent3_joins_successful_team_of_1 = (task1_completed & m3_t1=1 & team_size_t1=1) | (task2_completed & m3_t2=1 & team_size_t2=1); +formula agent3_joins_successful_team_of_2 = (task1_completed & m3_t1=1 & team_size_t1=2) | (task2_completed & m3_t2=1 & team_size_t2=2); +formula agent3_joins_successful_team_of_3 = (task1_completed & m3_t1=1 & team_size_t1=3) | (task2_completed & m3_t2=1 & team_size_t2=3); + +formula agent4_joins_successful_team = (task1_completed & m4_t1=1) | (task2_completed & m4_t2=1); +formula agent4_joins_successful_team_of_1 = (task1_completed & m4_t1=1 & team_size_t1=1) | (task2_completed & m4_t2=1 & team_size_t2=1); +formula agent4_joins_successful_team_of_2 = (task1_completed & m4_t1=1 & team_size_t1=2) | (task2_completed & m4_t2=1 & team_size_t2=2); +formula agent4_joins_successful_team_of_3 = (task1_completed & m4_t1=1 & team_size_t1=3) | (task2_completed & m4_t2=1 & team_size_t2=3); + +formula task1_completed = finished + & ((t1_r1=1)=>((m1_t1=1&resource1=1)|(m2_t1=1&resource2=1)|(m3_t1=1&resource3=1)|(m4_t1=1&resource4=1))) + & ((t1_r2=1)=>((m1_t1=1&resource1=2)|(m2_t1=1&resource2=2)|(m3_t1=1&resource3=2)|(m4_t1=1&resource4=2))) + & ((t1_r3=1)=>((m1_t1=1&resource1=3)|(m2_t1=1&resource2=3)|(m3_t1=1&resource3=3)|(m4_t1=1&resource4=3))); + +formula task2_completed = finished + & ((t2_r1=1)=>((m1_t2=1&resource1=1)|(m2_t2=1&resource2=1)|(m3_t2=1&resource3=1)|(m4_t2=1&resource4=1))) + & ((t2_r2=1)=>((m1_t2=1&resource1=2)|(m2_t2=1&resource2=2)|(m3_t2=1&resource3=2)|(m4_t2=1&resource4=2))) + & ((t2_r3=1)=>((m1_t2=1&resource1=3)|(m2_t2=1&resource2=3)|(m3_t2=1&resource3=3)|(m4_t2=1&resource4=3))); + +// rewards +rewards "w_1_total" + [] agent1_joins_successful_team : 1; + [] agent2_joins_successful_team : 1; + [] agent3_joins_successful_team : 1; + [] agent4_joins_successful_team : 1; +endrewards + +rewards "w_2_total" + [] task1_completed : 1; + [] task2_completed : 1; +endrewards + + + + + diff --git a/examples/multi-objective/mdp/team/team2obj_5.nm b/examples/multi-objective/mdp/team/team2obj_5.nm new file mode 100644 index 000000000..4a02b8746 --- /dev/null +++ b/examples/multi-objective/mdp/team/team2obj_5.nm @@ -0,0 +1,531 @@ +mdp + +// parameters +const int n_resources = 3; +const int n_tasks = 2; +const int n_sensors = 5; + + +// sensor resources +const int resource1=1; +const int resource2=2; +const int resource3=3; +const int resource4=1; +const int resource5=2; + +// network configuration +const int e12=1; +const int e13=1; +const int e14=1; +const int e15=1; + +const int e21=e12; +const int e23=1; +const int e24=1; +const int e25=1; + +const int e31=e13; +const int e32=e23; +const int e34=1; +const int e35=1; + +const int e41=e14; +const int e42=e24; +const int e43=e34; +const int e45=1; + +const int e51=e15; +const int e52=e25; +const int e53=e35; +const int e54=e45; + +module controller // schedules the algorithm + + // algorithm status + status : [0..8]; + + // task resource indicator variables + t1_r1 : [0..1]; + t1_r2 : [0..1]; + t1_r3 : [0..1]; + + t2_r1 : [0..1]; + t2_r2 : [0..1]; + t2_r3 : [0..1]; + + // schedule placeholders + turn1 : [0..n_sensors]; + turn2 : [0..n_sensors]; + turn3 : [0..n_sensors]; + turn4 : [0..n_sensors]; + turn5 : [0..n_sensors]; + + // selecting schedule uniformly at random + [] status=0 -> 1/120 : (turn1'=1) & (turn2'=2) & (turn3'=3) & (turn4'=4) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=2) & (turn3'=3) & (turn4'=5) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=2) & (turn3'=4) & (turn4'=3) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=2) & (turn3'=4) & (turn4'=5) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=2) & (turn3'=5) & (turn4'=3) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=2) & (turn3'=5) & (turn4'=4) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=3) & (turn3'=2) & (turn4'=4) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=3) & (turn3'=2) & (turn4'=5) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=3) & (turn3'=4) & (turn4'=2) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=3) & (turn3'=4) & (turn4'=5) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=3) & (turn3'=5) & (turn4'=2) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=3) & (turn3'=5) & (turn4'=4) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=4) & (turn3'=2) & (turn4'=3) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=4) & (turn3'=2) & (turn4'=5) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=4) & (turn3'=3) & (turn4'=2) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=4) & (turn3'=3) & (turn4'=5) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=4) & (turn3'=5) & (turn4'=2) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=4) & (turn3'=5) & (turn4'=3) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=5) & (turn3'=2) & (turn4'=3) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=5) & (turn3'=2) & (turn4'=4) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=5) & (turn3'=3) & (turn4'=2) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=5) & (turn3'=3) & (turn4'=4) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=5) & (turn3'=4) & (turn4'=2) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=5) & (turn3'=4) & (turn4'=3) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=1) & (turn3'=3) & (turn4'=4) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=1) & (turn3'=3) & (turn4'=5) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=1) & (turn3'=4) & (turn4'=3) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=1) & (turn3'=4) & (turn4'=5) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=1) & (turn3'=5) & (turn4'=3) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=1) & (turn3'=5) & (turn4'=4) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=3) & (turn3'=1) & (turn4'=4) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=3) & (turn3'=1) & (turn4'=5) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=3) & (turn3'=4) & (turn4'=1) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=3) & (turn3'=4) & (turn4'=5) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=3) & (turn3'=5) & (turn4'=1) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=3) & (turn3'=5) & (turn4'=4) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=4) & (turn3'=1) & (turn4'=3) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=4) & (turn3'=1) & (turn4'=5) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=4) & (turn3'=3) & (turn4'=1) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=4) & (turn3'=3) & (turn4'=5) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=4) & (turn3'=5) & (turn4'=1) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=4) & (turn3'=5) & (turn4'=3) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=5) & (turn3'=1) & (turn4'=3) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=5) & (turn3'=1) & (turn4'=4) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=5) & (turn3'=3) & (turn4'=1) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=5) & (turn3'=3) & (turn4'=4) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=5) & (turn3'=4) & (turn4'=1) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=5) & (turn3'=4) & (turn4'=3) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=1) & (turn3'=2) & (turn4'=4) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=1) & (turn3'=2) & (turn4'=5) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=1) & (turn3'=4) & (turn4'=2) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=1) & (turn3'=4) & (turn4'=5) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=1) & (turn3'=5) & (turn4'=2) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=1) & (turn3'=5) & (turn4'=4) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=2) & (turn3'=1) & (turn4'=4) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=2) & (turn3'=1) & (turn4'=5) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=2) & (turn3'=4) & (turn4'=1) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=2) & (turn3'=4) & (turn4'=5) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=2) & (turn3'=5) & (turn4'=1) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=2) & (turn3'=5) & (turn4'=4) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=4) & (turn3'=1) & (turn4'=2) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=4) & (turn3'=1) & (turn4'=5) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=4) & (turn3'=2) & (turn4'=1) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=4) & (turn3'=2) & (turn4'=5) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=4) & (turn3'=5) & (turn4'=1) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=4) & (turn3'=5) & (turn4'=2) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=5) & (turn3'=1) & (turn4'=2) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=5) & (turn3'=1) & (turn4'=4) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=5) & (turn3'=2) & (turn4'=1) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=5) & (turn3'=2) & (turn4'=4) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=5) & (turn3'=4) & (turn4'=1) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=5) & (turn3'=4) & (turn4'=2) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=1) & (turn3'=2) & (turn4'=3) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=1) & (turn3'=2) & (turn4'=5) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=1) & (turn3'=3) & (turn4'=2) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=1) & (turn3'=3) & (turn4'=5) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=1) & (turn3'=5) & (turn4'=2) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=1) & (turn3'=5) & (turn4'=3) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=2) & (turn3'=1) & (turn4'=3) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=2) & (turn3'=1) & (turn4'=5) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=2) & (turn3'=3) & (turn4'=1) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=2) & (turn3'=3) & (turn4'=5) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=2) & (turn3'=5) & (turn4'=1) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=2) & (turn3'=5) & (turn4'=3) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=3) & (turn3'=1) & (turn4'=2) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=3) & (turn3'=1) & (turn4'=5) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=3) & (turn3'=2) & (turn4'=1) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=3) & (turn3'=2) & (turn4'=5) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=3) & (turn3'=5) & (turn4'=1) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=3) & (turn3'=5) & (turn4'=2) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=5) & (turn3'=1) & (turn4'=2) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=5) & (turn3'=1) & (turn4'=3) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=5) & (turn3'=2) & (turn4'=1) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=5) & (turn3'=2) & (turn4'=3) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=5) & (turn3'=3) & (turn4'=1) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=5) & (turn3'=3) & (turn4'=2) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=1) & (turn3'=2) & (turn4'=3) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=1) & (turn3'=2) & (turn4'=4) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=1) & (turn3'=3) & (turn4'=2) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=1) & (turn3'=3) & (turn4'=4) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=1) & (turn3'=4) & (turn4'=2) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=1) & (turn3'=4) & (turn4'=3) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=2) & (turn3'=1) & (turn4'=3) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=2) & (turn3'=1) & (turn4'=4) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=2) & (turn3'=3) & (turn4'=1) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=2) & (turn3'=3) & (turn4'=4) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=2) & (turn3'=4) & (turn4'=1) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=2) & (turn3'=4) & (turn4'=3) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=3) & (turn3'=1) & (turn4'=2) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=3) & (turn3'=1) & (turn4'=4) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=3) & (turn3'=2) & (turn4'=1) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=3) & (turn3'=2) & (turn4'=4) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=3) & (turn3'=4) & (turn4'=1) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=3) & (turn3'=4) & (turn4'=2) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=4) & (turn3'=1) & (turn4'=2) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=4) & (turn3'=1) & (turn4'=3) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=4) & (turn3'=2) & (turn4'=1) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=4) & (turn3'=2) & (turn4'=3) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=4) & (turn3'=3) & (turn4'=1) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=4) & (turn3'=3) & (turn4'=2) & (turn5'=1) & (status'=1); + + + // initialising non-empty tasks uniformly at random + [] status=1 -> 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2); + + // executing the schedule + + // 1st round + [str1] status=2 & turn1=1 -> (status'=2); + [fin1] status=2 & turn1=1 -> (status'=3); + [str2] status=2 & turn1=2 -> (status'=2); + [fin2] status=2 & turn1=2 -> (status'=3); + [str3] status=2 & turn1=3 -> (status'=2); + [fin3] status=2 & turn1=3 -> (status'=3); + [str4] status=2 & turn1=4 -> (status'=2); + [fin4] status=2 & turn1=4 -> (status'=3); + [str5] status=2 & turn1=5 -> (status'=2); + [fin5] status=2 & turn1=5 -> (status'=3); + + // 2nd round + [str1] status=3 & turn2=1 -> (status'=3); + [fin1] status=3 & turn2=1 -> (status'=4); + [str2] status=3 & turn2=2 -> (status'=3); + [fin2] status=3 & turn2=2 -> (status'=4); + [str3] status=3 & turn2=3 -> (status'=3); + [fin3] status=3 & turn2=3 -> (status'=4); + [str4] status=3 & turn2=4 -> (status'=3); + [fin4] status=3 & turn2=4 -> (status'=4); + [str5] status=3 & turn2=5 -> (status'=3); + [fin5] status=3 & turn2=5 -> (status'=4); + + // 3rd round + [str1] status=4 & turn3=1 -> (status'=4); + [fin1] status=4 & turn3=1 -> (status'=5); + [str2] status=4 & turn3=2 -> (status'=4); + [fin2] status=4 & turn3=2 -> (status'=5); + [str3] status=4 & turn3=3 -> (status'=4); + [fin3] status=4 & turn3=3 -> (status'=5); + [str4] status=4 & turn3=4 -> (status'=4); + [fin4] status=4 & turn3=4 -> (status'=5); + [str5] status=4 & turn3=5 -> (status'=4); + [fin5] status=4 & turn3=5 -> (status'=5); + + // 4th round + [str1] status=5 & turn4=1 -> (status'=5); + [fin1] status=5 & turn4=1 -> (status'=6); + [str2] status=5 & turn4=2 -> (status'=5); + [fin2] status=5 & turn4=2 -> (status'=6); + [str3] status=5 & turn4=3 -> (status'=5); + [fin3] status=5 & turn4=3 -> (status'=6); + [str4] status=5 & turn4=4 -> (status'=5); + [fin4] status=5 & turn4=4 -> (status'=6); + [str5] status=5 & turn4=5 -> (status'=5); + [fin5] status=5 & turn4=5 -> (status'=6); + + // 5th round + [str1] status=6 & turn5=1 -> (status'=6); + [fin1] status=6 & turn5=1 -> (status'=7); + [str2] status=6 & turn5=2 -> (status'=6); + [fin2] status=6 & turn5=2 -> (status'=7); + [str3] status=6 & turn5=3 -> (status'=6); + [fin3] status=6 & turn5=3 -> (status'=7); + [str4] status=6 & turn5=4 -> (status'=6); + [fin4] status=6 & turn5=4 -> (status'=7); + [str5] status=6 & turn5=5 -> (status'=6); + [fin5] status=6 & turn5=5 -> (status'=7); + + [] status=7 -> (status'=8); + + [] status=8 -> (status'=8); + +endmodule + +module sensor1 + + state1 : [0..1]; + + // team membership indicators + m1_t1 : [0..1]; + m1_t2 : [0..1]; + + // starting turn, selecting order of tasks + [str1] state1=0 -> (state1'=1); + + // if there is no team and has required skill - initiating the team + [] state1=1 & !committed & team_size_t1=0 & has_resource_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2=0 & has_resource_t2 -> (m1_t2'=1); + + // if team already exists and one of the neighbours is in it - joining the team + [] state1=1 & !committed & team_size_t1>0 & can_join_t1 & has_resource_t1 & !resource_filled_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2>0 & can_join_t2 & has_resource_t2 & !resource_filled_t2 -> (m1_t2'=1); + + [fin1] state1>0 -> (state1'=0); + +endmodule + +module sensor2 = sensor1 +[ + state1=state2, + + str1=str2, + fin1=fin2, + + m1_t1=m2_t1, + m1_t2=m2_t2, + + m2_t1=m1_t1, + m2_t2=m1_t2, + + resource1=resource2, + resource2=resource1, + + e12=e21, + e13=e23, + e14=e24, + e15=e25, + + e21=e12, + e23=e13, + e24=e14, + e25=e15 +] +endmodule + +module sensor3 = sensor1 +[ + state1=state3, + + str1=str3, + fin1=fin3, + + m1_t1=m3_t1, + m1_t2=m3_t2, + m3_t1=m1_t1, + m3_t2=m1_t2, + + resource1=resource3, + resource3=resource1, + + e12=e32, + e13=e31, + e14=e34, + e15=e35, + + e31=e13, + e32=e12, + e34=e14, + e35=e15 +] +endmodule + +module sensor4 = sensor1 +[ + state1=state4, + + str1=str4, + fin1=fin4, + + m1_t1=m4_t1, + m1_t2=m4_t2, + + m4_t1=m1_t1, + m4_t2=m1_t2, + + resource1=resource4, + resource4=resource1, + + e12=e42, + e13=e43, + e14=e41, + e15=e45, + + e41=e14, + e42=e12, + e43=e13, + e45=e15 +] +endmodule + +module sensor5 = sensor1 +[ + state1=state5, + + str1=str5, + fin1=fin5, + + m1_t1=m5_t1, + m1_t2=m5_t2, + + m5_t1=m1_t1, + m5_t2=m1_t2, + + resource1=resource5, + resource5=resource1, + + e12=e52, + e13=e53, + e14=e54, + e15=e51, + + e51=e15, + e52=e12, + e53=e13, + e54=e14 +] +endmodule + +// formulae for scheduling +formula s1_sched = (turn1=1 | turn2=1 | turn3=1 | turn4=1 | turn5=1); +formula s2_sched = (turn1=2 | turn2=2 | turn3=2 | turn4=2 | turn5=2); +formula s3_sched = (turn1=3 | turn2=3 | turn3=3 | turn4=3 | turn5=3); +formula s4_sched = (turn1=4 | turn2=4 | turn3=4 | turn4=4 | turn5=4); +formula s5_sched = (turn1=5 | turn2=5 | turn3=5 | turn4=5 | turn5=5); +formula all_not_sched = !(s1_sched | s2_sched | s3_sched | s4_sched | s5_sched); +formula all_sched = (s1_sched & s2_sched & s3_sched & s4_sched & s5_sched); + + +// agent is committed to some team +formula committed = (m1_t1+m1_t2) > 0; + +// formulae to compute team sizes +formula team_size_t1 = m1_t1+m2_t1+m3_t1+m4_t1+m5_t1; +formula team_size_t2 = m1_t2+m2_t2+m3_t2+m4_t2+m5_t2; + +// formulae to check whether the agent can join the team +formula can_join_t1 = e12*m2_t1 + e13*m3_t1 + e14*m4_t1 + e15*m5_t1 > 0; +formula can_join_t2 = e12*m2_t2 + e13*m3_t2 + e14*m4_t2 + e15*m5_t2 > 0; + +// formulae to check whether agent has the resource required by the task +formula has_resource_t1 = ( (t1_r1=1&resource1=1) | (t1_r2=1&resource1=2) | (t1_r3=1&resource1=3) ); +formula has_resource_t2 = ( (t2_r1=1&resource1=1) | (t2_r2=1&resource1=2) | (t2_r3=1&resource1=3) ); + +// formulae to check whether the resource of an agent has been already filled in the team +formula resource_filled_t1 = (m2_t1=1 & resource1=resource2) | (m3_t1=1 & resource1=resource3) | (m4_t1=1 & resource1=resource4) | (m5_t1=1 & resource1=resource5); +formula resource_filled_t2 = (m2_t2=1 & resource1=resource2) | (m3_t2=1 & resource1=resource3) | (m4_t2=1 & resource1=resource4) | (m5_t2=1 & resource1=resource5); + +// formula to compute team initiation probability (assuming each agent has at least one connection) +formula IP = (e12*(1-((m2_t1+m2_t2)=0?0:1))+e13*(1-((m3_t1+m3_t2)=0?0:1))+e14*(1-((m4_t1+m4_t2)=0?0:1))+e15*(1-((m5_t1+m5_t2)=0?0:1))) / (e12+e13+e14+e15); + + + + +// labels and formulae for property specification +formula finished = (status=7); +label "end" = (status=8); + + +formula agent1_joins_successful_team = (task1_completed & m1_t1=1) | (task2_completed & m1_t2=1); +formula agent1_joins_successful_team_of_1 = (task1_completed & m1_t1=1 & team_size_t1=1) | (task2_completed & m1_t2=1 & team_size_t2=1); +formula agent1_joins_successful_team_of_2 = (task1_completed & m1_t1=1 & team_size_t1=2) | (task2_completed & m1_t2=1 & team_size_t2=2); +formula agent1_joins_successful_team_of_3 = (task1_completed & m1_t1=1 & team_size_t1=3) | (task2_completed & m1_t2=1 & team_size_t2=3); + +formula agent2_joins_successful_team = (task1_completed & m2_t1=1) | (task2_completed & m2_t2=1); +formula agent2_joins_successful_team_of_1 = (task1_completed & m2_t1=1 & team_size_t1=1) | (task2_completed & m2_t2=1 & team_size_t2=1); +formula agent2_joins_successful_team_of_2 = (task1_completed & m2_t1=1 & team_size_t1=2) | (task2_completed & m2_t2=1 & team_size_t2=2); +formula agent2_joins_successful_team_of_3 = (task1_completed & m2_t1=1 & team_size_t1=3) | (task2_completed & m2_t2=1 & team_size_t2=3); + +formula agent3_joins_successful_team = (task1_completed & m3_t1=1) | (task2_completed & m3_t2=1); +formula agent3_joins_successful_team_of_1 = (task1_completed & m3_t1=1 & team_size_t1=1) | (task2_completed & m3_t2=1 & team_size_t2=1); +formula agent3_joins_successful_team_of_2 = (task1_completed & m3_t1=1 & team_size_t1=2) | (task2_completed & m3_t2=1 & team_size_t2=2); +formula agent3_joins_successful_team_of_3 = (task1_completed & m3_t1=1 & team_size_t1=3) | (task2_completed & m3_t2=1 & team_size_t2=3); + +formula agent4_joins_successful_team = (task1_completed & m4_t1=1) | (task2_completed & m4_t2=1); +formula agent4_joins_successful_team_of_1 = (task1_completed & m4_t1=1 & team_size_t1=1) | (task2_completed & m4_t2=1 & team_size_t2=1); +formula agent4_joins_successful_team_of_2 = (task1_completed & m4_t1=1 & team_size_t1=2) | (task2_completed & m4_t2=1 & team_size_t2=2); +formula agent4_joins_successful_team_of_3 = (task1_completed & m4_t1=1 & team_size_t1=3) | (task2_completed & m4_t2=1 & team_size_t2=3); + +formula agent5_joins_successful_team = (task1_completed & m5_t1=1) | (task2_completed & m5_t2=1); +formula agent5_joins_successful_team_of_1 = (task1_completed & m5_t1=1 & team_size_t1=1) | (task2_completed & m5_t2=1 & team_size_t2=1); +formula agent5_joins_successful_team_of_2 = (task1_completed & m5_t1=1 & team_size_t1=2) | (task2_completed & m5_t2=1 & team_size_t2=2); +formula agent5_joins_successful_team_of_3 = (task1_completed & m5_t1=1 & team_size_t1=3) | (task2_completed & m5_t2=1 & team_size_t2=3); + +formula task1_completed = finished + & ((t1_r1=1)=>((m1_t1=1&resource1=1)|(m2_t1=1&resource2=1)|(m3_t1=1&resource3=1)|(m4_t1=1&resource4=1)|(m5_t1=1&resource5=1))) + & ((t1_r2=1)=>((m1_t1=1&resource1=2)|(m2_t1=1&resource2=2)|(m3_t1=1&resource3=2)|(m4_t1=1&resource4=2)|(m5_t1=1&resource5=2))) + & ((t1_r3=1)=>((m1_t1=1&resource1=3)|(m2_t1=1&resource2=3)|(m3_t1=1&resource3=3)|(m4_t1=1&resource4=3)|(m5_t1=1&resource5=3))); + +formula task2_completed = finished + & ((t2_r1=1)=>((m1_t2=1&resource1=1)|(m2_t2=1&resource2=1)|(m3_t2=1&resource3=1)|(m4_t2=1&resource4=1)|(m5_t2=1&resource5=1))) + & ((t2_r2=1)=>((m1_t2=1&resource1=2)|(m2_t2=1&resource2=2)|(m3_t2=1&resource3=2)|(m4_t2=1&resource4=2)|(m5_t2=1&resource5=2))) + & ((t2_r3=1)=>((m1_t2=1&resource1=3)|(m2_t2=1&resource2=3)|(m3_t2=1&resource3=3)|(m4_t2=1&resource4=3)|(m5_t2=1&resource5=3))); + +// rewards +rewards "w_1_total" + [] agent1_joins_successful_team : 1; + [] agent2_joins_successful_team : 1; + [] agent3_joins_successful_team : 1; + [] agent4_joins_successful_team : 1; + [] agent5_joins_successful_team : 1; +endrewards + +rewards "w_2_total" + [] task1_completed : 1; + [] task2_completed : 1; +endrewards + + + + + diff --git a/examples/multi-objective/mdp/team/team3obj_3.nm b/examples/multi-objective/mdp/team/team3obj_3.nm new file mode 100644 index 000000000..8a754d922 --- /dev/null +++ b/examples/multi-objective/mdp/team/team3obj_3.nm @@ -0,0 +1,287 @@ +mdp + +// parameters +const int n_resources = 3; +const int n_tasks = 2; +const int n_sensors = 3; + + +// sensor resources +const int resource1=1; +const int resource2=2; +const int resource3=3; + +// network configuration +const int e12=1; +const int e13=1; + +const int e21=e12; +const int e23=1; + +const int e31=e13; +const int e32=e23; + + +module controller // schedules the algorithm + + // algorithm status + status : [0..6]; + + // task resource indicator variables + t1_r1 : [0..1]; + t1_r2 : [0..1]; + t1_r3 : [0..1]; + + t2_r1 : [0..1]; + t2_r2 : [0..1]; + t2_r3 : [0..1]; + + // schedule placeholders + turn1 : [0..n_sensors]; + turn2 : [0..n_sensors]; + turn3 : [0..n_sensors]; + + // selecting schedule uniformly at random + [] status=0 -> 1/6 : (turn1'=1) & (turn2'=2) & (turn3'=3) & (status'=1) + + 1/6 : (turn1'=1) & (turn2'=3) & (turn3'=2) & (status'=1) + + 1/6 : (turn1'=2) & (turn2'=1) & (turn3'=3) & (status'=1) + + 1/6 : (turn1'=2) & (turn2'=3) & (turn3'=1) & (status'=1) + + 1/6 : (turn1'=3) & (turn2'=1) & (turn3'=2) & (status'=1) + + 1/6 : (turn1'=3) & (turn2'=2) & (turn3'=1) & (status'=1); + + + // initialising non-empty tasks uniformly at random + [] status=1 -> 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2); + + // executing the schedule + + // 1st round + [str1] status=2 & turn1=1 -> (status'=2); + [fin1] status=2 & turn1=1 -> (status'=3); + [str2] status=2 & turn1=2 -> (status'=2); + [fin2] status=2 & turn1=2 -> (status'=3); + [str3] status=2 & turn1=3 -> (status'=2); + [fin3] status=2 & turn1=3 -> (status'=3); + + // 2nd round + [str1] status=3 & turn2=1 -> (status'=3); + [fin1] status=3 & turn2=1 -> (status'=4); + [str2] status=3 & turn2=2 -> (status'=3); + [fin2] status=3 & turn2=2 -> (status'=4); + [str3] status=3 & turn2=3 -> (status'=3); + [fin3] status=3 & turn2=3 -> (status'=4); + + // 3rd round + [str1] status=4 & turn3=1 -> (status'=4); + [fin1] status=4 & turn3=1 -> (status'=5); + [str2] status=4 & turn3=2 -> (status'=4); + [fin2] status=4 & turn3=2 -> (status'=5); + [str3] status=4 & turn3=3 -> (status'=4); + [fin3] status=4 & turn3=3 -> (status'=5); + + [] status=5 -> (status'=6); + + [] status=6 -> true; + +endmodule + +module sensor1 + + state1 : [0..1]; + + // team membership indicators + m1_t1 : [0..1]; + m1_t2 : [0..1]; + + // starting turn, selecting order of tasks + [str1] state1=0 -> (state1'=1); + + // if there is no team and has required skill - initiating the team + [] state1=1 & !committed & team_size_t1=0 & has_resource_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2=0 & has_resource_t2 -> (m1_t2'=1); + + // if team already exists and one of the neighbours is in it - joining the team + [] state1=1 & !committed & team_size_t1>0 & can_join_t1 & has_resource_t1 & !resource_filled_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2>0 & can_join_t2 & has_resource_t2 & !resource_filled_t2 -> (m1_t2'=1); + + [fin1] state1>0 -> (state1'=0); + +endmodule + +module sensor2 = sensor1 +[ + state1=state2, + + str1=str2, + fin1=fin2, + + m1_t1=m2_t1, + m1_t2=m2_t2, + + m2_t1=m1_t1, + m2_t2=m1_t2, + + resource1=resource2, + resource2=resource1, + + e12=e21, + e13=e23, + e14=e24, + e15=e25, + + e21=e12, + e23=e13, + e24=e14, + e25=e15 +] +endmodule + +module sensor3 = sensor1 +[ + state1=state3, + + str1=str3, + fin1=fin3, + + m1_t1=m3_t1, + m1_t2=m3_t2, + m3_t1=m1_t1, + m3_t2=m1_t2, + + resource1=resource3, + resource3=resource1, + + e12=e32, + e13=e31, + e14=e34, + e15=e35, + + e31=e13, + e32=e12, + e34=e14, + e35=e15 +] +endmodule + + + +// agent is committed to some team +formula committed = (m1_t1+m1_t2) > 0; + +// formulae to compute team sizes +formula team_size_t1 = m1_t1+m2_t1+m3_t1; +formula team_size_t2 = m1_t2+m2_t2+m3_t2; + +// formulae to check whether the agent can join the team +formula can_join_t1 = e12*m2_t1 + e13*m3_t1 > 0; +formula can_join_t2 = e12*m2_t2 + e13*m3_t2 > 0; + +// formulae to check whether agent has the resource required by the task +formula has_resource_t1 = ( (t1_r1=1&resource1=1) | (t1_r2=1&resource1=2) | (t1_r3=1&resource1=3) ); +formula has_resource_t2 = ( (t2_r1=1&resource1=1) | (t2_r2=1&resource1=2) | (t2_r3=1&resource1=3) ); + +// formulae to check whether the resource of an agent has been already filled in the team +formula resource_filled_t1 = (m2_t1=1 & resource1=resource2) | (m3_t1=1 & resource1=resource3); +formula resource_filled_t2 = (m2_t2=1 & resource1=resource2) | (m3_t2=1 & resource1=resource3); + +// formula to compute team initiation probability (assuming each agent has at least one connection) +formula IP = (e12*(1-((m2_t1+m2_t2)=0?0:1))+e13*(1-((m3_t1+m3_t2)=0?0:1))) / (e12+e13); + + + + +// labels and formulae for property specification +formula finished = (status=5); +label "end" = (status=6); + + +formula task1_completed = finished + & ((t1_r1=1)=>((m1_t1=1&resource1=1)|(m2_t1=1&resource2=1)|(m3_t1=1&resource3=1))) + & ((t1_r2=1)=>((m1_t1=1&resource1=2)|(m2_t1=1&resource2=2)|(m3_t1=1&resource3=2))) + & ((t1_r3=1)=>((m1_t1=1&resource1=3)|(m2_t1=1&resource2=3)|(m3_t1=1&resource3=3))); + +formula task2_completed = finished + & ((t2_r1=1)=>((m1_t2=1&resource1=1)|(m2_t2=1&resource2=1)|(m3_t2=1&resource3=1))) + & ((t2_r2=1)=>((m1_t2=1&resource1=2)|(m2_t2=1&resource2=2)|(m3_t2=1&resource3=2))) + & ((t2_r3=1)=>((m1_t2=1&resource1=3)|(m2_t2=1&resource2=3)|(m3_t2=1&resource3=3))); + + + +formula agent1_joins_successful_team = (task1_completed & m1_t1=1) | (task2_completed & m1_t2=1); +formula agent1_joins_successful_team_of_1 = (task1_completed & m1_t1=1 & team_size_t1=1) | (task2_completed & m1_t2=1 & team_size_t2=1); +formula agent1_joins_successful_team_of_2 = (task1_completed & m1_t1=1 & team_size_t1=2) | (task2_completed & m1_t2=1 & team_size_t2=2); +formula agent1_joins_successful_team_of_3 = (task1_completed & m1_t1=1 & team_size_t1=3) | (task2_completed & m1_t2=1 & team_size_t2=3); + +formula agent2_joins_successful_team = (task1_completed & m2_t1=1) | (task2_completed & m2_t2=1); +formula agent2_joins_successful_team_of_1 = (task1_completed & m2_t1=1 & team_size_t1=1) | (task2_completed & m2_t2=1 & team_size_t2=1); +formula agent2_joins_successful_team_of_2 = (task1_completed & m2_t1=1 & team_size_t1=2) | (task2_completed & m2_t2=1 & team_size_t2=2); +formula agent2_joins_successful_team_of_3 = (task1_completed & m2_t1=1 & team_size_t1=3) | (task2_completed & m2_t2=1 & team_size_t2=3); + +formula agent3_joins_successful_team = (task1_completed & m3_t1=1) | (task2_completed & m3_t2=1); +formula agent3_joins_successful_team_of_1 = (task1_completed & m3_t1=1 & team_size_t1=1) | (task2_completed & m3_t2=1 & team_size_t2=1); +formula agent3_joins_successful_team_of_2 = (task1_completed & m3_t1=1 & team_size_t1=2) | (task2_completed & m3_t2=1 & team_size_t2=2); +formula agent3_joins_successful_team_of_3 = (task1_completed & m3_t1=1 & team_size_t1=3) | (task2_completed & m3_t2=1 & team_size_t2=3); + +// rewards +rewards "w_1_total" + [] agent1_joins_successful_team : 1; + [] agent2_joins_successful_team : 1; + [] agent3_joins_successful_team : 1; +endrewards + +rewards "w_2_total" + [] task1_completed : 1; + [] task2_completed : 1; +endrewards + + + + diff --git a/examples/multi-objective/mdp/team/team3obj_4.nm b/examples/multi-objective/mdp/team/team3obj_4.nm new file mode 100644 index 000000000..bc9e536c2 --- /dev/null +++ b/examples/multi-objective/mdp/team/team3obj_4.nm @@ -0,0 +1,364 @@ +mdp + +// parameters +const int n_resources = 3; +const int n_tasks = 2; +const int n_sensors = 4; + + +// sensor resources +const int resource1=1; +const int resource2=2; +const int resource3=3; +const int resource4=1; + +// network configuration +const int e12=1; +const int e13=1; +const int e14=1; + +const int e21=e12; +const int e23=1; +const int e24=1; + +const int e31=e13; +const int e32=e23; +const int e34=1; + +const int e41=e14; +const int e42=e24; +const int e43=e34; + + +module controller // schedules the algorithm + + // algorithm status + status : [0..7]; + + // task resource indicator variables + t1_r1 : [0..1]; + t1_r2 : [0..1]; + t1_r3 : [0..1]; + + t2_r1 : [0..1]; + t2_r2 : [0..1]; + t2_r3 : [0..1]; + + // schedule placeholders + turn1 : [0..n_sensors]; + turn2 : [0..n_sensors]; + turn3 : [0..n_sensors]; + turn4 : [0..n_sensors]; + turn5 : [0..n_sensors]; + + // selecting schedule uniformly at random + [] status=0 -> 1/24 : (turn1'=1) & (turn2'=2) & (turn3'=3) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=1) & (turn2'=2) & (turn3'=4) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=1) & (turn2'=3) & (turn3'=2) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=1) & (turn2'=3) & (turn3'=4) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=1) & (turn2'=4) & (turn3'=2) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=1) & (turn2'=4) & (turn3'=3) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=1) & (turn3'=3) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=1) & (turn3'=4) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=3) & (turn3'=1) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=3) & (turn3'=4) & (turn4'=1) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=4) & (turn3'=1) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=2) & (turn2'=4) & (turn3'=3) & (turn4'=1) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=1) & (turn3'=2) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=1) & (turn3'=4) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=2) & (turn3'=1) & (turn4'=4) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=2) & (turn3'=4) & (turn4'=1) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=4) & (turn3'=1) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=3) & (turn2'=4) & (turn3'=2) & (turn4'=1) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=1) & (turn3'=2) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=1) & (turn3'=3) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=2) & (turn3'=1) & (turn4'=3) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=2) & (turn3'=3) & (turn4'=1) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=3) & (turn3'=1) & (turn4'=2) & (status'=1) + + 1/24 : (turn1'=4) & (turn2'=3) & (turn3'=2) & (turn4'=1) & (status'=1); + + + // initialising non-empty tasks uniformly at random + [] status=1 -> 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2); + + // executing the schedule + + // 1st round + [str1] status=2 & turn1=1 -> (status'=2); + [fin1] status=2 & turn1=1 -> (status'=3); + [str2] status=2 & turn1=2 -> (status'=2); + [fin2] status=2 & turn1=2 -> (status'=3); + [str3] status=2 & turn1=3 -> (status'=2); + [fin3] status=2 & turn1=3 -> (status'=3); + [str4] status=2 & turn1=4 -> (status'=2); + [fin4] status=2 & turn1=4 -> (status'=3); + + // 2nd round + [str1] status=3 & turn2=1 -> (status'=3); + [fin1] status=3 & turn2=1 -> (status'=4); + [str2] status=3 & turn2=2 -> (status'=3); + [fin2] status=3 & turn2=2 -> (status'=4); + [str3] status=3 & turn2=3 -> (status'=3); + [fin3] status=3 & turn2=3 -> (status'=4); + [str4] status=3 & turn2=4 -> (status'=3); + [fin4] status=3 & turn2=4 -> (status'=4); + + // 3rd round + [str1] status=4 & turn3=1 -> (status'=4); + [fin1] status=4 & turn3=1 -> (status'=5); + [str2] status=4 & turn3=2 -> (status'=4); + [fin2] status=4 & turn3=2 -> (status'=5); + [str3] status=4 & turn3=3 -> (status'=4); + [fin3] status=4 & turn3=3 -> (status'=5); + [str4] status=4 & turn3=4 -> (status'=4); + [fin4] status=4 & turn3=4 -> (status'=5); + + // 4th round + [str1] status=5 & turn4=1 -> (status'=5); + [fin1] status=5 & turn4=1 -> (status'=6); + [str2] status=5 & turn4=2 -> (status'=5); + [fin2] status=5 & turn4=2 -> (status'=6); + [str3] status=5 & turn4=3 -> (status'=5); + [fin3] status=5 & turn4=3 -> (status'=6); + [str4] status=5 & turn4=4 -> (status'=5); + [fin4] status=5 & turn4=4 -> (status'=6); + + [] status=6 -> (status'=7); + + [] status=7 -> (status'=7); + +endmodule + +module sensor1 + + state1 : [0..1]; + + // team membership indicators + m1_t1 : [0..1]; + m1_t2 : [0..1]; + + // starting turn, selecting order of tasks + [str1] state1=0 -> (state1'=1); + + // if there is no team and has required skill - initiating the team + [] state1=1 & !committed & team_size_t1=0 & has_resource_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2=0 & has_resource_t2 -> (m1_t2'=1); + + // if team already exists and one of the neighbours is in it - joining the team + [] state1=1 & !committed & team_size_t1>0 & can_join_t1 & has_resource_t1 & !resource_filled_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2>0 & can_join_t2 & has_resource_t2 & !resource_filled_t2 -> (m1_t2'=1); + + [fin1] state1>0 -> (state1'=0); + +endmodule + +module sensor2 = sensor1 +[ + state1=state2, + + str1=str2, + fin1=fin2, + + m1_t1=m2_t1, + m1_t2=m2_t2, + + m2_t1=m1_t1, + m2_t2=m1_t2, + + resource1=resource2, + resource2=resource1, + + e12=e21, + e13=e23, + e14=e24, + e15=e25, + + e21=e12, + e23=e13, + e24=e14, + e25=e15 +] +endmodule + +module sensor3 = sensor1 +[ + state1=state3, + + str1=str3, + fin1=fin3, + + m1_t1=m3_t1, + m1_t2=m3_t2, + m3_t1=m1_t1, + m3_t2=m1_t2, + + resource1=resource3, + resource3=resource1, + + e12=e32, + e13=e31, + e14=e34, + e15=e35, + + e31=e13, + e32=e12, + e34=e14, + e35=e15 +] +endmodule + +module sensor4 = sensor1 +[ + state1=state4, + + str1=str4, + fin1=fin4, + + m1_t1=m4_t1, + m1_t2=m4_t2, + + m4_t1=m1_t1, + m4_t2=m1_t2, + + resource1=resource4, + resource4=resource1, + + e12=e42, + e13=e43, + e14=e41, + e15=e45, + + e41=e14, + e42=e12, + e43=e13, + e45=e15 +] +endmodule + + + +// agent is committed to some team +formula committed = (m1_t1+m1_t2) > 0; + +// formulae to compute team sizes +formula team_size_t1 = m1_t1+m2_t1+m3_t1+m4_t1; +formula team_size_t2 = m1_t2+m2_t2+m3_t2+m4_t2; + +// formulae to check whether the agent can join the team +formula can_join_t1 = e12*m2_t1 + e13*m3_t1 + e14*m4_t1 > 0; +formula can_join_t2 = e12*m2_t2 + e13*m3_t2 + e14*m4_t2 > 0; + +// formulae to check whether agent has the resource required by the task +formula has_resource_t1 = ( (t1_r1=1&resource1=1) | (t1_r2=1&resource1=2) | (t1_r3=1&resource1=3) ); +formula has_resource_t2 = ( (t2_r1=1&resource1=1) | (t2_r2=1&resource1=2) | (t2_r3=1&resource1=3) ); + +// formulae to check whether the resource of an agent has been already filled in the team +formula resource_filled_t1 = (m2_t1=1 & resource1=resource2) | (m3_t1=1 & resource1=resource3) | (m4_t1=1 & resource1=resource4); +formula resource_filled_t2 = (m2_t2=1 & resource1=resource2) | (m3_t2=1 & resource1=resource3) | (m4_t2=1 & resource1=resource4); + +// formula to compute team initiation probability (assuming each agent has at least one connection) +formula IP = (e12*(1-((m2_t1+m2_t2)=0?0:1))+e13*(1-((m3_t1+m3_t2)=0?0:1))+e14*(1-((m4_t1+m4_t2)=0?0:1))) / (e12+e13+e14); + + + + +// labels and formulae for property specification +formula finished = (status=6); +label "end" = (status=7); + + +formula agent1_joins_successful_team = (task1_completed & m1_t1=1) | (task2_completed & m1_t2=1); +formula agent1_joins_successful_team_of_1 = (task1_completed & m1_t1=1 & team_size_t1=1) | (task2_completed & m1_t2=1 & team_size_t2=1); +formula agent1_joins_successful_team_of_2 = (task1_completed & m1_t1=1 & team_size_t1=2) | (task2_completed & m1_t2=1 & team_size_t2=2); +formula agent1_joins_successful_team_of_3 = (task1_completed & m1_t1=1 & team_size_t1=3) | (task2_completed & m1_t2=1 & team_size_t2=3); + +formula agent2_joins_successful_team = (task1_completed & m2_t1=1) | (task2_completed & m2_t2=1); +formula agent2_joins_successful_team_of_1 = (task1_completed & m2_t1=1 & team_size_t1=1) | (task2_completed & m2_t2=1 & team_size_t2=1); +formula agent2_joins_successful_team_of_2 = (task1_completed & m2_t1=1 & team_size_t1=2) | (task2_completed & m2_t2=1 & team_size_t2=2); +formula agent2_joins_successful_team_of_3 = (task1_completed & m2_t1=1 & team_size_t1=3) | (task2_completed & m2_t2=1 & team_size_t2=3); + +formula agent3_joins_successful_team = (task1_completed & m3_t1=1) | (task2_completed & m3_t2=1); +formula agent3_joins_successful_team_of_1 = (task1_completed & m3_t1=1 & team_size_t1=1) | (task2_completed & m3_t2=1 & team_size_t2=1); +formula agent3_joins_successful_team_of_2 = (task1_completed & m3_t1=1 & team_size_t1=2) | (task2_completed & m3_t2=1 & team_size_t2=2); +formula agent3_joins_successful_team_of_3 = (task1_completed & m3_t1=1 & team_size_t1=3) | (task2_completed & m3_t2=1 & team_size_t2=3); + +formula agent4_joins_successful_team = (task1_completed & m4_t1=1) | (task2_completed & m4_t2=1); +formula agent4_joins_successful_team_of_1 = (task1_completed & m4_t1=1 & team_size_t1=1) | (task2_completed & m4_t2=1 & team_size_t2=1); +formula agent4_joins_successful_team_of_2 = (task1_completed & m4_t1=1 & team_size_t1=2) | (task2_completed & m4_t2=1 & team_size_t2=2); +formula agent4_joins_successful_team_of_3 = (task1_completed & m4_t1=1 & team_size_t1=3) | (task2_completed & m4_t2=1 & team_size_t2=3); + +formula task1_completed = finished + & ((t1_r1=1)=>((m1_t1=1&resource1=1)|(m2_t1=1&resource2=1)|(m3_t1=1&resource3=1)|(m4_t1=1&resource4=1))) + & ((t1_r2=1)=>((m1_t1=1&resource1=2)|(m2_t1=1&resource2=2)|(m3_t1=1&resource3=2)|(m4_t1=1&resource4=2))) + & ((t1_r3=1)=>((m1_t1=1&resource1=3)|(m2_t1=1&resource2=3)|(m3_t1=1&resource3=3)|(m4_t1=1&resource4=3))); + +formula task2_completed = finished + & ((t2_r1=1)=>((m1_t2=1&resource1=1)|(m2_t2=1&resource2=1)|(m3_t2=1&resource3=1)|(m4_t2=1&resource4=1))) + & ((t2_r2=1)=>((m1_t2=1&resource1=2)|(m2_t2=1&resource2=2)|(m3_t2=1&resource3=2)|(m4_t2=1&resource4=2))) + & ((t2_r3=1)=>((m1_t2=1&resource1=3)|(m2_t2=1&resource2=3)|(m3_t2=1&resource3=3)|(m4_t2=1&resource4=3))); + +// rewards +rewards "w_1_total" + [] agent1_joins_successful_team : 1; + [] agent2_joins_successful_team : 1; + [] agent3_joins_successful_team : 1; + [] agent4_joins_successful_team : 1; +endrewards + +rewards "w_2_total" + [] task1_completed : 1; + [] task2_completed : 1; +endrewards + + + + + diff --git a/examples/multi-objective/mdp/team/team3obj_5.nm b/examples/multi-objective/mdp/team/team3obj_5.nm new file mode 100644 index 000000000..4a02b8746 --- /dev/null +++ b/examples/multi-objective/mdp/team/team3obj_5.nm @@ -0,0 +1,531 @@ +mdp + +// parameters +const int n_resources = 3; +const int n_tasks = 2; +const int n_sensors = 5; + + +// sensor resources +const int resource1=1; +const int resource2=2; +const int resource3=3; +const int resource4=1; +const int resource5=2; + +// network configuration +const int e12=1; +const int e13=1; +const int e14=1; +const int e15=1; + +const int e21=e12; +const int e23=1; +const int e24=1; +const int e25=1; + +const int e31=e13; +const int e32=e23; +const int e34=1; +const int e35=1; + +const int e41=e14; +const int e42=e24; +const int e43=e34; +const int e45=1; + +const int e51=e15; +const int e52=e25; +const int e53=e35; +const int e54=e45; + +module controller // schedules the algorithm + + // algorithm status + status : [0..8]; + + // task resource indicator variables + t1_r1 : [0..1]; + t1_r2 : [0..1]; + t1_r3 : [0..1]; + + t2_r1 : [0..1]; + t2_r2 : [0..1]; + t2_r3 : [0..1]; + + // schedule placeholders + turn1 : [0..n_sensors]; + turn2 : [0..n_sensors]; + turn3 : [0..n_sensors]; + turn4 : [0..n_sensors]; + turn5 : [0..n_sensors]; + + // selecting schedule uniformly at random + [] status=0 -> 1/120 : (turn1'=1) & (turn2'=2) & (turn3'=3) & (turn4'=4) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=2) & (turn3'=3) & (turn4'=5) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=2) & (turn3'=4) & (turn4'=3) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=2) & (turn3'=4) & (turn4'=5) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=2) & (turn3'=5) & (turn4'=3) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=2) & (turn3'=5) & (turn4'=4) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=3) & (turn3'=2) & (turn4'=4) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=3) & (turn3'=2) & (turn4'=5) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=3) & (turn3'=4) & (turn4'=2) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=3) & (turn3'=4) & (turn4'=5) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=3) & (turn3'=5) & (turn4'=2) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=3) & (turn3'=5) & (turn4'=4) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=4) & (turn3'=2) & (turn4'=3) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=4) & (turn3'=2) & (turn4'=5) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=4) & (turn3'=3) & (turn4'=2) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=4) & (turn3'=3) & (turn4'=5) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=4) & (turn3'=5) & (turn4'=2) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=4) & (turn3'=5) & (turn4'=3) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=5) & (turn3'=2) & (turn4'=3) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=5) & (turn3'=2) & (turn4'=4) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=5) & (turn3'=3) & (turn4'=2) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=5) & (turn3'=3) & (turn4'=4) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=5) & (turn3'=4) & (turn4'=2) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=1) & (turn2'=5) & (turn3'=4) & (turn4'=3) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=1) & (turn3'=3) & (turn4'=4) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=1) & (turn3'=3) & (turn4'=5) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=1) & (turn3'=4) & (turn4'=3) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=1) & (turn3'=4) & (turn4'=5) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=1) & (turn3'=5) & (turn4'=3) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=1) & (turn3'=5) & (turn4'=4) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=3) & (turn3'=1) & (turn4'=4) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=3) & (turn3'=1) & (turn4'=5) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=3) & (turn3'=4) & (turn4'=1) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=3) & (turn3'=4) & (turn4'=5) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=3) & (turn3'=5) & (turn4'=1) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=3) & (turn3'=5) & (turn4'=4) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=4) & (turn3'=1) & (turn4'=3) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=4) & (turn3'=1) & (turn4'=5) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=4) & (turn3'=3) & (turn4'=1) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=4) & (turn3'=3) & (turn4'=5) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=4) & (turn3'=5) & (turn4'=1) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=4) & (turn3'=5) & (turn4'=3) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=5) & (turn3'=1) & (turn4'=3) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=5) & (turn3'=1) & (turn4'=4) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=5) & (turn3'=3) & (turn4'=1) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=5) & (turn3'=3) & (turn4'=4) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=5) & (turn3'=4) & (turn4'=1) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=2) & (turn2'=5) & (turn3'=4) & (turn4'=3) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=1) & (turn3'=2) & (turn4'=4) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=1) & (turn3'=2) & (turn4'=5) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=1) & (turn3'=4) & (turn4'=2) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=1) & (turn3'=4) & (turn4'=5) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=1) & (turn3'=5) & (turn4'=2) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=1) & (turn3'=5) & (turn4'=4) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=2) & (turn3'=1) & (turn4'=4) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=2) & (turn3'=1) & (turn4'=5) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=2) & (turn3'=4) & (turn4'=1) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=2) & (turn3'=4) & (turn4'=5) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=2) & (turn3'=5) & (turn4'=1) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=2) & (turn3'=5) & (turn4'=4) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=4) & (turn3'=1) & (turn4'=2) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=4) & (turn3'=1) & (turn4'=5) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=4) & (turn3'=2) & (turn4'=1) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=4) & (turn3'=2) & (turn4'=5) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=4) & (turn3'=5) & (turn4'=1) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=4) & (turn3'=5) & (turn4'=2) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=5) & (turn3'=1) & (turn4'=2) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=5) & (turn3'=1) & (turn4'=4) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=5) & (turn3'=2) & (turn4'=1) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=5) & (turn3'=2) & (turn4'=4) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=5) & (turn3'=4) & (turn4'=1) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=3) & (turn2'=5) & (turn3'=4) & (turn4'=2) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=1) & (turn3'=2) & (turn4'=3) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=1) & (turn3'=2) & (turn4'=5) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=1) & (turn3'=3) & (turn4'=2) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=1) & (turn3'=3) & (turn4'=5) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=1) & (turn3'=5) & (turn4'=2) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=1) & (turn3'=5) & (turn4'=3) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=2) & (turn3'=1) & (turn4'=3) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=2) & (turn3'=1) & (turn4'=5) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=2) & (turn3'=3) & (turn4'=1) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=2) & (turn3'=3) & (turn4'=5) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=2) & (turn3'=5) & (turn4'=1) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=2) & (turn3'=5) & (turn4'=3) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=3) & (turn3'=1) & (turn4'=2) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=3) & (turn3'=1) & (turn4'=5) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=3) & (turn3'=2) & (turn4'=1) & (turn5'=5) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=3) & (turn3'=2) & (turn4'=5) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=3) & (turn3'=5) & (turn4'=1) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=3) & (turn3'=5) & (turn4'=2) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=5) & (turn3'=1) & (turn4'=2) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=5) & (turn3'=1) & (turn4'=3) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=5) & (turn3'=2) & (turn4'=1) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=5) & (turn3'=2) & (turn4'=3) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=5) & (turn3'=3) & (turn4'=1) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=4) & (turn2'=5) & (turn3'=3) & (turn4'=2) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=1) & (turn3'=2) & (turn4'=3) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=1) & (turn3'=2) & (turn4'=4) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=1) & (turn3'=3) & (turn4'=2) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=1) & (turn3'=3) & (turn4'=4) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=1) & (turn3'=4) & (turn4'=2) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=1) & (turn3'=4) & (turn4'=3) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=2) & (turn3'=1) & (turn4'=3) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=2) & (turn3'=1) & (turn4'=4) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=2) & (turn3'=3) & (turn4'=1) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=2) & (turn3'=3) & (turn4'=4) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=2) & (turn3'=4) & (turn4'=1) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=2) & (turn3'=4) & (turn4'=3) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=3) & (turn3'=1) & (turn4'=2) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=3) & (turn3'=1) & (turn4'=4) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=3) & (turn3'=2) & (turn4'=1) & (turn5'=4) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=3) & (turn3'=2) & (turn4'=4) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=3) & (turn3'=4) & (turn4'=1) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=3) & (turn3'=4) & (turn4'=2) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=4) & (turn3'=1) & (turn4'=2) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=4) & (turn3'=1) & (turn4'=3) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=4) & (turn3'=2) & (turn4'=1) & (turn5'=3) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=4) & (turn3'=2) & (turn4'=3) & (turn5'=1) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=4) & (turn3'=3) & (turn4'=1) & (turn5'=2) & (status'=1) + + 1/120 : (turn1'=5) & (turn2'=4) & (turn3'=3) & (turn4'=2) & (turn5'=1) & (status'=1); + + + // initialising non-empty tasks uniformly at random + [] status=1 -> 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=0) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=0) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=0) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=0) & (t2_r2'=1) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=0) & (t2_r3'=1) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=0) & (status'=2) + + 1/49 : (t1_r1'=1) & (t1_r2'=1) & (t1_r3'=1) & (t2_r1'=1) & (t2_r2'=1) & (t2_r3'=1) & (status'=2); + + // executing the schedule + + // 1st round + [str1] status=2 & turn1=1 -> (status'=2); + [fin1] status=2 & turn1=1 -> (status'=3); + [str2] status=2 & turn1=2 -> (status'=2); + [fin2] status=2 & turn1=2 -> (status'=3); + [str3] status=2 & turn1=3 -> (status'=2); + [fin3] status=2 & turn1=3 -> (status'=3); + [str4] status=2 & turn1=4 -> (status'=2); + [fin4] status=2 & turn1=4 -> (status'=3); + [str5] status=2 & turn1=5 -> (status'=2); + [fin5] status=2 & turn1=5 -> (status'=3); + + // 2nd round + [str1] status=3 & turn2=1 -> (status'=3); + [fin1] status=3 & turn2=1 -> (status'=4); + [str2] status=3 & turn2=2 -> (status'=3); + [fin2] status=3 & turn2=2 -> (status'=4); + [str3] status=3 & turn2=3 -> (status'=3); + [fin3] status=3 & turn2=3 -> (status'=4); + [str4] status=3 & turn2=4 -> (status'=3); + [fin4] status=3 & turn2=4 -> (status'=4); + [str5] status=3 & turn2=5 -> (status'=3); + [fin5] status=3 & turn2=5 -> (status'=4); + + // 3rd round + [str1] status=4 & turn3=1 -> (status'=4); + [fin1] status=4 & turn3=1 -> (status'=5); + [str2] status=4 & turn3=2 -> (status'=4); + [fin2] status=4 & turn3=2 -> (status'=5); + [str3] status=4 & turn3=3 -> (status'=4); + [fin3] status=4 & turn3=3 -> (status'=5); + [str4] status=4 & turn3=4 -> (status'=4); + [fin4] status=4 & turn3=4 -> (status'=5); + [str5] status=4 & turn3=5 -> (status'=4); + [fin5] status=4 & turn3=5 -> (status'=5); + + // 4th round + [str1] status=5 & turn4=1 -> (status'=5); + [fin1] status=5 & turn4=1 -> (status'=6); + [str2] status=5 & turn4=2 -> (status'=5); + [fin2] status=5 & turn4=2 -> (status'=6); + [str3] status=5 & turn4=3 -> (status'=5); + [fin3] status=5 & turn4=3 -> (status'=6); + [str4] status=5 & turn4=4 -> (status'=5); + [fin4] status=5 & turn4=4 -> (status'=6); + [str5] status=5 & turn4=5 -> (status'=5); + [fin5] status=5 & turn4=5 -> (status'=6); + + // 5th round + [str1] status=6 & turn5=1 -> (status'=6); + [fin1] status=6 & turn5=1 -> (status'=7); + [str2] status=6 & turn5=2 -> (status'=6); + [fin2] status=6 & turn5=2 -> (status'=7); + [str3] status=6 & turn5=3 -> (status'=6); + [fin3] status=6 & turn5=3 -> (status'=7); + [str4] status=6 & turn5=4 -> (status'=6); + [fin4] status=6 & turn5=4 -> (status'=7); + [str5] status=6 & turn5=5 -> (status'=6); + [fin5] status=6 & turn5=5 -> (status'=7); + + [] status=7 -> (status'=8); + + [] status=8 -> (status'=8); + +endmodule + +module sensor1 + + state1 : [0..1]; + + // team membership indicators + m1_t1 : [0..1]; + m1_t2 : [0..1]; + + // starting turn, selecting order of tasks + [str1] state1=0 -> (state1'=1); + + // if there is no team and has required skill - initiating the team + [] state1=1 & !committed & team_size_t1=0 & has_resource_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2=0 & has_resource_t2 -> (m1_t2'=1); + + // if team already exists and one of the neighbours is in it - joining the team + [] state1=1 & !committed & team_size_t1>0 & can_join_t1 & has_resource_t1 & !resource_filled_t1 -> (m1_t1'=1); + [] state1=1 & !committed & team_size_t2>0 & can_join_t2 & has_resource_t2 & !resource_filled_t2 -> (m1_t2'=1); + + [fin1] state1>0 -> (state1'=0); + +endmodule + +module sensor2 = sensor1 +[ + state1=state2, + + str1=str2, + fin1=fin2, + + m1_t1=m2_t1, + m1_t2=m2_t2, + + m2_t1=m1_t1, + m2_t2=m1_t2, + + resource1=resource2, + resource2=resource1, + + e12=e21, + e13=e23, + e14=e24, + e15=e25, + + e21=e12, + e23=e13, + e24=e14, + e25=e15 +] +endmodule + +module sensor3 = sensor1 +[ + state1=state3, + + str1=str3, + fin1=fin3, + + m1_t1=m3_t1, + m1_t2=m3_t2, + m3_t1=m1_t1, + m3_t2=m1_t2, + + resource1=resource3, + resource3=resource1, + + e12=e32, + e13=e31, + e14=e34, + e15=e35, + + e31=e13, + e32=e12, + e34=e14, + e35=e15 +] +endmodule + +module sensor4 = sensor1 +[ + state1=state4, + + str1=str4, + fin1=fin4, + + m1_t1=m4_t1, + m1_t2=m4_t2, + + m4_t1=m1_t1, + m4_t2=m1_t2, + + resource1=resource4, + resource4=resource1, + + e12=e42, + e13=e43, + e14=e41, + e15=e45, + + e41=e14, + e42=e12, + e43=e13, + e45=e15 +] +endmodule + +module sensor5 = sensor1 +[ + state1=state5, + + str1=str5, + fin1=fin5, + + m1_t1=m5_t1, + m1_t2=m5_t2, + + m5_t1=m1_t1, + m5_t2=m1_t2, + + resource1=resource5, + resource5=resource1, + + e12=e52, + e13=e53, + e14=e54, + e15=e51, + + e51=e15, + e52=e12, + e53=e13, + e54=e14 +] +endmodule + +// formulae for scheduling +formula s1_sched = (turn1=1 | turn2=1 | turn3=1 | turn4=1 | turn5=1); +formula s2_sched = (turn1=2 | turn2=2 | turn3=2 | turn4=2 | turn5=2); +formula s3_sched = (turn1=3 | turn2=3 | turn3=3 | turn4=3 | turn5=3); +formula s4_sched = (turn1=4 | turn2=4 | turn3=4 | turn4=4 | turn5=4); +formula s5_sched = (turn1=5 | turn2=5 | turn3=5 | turn4=5 | turn5=5); +formula all_not_sched = !(s1_sched | s2_sched | s3_sched | s4_sched | s5_sched); +formula all_sched = (s1_sched & s2_sched & s3_sched & s4_sched & s5_sched); + + +// agent is committed to some team +formula committed = (m1_t1+m1_t2) > 0; + +// formulae to compute team sizes +formula team_size_t1 = m1_t1+m2_t1+m3_t1+m4_t1+m5_t1; +formula team_size_t2 = m1_t2+m2_t2+m3_t2+m4_t2+m5_t2; + +// formulae to check whether the agent can join the team +formula can_join_t1 = e12*m2_t1 + e13*m3_t1 + e14*m4_t1 + e15*m5_t1 > 0; +formula can_join_t2 = e12*m2_t2 + e13*m3_t2 + e14*m4_t2 + e15*m5_t2 > 0; + +// formulae to check whether agent has the resource required by the task +formula has_resource_t1 = ( (t1_r1=1&resource1=1) | (t1_r2=1&resource1=2) | (t1_r3=1&resource1=3) ); +formula has_resource_t2 = ( (t2_r1=1&resource1=1) | (t2_r2=1&resource1=2) | (t2_r3=1&resource1=3) ); + +// formulae to check whether the resource of an agent has been already filled in the team +formula resource_filled_t1 = (m2_t1=1 & resource1=resource2) | (m3_t1=1 & resource1=resource3) | (m4_t1=1 & resource1=resource4) | (m5_t1=1 & resource1=resource5); +formula resource_filled_t2 = (m2_t2=1 & resource1=resource2) | (m3_t2=1 & resource1=resource3) | (m4_t2=1 & resource1=resource4) | (m5_t2=1 & resource1=resource5); + +// formula to compute team initiation probability (assuming each agent has at least one connection) +formula IP = (e12*(1-((m2_t1+m2_t2)=0?0:1))+e13*(1-((m3_t1+m3_t2)=0?0:1))+e14*(1-((m4_t1+m4_t2)=0?0:1))+e15*(1-((m5_t1+m5_t2)=0?0:1))) / (e12+e13+e14+e15); + + + + +// labels and formulae for property specification +formula finished = (status=7); +label "end" = (status=8); + + +formula agent1_joins_successful_team = (task1_completed & m1_t1=1) | (task2_completed & m1_t2=1); +formula agent1_joins_successful_team_of_1 = (task1_completed & m1_t1=1 & team_size_t1=1) | (task2_completed & m1_t2=1 & team_size_t2=1); +formula agent1_joins_successful_team_of_2 = (task1_completed & m1_t1=1 & team_size_t1=2) | (task2_completed & m1_t2=1 & team_size_t2=2); +formula agent1_joins_successful_team_of_3 = (task1_completed & m1_t1=1 & team_size_t1=3) | (task2_completed & m1_t2=1 & team_size_t2=3); + +formula agent2_joins_successful_team = (task1_completed & m2_t1=1) | (task2_completed & m2_t2=1); +formula agent2_joins_successful_team_of_1 = (task1_completed & m2_t1=1 & team_size_t1=1) | (task2_completed & m2_t2=1 & team_size_t2=1); +formula agent2_joins_successful_team_of_2 = (task1_completed & m2_t1=1 & team_size_t1=2) | (task2_completed & m2_t2=1 & team_size_t2=2); +formula agent2_joins_successful_team_of_3 = (task1_completed & m2_t1=1 & team_size_t1=3) | (task2_completed & m2_t2=1 & team_size_t2=3); + +formula agent3_joins_successful_team = (task1_completed & m3_t1=1) | (task2_completed & m3_t2=1); +formula agent3_joins_successful_team_of_1 = (task1_completed & m3_t1=1 & team_size_t1=1) | (task2_completed & m3_t2=1 & team_size_t2=1); +formula agent3_joins_successful_team_of_2 = (task1_completed & m3_t1=1 & team_size_t1=2) | (task2_completed & m3_t2=1 & team_size_t2=2); +formula agent3_joins_successful_team_of_3 = (task1_completed & m3_t1=1 & team_size_t1=3) | (task2_completed & m3_t2=1 & team_size_t2=3); + +formula agent4_joins_successful_team = (task1_completed & m4_t1=1) | (task2_completed & m4_t2=1); +formula agent4_joins_successful_team_of_1 = (task1_completed & m4_t1=1 & team_size_t1=1) | (task2_completed & m4_t2=1 & team_size_t2=1); +formula agent4_joins_successful_team_of_2 = (task1_completed & m4_t1=1 & team_size_t1=2) | (task2_completed & m4_t2=1 & team_size_t2=2); +formula agent4_joins_successful_team_of_3 = (task1_completed & m4_t1=1 & team_size_t1=3) | (task2_completed & m4_t2=1 & team_size_t2=3); + +formula agent5_joins_successful_team = (task1_completed & m5_t1=1) | (task2_completed & m5_t2=1); +formula agent5_joins_successful_team_of_1 = (task1_completed & m5_t1=1 & team_size_t1=1) | (task2_completed & m5_t2=1 & team_size_t2=1); +formula agent5_joins_successful_team_of_2 = (task1_completed & m5_t1=1 & team_size_t1=2) | (task2_completed & m5_t2=1 & team_size_t2=2); +formula agent5_joins_successful_team_of_3 = (task1_completed & m5_t1=1 & team_size_t1=3) | (task2_completed & m5_t2=1 & team_size_t2=3); + +formula task1_completed = finished + & ((t1_r1=1)=>((m1_t1=1&resource1=1)|(m2_t1=1&resource2=1)|(m3_t1=1&resource3=1)|(m4_t1=1&resource4=1)|(m5_t1=1&resource5=1))) + & ((t1_r2=1)=>((m1_t1=1&resource1=2)|(m2_t1=1&resource2=2)|(m3_t1=1&resource3=2)|(m4_t1=1&resource4=2)|(m5_t1=1&resource5=2))) + & ((t1_r3=1)=>((m1_t1=1&resource1=3)|(m2_t1=1&resource2=3)|(m3_t1=1&resource3=3)|(m4_t1=1&resource4=3)|(m5_t1=1&resource5=3))); + +formula task2_completed = finished + & ((t2_r1=1)=>((m1_t2=1&resource1=1)|(m2_t2=1&resource2=1)|(m3_t2=1&resource3=1)|(m4_t2=1&resource4=1)|(m5_t2=1&resource5=1))) + & ((t2_r2=1)=>((m1_t2=1&resource1=2)|(m2_t2=1&resource2=2)|(m3_t2=1&resource3=2)|(m4_t2=1&resource4=2)|(m5_t2=1&resource5=2))) + & ((t2_r3=1)=>((m1_t2=1&resource1=3)|(m2_t2=1&resource2=3)|(m3_t2=1&resource3=3)|(m4_t2=1&resource4=3)|(m5_t2=1&resource5=3))); + +// rewards +rewards "w_1_total" + [] agent1_joins_successful_team : 1; + [] agent2_joins_successful_team : 1; + [] agent3_joins_successful_team : 1; + [] agent4_joins_successful_team : 1; + [] agent5_joins_successful_team : 1; +endrewards + +rewards "w_2_total" + [] task1_completed : 1; + [] task2_completed : 1; +endrewards + + + + + diff --git a/examples/multi-objective/mdp/zeroconf-tb/origFiles/zeroconf_host_multi2_time.nm b/examples/multi-objective/mdp/zeroconf-tb/origFiles/zeroconf_host_multi2_time.nm new file mode 100644 index 000000000..ad0f4a3b7 --- /dev/null +++ b/examples/multi-objective/mdp/zeroconf-tb/origFiles/zeroconf_host_multi2_time.nm @@ -0,0 +1,169 @@ +// IPv4: PTA model with digitial clocks +// multi-objective model of the host +// gxn/dxp 28/09/09 + +mdp + +//------------------------------------------------------------- +// VARIABLES +const int N=20; // number of abstract hosts +const int K=2; // number of probes to send + +// PROBABILITIES +const double old = N/65024; // probability pick an ip address being used +//const double old = 1/2; // probability pick an ip address being used +const double new = (1-old); // probability pick a new ip address + +// TIMING CONSTANTS +const int CONSEC = 2; // time interval between sending consecutive probles +const int TRANSTIME = 1; // upper bound on transmission time delay +const int LONGWAIT = 60; // minimum time delay after a high number of address collisions +const int DEFEND = 10; + +const int TIME_MAX_X = 60; // max value of clock x +const int TIME_MAX_Y = 10; // max value of clock y +const int TIME_MAX_Z = 1; // max value of clock z + +// OTHER CONSTANTS +const int MAXCOLL = 10; // maximum number of collisions before long wait + + +//------------------------------------------------------------- +// CONCRETE HOST +module host0 + + x : [0..TIME_MAX_X]; // first clock of the host + y : [0..TIME_MAX_Y]; // second clock of the host + + coll : [0..MAXCOLL]; // number of address collisions + probes : [0..K]; // counter (number of probes sent) + mess : [0..1]; // need to send a message or not + defend : [0..1]; // defend (if =1, try to defend IP address) + + ip : [1..2]; // ip address (1 - in use & 2 - fresh) + + l : [0..4] init 1; // location + // 0 : RECONFIGURE + // 1 : RANDOM + // 2 : WAITSP + // 3 : WAITSG + // 4 : USE + + // RECONFIGURE + [reset] l=0 -> (l'=1); + + // RANDOM (choose IP address) + [rec0] (l=1) -> true; // get message (ignore since have no ip address) + [rec1] (l=1) -> true; // get message (ignore since have no ip address) + // small number of collisions (choose straight away) + [] l=1 & coll 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + // large number of collisions: (wait for LONGWAIT) + [time] l=1 & coll=MAXCOLL & x (x'=min(x+1,TIME_MAX_X)); + [] l=1 & coll=MAXCOLL & x=LONGWAIT -> 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + + // WAITSP + // let time pass + [time] l=2 & x<2 -> (x'=min(x+1,2)); + // send probe + [send1] l=2 & ip=1 & x=2 & probes (x'=0) & (probes'=probes+1); + [send2] l=2 & ip=2 & x=2 & probes (x'=0) & (probes'=probes+1); + // sent K probes and waited 2 seconds + [configured] l=2 & x=2 & probes=K -> (l'=3) & (probes'=0) & (coll'=0) & (x'=0); + // get message and ip does not match: ignore + [rec0] l=2 & ip!=0 -> (l'=l); + [rec1] l=2 & ip!=1 -> (l'=l); + // get a message with matching ip: reconfigure + [rec1] l=2 & ip=1 -> (l'=0) & (coll'=min(coll+1,MAXCOLL)) & (x'=0) & (probes'=0); + + // WAITSG (sends two gratuitious arp probes) + // time passage + [time] l=3 & mess=0 & defend=0 & x (x'=min(x+1,TIME_MAX_X)); + [time] l=3 & mess=0 & defend=1 & x (x'=min(x+1,TIME_MAX_X)) & (y'=min(y+1,DEFEND)); + + // receive message and same ip: defend + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y>=DEFEND) -> (defend'=1) & (mess'=1) & (y'=0); + // receive message and same ip: defer + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y (l'=0) & (probes'=0) & (defend'=0) & (x'=0) & (y'=0); + // receive message and different ip + [rec0] l=3 & mess=0 & ip!=0 -> (l'=l); + [rec1] l=3 & mess=0 & ip!=1 -> (l'=l); + + + // send probe reply or message for defence + [send1] l=3 & ip=1 & mess=1 -> (mess'=0); + [send2] l=3 & ip=2 & mess=1 -> (mess'=0); + // send first gratuitous arp message + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + // send second gratuitous arp message (move to use) + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + + // USE (only interested in reaching this state so do not need to add anything here) + [] l=4 -> true; + +endmodule + +//------------------------------------------------------------- +// error automaton for the environment assumption +// do not get a reply when K probes are sent +const int M; // time between sending and receiving a message + +module env_error2 + + env : [0..1]; // 0 active and 1 done + k : [0..2]; // counts the number of messages sent + c1 : [0..M+1]; // time since first message + c2 : [0..M+1]; // time since second message + error : [0..1]; + + // message with new ip address arrives so done + [send2] error=0 & env=0 -> (env'=1); + // message with old ip address arrives so count + [send1] error=0 & env=0 -> (k'=min(k+1,K)); + // time passgae so update relevant clocks + [time] error=0 & env=0 & k=0 -> true; + [time] error=0 & env=0 & k=1 & min(c1,c2) (c1'=min(c1+1,M+1)); + [time] error=0 & env=0 & k=2 & min(c1,c2) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)); + // all clocks reached their bound so an error + [time] error=0 & env=0 & min(c1,c2)=M -> (error'=1); + // send a reply (then done) + [rec1] error=0 & env=0 & k>0 & min(c1,c2)<=M -> (env'=1); + // finished so any action can be performed + [time] error=1 | env=1 -> true; + [send1] error=1 | env=1 -> true; + [send2] error=1 | env=1 -> true; + [rec1] error=1 | env=1 -> true; + +endmodule + +//------------------------------------------------------------- +// error automaton for the time bounded assumption +// host does not send configured signal within T seconds +const int T; + +module time_error + + time_error : [0..1]; + done : [0..1]; + t : [0..T]; + + [time] t (t'=t+1); // time passes and bound not reached + [time] t=T-1 & done=0 & time_error=0 -> (time_error'=1); // bound reached so error + [configured] time_error=0 -> (done'=1); // configured within the time bound + + // when in error or done state can loop with either action + [configured] time_error=1 | done=1 -> true; + [time] time_error=1 | done=1 -> true; + +endmodule diff --git a/examples/multi-objective/mdp/zeroconf-tb/origFiles/zeroconf_host_multi4_time.nm b/examples/multi-objective/mdp/zeroconf-tb/origFiles/zeroconf_host_multi4_time.nm new file mode 100644 index 000000000..71984c286 --- /dev/null +++ b/examples/multi-objective/mdp/zeroconf-tb/origFiles/zeroconf_host_multi4_time.nm @@ -0,0 +1,174 @@ +// IPv4: PTA model with digitial clocks +// multi-objective model of the host +// gxn/dxp 28/09/09 + +mdp + +//------------------------------------------------------------- +// VARIABLES +const int N=20; // number of abstract hosts +const int K=4; // number of probes to send + +// PROBABILITIES +const double old = N/65024; // probability pick an ip address being used +//const double old = 0.5; // probability pick an ip address being used +const double new = (1-old); // probability pick a new ip address + +// TIMING CONSTANTS +const int CONSEC = 2; // time interval between sending consecutive probles +const int TRANSTIME = 1; // upper bound on transmission time delay +const int LONGWAIT = 60; // minimum time delay after a high number of address collisions +const int DEFEND = 10; + +const int TIME_MAX_X = 60; // max value of clock x +const int TIME_MAX_Y = 10; // max value of clock y +const int TIME_MAX_Z = 1; // max value of clock z + +// OTHER CONSTANTS +const int MAXCOLL = 10; // maximum number of collisions before long wait + + +//------------------------------------------------------------- +// CONCRETE HOST +module host0 + + x : [0..TIME_MAX_X]; // first clock of the host + y : [0..TIME_MAX_Y]; // second clock of the host + + coll : [0..MAXCOLL]; // number of address collisions + probes : [0..K]; // counter (number of probes sent) + mess : [0..1]; // need to send a message or not + defend : [0..1]; // defend (if =1, try to defend IP address) + + ip : [1..2]; // ip address (1 - in use & 2 - fresh) + + l : [0..4] init 1; // location + // 0 : RECONFIGURE + // 1 : RANDOM + // 2 : WAITSP + // 3 : WAITSG + // 4 : USE + + // RECONFIGURE + [reset] l=0 -> (l'=1); + + // RANDOM (choose IP address) + [rec0] (l=1) -> true; // get message (ignore since have no ip address) + [rec1] (l=1) -> true; // get message (ignore since have no ip address) + // small number of collisions (choose straight away) + [] l=1 & coll 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + // large number of collisions: (wait for LONGWAIT) + [time] l=1 & coll=MAXCOLL & x (x'=min(x+1,TIME_MAX_X)); + [] l=1 & coll=MAXCOLL & x=LONGWAIT -> 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + + // WAITSP + // let time pass + [time] l=2 & x<2 -> (x'=min(x+1,2)); + // send probe + [send1] l=2 & ip=1 & x=2 & probes (x'=0) & (probes'=probes+1); + [send2] l=2 & ip=2 & x=2 & probes (x'=0) & (probes'=probes+1); + // sent K probes and waited 2 seconds + [configured] l=2 & x=2 & probes=K -> (l'=3) & (probes'=0) & (coll'=0) & (x'=0); + // get message and ip does not match: ignore + [rec0] l=2 & ip!=0 -> (l'=l); + [rec1] l=2 & ip!=1 -> (l'=l); + // get a message with matching ip: reconfigure + [rec1] l=2 & ip=1 -> (l'=0) & (coll'=min(coll+1,MAXCOLL)) & (x'=0) & (probes'=0); + + // WAITSG (sends two gratuitious arp probes) + // time passage + [time] l=3 & mess=0 & defend=0 & x (x'=min(x+1,TIME_MAX_X)); + [time] l=3 & mess=0 & defend=1 & x (x'=min(x+1,TIME_MAX_X)) & (y'=min(y+1,DEFEND)); + + // receive message and same ip: defend + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y>=DEFEND) -> (defend'=1) & (mess'=1) & (y'=0); + // receive message and same ip: defer + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y (l'=0) & (probes'=0) & (defend'=0) & (x'=0) & (y'=0); + // receive message and different ip + [rec0] l=3 & mess=0 & ip!=0 -> (l'=l); + [rec1] l=3 & mess=0 & ip!=1 -> (l'=l); + + + // send probe reply or message for defence + [send1] l=3 & ip=1 & mess=1 -> (mess'=0); + [send2] l=3 & ip=2 & mess=1 -> (mess'=0); + // send first gratuitous arp message + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + // send second gratuitous arp message (move to use) + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + + // USE (only interested in reaching this state so do not need to add anything here) + [] l=4 -> true; + +endmodule + +//------------------------------------------------------------- +// error automaton for the environment assumption +// do not get a reply when K probes are sent +const int M; // time between sending and receiving a message + +module env_error4 + + env : [0..1]; // 0 active and 1 done + k : [0..4]; // counts the number of messages sent + c1 : [0..M+1]; // time since first message + c2 : [0..M+1]; // time since second message + c3 : [0..M+1]; // time since third message + c4 : [0..M+1]; // time since fourth message + error : [0..1]; + + // message with new ip address arrives so done + [send2] error=0 & env=0 -> (env'=1); + // message with old ip address arrives so count + [send1] error=0 & env=0 -> (k'=min(k+1,K)); + // time passgae so update relevant clocks + [time] error=0 & env=0 & k=0 -> true; + [time] error=0 & env=0 & k=1 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)); + [time] error=0 & env=0 & k=2 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)); + [time] error=0 & env=0 & k=3 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)); + [time] error=0 & env=0 & k=4 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)) & (c4'=min(c4+1,M+1)); + // all clocks reached their bound so an error + [time] error=0 & env=0 & min(c1,c2,c3,c4)=M -> (error'=1); + // send a reply (then done) + [rec1] error=0 & env=0 & k>0 & min(c1,c2,c3,c4)<=M -> (env'=1); + // finished so any action can be performed + [time] error=1 | env=1 -> true; + [send1] error=1 | env=1 -> true; + [send2] error=1 | env=1 -> true; + [send2] error=1 | env=1 -> true; + [rec1] error=1 | env=1 -> true; + +endmodule + +//------------------------------------------------------------- +// error automaton for the time bounded assumption +// host does not send configured signal within T seconds +const int T; + +module time_error + + time_error : [0..1]; + done : [0..1]; + t : [0..T]; + + [time] t (t'=t+1); // time passes and bound not reached + [time] t=T-1 & done=0 & time_error=0 -> (time_error'=1); // bound reached so error + [configured] time_error=0 -> (done'=1); // configured within the time bound + + // when in error or done state can loop with either action + [configured] time_error=1 | done=1 -> true; + [time] time_error=1 | done=1 -> true; + +endmodule diff --git a/examples/multi-objective/mdp/zeroconf-tb/origFiles/zeroconf_host_multi_time.pctl b/examples/multi-objective/mdp/zeroconf-tb/origFiles/zeroconf_host_multi_time.pctl new file mode 100644 index 000000000..078b34c65 --- /dev/null +++ b/examples/multi-objective/mdp/zeroconf-tb/origFiles/zeroconf_host_multi_time.pctl @@ -0,0 +1,13 @@ +// Max probability of component violating assumption property (checked separately) +const double p_fail = +K=2 ? 0.19 : +K=4 ? 0.006859000000000001 : +K=6 ? 2.476099000000001E-4 : +K=8 ? 8.938717390000006E-6 : +0; + +// Assume-guarantee check via multi-objective +"num_ag": multi(Pmax=? [ F time_error=1 ] , P>=1-p_fail [ G (error=0) ]) + +// Pareto query for assume-guarantee check +"pareto": multi(Pmax=? [ F time_error=1 ] , Pmax=? [ G (error=0) ]) diff --git a/examples/multi-objective/mdp/zeroconf-tb/zeroconf-tb2_14.nm b/examples/multi-objective/mdp/zeroconf-tb/zeroconf-tb2_14.nm new file mode 100644 index 000000000..30dfd9e08 --- /dev/null +++ b/examples/multi-objective/mdp/zeroconf-tb/zeroconf-tb2_14.nm @@ -0,0 +1,169 @@ +// IPv4: PTA model with digitial clocks +// multi-objective model of the host +// gxn/dxp 28/09/09 + +mdp + +//------------------------------------------------------------- +// VARIABLES +const int N=20; // number of abstract hosts +const int K=2; // number of probes to send + +// PROBABILITIES +const double old = N/65024; // probability pick an ip address being used +//const double old = 1/2; // probability pick an ip address being used +const double new = (1-old); // probability pick a new ip address + +// TIMING CONSTANTS +const int CONSEC = 2; // time interval between sending consecutive probles +const int TRANSTIME = 1; // upper bound on transmission time delay +const int LONGWAIT = 60; // minimum time delay after a high number of address collisions +const int DEFEND = 10; + +const int TIME_MAX_X = 60; // max value of clock x +const int TIME_MAX_Y = 10; // max value of clock y +const int TIME_MAX_Z = 1; // max value of clock z + +// OTHER CONSTANTS +const int MAXCOLL = 10; // maximum number of collisions before long wait + + +//------------------------------------------------------------- +// CONCRETE HOST +module host0 + + x : [0..TIME_MAX_X]; // first clock of the host + y : [0..TIME_MAX_Y]; // second clock of the host + + coll : [0..MAXCOLL]; // number of address collisions + probes : [0..K]; // counter (number of probes sent) + mess : [0..1]; // need to send a message or not + defend : [0..1]; // defend (if =1, try to defend IP address) + + ip : [1..2]; // ip address (1 - in use & 2 - fresh) + + l : [0..4] init 1; // location + // 0 : RECONFIGURE + // 1 : RANDOM + // 2 : WAITSP + // 3 : WAITSG + // 4 : USE + + // RECONFIGURE + [reset] l=0 -> (l'=1); + + // RANDOM (choose IP address) + [rec0] (l=1) -> true; // get message (ignore since have no ip address) + [rec1] (l=1) -> true; // get message (ignore since have no ip address) + // small number of collisions (choose straight away) + [] l=1 & coll 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + // large number of collisions: (wait for LONGWAIT) + [time] l=1 & coll=MAXCOLL & x (x'=min(x+1,TIME_MAX_X)); + [] l=1 & coll=MAXCOLL & x=LONGWAIT -> 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + + // WAITSP + // let time pass + [time] l=2 & x<2 -> (x'=min(x+1,2)); + // send probe + [send1] l=2 & ip=1 & x=2 & probes (x'=0) & (probes'=probes+1); + [send2] l=2 & ip=2 & x=2 & probes (x'=0) & (probes'=probes+1); + // sent K probes and waited 2 seconds + [configured] l=2 & x=2 & probes=K -> (l'=3) & (probes'=0) & (coll'=0) & (x'=0); + // get message and ip does not match: ignore + [rec0] l=2 & ip!=0 -> (l'=l); + [rec1] l=2 & ip!=1 -> (l'=l); + // get a message with matching ip: reconfigure + [rec1] l=2 & ip=1 -> (l'=0) & (coll'=min(coll+1,MAXCOLL)) & (x'=0) & (probes'=0); + + // WAITSG (sends two gratuitious arp probes) + // time passage + [time] l=3 & mess=0 & defend=0 & x (x'=min(x+1,TIME_MAX_X)); + [time] l=3 & mess=0 & defend=1 & x (x'=min(x+1,TIME_MAX_X)) & (y'=min(y+1,DEFEND)); + + // receive message and same ip: defend + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y>=DEFEND) -> (defend'=1) & (mess'=1) & (y'=0); + // receive message and same ip: defer + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y (l'=0) & (probes'=0) & (defend'=0) & (x'=0) & (y'=0); + // receive message and different ip + [rec0] l=3 & mess=0 & ip!=0 -> (l'=l); + [rec1] l=3 & mess=0 & ip!=1 -> (l'=l); + + + // send probe reply or message for defence + [send1] l=3 & ip=1 & mess=1 -> (mess'=0); + [send2] l=3 & ip=2 & mess=1 -> (mess'=0); + // send first gratuitous arp message + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + // send second gratuitous arp message (move to use) + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + + // USE (only interested in reaching this state so do not need to add anything here) + [] l=4 -> true; + +endmodule + +//------------------------------------------------------------- +// error automaton for the environment assumption +// do not get a reply when K probes are sent +const int M; // time between sending and receiving a message + +module env_error2 + + env : [0..1]; // 0 active and 1 done + k : [0..2]; // counts the number of messages sent + c1 : [0..M+1]; // time since first message + c2 : [0..M+1]; // time since second message + error : [0..1]; + + // message with new ip address arrives so done + [send2] error=0 & env=0 -> (env'=1); + // message with old ip address arrives so count + [send1] error=0 & env=0 -> (k'=min(k+1,K)); + // time passgae so update relevant clocks + [time] error=0 & env=0 & k=0 -> true; + [time] error=0 & env=0 & k=1 & min(c1,c2) (c1'=min(c1+1,M+1)); + [time] error=0 & env=0 & k=2 & min(c1,c2) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)); + // all clocks reached their bound so an error + [time] error=0 & env=0 & min(c1,c2)=M -> (error'=1); + // send a reply (then done) + [rec1] error=0 & env=0 & k>0 & min(c1,c2)<=M -> (env'=1); + // finished so any action can be performed + [time] error=1 | env=1 -> true; + [send1] error=1 | env=1 -> true; + [send2] error=1 | env=1 -> true; + [rec1] error=1 | env=1 -> true; + +endmodule + +//------------------------------------------------------------- +// error automaton for the time bounded assumption +// host does not send configured signal within T seconds +const int T=14; + +module time_error + + time_error : [0..1]; + done : [0..1]; + t : [0..T]; + + [time] t (t'=t+1); // time passes and bound not reached + [time] t=T-1 & done=0 & time_error=0 -> (time_error'=1); // bound reached so error + [configured] time_error=0 -> (done'=1); // configured within the time bound + + // when in error or done state can loop with either action + [configured] time_error=1 | done=1 -> true; + [time] time_error=1 | done=1 -> true; + +endmodule diff --git a/examples/multi-objective/mdp/zeroconf-tb/zeroconf-tb4_10.nm b/examples/multi-objective/mdp/zeroconf-tb/zeroconf-tb4_10.nm new file mode 100644 index 000000000..05c500235 --- /dev/null +++ b/examples/multi-objective/mdp/zeroconf-tb/zeroconf-tb4_10.nm @@ -0,0 +1,174 @@ +// IPv4: PTA model with digitial clocks +// multi-objective model of the host +// gxn/dxp 28/09/09 + +mdp + +//------------------------------------------------------------- +// VARIABLES +const int N=20; // number of abstract hosts +const int K=4; // number of probes to send + +// PROBABILITIES +const double old = N/65024; // probability pick an ip address being used +//const double old = 0.5; // probability pick an ip address being used +const double new = (1-old); // probability pick a new ip address + +// TIMING CONSTANTS +const int CONSEC = 2; // time interval between sending consecutive probles +const int TRANSTIME = 1; // upper bound on transmission time delay +const int LONGWAIT = 60; // minimum time delay after a high number of address collisions +const int DEFEND = 10; + +const int TIME_MAX_X = 60; // max value of clock x +const int TIME_MAX_Y = 10; // max value of clock y +const int TIME_MAX_Z = 1; // max value of clock z + +// OTHER CONSTANTS +const int MAXCOLL = 10; // maximum number of collisions before long wait + + +//------------------------------------------------------------- +// CONCRETE HOST +module host0 + + x : [0..TIME_MAX_X]; // first clock of the host + y : [0..TIME_MAX_Y]; // second clock of the host + + coll : [0..MAXCOLL]; // number of address collisions + probes : [0..K]; // counter (number of probes sent) + mess : [0..1]; // need to send a message or not + defend : [0..1]; // defend (if =1, try to defend IP address) + + ip : [1..2]; // ip address (1 - in use & 2 - fresh) + + l : [0..4] init 1; // location + // 0 : RECONFIGURE + // 1 : RANDOM + // 2 : WAITSP + // 3 : WAITSG + // 4 : USE + + // RECONFIGURE + [reset] l=0 -> (l'=1); + + // RANDOM (choose IP address) + [rec0] (l=1) -> true; // get message (ignore since have no ip address) + [rec1] (l=1) -> true; // get message (ignore since have no ip address) + // small number of collisions (choose straight away) + [] l=1 & coll 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + // large number of collisions: (wait for LONGWAIT) + [time] l=1 & coll=MAXCOLL & x (x'=min(x+1,TIME_MAX_X)); + [] l=1 & coll=MAXCOLL & x=LONGWAIT -> 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + + // WAITSP + // let time pass + [time] l=2 & x<2 -> (x'=min(x+1,2)); + // send probe + [send1] l=2 & ip=1 & x=2 & probes (x'=0) & (probes'=probes+1); + [send2] l=2 & ip=2 & x=2 & probes (x'=0) & (probes'=probes+1); + // sent K probes and waited 2 seconds + [configured] l=2 & x=2 & probes=K -> (l'=3) & (probes'=0) & (coll'=0) & (x'=0); + // get message and ip does not match: ignore + [rec0] l=2 & ip!=0 -> (l'=l); + [rec1] l=2 & ip!=1 -> (l'=l); + // get a message with matching ip: reconfigure + [rec1] l=2 & ip=1 -> (l'=0) & (coll'=min(coll+1,MAXCOLL)) & (x'=0) & (probes'=0); + + // WAITSG (sends two gratuitious arp probes) + // time passage + [time] l=3 & mess=0 & defend=0 & x (x'=min(x+1,TIME_MAX_X)); + [time] l=3 & mess=0 & defend=1 & x (x'=min(x+1,TIME_MAX_X)) & (y'=min(y+1,DEFEND)); + + // receive message and same ip: defend + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y>=DEFEND) -> (defend'=1) & (mess'=1) & (y'=0); + // receive message and same ip: defer + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y (l'=0) & (probes'=0) & (defend'=0) & (x'=0) & (y'=0); + // receive message and different ip + [rec0] l=3 & mess=0 & ip!=0 -> (l'=l); + [rec1] l=3 & mess=0 & ip!=1 -> (l'=l); + + + // send probe reply or message for defence + [send1] l=3 & ip=1 & mess=1 -> (mess'=0); + [send2] l=3 & ip=2 & mess=1 -> (mess'=0); + // send first gratuitous arp message + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + // send second gratuitous arp message (move to use) + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + + // USE (only interested in reaching this state so do not need to add anything here) + [] l=4 -> true; + +endmodule + +//------------------------------------------------------------- +// error automaton for the environment assumption +// do not get a reply when K probes are sent +const int M; // time between sending and receiving a message + +module env_error4 + + env : [0..1]; // 0 active and 1 done + k : [0..4]; // counts the number of messages sent + c1 : [0..M+1]; // time since first message + c2 : [0..M+1]; // time since second message + c3 : [0..M+1]; // time since third message + c4 : [0..M+1]; // time since fourth message + error : [0..1]; + + // message with new ip address arrives so done + [send2] error=0 & env=0 -> (env'=1); + // message with old ip address arrives so count + [send1] error=0 & env=0 -> (k'=min(k+1,K)); + // time passgae so update relevant clocks + [time] error=0 & env=0 & k=0 -> true; + [time] error=0 & env=0 & k=1 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)); + [time] error=0 & env=0 & k=2 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)); + [time] error=0 & env=0 & k=3 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)); + [time] error=0 & env=0 & k=4 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)) & (c4'=min(c4+1,M+1)); + // all clocks reached their bound so an error + [time] error=0 & env=0 & min(c1,c2,c3,c4)=M -> (error'=1); + // send a reply (then done) + [rec1] error=0 & env=0 & k>0 & min(c1,c2,c3,c4)<=M -> (env'=1); + // finished so any action can be performed + [time] error=1 | env=1 -> true; + [send1] error=1 | env=1 -> true; + [send2] error=1 | env=1 -> true; + [send2] error=1 | env=1 -> true; + [rec1] error=1 | env=1 -> true; + +endmodule + +//------------------------------------------------------------- +// error automaton for the time bounded assumption +// host does not send configured signal within T seconds +const int T=10; + +module time_error + + time_error : [0..1]; + done : [0..1]; + t : [0..T]; + + [time] t (t'=t+1); // time passes and bound not reached + [time] t=T-1 & done=0 & time_error=0 -> (time_error'=1); // bound reached so error + [configured] time_error=0 -> (done'=1); // configured within the time bound + + // when in error or done state can loop with either action + [configured] time_error=1 | done=1 -> true; + [time] time_error=1 | done=1 -> true; + +endmodule diff --git a/examples/multi-objective/mdp/zeroconf-tb/zeroconf-tb4_14.nm b/examples/multi-objective/mdp/zeroconf-tb/zeroconf-tb4_14.nm new file mode 100644 index 000000000..b91ec7995 --- /dev/null +++ b/examples/multi-objective/mdp/zeroconf-tb/zeroconf-tb4_14.nm @@ -0,0 +1,174 @@ +// IPv4: PTA model with digitial clocks +// multi-objective model of the host +// gxn/dxp 28/09/09 + +mdp + +//------------------------------------------------------------- +// VARIABLES +const int N=20; // number of abstract hosts +const int K=4; // number of probes to send + +// PROBABILITIES +const double old = N/65024; // probability pick an ip address being used +//const double old = 0.5; // probability pick an ip address being used +const double new = (1-old); // probability pick a new ip address + +// TIMING CONSTANTS +const int CONSEC = 2; // time interval between sending consecutive probles +const int TRANSTIME = 1; // upper bound on transmission time delay +const int LONGWAIT = 60; // minimum time delay after a high number of address collisions +const int DEFEND = 10; + +const int TIME_MAX_X = 60; // max value of clock x +const int TIME_MAX_Y = 10; // max value of clock y +const int TIME_MAX_Z = 1; // max value of clock z + +// OTHER CONSTANTS +const int MAXCOLL = 10; // maximum number of collisions before long wait + + +//------------------------------------------------------------- +// CONCRETE HOST +module host0 + + x : [0..TIME_MAX_X]; // first clock of the host + y : [0..TIME_MAX_Y]; // second clock of the host + + coll : [0..MAXCOLL]; // number of address collisions + probes : [0..K]; // counter (number of probes sent) + mess : [0..1]; // need to send a message or not + defend : [0..1]; // defend (if =1, try to defend IP address) + + ip : [1..2]; // ip address (1 - in use & 2 - fresh) + + l : [0..4] init 1; // location + // 0 : RECONFIGURE + // 1 : RANDOM + // 2 : WAITSP + // 3 : WAITSG + // 4 : USE + + // RECONFIGURE + [reset] l=0 -> (l'=1); + + // RANDOM (choose IP address) + [rec0] (l=1) -> true; // get message (ignore since have no ip address) + [rec1] (l=1) -> true; // get message (ignore since have no ip address) + // small number of collisions (choose straight away) + [] l=1 & coll 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + // large number of collisions: (wait for LONGWAIT) + [time] l=1 & coll=MAXCOLL & x (x'=min(x+1,TIME_MAX_X)); + [] l=1 & coll=MAXCOLL & x=LONGWAIT -> 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + + // WAITSP + // let time pass + [time] l=2 & x<2 -> (x'=min(x+1,2)); + // send probe + [send1] l=2 & ip=1 & x=2 & probes (x'=0) & (probes'=probes+1); + [send2] l=2 & ip=2 & x=2 & probes (x'=0) & (probes'=probes+1); + // sent K probes and waited 2 seconds + [configured] l=2 & x=2 & probes=K -> (l'=3) & (probes'=0) & (coll'=0) & (x'=0); + // get message and ip does not match: ignore + [rec0] l=2 & ip!=0 -> (l'=l); + [rec1] l=2 & ip!=1 -> (l'=l); + // get a message with matching ip: reconfigure + [rec1] l=2 & ip=1 -> (l'=0) & (coll'=min(coll+1,MAXCOLL)) & (x'=0) & (probes'=0); + + // WAITSG (sends two gratuitious arp probes) + // time passage + [time] l=3 & mess=0 & defend=0 & x (x'=min(x+1,TIME_MAX_X)); + [time] l=3 & mess=0 & defend=1 & x (x'=min(x+1,TIME_MAX_X)) & (y'=min(y+1,DEFEND)); + + // receive message and same ip: defend + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y>=DEFEND) -> (defend'=1) & (mess'=1) & (y'=0); + // receive message and same ip: defer + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y (l'=0) & (probes'=0) & (defend'=0) & (x'=0) & (y'=0); + // receive message and different ip + [rec0] l=3 & mess=0 & ip!=0 -> (l'=l); + [rec1] l=3 & mess=0 & ip!=1 -> (l'=l); + + + // send probe reply or message for defence + [send1] l=3 & ip=1 & mess=1 -> (mess'=0); + [send2] l=3 & ip=2 & mess=1 -> (mess'=0); + // send first gratuitous arp message + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + // send second gratuitous arp message (move to use) + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + + // USE (only interested in reaching this state so do not need to add anything here) + [] l=4 -> true; + +endmodule + +//------------------------------------------------------------- +// error automaton for the environment assumption +// do not get a reply when K probes are sent +const int M; // time between sending and receiving a message + +module env_error4 + + env : [0..1]; // 0 active and 1 done + k : [0..4]; // counts the number of messages sent + c1 : [0..M+1]; // time since first message + c2 : [0..M+1]; // time since second message + c3 : [0..M+1]; // time since third message + c4 : [0..M+1]; // time since fourth message + error : [0..1]; + + // message with new ip address arrives so done + [send2] error=0 & env=0 -> (env'=1); + // message with old ip address arrives so count + [send1] error=0 & env=0 -> (k'=min(k+1,K)); + // time passgae so update relevant clocks + [time] error=0 & env=0 & k=0 -> true; + [time] error=0 & env=0 & k=1 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)); + [time] error=0 & env=0 & k=2 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)); + [time] error=0 & env=0 & k=3 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)); + [time] error=0 & env=0 & k=4 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)) & (c4'=min(c4+1,M+1)); + // all clocks reached their bound so an error + [time] error=0 & env=0 & min(c1,c2,c3,c4)=M -> (error'=1); + // send a reply (then done) + [rec1] error=0 & env=0 & k>0 & min(c1,c2,c3,c4)<=M -> (env'=1); + // finished so any action can be performed + [time] error=1 | env=1 -> true; + [send1] error=1 | env=1 -> true; + [send2] error=1 | env=1 -> true; + [send2] error=1 | env=1 -> true; + [rec1] error=1 | env=1 -> true; + +endmodule + +//------------------------------------------------------------- +// error automaton for the time bounded assumption +// host does not send configured signal within T seconds +const int T=14; + +module time_error + + time_error : [0..1]; + done : [0..1]; + t : [0..T]; + + [time] t (t'=t+1); // time passes and bound not reached + [time] t=T-1 & done=0 & time_error=0 -> (time_error'=1); // bound reached so error + [configured] time_error=0 -> (done'=1); // configured within the time bound + + // when in error or done state can loop with either action + [configured] time_error=1 | done=1 -> true; + [time] time_error=1 | done=1 -> true; + +endmodule diff --git a/examples/multi-objective/mdp/zeroconf/zeroconf_host_multi.pctl b/examples/multi-objective/mdp/zeroconf/origFiles/zeroconf_host_multi.pctl similarity index 100% rename from examples/multi-objective/mdp/zeroconf/zeroconf_host_multi.pctl rename to examples/multi-objective/mdp/zeroconf/origFiles/zeroconf_host_multi.pctl diff --git a/examples/multi-objective/mdp/zeroconf/zeroconf_host_multi2.nm b/examples/multi-objective/mdp/zeroconf/origFiles/zeroconf_host_multi2.nm similarity index 100% rename from examples/multi-objective/mdp/zeroconf/zeroconf_host_multi2.nm rename to examples/multi-objective/mdp/zeroconf/origFiles/zeroconf_host_multi2.nm diff --git a/examples/multi-objective/mdp/zeroconf/zeroconf_host_multi4.nm b/examples/multi-objective/mdp/zeroconf/origFiles/zeroconf_host_multi4.nm similarity index 100% rename from examples/multi-objective/mdp/zeroconf/zeroconf_host_multi4.nm rename to examples/multi-objective/mdp/zeroconf/origFiles/zeroconf_host_multi4.nm diff --git a/examples/multi-objective/mdp/zeroconf/zeroconf_host_multi6.nm b/examples/multi-objective/mdp/zeroconf/origFiles/zeroconf_host_multi6.nm similarity index 100% rename from examples/multi-objective/mdp/zeroconf/zeroconf_host_multi6.nm rename to examples/multi-objective/mdp/zeroconf/origFiles/zeroconf_host_multi6.nm diff --git a/examples/multi-objective/mdp/zeroconf/zeroconf_host_multi8.nm b/examples/multi-objective/mdp/zeroconf/origFiles/zeroconf_host_multi8.nm similarity index 100% rename from examples/multi-objective/mdp/zeroconf/zeroconf_host_multi8.nm rename to examples/multi-objective/mdp/zeroconf/origFiles/zeroconf_host_multi8.nm diff --git a/examples/multi-objective/mdp/zeroconf/zeroconf4.nm b/examples/multi-objective/mdp/zeroconf/zeroconf4.nm new file mode 100644 index 000000000..1c3bafd53 --- /dev/null +++ b/examples/multi-objective/mdp/zeroconf/zeroconf4.nm @@ -0,0 +1,153 @@ +// IPv4: PTA model with digitial clocks +// multi-objective model of the host +// gxn/dxp 28/09/09 + +mdp + +//------------------------------------------------------------- +// VARIABLES +const int N=20; // number of abstract hosts +const int K=4; // number of probes to send + +// PROBABILITIES +const double old = N/65024; // probability pick an ip address being used +//const double old = 0.5; // probability pick an ip address being used +const double new = (1-old); // probability pick a new ip address + +// TIMING CONSTANTS +const int CONSEC = 2; // time interval between sending consecutive probles +const int TRANSTIME = 1; // upper bound on transmission time delay +const int LONGWAIT = 60; // minimum time delay after a high number of address collisions +const int DEFEND = 10; + +const int TIME_MAX_X = 60; // max value of clock x +const int TIME_MAX_Y = 10; // max value of clock y +const int TIME_MAX_Z = 1; // max value of clock z + +// OTHER CONSTANTS +const int MAXCOLL = 10; // maximum number of collisions before long wait + + +//------------------------------------------------------------- +// CONCRETE HOST +module host0 + + x : [0..TIME_MAX_X]; // first clock of the host + y : [0..TIME_MAX_Y]; // second clock of the host + + coll : [0..MAXCOLL]; // number of address collisions + probes : [0..K]; // counter (number of probes sent) + mess : [0..1]; // need to send a message or not + defend : [0..1]; // defend (if =1, try to defend IP address) + + ip : [1..2]; // ip address (1 - in use & 2 - fresh) + + l : [0..4] init 1; // location + // 0 : RECONFIGURE + // 1 : RANDOM + // 2 : WAITSP + // 3 : WAITSG + // 4 : USE + + // RECONFIGURE + [reset] l=0 -> (l'=1); + + // RANDOM (choose IP address) + [rec0] (l=1) -> true; // get message (ignore since have no ip address) + [rec1] (l=1) -> true; // get message (ignore since have no ip address) + // small number of collisions (choose straight away) + [] l=1 & coll 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + // large number of collisions: (wait for LONGWAIT) + [time] l=1 & coll=MAXCOLL & x (x'=min(x+1,TIME_MAX_X)); + [] l=1 & coll=MAXCOLL & x=LONGWAIT -> 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + + // WAITSP + // let time pass + [time] l=2 & x<2 -> (x'=min(x+1,2)); + // send probe + [send1] l=2 & ip=1 & x=2 & probes (x'=0) & (probes'=probes+1); + [send2] l=2 & ip=2 & x=2 & probes (x'=0) & (probes'=probes+1); + // sent K probes and waited 2 seconds + [] l=2 & x=2 & probes=K -> (l'=3) & (probes'=0) & (coll'=0) & (x'=0); + // get message and ip does not match: ignore + [rec0] l=2 & ip!=0 -> (l'=l); + [rec1] l=2 & ip!=1 -> (l'=l); + // get a message with matching ip: reconfigure + [rec1] l=2 & ip=1 -> (l'=0) & (coll'=min(coll+1,MAXCOLL)) & (x'=0) & (probes'=0); + + // WAITSG (sends two gratuitious arp probes) + // time passage + [time] l=3 & mess=0 & defend=0 & x (x'=min(x+1,TIME_MAX_X)); + [time] l=3 & mess=0 & defend=1 & x (x'=min(x+1,TIME_MAX_X)) & (y'=min(y+1,DEFEND)); + + // receive message and same ip: defend + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y>=DEFEND) -> (defend'=1) & (mess'=1) & (y'=0); + // receive message and same ip: defer + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y (l'=0) & (probes'=0) & (defend'=0) & (x'=0) & (y'=0); + // receive message and different ip + [rec0] l=3 & mess=0 & ip!=0 -> (l'=l); + [rec1] l=3 & mess=0 & ip!=1 -> (l'=l); + + + // send probe reply or message for defence + [send1] l=3 & ip=1 & mess=1 -> (mess'=0); + [send2] l=3 & ip=2 & mess=1 -> (mess'=0); + // send first gratuitous arp message + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + // send second gratuitous arp message (move to use) + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + + // USE (only interested in reaching this state so do not need to add anything here) + [] l=4 -> true; + +endmodule + +//------------------------------------------------------------- +// error automaton for the environment assumption +// do not get a reply when K probes are sent +const int M; // time between sending and receiving a message + +module env_error4 + + env : [0..1]; // 0 active and 1 done + k : [0..4]; // counts the number of messages sent + c1 : [0..M+1]; // time since first message + c2 : [0..M+1]; // time since second message + c3 : [0..M+1]; // time since third message + c4 : [0..M+1]; // time since fourth message + error : [0..1]; + + // message with new ip address arrives so done + [send2] error=0 & env=0 -> (env'=1); + // message with old ip address arrives so count + [send1] error=0 & env=0 -> (k'=min(k+1,K)); + // time passgae so update relevant clocks + [time] error=0 & env=0 & k=0 -> true; + [time] error=0 & env=0 & k=1 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)); + [time] error=0 & env=0 & k=2 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)); + [time] error=0 & env=0 & k=3 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)); + [time] error=0 & env=0 & k=4 & min(c1,c2,c3,c4) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)) & (c4'=min(c4+1,M+1)); + // all clocks reached their bound so an error + [time] error=0 & env=0 & min(c1,c2,c3,c4)=M -> (error'=1); + // send a reply (then done) + [rec1] error=0 & env=0 & k>0 & min(c1,c2,c3,c4)<=M -> (env'=1); + // finished so any action can be performed + [time] error=1 | env=1 -> true; + [send1] error=1 | env=1 -> true; + [send2] error=1 | env=1 -> true; + [send2] error=1 | env=1 -> true; + [rec1] error=1 | env=1 -> true; + +endmodule diff --git a/examples/multi-objective/mdp/zeroconf/zeroconf6.nm b/examples/multi-objective/mdp/zeroconf/zeroconf6.nm new file mode 100644 index 000000000..cde22a032 --- /dev/null +++ b/examples/multi-objective/mdp/zeroconf/zeroconf6.nm @@ -0,0 +1,157 @@ +// IPv4: PTA model with digitial clocks +// multi-objective model of the host +// gxn/dxp 28/09/09 + +mdp + +//------------------------------------------------------------- +// VARIABLES +const int N=20; // number of abstract hosts +const int K=6; // number of probes to send + +// PROBABILITIES +const double old = N/65024; // probability pick an ip address being used +//const double old = 0.5; // probability pick an ip address being used +const double new = (1-old); // probability pick a new ip address + +// TIMING CONSTANTS +const int CONSEC = 2; // time interval between sending consecutive probles +const int TRANSTIME = 1; // upper bound on transmission time delay +const int LONGWAIT = 60; // minimum time delay after a high number of address collisions +const int DEFEND = 10; + +const int TIME_MAX_X = 60; // max value of clock x +const int TIME_MAX_Y = 10; // max value of clock y +const int TIME_MAX_Z = 1; // max value of clock z + +// OTHER CONSTANTS +const int MAXCOLL = 10; // maximum number of collisions before long wait + + +//------------------------------------------------------------- +// CONCRETE HOST +module host0 + + x : [0..TIME_MAX_X]; // first clock of the host + y : [0..TIME_MAX_Y]; // second clock of the host + + coll : [0..MAXCOLL]; // number of address collisions + probes : [0..K]; // counter (number of probes sent) + mess : [0..1]; // need to send a message or not + defend : [0..1]; // defend (if =1, try to defend IP address) + + ip : [1..2]; // ip address (1 - in use & 2 - fresh) + + l : [0..4] init 1; // location + // 0 : RECONFIGURE + // 1 : RANDOM + // 2 : WAITSP + // 3 : WAITSG + // 4 : USE + + // RECONFIGURE + [reset] l=0 -> (l'=1); + + // RANDOM (choose IP address) + [rec0] (l=1) -> true; // get message (ignore since have no ip address) + [rec1] (l=1) -> true; // get message (ignore since have no ip address) + // small number of collisions (choose straight away) + [] l=1 & coll 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + // large number of collisions: (wait for LONGWAIT) + [time] l=1 & coll=MAXCOLL & x (x'=min(x+1,TIME_MAX_X)); + [] l=1 & coll=MAXCOLL & x=LONGWAIT -> 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + + // WAITSP + // let time pass + [time] l=2 & x<2 -> (x'=min(x+1,2)); + // send probe + [send1] l=2 & ip=1 & x=2 & probes (x'=0) & (probes'=probes+1); + [send2] l=2 & ip=2 & x=2 & probes (x'=0) & (probes'=probes+1); + // sent K probes and waited 2 seconds + [] l=2 & x=2 & probes=K -> (l'=3) & (probes'=0) & (coll'=0) & (x'=0); + // get message and ip does not match: ignore + [rec0] l=2 & ip!=0 -> (l'=l); + [rec1] l=2 & ip!=1 -> (l'=l); + // get a message with matching ip: reconfigure + [rec1] l=2 & ip=1 -> (l'=0) & (coll'=min(coll+1,MAXCOLL)) & (x'=0) & (probes'=0); + + // WAITSG (sends two gratuitious arp probes) + // time passage + [time] l=3 & mess=0 & defend=0 & x (x'=min(x+1,TIME_MAX_X)); + [time] l=3 & mess=0 & defend=1 & x (x'=min(x+1,TIME_MAX_X)) & (y'=min(y+1,DEFEND)); + + // receive message and same ip: defend + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y>=DEFEND) -> (defend'=1) & (mess'=1) & (y'=0); + // receive message and same ip: defer + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y (l'=0) & (probes'=0) & (defend'=0) & (x'=0) & (y'=0); + // receive message and different ip + [rec0] l=3 & mess=0 & ip!=0 -> (l'=l); + [rec1] l=3 & mess=0 & ip!=1 -> (l'=l); + + + // send probe reply or message for defence + [send1] l=3 & ip=1 & mess=1 -> (mess'=0); + [send2] l=3 & ip=2 & mess=1 -> (mess'=0); + // send first gratuitous arp message + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + // send second gratuitous arp message (move to use) + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + + // USE (only interested in reaching this state so do not need to add anything here) + [] l=4 -> true; + +endmodule + +//------------------------------------------------------------- +// error automaton for the environment assumption +// do not get a reply when K probes are sent +const int M; // time between sending and receiving a message + +module env_error6 + + env : [0..1]; // 0 active and 1 done + k : [0..6]; // counts the number of messages sent + c1 : [0..M+1]; // time since first message + c2 : [0..M+1]; // time since second message + c3 : [0..M+1]; // time since third message + c4 : [0..M+1]; // time since fourth message + c5 : [0..M+1]; // time since fifth message + c6 : [0..M+1]; // time since sixth message + error : [0..1]; + + // message with new ip address arrives so done + [send2] error=0 & env=0 -> (env'=1); + // message with old ip address arrives so count + [send1] error=0 & env=0 -> (k'=min(k+1,K)); + // time passgae so update relevant clocks + [time] error=0 & env=0 & k=0 -> true; + [time] error=0 & env=0 & k=1 & min(c1,c2,c3,c4,c5,c6) (c1'=min(c1+1,M+1)); + [time] error=0 & env=0 & k=2 & min(c1,c2,c3,c4,c5,c6) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)); + [time] error=0 & env=0 & k=3 & min(c1,c2,c3,c4,c5,c6) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)); + [time] error=0 & env=0 & k=4 & min(c1,c2,c3,c4,c5,c6) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)) & (c4'=min(c4+1,M+1)); + [time] error=0 & env=0 & k=5 & min(c1,c2,c3,c4,c5,c6) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)) & (c4'=min(c4+1,M+1)) & (c5'=min(c5+1,M+1)); + [time] error=0 & env=0 & k=6 & min(c1,c2,c3,c4,c5,c6) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)) & (c4'=min(c4+1,M+1)) & (c5'=min(c5+1,M+1)) & (c6'=min(c6+1,M+1)); + // all clocks reached their bound so an error + [time] error=0 & env=0 & min(c1,c2,c3,c4,c5,c6)=M -> (error'=1); + // send a reply (then done) + [rec1] error=0 & env=0 & k>0 & min(c1,c2,c3,c4,c5,c6)<=M -> (env'=1); + // finished so any action can be performed + [time] error=1 | env=1 -> true; + [send1] error=1 | env=1 -> true; + [send2] error=1 | env=1 -> true; + [rec1] error=1 | env=1 -> true; + +endmodule + diff --git a/examples/multi-objective/mdp/zeroconf/zeroconf8.nm b/examples/multi-objective/mdp/zeroconf/zeroconf8.nm new file mode 100644 index 000000000..e843a8c12 --- /dev/null +++ b/examples/multi-objective/mdp/zeroconf/zeroconf8.nm @@ -0,0 +1,161 @@ +// IPv4: PTA model with digitial clocks +// multi-objective model of the host +// gxn/dxp 28/09/09 + +mdp + +//------------------------------------------------------------- +// VARIABLES +const int N=20; // number of abstract hosts +const int K=8; // number of probes to send + +// PROBABILITIES +const double old = N/65024; // probability pick an ip address being used +//const double old = 0.5; // probability pick an ip address being used +const double new = (1-old); // probability pick a new ip address + +// TIMING CONSTANTS +const int CONSEC = 2; // time interval between sending consecutive probles +const int TRANSTIME = 1; // upper bound on transmission time delay +const int LONGWAIT = 60; // minimum time delay after a high number of address collisions +const int DEFEND = 10; + +const int TIME_MAX_X = 60; // max value of clock x +const int TIME_MAX_Y = 10; // max value of clock y +const int TIME_MAX_Z = 1; // max value of clock z + +// OTHER CONSTANTS +const int MAXCOLL = 10; // maximum number of collisions before long wait + + +//------------------------------------------------------------- +// CONCRETE HOST +module host0 + + x : [0..TIME_MAX_X]; // first clock of the host + y : [0..TIME_MAX_Y]; // second clock of the host + + coll : [0..MAXCOLL]; // number of address collisions + probes : [0..K]; // counter (number of probes sent) + mess : [0..1]; // need to send a message or not + defend : [0..1]; // defend (if =1, try to defend IP address) + + ip : [1..2]; // ip address (1 - in use & 2 - fresh) + + l : [0..4] init 1; // location + // 0 : RECONFIGURE + // 1 : RANDOM + // 2 : WAITSP + // 3 : WAITSG + // 4 : USE + + // RECONFIGURE + [reset] l=0 -> (l'=1); + + // RANDOM (choose IP address) + [rec0] (l=1) -> true; // get message (ignore since have no ip address) + [rec1] (l=1) -> true; // get message (ignore since have no ip address) + // small number of collisions (choose straight away) + [] l=1 & coll 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + // large number of collisions: (wait for LONGWAIT) + [time] l=1 & coll=MAXCOLL & x (x'=min(x+1,TIME_MAX_X)); + [] l=1 & coll=MAXCOLL & x=LONGWAIT -> 1/3*old : (l'=2) & (ip'=1) & (x'=0) + + 1/3*old : (l'=2) & (ip'=1) & (x'=1) + + 1/3*old : (l'=2) & (ip'=1) & (x'=2) + + 1/3*new : (l'=2) & (ip'=2) & (x'=0) + + 1/3*new : (l'=2) & (ip'=2) & (x'=1) + + 1/3*new : (l'=2) & (ip'=2) & (x'=2); + + // WAITSP + // let time pass + [time] l=2 & x<2 -> (x'=min(x+1,2)); + // send probe + [send1] l=2 & ip=1 & x=2 & probes (x'=0) & (probes'=probes+1); + [send2] l=2 & ip=2 & x=2 & probes (x'=0) & (probes'=probes+1); + // sent K probes and waited 2 seconds + [] l=2 & x=2 & probes=K -> (l'=3) & (probes'=0) & (coll'=0) & (x'=0); + // get message and ip does not match: ignore + [rec0] l=2 & ip!=0 -> (l'=l); + [rec1] l=2 & ip!=1 -> (l'=l); + // get a message with matching ip: reconfigure + [rec1] l=2 & ip=1 -> (l'=0) & (coll'=min(coll+1,MAXCOLL)) & (x'=0) & (probes'=0); + + // WAITSG (sends two gratuitious arp probes) + // time passage + [time] l=3 & mess=0 & defend=0 & x (x'=min(x+1,TIME_MAX_X)); + [time] l=3 & mess=0 & defend=1 & x (x'=min(x+1,TIME_MAX_X)) & (y'=min(y+1,DEFEND)); + + // receive message and same ip: defend + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y>=DEFEND) -> (defend'=1) & (mess'=1) & (y'=0); + // receive message and same ip: defer + [rec1] l=3 & mess=0 & ip=1 & (defend=0 | y (l'=0) & (probes'=0) & (defend'=0) & (x'=0) & (y'=0); + // receive message and different ip + [rec0] l=3 & mess=0 & ip!=0 -> (l'=l); + [rec1] l=3 & mess=0 & ip!=1 -> (l'=l); + + + // send probe reply or message for defence + [send1] l=3 & ip=1 & mess=1 -> (mess'=0); + [send2] l=3 & ip=2 & mess=1 -> (mess'=0); + // send first gratuitous arp message + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes<1 -> (x'=0) & (probes'=probes+1); + // send second gratuitous arp message (move to use) + [send1] l=3 & ip=1 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + [send2] l=3 & ip=2 & mess=0 & x=CONSEC & probes=1 -> (l'=4) & (x'=0) & (y'=0) & (probes'=0); + + // USE (only interested in reaching this state so do not need to add anything here) + [] l=4 -> true; + +endmodule + +//------------------------------------------------------------- +// error automaton for the environment assumption +// do not get a reply when K probes are sent +const int M; // time between sending and receiving a message + +module env_error8 + + env : [0..1]; // 0 active and 1 done + k : [0..8]; // counts the number of messages sent + c1 : [0..M+1]; // time since first message + c2 : [0..M+1]; // time since second message + c3 : [0..M+1]; // time since third message + c4 : [0..M+1]; // time since fourth message + c5 : [0..M+1]; // time since fifth message + c6 : [0..M+1]; // time since sixth message + c7 : [0..M+1]; // time since seventh message + c8 : [0..M+1]; // time since eighth message + error : [0..1]; + + // message with new ip address arrives so done + [send2] error=0 & env=0 -> (env'=1); + // message with old ip address arrives so count + [send1] error=0 & env=0 -> (k'=min(k+1,K)); + // time passgae so update relevant clocks + [time] error=0 & env=0 & k=0 -> true; + [time] error=0 & env=0 & k=1 & min(c1,c2,c3,c4,c5,c6,c7,c8) (c1'=min(c1+1,M+1)); + [time] error=0 & env=0 & k=2 & min(c1,c2,c3,c4,c5,c6,c7,c8) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)); + [time] error=0 & env=0 & k=3 & min(c1,c2,c3,c4,c5,c6,c7,c8) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)); + [time] error=0 & env=0 & k=4 & min(c1,c2,c3,c4,c5,c6,c7,c8) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)) & (c4'=min(c4+1,M+1)); + [time] error=0 & env=0 & k=5 & min(c1,c2,c3,c4,c5,c6,c7,c8) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)) & (c4'=min(c4+1,M+1)) & (c5'=min(c5+1,M+1)); + [time] error=0 & env=0 & k=6 & min(c1,c2,c3,c4,c5,c6,c7,c8) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)) & (c4'=min(c4+1,M+1)) & (c5'=min(c5+1,M+1)) & (c6'=min(c6+1,M+1)); + [time] error=0 & env=0 & k=7 & min(c1,c2,c3,c4,c5,c6,c7,c8) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)) & (c4'=min(c4+1,M+1)) & (c5'=min(c5+1,M+1)) & (c6'=min(c6+1,M+1)) & (c7'=min(c7+1,M+1)); + [time] error=0 & env=0 & k=8 & min(c1,c2,c3,c4,c5,c6,c7,c8) (c1'=min(c1+1,M+1)) & (c2'=min(c2+1,M+1)) & (c3'=min(c3+1,M+1)) & (c4'=min(c4+1,M+1)) & (c5'=min(c5+1,M+1)) & (c6'=min(c6+1,M+1)) & (c7'=min(c7+1,M+1)) & (c8'=min(c8+1,M+1)); + // all clocks reached their bound so an error + [time] error=0 & env=0 & min(c1,c2,c3,c4,c5,c6,c7,c8)=M -> (error'=1); + // send a reply (then done) + [rec1] error=0 & env=0 & k>0 & min(c1,c2,c3,c4,c5,c6,c7,c8)<=M -> (env'=1); + // finished so any action can be performed + [time] error=1 | env=1 -> true; + [send1] error=1 | env=1 -> true; + [send2] error=1 | env=1 -> true; + [rec1] error=1 | env=1 -> true; + +endmodule +