Traffic light in NuSMV - model-checking

I'm trying to create a traffic light system implementation in NuSMV. Right now I have 6 booleans for NS/EW red, yellow, green. However when I specify that they are each always true in a future state, it comes back false. If anyone sees any errors in my code I would appreciate the help. Thanks.
MODULE main
VAR
nsRed : boolean;
nsYellow : boolean;
nsGreen : boolean;
time : 0..60;
ewRed : boolean;
ewYellow : boolean;
ewGreen : boolean;
ASSIGN
init(nsRed) := TRUE;
init(nsYellow) := FALSE;
init(nsGreen) := FALSE;
init(ewRed) := FALSE;
init(ewYellow) := FALSE;
init(ewGreen) := TRUE;
init(time) := 60;
next(nsRed) :=
case
(nsYellow = TRUE & (ewGreen = TRUE | ewYellow = TRUE) & time = 0) : TRUE;
(nsRed = TRUE & time = 0) : FALSE;
TRUE : nsRed;
esac;
next(nsYellow) :=
case
(nsGreen = TRUE & ewRed = TRUE & time = 0) : TRUE;
(nsYellow = TRUE & time = 0) : FALSE;
TRUE : nsYellow;
esac;
next(nsGreen) :=
case
(nsRed = TRUE & ewRed = TRUE & time = 0) : TRUE;
(nsGreen = TRUE & time = 0) : FALSE;
TRUE : nsGreen;
esac;
next(ewRed) :=
case
(ewYellow = TRUE & (nsGreen = TRUE | nsYellow = TRUE) & time = 0) : TRUE;
(ewRed = TRUE & time = 0) : FALSE;
TRUE : ewRed;
esac;
next(ewYellow) :=
case
(ewGreen = TRUE & nsRed = TRUE & time = 0) : TRUE;
(ewYellow = TRUE & time = 0) : FALSE;
TRUE : ewYellow;
esac;
next(ewGreen) :=
case
(ewRed = TRUE & nsRed = TRUE & time = 0) : TRUE;
(ewGreen = TRUE & time = 0) : FALSE;
TRUE : ewGreen;
esac;
next(time) :=
case
(time > 0) : time - 1;
(time = 0 & nsRed = TRUE) : 60;
(time = 0 & nsYellow = TRUE) : 60;
(time = 0 & nsGreen = TRUE) : 3;
(time = 0 & ewRed = TRUE) : 60;
(time = 0 & ewYellow = TRUE) : 60;
(time = 0 & ewGreen = TRUE) : 3;
--(time = 0 & nsRed = TRUE & ewRed = TRUE) : 3
TRUE : time;
esac;
-- specification
SPEC AG !(nsRed = TRUE & nsYellow = TRUE)
SPEC AG !(nsGreen = TRUE & nsRed = TRUE)
SPEC AG !(nsGreen = TRUE & ewGreen = TRUE)
SPEC AG !(nsYellow = TRUE & ewYellow = TRUE)
SPEC AG !(nsRed = TRUE & ewRed = TRUE)
SPEC AG (nsRed = TRUE | nsYellow = TRUE | nsGreen = TRUE | ewRed = TRUE | ewYellow = TRUE | ewGreen = TRUE)
--LTLSPEC F nsGreen = TRUE
LTLSPEC F ewGreen = TRUE

The reason that the property F nsGreen = TRUE is false is that there exists an infinite execution where nsGreen is never true. This is the counter-example that NuSMV generates (I cut out the counting down of the timer). Note that only updates of variables are printed.
-- specification F nsGreen = TRUE is false
-- as demonstrated by the following execution sequence
Trace Description: LTL Counterexample
Trace Type: Counterexample
-> State: 1.1 <-
nsRed = TRUE
nsYellow = FALSE
nsGreen = FALSE
time = 60
ewRed = FALSE
ewYellow = FALSE
ewGreen = TRUE
-> State: 1.2 <-
time = 59
...
-> State: 1.61 <-
time = 0
-> State: 1.62 <-
nsRed = FALSE
time = 60
ewYellow = TRUE
ewGreen = FALSE
-> State: 1.63 <-
time = 59
...
-> State: 1.122 <-
time = 0
-> State: 1.123 <-
time = 60
ewYellow = FALSE
-> State: 1.124 <-
time = 59
...
-> State: 1.182 <-
time = 1
-- Loop starts here
-> State: 1.183 <-
time = 0
-> State: 1.184 <-
The trace shows that nsRed is already set to false when the timer reaches 0 for the first time. Also, ewYellow becomes false, but ewRed is not set to true.
I would suggested you use an enum variable for the traffic lights instead of three booleans, like this:
MODULE main
VAR
ns : {RED, YELLOW, GREEN};
ew : {RED, YELLOW, GREEN};

