
----------------------------------------------------------
--boolarray.lus
----------------------------------------------------------
--Lustre library for boolean arrays
--All nodes are parametrized by a constant integer
--parameter n wich is the size of the array(s)
----------------------------------------------------------
--Operators from bool^n to bool
----------------------------------------------------------
--ba_none  : all elements are false
--ba_all   : all elements are true
--ba_diese : at most one element true
--ba_one   : exactly one element true
----------------------------------------------------------
--Operators from bool^n x bool^n to bool
----------------------------------------------------------
--ba_eq    : test equality
----------------------------------------------------------
--Operators from bool^n to bool^n
----------------------------------------------------------
--ba_right_shift : res[0]=false res[t]=input[t-1]
--ba_left_shift  : res[n-1]=false res[t]=input[t+1]
----------------------------------------------------------
--Operators from bool^n^m to bool^(n*m)
----------------------------------------------------------
--ba_flat : cast a matrix (2 dimension) into a
--          vector (single dimension)
----------------------------------------------------------
node ba_none(const n : int; I : bool^n) returns ( ok : bool);
var
	Nor : bool^n;
let
	Nor = [not I[0]] | ( Nor[0..n-2] and not I[1..n-1]);
	ok = Nor[n-1];
tel

node ba_all(const n : int; I : bool^n) returns ( ok : bool);
var
	All : bool^n;
let
	All = [I[0]] | ( All[0..n-2] and I[1..n-1]);
	ok = All[n-1];
tel

node ba_diese(const n : int; I : bool^n) returns ( ok : bool);
var
	Diese, Nor : bool^n;
let
	Nor = [not I[0]] | ( Nor[0..n-2] and not I[1..n-1]);
	Diese = [true] | (Diese[0..n-2] and (not I[1..n-1] or Nor[0..n-2]));
	ok = Diese[n-1];
tel

node ba_one(const n : int; I : bool^n) returns ( ok : bool);
var
	Diese, Nor : bool^n;
let
	Nor = [not I[0]] | ( Nor[0..n-2] and not I[1..n-1]);
	Diese = [true] | (Diese[0..n-2] and (not I[1..n-1] or Nor[0..n-2]));
	ok = Diese[n-1] and not Nor[n-1];
tel

node test(I, J : bool^8) returns (ok : bool);
let ok = ba_eq(8, I, J); tel

node ba_eq(const n : int; I, J : bool^n) returns ( ok : bool);
var
	And : bool^n;
let
	And[0] = (I[0] = J[0]);
	And[1..n-1] = And[0..n-2] and (I[1..n-1] = J[1..n-1]);
	ok = And[n-1];
tel
node ba_right_shift(const n : int; I : bool^n) returns (O : bool^n);
let
	O = [false] | I[0..n-2] ;
tel

node ba_left_shift(const n : int; I : bool^n) returns (O : bool^n);
let
	O = I[1..n-1] | [false] ;
tel

node ba_flat(const m, n : bool; x : bool^m^n) returns (y : bool^(m*n));
let 
	y = with (n = 1) then x[0]
	    else (ba_flat(m, n-1, x[0..n-2]) | x[n-1]); 
tel
