Christiano Braga
Universidade Federal Fluminense
http://www.ic.uff.br/~cbraga/tcs
Nov. 2020
Formal semantics in compiler construction and program analysis.
Automata-based verification techniques for component-based system.
π is a semantic framework to teach formal compiler construction.
It joins Peter Mosses’ funcons, from Component-Based Semantics, with Gordon Plotkin’s Interpreting Automata.
Implementations in Maude, Python and Racket.
Research in the context of Language-oriented Programming and Program Analysis.
Joint work with Narciso Martí Oliet.
Is a prototype executable environment for specifications in the Abstract Machine Notation, the description language used in Abrial’s B Method.
The project started with the intention to build a collaboration with Brazilian colleagues David Deharbe and Anamaria Moreira, specialists in the B Method.
There exists a possibility of collaboration with ClearSy Systems Engineering. (They develop the Attelier B tool.)
The semantics of a component in a Cyber-Physical Systems (CPS) is specified by a hybrid automaton.
The model of a Component-based CPS (CB-CPS) is the result of the synchronous product of the hybrid automata of its components.
It has two components: π Lib and π Automaton.
Cmd ::= `loop`(Exp, Cmd)
call/cc
primitive will be incorporated in the next release. (This will endow the framework with exceptions and co-routines.)δ : L(G)* × L(G)* × Store → Q
δ(Loop(X,M) :: C, V, E, S) = δ(X :: #LOOP :: C, Loop(X,M)::V, E, S)
δ(#LOOP :: C, Boo(true) :: Loop(X,M) :: V, E, S) = δ(M :: Loop(X,M) :: C, V, E, S)
δ(#LOOP :: C, Boo(false) :: Loop(X,M) :: V, E, S) = δ(C, V, E, S)
To give semantics to a programming language one needs to define π denotations for the given programming language constructs, that is, functions relating the given programming language construct and π Lib constructs.
π Lib constructs are represented by the signature of a system module.
π Lib constructs with terminating semantics are equationally specified and (possibly) non-terminating constructs are specified by rules.
var ... : Set{SemComp} .
var E : Env .
var S : Store .
var C : ControlStack .
var V : ValueStack .
eq [loop] :
< cnt : loop(E:Exp, K:Cmd) C, val : V, ... > =
< cnt : E:Exp LOOP C,
val : val(loop(E:Exp, K:Cmd)) V, ... > [variant] .
rl [loop] :
< cnt : LOOP C,
val : val(true) val(loop(E:Exp, K:Cmd)) V, ... > =>
< cnt : K:Cmd loop(E:Exp, K:Cmd) C,
val : V, ... > [narrowing] .
eq [loop] :
< cnt : LOOP C,
val : val(false) val(loop(E:Exp, K:Cmd)) V, ... > =
< cnt : C, val : V, ... > [variant] .
π denotations are equtionally specified.
op compile : GSLSubstitution -> Cmd .
eq compile(WHILE P:GSLPredicate DO S:GSLSubstitution) =
loop(compile(P:GSLPredicate), compile(S:GSLSubstitution)) .
The execution environment allows for simulation by term rewriting, symbolic execution by narrowing and LTL model checking. (See examples in B Maude project.)
Both π Lib and Automata are represented as classes, organized by syntactical classes and facets, respectively.
A class constructor has a similar meaning of an algebraic constructor operation.
In the example below __init__
is the (object) constructor and cond
and body
are projection
functions.
class Loop(Cmd):
def __init__(self, be, c):
if isinstance(be, BoolExp):
if isinstance(c, Cmd):
Cmd.__init__(self, be, c)
else:
raise IllFormed(self, c)
else:
raise IllFormed(self, be)
def cond(self):
return self.operand(0)
def body(self):
return self.operand(1)
class CmdPiAut(ExpPiAut):
# ...
def __evalLoop(self, c):
be = c.cond()
bl = c.body()
self.pushVal(Loop(be, bl))
self.pushVal(bl)
self.pushCnt(CmdKW.LOOP)
self.pushCnt(be)
def __evalLoopKW(self):
t = self.popVal()
if t:
c = self.popVal()
lo = self.popVal()
self.pushCnt(lo)
self.pushCnt(c)
else:
self.popVal()
self.popVal()
# Imp.ebnf
cmd = loop | ... ;
# Impiler.py
class Impiler(object):
# ...
def loop(self, ast):
if isinstance(ast.c, pi.Cmd):
return pi.Loop(ast.e, ast.c)
else:
cmd = ast.c[0]
for i in range(1, len(ast.c)):
cmd = pi.CSeq(cmd, ast.c[i])
return pi.Loop(ast.e, cmd)
Imπ source code:
# The classic iterative factorial example
let var z = 1
in
let var y = 10
in
while not (y == 0)
do
z := z * y
y := y - 1
State #232 of the π automaton:
locs : [0]
env : {'z': 0}
sto : {0: 3628800}
val : [[], {}]
cnt : ['#BLKCMD']
Number of evaluation steps: 234
Evaluation time: 0:00:00.004149
; ModuleID = "main_module"
target triple = "x86_64-apple-darwin18.0.0"
target datalayout = ""
define i64 @"main_function"()
{
entry:
%"ptr" = alloca i64
store i64 1, i64* %"ptr"
%"ptr.1" = alloca i64
store i64 10, i64* %"ptr.1"
br label %"loop"
loop:
%"val" = load i64, i64* %"ptr.1"
%"temp_eq" = icmp eq i64 %"val", 0
%"temp_not" = xor i1 %"temp_eq", -1
%"val.1" = load i64, i64* %"ptr"
%"val.2" = load i64, i64* %"ptr.1"
%"tmp_mul" = mul i64 %"val.1", %"val.2"
store i64 %"tmp_mul", i64* %"ptr"
%"val.3" = load i64, i64* %"ptr.1"
%"tmp_sub" = sub i64 %"val.3", 1
store i64 %"tmp_sub", i64* %"ptr.1"
br i1 %"temp_not", label %"loop", label %"after_loop"
after_loop:
ret i64 0
}
B Maude is an executable enviroment for the Abstract Machine Notation (AMN), the description language of the B method.
It essentially defines a theory transformation from the one decribing AMN syntax to the π Lib theory, that is, it implements the π denotations of AMN.
The π denotation for the WHILE construct above is an example.
BMaude: Machine FACT loaded.
rewrites: 89 in 0ms cpu (1ms real) (99775 rewrites/second)
MACHINE FACT
VARIABLES y
VALUES y = 1
OPERATIONS
fact(x)=
WHILE ~(0 == x) DO y := y * x ; x := x - 1 ; print(y)
END
rewrites: 26127 in 318ms cpu (322ms real) (82007 rewrites/second)
BMaude: Execution result
402387260077093773543702433923003985719374864210714632543799910429938...
eq compile(S1:GSLSubstitution [] S2:GSLSubstitution) =
choice(compile(S1:GSLSubstitution), compile(S2:GSLSubstitution)) .
BMaude: Machine MUTEX loaded.
Maude> (view)
rewrites: 483 in 2ms cpu (2ms real) (182746 rewrites/second)
MACHINE MUTEX
VARIABLES p1, p2
CONSTANTS idle, wait, crit
VALUES crit = 2 ; idle = 0 ; p1 = 0 ; p2 = 0 ; wait = 1
OPERATIONS
mutex =
WHILE true DO
IF p2 == idle /\ p1 == idle
THEN p2 := wait [] p1 := wait
ELSE
IF wait == p2 /\ p1 == idle
THEN p2 := crit [] p1 := wait
ELSE
IF p1 == idle /\ p2 == crit
THEN p2 := idle [] p1 := wait
ELSE
IF wait == p1 /\ p2 == idle
THEN p2 := wait [] p1 := crit
ELSE
IF wait == p2 /\ wait == p1
THEN p2 := crit [] p1 := crit
ELSE
IF wait == p1 /\ p2 == crit
THEN p2 := idle
ELSE
IF p2 == idle /\ p1 == crit
THEN p2 := wait [] p1 := idle
ELSE
IF wait == p2 /\ p1 == crit
THEN p1 := idle
ELSE skip
END
END
END
END
END
END
END
END
END
Maude> (mc mutex() |= [] (p1(1) -> <> p1(2)))
rewrites: 1009 in 40ms cpu (41ms real) (24825 rewrites/second)
BMaude: Model check counter example
Path from the initial state:
WHILE(true)...[p1 = 0 p2 = 0]-> WHILE(true)...[p1 = 0 p2 = 0]-> p2
:= wait OR p1 := wait[p1 = 0 p2 = 0]
Loop:
WHILE(true)...[p1 = 1 p2 = 0]-> p2 := wait OR p1 := crit[p1 = 1 p2 =
0]-> WHILE(true)...[p1 = 1 p2 = 1]-> p2 := crit OR p1 := crit[p1
= 1 p2 = 1]-> WHILE(true)...[p1 = 1 p2 = 2]
Cyber-physical Systems (CPS) are distributed system where its components are either sensors or actuators.
Such components can be modeled as hybrid automata: finite state transition systems that allows for both discrete-time and continuous-time transitions.
The model of a Component-based CPS (CB-CPS) is the synchronous product of hybrid automata of its constituent components.
In general, continuous-time transitions are modeled by a system of differential equations. A LHA is a Hybrid Automaton where its differential equations are:
We give a rewriting semantics for LHA that have an additional constraint: they are assumed eager in the sense that if a discrete transition is enabled it will take place. The state invariants must be properly specified to guarantee eagerness.
The behavioral semantics of a given component is denoted by a rewrite theory. Both discrete and continuous time transitions are modeled by rules. The rewrites that are deductible in the given theory are controled by a strategy that applies the discrete-time transitions as much as possible before applying the continuous-time rule.
The rewrite theory that models a given CB-CPS is the synchronous product of the rewrite systems of its constituent components.
We have developed some small case studies. There are still semantic issues to be worked out.