How about defining two different states indicating the trafic lights for NS and EW sides of the street?
I have written a sample code, hope you find it useful...
MODULE main
VAR
nsLight : {RED, YELLOW, GREEN};
ewLight : {RED, YELLOW, GREEN};
timeMove : 0..10;
timeYellow : 0..5;
ASSIGN
init(nsLight) := RED;
init(ewLight) := GREEN;
init(timeMove) := 10;
init(timeYellow):= 5;
-- NS: | EW:
-- R (10 sec) -> R -> G (10 sec) | G (10 sec) -> Y (5 sec) -> R (10 sec)
-- / \ | | | |
-- | \ / | | \ /
-- |------------------- Y (5 sec) | |--------------------------- R
next(nsLight) := case
(nsLight = RED & ewLight = GREEN & timeMove = 0) : RED;
(nsLight = RED & ewLight = YELLOW & timeYellow = 0) : GREEN;
(nsLight = GREEN & ewLight = RED & timeMove = 0) : YELLOW;
(nsLight = YELLOW & ewLight = RED & timeYellow = 0) : RED;
TRUE : nsLight;
esac;
next(ewLight) := case
(ewLight = GREEN & nsLight = RED & timeMove = 0) : YELLOW;
(ewLight = YELLOW & nsLight = RED & timeYellow = 0) : RED;
(ewLight = RED & nsLight = GREEN & timeMove = 0) : RED;
(ewLight = RED & nsLight = YELLOW & timeYellow = 0) : GREEN;
TRUE : ewLight;
esac;
next(timeMove) := case
timeMove > 0 & ewLight != YELLOW & nsLight != YELLOW : timeMove - 1;
timeMove = 0 : 10;
TRUE : timeMove;
esac;
next(timeYellow) := case
timeYellow > 0 & (ewLight = YELLOW | nsLight = YELLOW) : timeYellow - 1;
timeYellow = 0 : 5;
TRUE : timeYellow;
esac;
The idea is to have a moving counter from 10 -> 0 while we're in the states of GREEN or RED and another counter 5 -> 0, I called it timeYellow, to make sure the transition from GREEN to YELLOW is smooth and less dangerous!

Related

How can I modify a M/M/1 queuing system to G/G/1?

I wrote a Monte Carlo simulation for M/M/1 queuing system since it's deterministic. Now I tried modifying the same code for a G/G/1 queueing system with interarrival times and service times having a triangular distribution. Instead of drawing samples from Poisson and exponential distribution, I am drawing samples from the triangular distribution (for G/G/1). However, I am getting results that are hard to make sense of. The analytical approximation results say that the mean waiting time in the queue is 0.9708 which is kinda off from the result (~0.75) I am getting with the simulation.
clc
clear
tic
Nc = 1008;
Tsys = zeros(1,Nc);
Tia = zeros(1,Nc);
Ta = zeros(1,Nc);
Tsrv = zeros(1,Nc);
Tnsrv = zeros(1,Nc);
Txsys = zeros(1,Nc);
WTqmc = zeros(1,Nc);
MTqmc = zeros(1,Nc);
MTsys = zeros(1,Nc);
Tri1_min = 2;
Tri1_mid = 3;
Tri1_max = 5;
Tri2_min = 1.8;
Tri2_mid = 2.8;
Tri2_max = 4.5;
pdat = makedist('Triangular','a',Tri1_min,'b',Tri1_mid,'c',Tri1_max);
pdser = makedist('Triangular','a',Tri2_min,'b',Tri2_mid,'c',Tri2_max);
Tia(1) = random(pdat);
Ta(1) = Tia(1);
Tsys(1) = Tsrv(1);
Tnsrv(1) = Ta(1);
Tsrv(1) = random(pdser);
Txsys(1) = Ta(1) + Tsrv(1);
WTqmc(1) = 0;
MTqmc(1) = WTqmc(1);
for i = 2:1:Nc
Tia(i) = random(pdat);
Ta(i) = Ta(i-1) + Tia(i);
Tsys(i) = Ta(i);
if Ta(i) < Txsys(i-1)
Tnsrv(i) = Tnsrv(i-1) + Tsrv(i-1);
else
Tnsrv(i) = Ta(i);
end
Tsrv(i) = random(pdser);
Txsys(i) = Tnsrv(i) + Tsrv(i);
WTqmc(i) = Tnsrv(i)-Ta(i);
Tsys(i) = Txsys(i) - Ta(i);
MTqmc(i) = ((i-1)* MTqmc(i-1) + WTqmc(i))/i;
% MTsys(i) = ((i-1)* MTsys(i-1) + Tsys(i))/i;
end
Tend = Txsys(Nc);
Nts = floor(Tend);
dt = 1;
Time = zeros(1,Nts);
Lq = zeros(1,Nts);
Time(1) = 0;
Lq(1) = 0;
for j = 2:1:Nts
Time(j) = Time(j-1)+dt;
Lq(j) = 0;
for i = 1:1:Nc
if (Ta(i) < Time(j) && Txsys(i) > Time(j) && Tnsrv(i) > Time(j))
Lq(j) = Lq(j)+1;
end
end
end
MLqmc = mean(Lq)
MTqmc1 = MTqmc(Nc)
MTqmc_mean = mean(WTqmc)
SDmtamc = std(WTqmc)
SEmtamc = SDmtamc/sqrt(Nc)
toc
mean1= (2+3+5)/3;
mean2=(1.8+2.8+4.5)/3;
var1=(4+9+25-2*3-2*5-3*5)/18;
var2=(1.8*1.8+2.8*2.8+4.5*4.5-1.8*2.8-1.8*4.5-2.8*4.5)/18;
rho= (1/mean1)/(1/mean2);
ca2= var1/mean1^2;
cs2=var2/mean2^2;
Lq=((rho^2)*(1+cs2)*(ca2+(rho^2)*cs2))/(2*(1-rho)*(1+(rho^2)*cs2));
wq=Lq/(1/mean1)
%Plot Outcomes
figure(1)
plot(Ta,MTqmc)
xlabel('Arrivals')
ylabel('Mean Time in Queue')
title('Queue Length vs Time')

