From ea652ee621ce4ff6d32b157ae13e88e4bac99415 Mon Sep 17 00:00:00 2001 From: Michael Leuschel <leuschel@uni-duesseldorf.de> Date: Wed, 5 May 2021 10:35:56 +0200 Subject: [PATCH] add new more sophisticated example --- Train/TwoTrains.json | 6 ++ Train/TwoTrains.svg | 15 +++++ Train/TwoTrainsMA.json | 111 +++++++++++++++++++++++++++++++++++++ Train/TwoTrainsMA.mch | 79 ++++++++++++++++++++++++++ VisB-Examples.prob2project | 18 +++++- 5 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 Train/TwoTrainsMA.json create mode 100644 Train/TwoTrainsMA.mch diff --git a/Train/TwoTrains.json b/Train/TwoTrains.json index 334f5c0..ee5409b 100644 --- a/Train/TwoTrains.json +++ b/Train/TwoTrains.json @@ -61,6 +61,12 @@ "attr":"points", "value":"svg_set_polygon(FREE_TE,100.0/real(TrackElementNumber+1),100.0,2.0)", "comment":"show free TTD zones" + }, + { + "id":"ma_polygon", + "attr":"visibility", + "value":"\"hidden\"", + "comment":"hide MA reserved zones" } ], "events":[ diff --git a/Train/TwoTrains.svg b/Train/TwoTrains.svg index c066b51..988efb4 100644 --- a/Train/TwoTrains.svg +++ b/Train/TwoTrains.svg @@ -30,10 +30,21 @@ stroke : black; } .train-back { + stroke-width: 0.2; + stroke : black; + fill : gray80 + } + .train-back-connected { stroke-width: 0.2; stroke : black; fill : green } + .green-ma { + fill : lightgreen; + stroke : none; + stroke-width: 0.1; + opacity: 1.0 + } </style> <polygon id = "train_polygon_tr1" @@ -77,6 +88,10 @@ stroke="gray" fill="none" transform="translate(10,22.5)" /> + <polygon id = "ma_polygon" + points="0,0 0,2 10,2 10,0 70,0 70,1 90,1 90,0" + class = "green-ma" + transform="translate(10,19.5)" /> <rect id = "ttd_rect" style="stroke-width: 0.1" diff --git a/Train/TwoTrainsMA.json b/Train/TwoTrainsMA.json new file mode 100644 index 0000000..508fe86 --- /dev/null +++ b/Train/TwoTrainsMA.json @@ -0,0 +1,111 @@ +{ + "svg":"TwoTrains.svg", + "definitions":[ + { "name":"OCC_TE", + "value" : "union(ran(%tt.(tt:occ|TTD_TrackElements(tt))))" + }, + { "name":"FREE_TE", + "value" : "union(ran(%tt.(tt/:occ|TTD_TrackElements(tt))))" + }], + "items":[ + + { + "repeat": ["tr1","tr2"], + "id":"train_polygon_%0", + "attr":"points", + "value":"svg_train(train_rear_end(%0), train_length(%0) ,100.0/real(TrackElementNumber+1),1.0,3.0)", + "comment":"show train position using a slanted polygon" + }, + { + "repeat": ["tr1","tr2"], + "id":"train_back_%0", + "attr":"points", + "value":"svg_train(real(train_rear_end(%0)), 0.3 ,100.0/real(TrackElementNumber+1),0.0,3.0)", + "comment":"show train back polygon" + }, + { + "repeat": ["tr1","tr2"], + "id":"train_back_%0", + "attr":"class", + "value":"IF %0 : dom(train_ma) THEN \"train-back-connected\" ELSE \"train-back\" END", + "comment":"show train back polygon" + }, + { + "repeat": ["tr1","tr2"], + "id":"train_info_text_%0", + "attr":"x", + "value":"real(train_rear_end(%0))*100.0/real(TrackElementNumber+1)", + "comment":"move info field above train" + }, + { + "repeat": ["tr1","tr2"], + "id":"train_info_text_%0", + "attr":"text", + "value":"\"Train %0: \" ^ TO_STRING(train_rear_end(%0)) ^ \"..\" ^ TO_STRING(train_rear_end(%0)+train_length(%0))", + "comment":"adapt info field of train" + }, + + { + "id":"track_polyline", + "attr":"points", + "value":"svg_axis({TrackElementNumber+1} \\/ TRACK ,100.0/real(TrackElementNumber+1),100.0,1.0)", + "comment":"show ticks for Track units" + }, + { + "id":"ttd_polyline", + "attr":"points", + "value":"svg_axis({0} \\/ ran(%tt.(tt:TTDS|1+max(TTD_TrackElements(tt)))),100.0/real(TrackElementNumber+1),100.0,2.0)", + "comment":"show ticks for TTD Limits" + }, + { + "id":"occupied_ttd_polygon", + "attr":"points", + "value":"svg_set_polygon(OCC_TE,100.0/real(TrackElementNumber+1),100.0,2.0)", + "comment":"show occupied TTD zones" + }, + { + "id":"cleared_ttd_polygon", + "attr":"points", + "value":"svg_set_polygon(FREE_TE,100.0/real(TrackElementNumber+1),100.0,2.0)", + "comment":"show free TTD zones" + }, + { + "id":"ma_polygon", + "attr":"points", + "value":"svg_set_polygon(train_ma_all,100.0/real(TrackElementNumber+1),100.0,0.5)", + "comment":"show MA reserved zones" + } + ], + "events":[ + { + "id":"occupied_ttd_polygon", + "event":"TTD_Free", + "optional" : true, + "hovers": [{ "attr":"stroke", "enter":"black", "leave":"none"}, + { "attr":"opacity", "enter":"0.5", "leave":"1.0"}] + }, + { + "id":"cleared_ttd_polygon", + "event":"TTD_Occupied_By_Train", + "optional" : true, + "hovers": [{ "attr":"stroke", "enter":"black", "leave":"none"}, + { "attr":"opacity", "enter":"0.5", "leave":"1.0"}] + }, + { + "id":"train_polygon_tr1", + "event":"TrainMoveForward", + "predicates" : ["tr=tr1"], + "optional" : true, + "hovers": [{ "attr":"class", "enter":"train-hover", "leave":"train-normal"}, + { "id":"train_info_text_tr1", "attr":"visibility", "enter":"visible", "leave":"hidden"}] + }, + { + "id":"train_polygon_tr2", + "event":"TrainMoveForward", + "predicates" : ["tr=tr2"], + "optional" : true, + "hovers": [{ "attr":"class", "enter":"train-hover", "leave":"train-normal"}, + { "id":"train_info_text_tr2", "attr":"visibility", "enter":"visible", "leave":"hidden"}] + } + ] +} \ No newline at end of file diff --git a/Train/TwoTrainsMA.mch b/Train/TwoTrainsMA.mch new file mode 100644 index 0000000..5348d5a --- /dev/null +++ b/Train/TwoTrainsMA.mch @@ -0,0 +1,79 @@ +MACHINE TwoTrainsMA +// A small example to show how one can use LibrarySVG to flexibliy visualise +// train track zones and MAs; model contains some errors on purpose to show how visualisation can help spot them +SETS + TTDS = {ttd1,ttd2,ttd3,ttd4}; + TRAINS = {tr1,tr2} +CONSTANTS + TrackElementNumber, TRACK, TTD_TrackElements +PROPERTIES + TrackElementNumber : NATURAL1 +& TRACK = 0..TrackElementNumber + +& TTD_TrackElements : TTDS --> FIN1(TRACK) + +& TrackElementNumber = 30 +& TTD_TrackElements = {ttd1 |-> 0..4 , ttd2 |-> 5..10 , ttd3 |-> 11..25, ttd4 |-> 26..30} +& !(ttd1,ttd2).(ttd1:TTDS & ttd2 /= ttd1 => TTD_TrackElements(ttd1) /\ TTD_TrackElements(ttd2) = {}) /*desc "TTDs are disjoint" */ +& union(ran(TTD_TrackElements)) = TRACK /*desc "TTDs cover the entire track" */ +VARIABLES + occ /*@desc "the occupied TTDs" */, + train_rear_end /*@desc "the minimal (aka left) position of a train" */, + train_front_end /*@desc "the maximal (aka right) position of a train" */, + train_ma /*@desc "the Movement Authority given to a train" */ +INVARIANT + occ <: TTDS & + train_rear_end : TRAINS --> TRACK & + train_front_end : TRAINS --> TRACK & + train_ma : TRAINS +-> TRACK & + !tr.(tr:dom(train_ma) => train_front_end(tr) <= train_ma(tr)) /*@desc "trains stay within their MA" */ & + !tr.(tr:TRAINS => train_front_end(tr) >= train_rear_end(tr)) /*@desc "train image not empty" */ & + !(t1,t2).(t1:TRAINS & t2 /= t1 => train_occ(t1) /\ train_occ(t2) = {}) /*@desc "no collision" */ & + !(t1,t2).(t1:TRAINS & t2 /= t1 => train_reserved(t1) /\ train_reserved(t2) = {}) /*@desc "reserved areas disjoint" */ ASSERTIONS + !(ttd,tr).(ttd /: occ & tr:TRAINS + => train_occ(tr) /\ TTD_TrackElements(ttd) = {}) /*@desc "TTDs marked as free are really free" */ +INITIALISATION + occ := {ttd1,ttd2} || + train_rear_end := {tr1 |-> 0, tr2 |-> 5} || train_front_end := {tr1 |->2, tr2|->6} || train_ma := {} +OPERATIONS + + + TrainAcceptsFirstMA(tr,newMA) = PRE tr/:dom(train_ma) & newMA:TRACK & newMA > train_front_end(tr) & + !(t2).(t2 /= tr => train_rear_end(tr)..newMA /\ train_reserved(t2) = {}) /*@desc "MA is safe" */ THEN + train_ma(tr) := newMA + END; + + TrainAcceptsNewMA(tr,newMA) = PRE tr:dom(train_ma) & newMA:TRACK & newMA > train_ma(tr) & + !(t2).(t2 /= tr => train_ma(tr)..newMA /\ train_reserved(t2) = {}) /*@desc "MA extension is safe" */ + // !(ttd).(ttd:occ => train_ma(tr)..newMA + THEN + train_ma(tr) := newMA + END; + + TrainMoveForward(tr,new_front) = PRE tr:dom(train_ma) & + new_front = train_rear_end(tr) + train_length(tr) + 1 & //buggy + new_front:TRACK & new_front < train_ma(tr) THEN + train_rear_end(tr) := train_rear_end(tr) + 1 || + train_front_end(tr) := new_front || + occ := {ttd | ttd:TTDS & TTD_TrackElements(ttd) /\ train_occ_all /= {}} /* buggy ; use seq. composition*/ + END +DEFINITIONS + "LibrarySVG.def"; // enable to use the external functions in the VisB json file + train_occ(train) == + train_rear_end(train)..(train_rear_end(train)+train_length(train)-1); + train_reserved(train) == + train_rear_end(train)..IF train:dom(train_ma) THEN train_ma(train) ELSE train_front_end(train) END; + train_occ_all == UNION(train).(train:TRAINS|train_occ(train)); + train_ma_all == UNION(train).(train:dom(train_ma)|(1+train_front_end(train))..train_ma(train)); + train_length(train) == 1+train_front_end(train)-train_rear_end(train); + VISB_JSON_FILE == "TwoTrains.json" +END + + +/* +Demo + 1. Find deadlock, fix TrainMoveForward + 2. add disjunct or train_rear_end(tr) > train_front_end(t2) + 3. animate and see that everything works + 4. show visualisation +*/ \ No newline at end of file diff --git a/VisB-Examples.prob2project b/VisB-Examples.prob2project index cfd613e..daa043b 100644 --- a/VisB-Examples.prob2project +++ b/VisB-Examples.prob2project @@ -410,13 +410,29 @@ ], "simulation": null, "visBVisualisation": "Train/TwoTrains.json" + }, + { + "name": "TwoTrainsMA", + "description": "", + "location": "Train/TwoTrainsMA.mch", + "lastUsedPreferenceName": "default", + "ltlFormulas": [], + "ltlPatterns": [], + "symbolicCheckingFormulas": [], + "symbolicAnimationFormulas": [], + "simulationItems": [], + "testCases": [], + "traces": [], + "modelcheckingItems": [], + "simulation": null, + "visBVisualisation": null } ], "preferences": [], "metadata": { "fileType": "Project", "formatVersion": 12, - "savedAt": "2021-05-04T20:43:11.650963Z", + "savedAt": "2021-05-05T07:39:51.437871Z", "creator": "User", "proB2KernelVersion": "4.0.0-SNAPSHOT", "proBCliVersion": null, -- GitLab