Luca Franceschini
Advisor: Prof. Davide Ancona
External reviewers: Ferruccio Damiani, Wolfgang Ahrendt, Adrian Francalanza
PhD defense, Genoa, 19/03/2020
Executions,
not programs
Still formal
verification
Why?
Easier than static verification?
Goals:
Event specification
+
Property specification
... but they can be everything (JSON-encoded!)
Observations made on the system under scrutiny
{function∶ "open", args∶ ["john.txt", "r"]}
{function∶ "random", result∶ 7324}
{function∶ "httpRequest",
args: [{
url: "www.google.it",
port: 8080
}]}
A concise syntax to describe a set of events...
{function: "sum"|"divide"|"round", args: [_, more]}
... and to capture relevant data
{function: "foo", args: [x, y], result: _}
Patterns can match events
{function: "foo", args: [x, y], result: _}
{function: "foo", args: [1, "hello"], result: true}
Event
Pattern
And produce substitutions
acquire(id) matches {function∶ "lock", result∶ id};
use(id) matches {function∶ "foo"|"bar", args∶ [id, more]};
release(id) matches {function∶ "unlock", args∶ [id, more]};
relevant matches acquire(_) | use(_) | release(_);
irrelevant not matches relevant;
Semantics is fully formalized
One or more (recursive) equations
// event types from previous example
Main = { let id; acquire(id) ((use(id)* release(id)) | Main )}?;
acquire(1) use(1) acquire(2) release(1) use(2) release(2)
acquire(3) release(3) use(3)
acquire(4) acquire(4)
One or more (recursive) equations
// event types from previous example
acqRel(id) matches acquire(id) | release(id);
Main = {let id; acquire(id)
((Main | use(id)* release(id))
/\ (acqRel(id) >> release(id) all))
}?;
acquire(4) acquire(4)
Stack (LIFO) specification
push(val) matches { ... };
pop(val) matches { ... };
Stack = { let val; push(val) Stack pop(val) }*;
push(7) push(42) pop(42) pop(7)
push(7) push(42) pop(7)
push(7) push(42) pop(42)
Stack (LIFO) specification (revisited)
push(val) matches { ... };
pop(val) matches { ... };
Main = Stack!;
Stack = { let val; push(val) Stack pop(val) }*;
push(7) push(42) pop(42)
Stack (LIFO) specification (pt. 3)
push(val) matches { ... };
pop(val) matches { ... };
size(s) matches { ... };
Main = Stack<0>!;
Stack<s> = size(s)* { let val;
push(val) Stack<s+1> pop(val) Stack<s>
}?;
A simpler, fully formalized, core calculus
A rewriting-based semantics
A proof of determinism
(including event matching)
A semantics in terms of traces
... and related algebraic properties: optimizations!
A formalized translation from RML