Vending Machine in NuSMV

I am new to NuSMV, I am trying to create Vending Machine implementation from Kripke structure, I have three boolean (coin, selection, brewing) as well as three states.However, When I compile the code I receive "Line 25: at token ":": syntax error" If anyone sees any errors in my code I would appreciate the help.
Kripke structure
my attempt to write the code is as follow:
MODULE main
VAR
location : {s1,s2,s3};
coin : boolean;
selection: boolean;
brweing: boolean;
ASSIGN
init(location) := s1;
init(coin) := FALSE;
init(selection) := FALSE;
init(brweing) := FALSE;
next(location) :=
case
location = s1 : s2;
TRUE: coin;
esac;
next(location) :=
case
location = (s2 : s3 & (TRUE: selection));
location = (s2 : s1 & (FALSE: selection) & (FALSE: coin));
esac;
next(location) :=
case
location = (s3 : s3 & (TRUE: brewing));
location = (s3 : s1 & (FALSE: selection) & (FALSE: coin) & (FALSE: brewing));
esac;
-- specification
• AG [s ⇒ b] whenever a selection is made coffee is brewed for sure.
• E [(¬s) U (b)] the coffee will not be brewed as no selection were made.
• EF[b] there is a state where coffee is brewed.
The line (among others)
location = (s2 : s3 & (TRUE: selection));
doesn't make much sense. You need only one next statement to assign the next location from all possible values of location. Also, you don't need to declare coin, selection, and brewing as variables. Use DEFINE to define their values based on location:
MODULE main
VAR
location : {s1,s2,s3};
ASSIGN
init(location) := s1;
next(location) :=
case
location = s1 : s2;
location = s2 : {s1,s3};
location = s3 : {s1,s3};
esac;
DEFINE
coin := location = s2 | location = s3;
-- similarly for selection and brewing
What I understand from the model is that coin, selection and brew are not only labels but events that trigger the transition. If so, I would write the model like this:
MODULE main
VAR
location: {s1, s2, s3};
coin: boolean;
selection: boolean;
brew: boolean;
abort: boolean;
INIT
!coin & !selection & !brew;
ASSIGN
init(location) := s1;
next(location) := case
location = s1 & next(coin) : s2;
location = s2 & next(selection) : s3;
location = s2 & next(abort) : s1;
location = s3 : {s1, s3};
TRUE : location;
esac;
next(brew) := (next(location) = s3);
next(coin) := case
next(state) = s1 : FALSE;
state = s1 : {TRUE, FALSE};
TRUE : coin;
esac;
next(selection) := case
state = s2 : {TRUE, FALSE};
next(state) = s1 : FALSE;
esac;

Processing special characters

