package Numeric function #pragma kcg expand #end id (x: 'a) returns (y: 'a) y = x; package Generic function #pragma kcg expand #end max (x, y: 'a) returns (o: 'a) where 'a numeric o = if x >= y then x else y; function #pragma kcg expand #end min (x, y: 'a) returns (o: 'a) where 'a numeric o = if x <= y then x else y; function #pragma kcg expand #end saturate <> (i: 'a) returns (o: 'a) where 'a numeric o = min(max(i, min_v), max_v); /* Absolute value applied to a Signed Integer t has 2 variants: 1- the value is saturated to max value of the domain defined by the type 2- the most negative int value is stuck to itself The function avoids to refer to the min value of the type as a parameter of the function */ function #pragma kcg expand #end signed_abs_sat <> (x: 'a) returns (y: 'a) where 'a signed y = if x >= 0 then x else if x > (-max - 1) then -x else max; function #pragma kcg expand #end signed_abs_wrap <> (x: 'a) returns (y: 'a) where 'a signed y = if x >= 0 then x else if x > (-max - 1) then -x else ((-max - 1):'a); function #pragma kcg expand #end abs(x: 'a) returns (y: 'a) where 'a float y = if x < 0.0 then -x else x; function #pragma kcg expand #end u_sign (x: 'a) returns (y: 'a) where 'a unsigned y = if x = 0 then 0 else 1; function #pragma kcg expand #end sign (x: 'a) returns (y: 'a) where 'a numeric y = if x = 0 then 0 else if x > 0 then 1 else -1; function round(phantom: 'b ; x: 'a) returns (y: 'b) where 'a float where 'b signed var rx: 'a; d: 'a; tmp_b: 'a; let _ = phantom; rx = ((x:'b):'a); d = x - rx; tmp_b = if d <= (-0.5: 'a) then rx - (1: 'a) else if d >= (0.5: 'a) then rx + (1: 'a) else rx; y = (tmp_b: 'b); tel function #pragma kcg expand #end of_bool(phantom: 'a ; x: bool) returns (y: 'a) where 'a numeric let y = if x then 1 else 0; _ = phantom; tel end; package Boolean function #pragma kcg expand #end of_numeric (x: 'a) returns (b: bool) where 'a numeric b = (x <> (0: 'a)); function #pragma kcg expand #end LT(a, b: bool) returns (c: bool) c = not a and b; function #pragma kcg expand #end GT(a, b: bool) returns (c: bool) c = a and not b; function #pragma kcg expand #end LE(a, b: bool) returns (c: bool) c = not a or b; function #pragma kcg expand #end GE(a, b: bool) returns (c: bool) c = a or not b; end; -- Boolean package Double type t = float64; const imported eps: t; function #pragma kcg expand #end eq(x, y: float64) returns (b: bool) b = Generic::abs(x - y) < eps; function #pragma kcg expand #end sign(x: t) returns (y: t) y = Generic::sign(x); function #pragma kcg expand #end of_bool(x: bool) returns (y: t) y = Generic::of_bool((0:t),x); function #pragma kcg expand #end cast (x:'a) returns (y: t) where 'a numeric y = (x: t); end; package Single type t = float32; const imported eps: t; function #pragma kcg expand #end eq(x, y: float32) returns (b: bool) b = Generic::abs(x - y) < eps; function #pragma kcg expand #end sign(x: t) returns (y: t) y = Generic::sign(x); function #pragma kcg expand #end of_bool(x: bool) returns (y: t) y = Generic::of_bool((0:t),x); function #pragma kcg expand #end cast (x:'a) returns (y: t) where 'a numeric y = (x: t); end; /***********************************************************/ package Uint8 type t = uint8; const min_t : t = 0; const max_t : t = 0xFF; function #pragma kcg expand #end saturate(x: 'a) returns (y: t) where 'a numeric y = (Generic::min(Generic::max(x, (min_t: 'a)), (max_t: 'a)) : t); function #pragma kcg expand #end sign(x:t) returns (y:t) y = Generic::u_sign(x); function #pragma kcg expand #end of_bool(x: bool) returns (y: t) y = Generic::of_bool((0:t),x); function #pragma kcg expand #end cast (x:'a) returns (y: t) where 'a numeric y = (x: t); end; package Uint16 type t = uint16; const min_t : t = 0; const max_t : t = 0xFFFF; function #pragma kcg expand #end saturate(x: 'a) returns (y: t) where 'a numeric y = (Generic::min(Generic::max(x, (min_t: 'a)), (max_t: 'a)) : t); function #pragma kcg expand #end sign(x:t) returns (y:t) y = Generic::u_sign(x); function #pragma kcg expand #end of_bool(x: bool) returns (y: t) y = Generic::of_bool((0:t),x); function #pragma kcg expand #end cast (x:'a) returns (y: t) where 'a numeric y = (x: t); end; package Uint32 type t = uint32; const min_t : t = 0; const max_t : t = 0xFFFFFFFF; function #pragma kcg expand #end saturate(x: 'a) returns (y: t) where 'a numeric y = (Generic::min(Generic::max(x, (min_t: 'a)), (max_t: 'a)) : t); function #pragma kcg expand #end sign(x:t) returns (y:t) y = Generic::u_sign(x); function #pragma kcg expand #end of_bool(x: bool) returns (y: t) y = Generic::of_bool((0:t),x); function #pragma kcg expand #end cast (x:'a) returns (y: t) where 'a numeric y = (x: t); end; package Uint64 type t = uint64; const min_t : t = 0; const max_t : t = 0xFFFFFFFFFFFFFFFF; function #pragma kcg expand #end saturate(x: 'a) returns (y: t) where 'a numeric y = (Generic::min(Generic::max(x, (min_t: 'a)), (max_t: 'a)) : t); function #pragma kcg expand #end sign(x:t) returns (y:t) y = Generic::u_sign(x); function #pragma kcg expand #end of_bool(x: bool) returns (y: t) y = Generic::of_bool((0:t),x); function #pragma kcg expand #end cast (x:'a) returns (y: t) where 'a numeric y = (x: t); end; /***********************************************************/ package Int8 type t = int8; const min_t : t = -128; const max_t : t = 127; function #pragma kcg expand #end saturate(x: 'a) returns (y: t) where 'a numeric y = (Generic::min(Generic::max(x, (min_t: 'a)), (max_t: 'a)) : t); function #pragma kcg expand #end abs_sat(x: t) returns (y: t) y = (Generic::signed_abs_sat <>)(x); function #pragma kcg expand #end abs_wrap(x: t) returns (y: t) y = (Generic::signed_abs_wrap <>)(x); function #pragma kcg expand #end sign (x:t) returns (y: t) y = Generic::sign (x); function #pragma kcg expand #end round(x:'a) returns (y: t) where 'a float y = Generic::round((0:t), x); function #pragma kcg expand #end of_bool(x: bool) returns (y: t) y = Generic::of_bool((0:t),x); function #pragma kcg expand #end cast (x:'a) returns (y: t) where 'a numeric y = (x: t); end; -- Int8 /***********************************************************/ package Int16 type t = int16; const min_t : t = -32768; const max_t : t = 32767; function #pragma kcg expand #end saturate(x: 'a) returns (y: t) where 'a numeric y = (Generic::min(Generic::max(x, (min_t: 'a)), (max_t: 'a)) : t); function #pragma kcg expand #end abs_sat(x: t) returns (y: t) y = (Generic::signed_abs_sat <>)(x); function #pragma kcg expand #end abs_wrap(x: t) returns (y: t) y = (Generic::signed_abs_wrap <>)(x); function #pragma kcg expand #end sign (x:t) returns (y: t) y = Generic::sign (x); function #pragma kcg expand #end round(x:'a) returns (y: t) where 'a float y = Generic::round((0:t), x); function #pragma kcg expand #end of_bool(x: bool) returns (y: t) y = Generic::of_bool((0:t),x); function #pragma kcg expand #end cast (x:'a) returns (y: t) where 'a numeric y = (x: t); end; -- Int16 /***********************************************************/ package Int32 type t = int32; const min_t : t = -2147483648; const max_t : t = 2147483647; function #pragma kcg expand #end saturate(x: 'a) returns (y: t) where 'a numeric y = (Generic::min(Generic::max(x, (min_t: 'a)), (max_t: 'a)) : t); function #pragma kcg expand #end abs_sat(x: t) returns (y: t) y = (Generic::signed_abs_sat <>)(x); function #pragma kcg expand #end abs_wrap(x: t) returns (y: t) y = (Generic::signed_abs_wrap <>)(x); function #pragma kcg expand #end sign (x:t) returns (y: t) y = Generic::sign (x); function #pragma kcg expand #end round(x:'a) returns (y: t) where 'a float y = Generic::round((0:t), x); function #pragma kcg expand #end of_bool(x: bool) returns (y: t) y = Generic::of_bool((0:t),x); function #pragma kcg expand #end cast (x:'a) returns (y: t) where 'a numeric y = (x: t); end; -- Int32 /***********************************************************/ package Int64 type t = int64; const min_t : t = -9223372036854775808; const max_t : t = 9223372036854775807; function #pragma kcg expand #end saturate(x: 'a) returns (y: t) where 'a numeric y = (Generic::min(Generic::max(x, (min_t: 'a)), (max_t: 'a)) : t); function #pragma kcg expand #end abs_sat(x: t) returns (y: t) y = (Generic::signed_abs_sat <>)(x); function #pragma kcg expand #end abs_wrap(x: t) returns (y: t) y = (Generic::signed_abs_wrap <>)(x); function #pragma kcg expand #end sign (x:t) returns (y: t) y = Generic::sign (x); function #pragma kcg expand #end round(x:'a) returns (y: t) where 'a float y = Generic::round((0:t), x); function #pragma kcg expand #end of_bool(x: bool) returns (y: t) y = Generic::of_bool((0:t),x); function #pragma kcg expand #end cast (x:'a) returns (y: t) where 'a numeric y = (x: t); end; -- Int64 /***********************************************************/ package Polynomial function #pragma kcg expand #end s_horner(acc_in, x_i, a_i: 't) returns (acc_out: 't) where 't numeric acc_out = x_i * acc_in + a_i; function #pragma kcg expand #end horner <> (x: 't ; coef: 't^N) returns (y: 't) where 't numeric y = (fold s_horner <>)((0: 't), x^N, coef); end; -- Polynomial end;