Transpose a matrix with Lustre V6
This Tiny Tutorial:
- shows how one can transpose a Lustre V6 matrix;
- illustrates the concepts of parametric nodes and static recursivity in Lustre V6;
- illustrates how to use the lesar model-checker to validate it.
In order to write a generic transpose, that works whatever the size of
the matrix is, we will use 2 static parameters n
and m
:
function transpose<<const n:int; const m:int; type t>>(x:t^m^n) returns (y:t^n^m);
Now to perform the transposition of a generic matrix, we need to
use a Statically Recursive function using the with/then/else
construct.
let
y =
-- with n = 0 then []
-- No empty array in Lustre! grrr.
with n = 1 then
map<<scal_to_array<<t>>, m >>(x[0])
else
add_vect_to_matrix <<n-1,m,t>>(x[0], transpose<<n-1,m,t>>(x[1..n-1]));
tel
A current limitation of the Verimag Lustre V6 compiler prevents us to
manipulate empty arrays. Therefore we need to finish our recursion
with n=1. The trivial function scal_to_array
lifts scalars to arrays of
size 1.
function scal_to_array<<type t>>(x:t) returns (res:t^1);
let
res = [x];
tel
The add_vect_to_matrix
function appends a vector to a matrix.
function add_vect_to_matrix<<const n:int; const m:int; type t>>(x:t^m; y:t^n^m)
returns (res:t^(n+1)^m);
let
res =
with m = 1 then [ [ x[0]] | y[0] ]
else [ [ x[0]] | y[0] ]
| add_vect_to_matrix<<n,m-1,t>> (x[1..m-1], y[1..m-1]);
tel
Of course, in order to test this node, one need to set values for the matrix sizes.
function test_transpose(x:int^4^2) returns (res:int^2^4);
let
res = transpose<<2,4,int>>(x);
tel
And then, one can to simulate this node:
lv6 -exec transpose.lus -n test_transpose
luciole-rif lv6 -exec transpose.lus -n test_transpose
Now, let’s show with lesar that transpose
is an
involution. We can not prove this property for any n
and m
with a
model-checker, but we can do it for some specific values:
function transpose_is_involutive(x:bool^4^2) returns (res:bool);
var
y: bool^2^4;
z: bool^4^2;
let
y = transpose<<2,4,bool>>(x);
z = transpose<<4,2,bool>>(y);
res = ( x = z );
tel
In order to model-check with lesar the transpose
program against the property transpose_is_involutive
property, we
need to convert it into a language that it can handle (Lustre V4 or
ec). Here we first compile transpose
into ec
:
lv6 transpose.lus -n transpose_is_involutive -ec -o proove_me.ec &&
lesar proove_me.ec transpose_is_involutive