Let's say I receive the following string in Lua mÜ⌠⌠í∩and would like to apply it to my current processing code, which is the following
function inTable(tbl, item)
for key, value in pairs(tbl) do
if value == item then return true end
end
return false
end
function processstring(instr)
finmsg = ""
achar = {131,132,133,134,142,143,145,146,160,166,181,182,183,198,199,224}
echar = {130,137,138,144,228}
ichar = {139,140,141,161,173,179,244}
ochar = {147,148,149,153,162,167,229,233,234,248}
uchar = {129,150,151,154,163}
nchar = {164,165,227,252}
outmsg = string.upper(instr)
for c in outmsg:gmatch"." do
bc = string.byte(c)
if(bc <= 47 or (bc>=58 and bc<=64) or (bc>=91 and bc<=96) or bc >=123)then
elseif (bc == 52) then finmsg = finmsg.."A"
elseif (bc == 51) then finmsg = finmsg.."E"
elseif (bc == 49) then finmsg = finmsg.."I"
elseif (bc == 48) then finmsg = finmsg.."O"
elseif (inTable(achar, bc)==true) then finmsg = finmsg.."A"
elseif (inTable(echar, bc)==true) then finmsg = finmsg.."E"
elseif (inTable(ichar, bc)==true) then finmsg = finmsg.."I"
elseif (inTable(ochar, bc)==true) then finmsg = finmsg.."O"
elseif (inTable(uchar, bc)==true) then finmsg = finmsg.."U"
elseif (inTable(nchar, bc)==true) then finmsg = finmsg.."N"
else
finmsg = finmsg..c
end
end
return finmsg
end
function checkword (instr)
specword = [[]]
wordlist = {"FIN", "FFI", "PHIN", "PHEN", "FIN", "PHIN", "IFFUM", "MUF", "MEUFEEN", "FEN","FEEN"}
for i, v in ipairs (wordlist) do
if (string.match(processstring(instr), v) ~= nil)then
return 1
end
end
--if (string.match(instr,specword) ~= nil)then
-- return 1
--end
end
print (checkword("mÜ⌠⌠í∩"))
As of now, I have found no way to proof strings like that. Not even by using string.byte() to reduce it to ASCII have I been able to reliably work with exoctic characters like those. Even more weird is that if I do a print(bc) on processstring I get the folowing output
160 226 140 160 195 173 226 136 169
Now, that's 9 ASCII codes for a 6 letter word, how can this be? I built the code referencing http://www.asciitable.com/, is it wrong? How can I approach this processing?
local subst = {
U = "üûùÜú",
N = "ñÑπⁿ∩",
O = "ôöòÖóºσΘΩ°",
I = "ïîìí¡│",
F = "⌠",
A = "âäàåÄÅæÆáª╡╢╖╞╟α",
E = "éëèÉΣ",
}
local subst_utf8 = {}
for base_letter, list_of_letters in pairs(subst) do
for utf8letter in list_of_letters:gmatch'[%z\1-\x7F\xC0-\xFF][\x80-\xBF]*' do
subst_utf8[utf8letter] = base_letter
end
end
function processstring(instr)
return (instr:upper():gsub('[%z\1-\x7F\xC0-\xFF][\x80-\xBF]*', subst_utf8))
end
print(processstring("mÜ⌠⌠í∩")) --> MUFFIN

unexpected token error while using update query in groovy

