Davide Ancona, Luca Franceschini, Angelo Ferrando, Viviana Mascardi
20th Italian Conference on Theoretical Computer Science
11 September 2019, Como, Italy
Basic idea: do not verify programs, verify executions.
Why?
The observations made on the monitored system are called events.
The execution of a program is characterized by a sequence of events.
All the events matching a given pattern constitutes an event type.
open matches {event: "func_call", name: "open"};
rw matches {event: "func_call", name: "read"|"write"};
close matches {event: "func_call", name: "close"};
Main = open rw* close;
Then derived operators, regex-like support, and more...
RQNR = { let val;
enq(val)
(enq(val)* deq(val) | RQNR)
}?;
Data structure: Randomized Queue with No Repetition
enq(1) enq(1) deq(1) deq(1)
(enq(1)* deq(1)) | RQNR
enq(1) deq(1) deq(1)
(enq(1)* deq(1)) | (enq(1)* deq(1))
deq(1) deq(1)
empty | (enq(1)* deq(1))
deq(1)
empty | empty
Accepted! But...
RQNR = { let val;
enq(val)
(enq(val)* deq(val) | RQNR)
}?;
Deterministic semantics
enq(1) enq(1) deq(1) deq(1)
(enq(1)* deq(1)) | RQNR
enq(1) deq(1) deq(1)
(enq(1)* deq(1)) | RQNR
deq(1) deq(1)
empty | RQNR
deq(1)
(data value)
(event type)
(empty trace)
(prefix)
(concatenation)
(intersection)
(union)
(shuffle)
(parametric expression)
The resulting calculus is deterministic