Line 29: | Line 29: | ||
* '''**''' (create an instance of target) | * '''**''' (create an instance of target) | ||
* '''!!''' (destroy an instance of target) | * '''!!''' (destroy an instance of target) | ||
== Example == | |||
<pre> | |||
MACHINE scheduler_UML | |||
SETS | |||
PID = {process1,process2,process3} | |||
VARIABLES active, ready, waiting | |||
DEFINITIONS | |||
"CHOOSE.def"; | |||
SEQUENCE_CHART_INITIALISATION == ""; // ignore | |||
SEQUENCE_CHART_new(pp) == ("Master", "-->","**",pp); | |||
SEQUENCE_CHART_del(pp) == ("Master", "-->","!!",pp); | |||
SEQUENCE_CHART_ready(pp) == (pp, "-->","Master"); | |||
SEQUENCE_CHART_swap == ("Master", "-->","--",CHOOSE(active)) | |||
INVARIANT | |||
active <: PID & | |||
ready <: PID & | |||
waiting <: PID & | |||
(ready /\ waiting) = {} & | |||
active /\ (ready \/ waiting) = {} & | |||
/*@label "SAF" */ card(active) <= 1 & | |||
((active = {}) => (ready = {})) | |||
INITIALISATION | |||
active := {} || ready := {} || waiting := {} | |||
OPERATIONS | |||
new(pp) = | |||
SELECT | |||
pp : PID & | |||
pp /: active & | |||
pp /: (ready \/ waiting) | |||
THEN | |||
waiting := (waiting \/ { pp }) | |||
END; | |||
del(pp) = | |||
SELECT | |||
pp : waiting | |||
THEN | |||
waiting := waiting - {pp} | |||
END; | |||
ready(rr) = | |||
SELECT | |||
rr : waiting | |||
THEN | |||
waiting := (waiting - {rr}) || | |||
IF (active = {}) THEN | |||
active := {rr} | |||
ELSE | |||
ready := ready \/ {rr} | |||
END | |||
END; | |||
swap = | |||
SELECT | |||
active /= {} | |||
THEN | |||
waiting := (waiting \/ active) || | |||
IF (ready = {}) THEN | |||
active := {} | |||
ELSE | |||
ANY pp WHERE pp : ready | |||
THEN | |||
active := {pp} || | |||
ready := ready - {pp} | |||
END | |||
END | |||
END | |||
END | |||
</pre> |
= UML Sequence Charts for Traces
ProB has a new experimental feature to generate a UML sequence chart from the current animation trace. It currently only works for classical B models and you need to copy the plantUML.jar file to ProB's lib folder.
For every B Operation Op that you want to visualise you need to add a definition
SEQUENCE_CHART_Op
in your DEFINITIONS. The definition can take arguments, in which case the actual arguments in the trace are passed to the definition. The definition can take fewer arguments (but not more) than the B operation.
The definition should either return
Currently these arrow styles are supported:
etc
Optionally you can add these suffixes:
MACHINE scheduler_UML SETS PID = {process1,process2,process3} VARIABLES active, ready, waiting DEFINITIONS "CHOOSE.def"; SEQUENCE_CHART_INITIALISATION == ""; // ignore SEQUENCE_CHART_new(pp) == ("Master", "-->","**",pp); SEQUENCE_CHART_del(pp) == ("Master", "-->","!!",pp); SEQUENCE_CHART_ready(pp) == (pp, "-->","Master"); SEQUENCE_CHART_swap == ("Master", "-->","--",CHOOSE(active)) INVARIANT active <: PID & ready <: PID & waiting <: PID & (ready /\ waiting) = {} & active /\ (ready \/ waiting) = {} & /*@label "SAF" */ card(active) <= 1 & ((active = {}) => (ready = {})) INITIALISATION active := {} || ready := {} || waiting := {} OPERATIONS new(pp) = SELECT pp : PID & pp /: active & pp /: (ready \/ waiting) THEN waiting := (waiting \/ { pp }) END; del(pp) = SELECT pp : waiting THEN waiting := waiting - {pp} END; ready(rr) = SELECT rr : waiting THEN waiting := (waiting - {rr}) || IF (active = {}) THEN active := {rr} ELSE ready := ready \/ {rr} END END; swap = SELECT active /= {} THEN waiting := (waiting \/ active) || IF (ready = {}) THEN active := {} ELSE ANY pp WHERE pp : ready THEN active := {pp} || ready := ready - {pp} END END END END