I am trying to update the table with the query result using simple update query.
here is the query.
def restore(def id, def contentId) {
String hql = ""
def q = revisionService.getRevisionById(id)
hql = """UPDATE Content
SET
parentId = ${q.parent_id}
,user_id = ${q.user_id}
,inheritFromParent = ${q.inherit_from_parent}
,forceSSL = ${q.forcessl}
,title = ${q.title}
,fileName = ${q.file_name}
,fileNamePath = ${q.file_name_path}
,fileNameLookup = ${q.file_name_lookup}
,body = ${q.body}
,summary = ${q.summary}
,template = ${q.template}
,layout = ${q.layout}
,contentType = ${q.content_type}
,isNavItem = ${q.is_nav_item}
,navDepth = ${q.nav_depth}
,navOrder = ${q.nav_order}
,metaTitle = ${q.meta_title}
,metaKeywords = ${q.meta_keywords}
,metaDescription = ${q.meta_description}
,isActive = ${q.is_active}
,col1 = ${q.col1}
,col2 = ${q.col2}
,col3 = ${q.col3}
,col4 = ${q.col4}
,col5 = ${q.col5}
,col6 = ${q.col6}
,col7 = ${q.col7}
,col8 = ${q.col8}
,col9 = ${q.col9}
WHERE id = ${contentId}"""
try {
Content.executeUpdate(hql)
} catch(Exception e) {
println e
}
}
when i execute this query getting an exception saying org.springframework.orm.hibernate4.HibernateQueryException: unexpected token: about near line 7, column 50.
here is stacktrace from my terminal.
line 7:50: unexpected token: about
Message: unexpected token: about
Line | Method
->> 353 | $tt__restore in org.regionscms.ContentService$$EOqIswWO
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 48 | restore in org.regionscms.ContentController
| 198 | doFilter . . in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 53 | doFilter . . in grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter
| 49 | doFilter in grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter
| 82 | doFilter . . in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run in java.lang.Thread
org.springframework.orm.hibernate4.HibernateQueryException: unexpected token: about near line 7, column 50 [UPDATE org.regionscms.Content
SET
parentId = 1
,user_id = 1
,inheritFromParent = true
,forceSSL = false
,title = about us
,fileName = about-us
,fileNamePath = home/about-us
,fileNameLookup = 72635069142711694
,body = tests
,summary = tests
,template = index.gsp
,layout = Main
,contentType = Page
,isNavItem = true
,navDepth = 1
,navOrder = 2
,metaTitle = null
,metaKeywords = null
,metaDescription = null
,isActive = true
,col1 = 1045719790170831251
,col2 = 72635069142711694
,col3 = 0
,col4 = 0
,col5 = 0
,col6 = 0
,col7 = 0
,col8 = 0
,col9 = 0
WHERE id = 2]; nested exception is org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: about near line 7, column 50 [UPDATE org.regionscms.Content
SET
parentId = 1
,user_id = 1
,inheritFromParent = true
,forceSSL = false
,title = about us
,fileName = about-us
,fileNamePath = home/about-us
,fileNameLookup = 72635069142711694
,body = tests
,summary = tests
,template = index.gsp
,layout = Main
,contentType = Page
,isNavItem = true
,navDepth = 1
,navOrder = 2
,metaTitle = null
,metaKeywords = null
,metaDescription = null
,isActive = true
,col1 = 1045719790170831251
,col2 = 72635069142711694
,col3 = 0
,col4 = 0
,col5 = 0
,col6 = 0
,col7 = 0
,col8 = 0
,col9 = 0
WHERE id = 2]
see the manual for executeUpdate how to properly use a param map like this:
Content.executeUpdate("UPDATE Content c SET parentId = :parentId, ... WHERE id = :contentId",
[cotentId: contentId, parentId: q.parentId, ...])
Code like yours is basically the road to SQL-Injection. The problem here is the use of GString replacements, which leads to invalid SQL (it should be 'about us' and not about us)

Compare to string of names

I am trying to compare the names of two strings, and trying to pick out the name that are not included in the other string.
h = 1;
for i = 1:name_size_main
checker = 0;
main_name = main(i);
for j = 1:name_size_image
image_name = image(j);
temp = strcmpi(image_name, main_name);
if temp == 1;
checker = temp;
end
end
if checker == 0
result(h) = main_name;
h = h+1;
end
end
but it keeps returning the entire string as result, the main string contain roughly 1000 names, the images name contain about 300 names, so it should return about 700 names in result but it keep returning all 1000 names.
I tried your code with small vectors:
main = ['aaa' 'bbb' 'ccc' 'ddd'];
image = ['bbb' 'ddd'];
name_size_main = size(main,2);
name_size_image = size(image,2);
h = 1;
for i = 1:name_size_main
checker = 0;
main_name = main(i);
for j = 1:name_size_image
image_name = image(j);
temp = strcmpi(image_name, main_name);
if temp == 1;
checker = temp;
end
end
if checker == 0
result(h) = main_name;
h = h+1;
end
end
I get result = 'aaaccc', is it not what you want to get?
EDIT:
If you are using cell arrays, you should change the line result(h) = main_name; to result{h} = main_name; like that:
main = {'aaa' 'bbb' 'ccc' 'ddd'};
image = {'bbb' 'ddd'};
name_size_main = size(main,2);
name_size_image = size(image,2);
result = cell(0);
h = 1;
for i = 1:name_size_main
checker = 0;
main_name = main(i);
for j = 1:name_size_image
image_name = image(j);
temp = strcmpi(image_name, main_name);
if temp == 1;
checker = temp;
end
end
if checker == 0
result{h} = main_name;
h = h+1;
end
end
You can use cells of string along with setdiff or setxor.
A = cellstr(('a':'t')') % a cell of string, 'a' to 't'
B = cellstr(('f':'z')') % 'f' to 'z'
C1 = setdiff(A,B,'rows') % gives 'a' to 'e'
C2 = setdiff(B,A,'rows') % gives 'u' to 'z'
C3 = setxor(A,B,'rows') % gives 'a' to 'e' and 'u' to 'z'

Resources