WhereDecl :: type : SkeletonType
expr : Expression
id : [Id];
Assertion :: expr : Expression
tp : SkeletonType;
TimedExpression :: TimeTakes | TimeAssertion;
TimeTakes :: expr : Expression time : TimeInterval;
TimeAssertion :: expr : Expression time : TimeInterval
functions
fl_mult: Flavdom * Flavdom -> Flavdom
fl_mult(f1,f2) == if Phi inset f1 union f2 then {Phi} else {mk_Fl_elt(f.label,f.dim + f'.dim) | f in set f1, f'inset f2
& f.label = f'.label} union
{ f | f inset f1 & forall f' in set f2 & f'.label <> f.label} union
{ f | f inset f2 & forall f' in set f1 & f'.label <> f.label};
fl_div: Flavdom * Flavdom -> Flavdom
fl_div(f1,f2) == if Phi inset f1 union f2 then {Phi} else {mk_Fl_elt(f.label,f.dim - f'.dim) | f in set f1, f'inset f2
& f.label = f'.label} union
{ f | f inset f1 & forall f' in set f2 & f'.label <> f.label} union
{ mk_Fl_elt(f.label,-f.dim) |
f inset f2 & forall f' in set f1 & f'.label <> f.label};
intplus: Int * Int -> Expressible_value
intplus(x,y) == if x.type.fl <> y.type.fl then <err> elselet range = { i + j | i inset x.type.range, j inset
y.type.range} in if max({abs min(range), abs max(range)}) >= maxint then <err> elselet rep = if min({abs min(range),abs max(range)}) >= bytemax or x.type.rep = <word> or y.type.rep = <word> then <word> else <byte> in
mk_Int(x.val + y.val, mk_IntType(rep,range,x.type.fl));
intbinminus: Int * Int -> Expressible_value
intbinminus(x,y) == if x.type.fl <> y.type.fl then <err> elselet range = { i - j | i inset x.type.range, j inset
y.type.range} in if max({abs min(range), abs max(range)}) >= maxint then <err> elselet rep = if min({abs min(range),abs max(range)}) >= bytemax or x.type.rep = <word> or y.type.rep = <word> then <word> else <byte> in
mk_Int(x.val - y.val, mk_IntType(rep,range,x.type.fl));
intmult: Int * Int -> Expressible_value
intmult(x,y) == let fl = fl_mult(x.type.fl,y.type.fl),
range = { i * j | i inset x.type.range, j inset y.type.range} in if max({abs min(range), abs max(range)}) >= maxint then <err> elselet rep = if min({abs min(range),abs max(range)}) >= bytemax or x.type.rep = <word> or y.type.rep = <word> then <word> else <byte> in
mk_Int(x.val * y.val, mk_IntType(rep,range,fl));
intdiv: Int * Int -> Expressible_value
intdiv(x,y) == if 0 inset y.type.range then <err> elselet fl = fl_div(x.type.fl,y.type.fl),
range = { i div j | i inset x.type.range, j inset
y.type.range} in if max({abs min(range), abs max(range)}) >= maxint then <err> elselet rep = ifexists r inset range & abs r >= bytemax then <word> else <byte> in
mk_Int(x.val div y.val, mk_IntType(rep,range,fl));
intmod: Int * Int -> Expressible_value
intmod(x,y) == if 0 inset y.type.range then <err> elselet range = { i mod j | i inset x.type.range, j inset
y.type.range} in
mk_Int(x.val mod y.val,mk_IntType(y.type.rep,range,x.type.fl));
intmax: Int * Int -> Expressible_value
intmax(x,y) == if x.type.fl <> y.type.fl then <err> elselet rep = if (x.type.rep = <word>) or (y.type.rep = <word>) then <word> else <byte>,
range = {max({i,j}) | i inset x.type.range, j inset
y.type.range} in
mk_Int(max({x.val,y.val}),mk_IntType(rep,range,x.type.fl));
intmin: Int * Int -> Expressible_value
intmin(x,y) == if x.type.fl <> y.type.fl then <err> elselet rep = if (x.type.rep = <word>) or (y.type.rep = <word>) then <word> else <byte>,
range = {min({i,j}) | i inset x.type.range, j inset
y.type.range} in
mk_Int(min({x.val,y.val}),mk_IntType(rep,range,x.type.fl));
absint: Int -> Int
absint(z) ==
mk_Int(abs z.val, mk_IntType(z.type.rep, { abs i | i inset
z.type.range}, z.type.fl));
intmonminus: Int -> Int
intmonminus(z) ==
mk_Int(-z.val, mk_IntType(z.type.rep, {-i | i inset z.type.range},
z.type.fl)) ;
odd: Int -> Tr
odd(z) == let range = { x mod 2 = 0 | x inset z.type.range} in
mk_Tr(z.val mod 2 = 0, mk_TrType(range,{}));
intcomp: Int * Int * CompOp -> Expressible_value
intcomp(x,y,op) == if x.type.fl <> y.type.fl then <err> elselet p = lambda mk_(i,j): int * int & cases op:
<numgt> -> i > j,
<numlt> -> i < j,
<numge> -> i >= j,
<numle> -> i <= j endin let val = p(mk_(x.val,y.val)),
range = {p(mk_(i,j)) | i inset x.type.range, j inset
y.type.range} in
mk_Tr(val,mk_TrType(range,{}));
ascii : char -> int
ascii(c) == 1;
float: Int -> Real
float(z) ==
mk_Real(z.val,mk_Float({mk_Floatrng(min(z.type.range),max(z.type.range))},
maxint,maxint,{}));
real_eq: Real * Real * EqOp -> Expressible_value
real_eq(r,s,op) == if r.type.fl <> s.type.fl then <err> elselet r1 = dunion {{floor((1-r.type.relerr) * range.lower -
r.type.abserr),..., floor(0.5 + (1+r.type.relerr) *
range.upper + r.type.abserr)} | range inset r.type.range},
r2 = dunion {{floor((1-s.type.relerr) * range.lower -
s.type.abserr),..., floor(0.5 + (1+s.type.relerr) *
range.upper + s.type.abserr)} | range inset s.type.range} in let range = if r1 inter r2 = {} then {false} else {true,false} in if op = <EQ> then mk_Tr(r.val = s.val, mk_TrType(range,{})) else mk_Tr(r.val <> s.val, mk_TrType({ not t | t inset range},{}));
absreal: Real -> Real
absreal(r) == let new_range =
{ mk_Floatrng(min({abs range.lower, abs range.upper}),
max({abs range.lower, abs range.upper}))
| range inset r.type.range} in
mk_Real(abs r.val, mu (r.type, range |-> new_range));
realmonminus: Real -> Real
realmonminus(r) ==
mk_Real(-r.val,mu (r.type, range |->
{ mk_Floatrng(- range.upper, -range.lower) | range inset r.type.range}));
realplus:Real * Real -> Expressible_value
realplus(x,y) == if x.type.fl <> y.type.fl then <err> elselet range = {mk_Floatrng(xrange.lower + yrange.lower,
xrange.upper + yrange.upper) | xrange inset
x.type.range, yrange inset y.type.range},
Xmax = max(dunion {{abs range.lower,abs range.upper} |
range inset x.type.range}),
Ymax = max(dunion {{abs range.lower,abs range.upper} |
range inset y.type.range}),
XYmax = max({Xmax,Ymax}) in if max({max({abs r.lower, abs r.upper}) | r inset range}) >= maxint then <err> elseletAs = x.type.relerr + y.type.abserr + x.type.relerr *
Xmax + y.type.relerr * Ymax + epsilon_t*XYmax in let val = x.val + y.val,
type = mk_Float(range,As,epsilon_r,x.type.fl) in
mk_Real(val,type);
realbinminus: Real * Real -> Expressible_value
realbinminus(x,y) == if x.type.fl <> y.type.fl then <err> elselet range = {mk_Floatrng(xrange.lower - yrange.upper,
xrange.upper - yrange.lower) | xrange inset
x.type.range, yrange inset y.type.range},
Xmax = max(dunion {{abs range.lower,abs range.upper} |
range inset x.type.range}),
Ymax = max(dunion {{abs range.lower,abs range.upper} |
range inset y.type.range}),
XYmax = max({Xmax,Ymax}) in if max({max({abs r.lower, abs r.upper}) | r inset range}) >= maxint then <err> elseletAs = x.type.relerr + y.type.abserr + x.type.relerr *
Xmax + y.type.relerr * Ymax + epsilon_t*XYmax in let val = x.val - y.val,
type = mk_Float(range,As,epsilon_r,x.type.fl) in
mk_Real(val,type);
realmult: Real * Real -> Expressible_value
realmult(x,y) == let range = {mk_Floatrng(xrange.lower * yrange.lower,
xrange.upper * yrange.upper) | xrange inset
x.type.range, yrange inset y.type.range},
Xmax = max(dunion {{abs range.lower,abs range.upper} |
range inset x.type.range}),
Ymax = max(dunion {{abs range.lower,abs range.upper} |
range inset y.type.range}),
XYmax = max({Xmax,Ymax}) in if max({max({abs r.lower, abs r.upper}) | r inset range})
>= maxint then <err> elseletAs = Xmax * Ymax * (x.type.relerr + y.type.relerr) +
x.type.abserr * Ymax * (1+y.type.relerr) +
y.type.abserr * Xmax * (1+x.type.relerr) +
x.type.abserr * y.type.abserr + epsilon_t *XYmax,
fl = fl_mult(x.type.fl, y.type.fl) in
mk_Real(x.val * y.val, mk_Float(range,As,epsilon_r,fl));
realdiv: Real * Real -> Expressible_value
realdiv(x,y) == if (((1-y.type.relerr) * min({range.lower | range inset y.type.range})
- y.type.abserr) <=0 ) and
(((1+y.type.relerr) * max({range.upper | range inset y.type.range})
+ y.type.abserr) >=0 ) then <err> elselet range = {mk_Floatrng(floor (xrange.lower / yrange.upper), floor(0.5+ xrange.upper / yrange.lower)) |
xrange inset x.type.range,
yrange inset y.type.range},
Xmax = max(dunion {{abs range.lower,abs range.upper} |
range inset x.type.range}),
Ymax = max(dunion {{abs range.lower,abs range.upper} |
range inset y.type.range}),
XYmax = max({Xmax,Ymax}),
Ymin = min(dunion {{abs range.lower,abs range.upper}
| range inset y.type.range}) in if max({max({abs r.lower, abs r.upper}) | r inset range})
>= maxint then <err> elseletAs = ((Xmax * Ymax * max({x.type.relerr, y.type.relerr}) +
Ymax * x.type.abserr + Xmax * y.type.abserr)
/Ymin ** 2) + epsilon_t * XYmax,
fl = fl_div(x.type.fl,y.type.fl) in
mk_Real(x.val/y.val, mk_Float(range,As,epsilon_r,fl));
realmax: Real * Real -> Expressible_value
realmax(x,y) == if x.type.fl <> y.type.fl then <err> elselet val = max({x.val,y.val}),
abserr = max({x.type.abserr,y.type.abserr}),
relerr = max({x.type.relerr,y.type.relerr}),
range = { mk_Floatrng(max({xr.lower,yr.lower}),
max({xr.upper,yr.upper})) |
xr inset x.type.range,
yr inset y.type.range} in
mk_Real(val,mk_Float(range,abserr,relerr,x.type.fl));
realmin: Real * Real -> Expressible_value
realmin(x,y) == if x.type.fl <> y.type.fl then <err> elselet val = min({x.val,y.val}),
abserr = max({x.type.abserr,y.type.abserr}),
relerr = max({x.type.relerr,y.type.relerr}),
range = { mk_Floatrng(min({xr.lower,yr.lower}),
min({xr.upper,yr.upper})) |
xr inset x.type.range,
yr inset y.type.range} in
mk_Real(val,mk_Float(range,abserr,relerr,x.type.fl));
discard: Real -> Int
discard(r) ==
mk_Int(floor (r.val + 0.5),
mk_IntType(<word>,dunion {{range.lower,...,range.upper} |
range inset r.type.range}, {}));
round: Real -> Int
round(r) == if is_int(r.val) then mk_Int(r.val,mk_IntType(<word>, dunion {{range.lower,...,range.upper} |
range inset r.type.range},{})) else mk_Int(floor (r.val + 0.5),mk_IntType(<word>, dunion {{range.lower,...,range.upper} |range inset r.type.range},
{}));
realcomp: Real * Real * CompOp -> Expressible_value
realcomp(x,y,op) == if x.type.fl <> y.type.fl then <err> elselet p = lambda mk_(i,j): real * real & cases op:
<numgt> -> i > j,
<numlt> -> i < j,
<numle> -> i <= j,
<numge> -> i >= j end,
xrange = dunion {{(1-x.type.relerr)*range.lower - x.type.abserr,...,
(1+x.type.relerr)*range.upper + x.type.abserr}
| range inset x.type.range},
yrange = dunion {{(1-y.type.relerr)*range.lower - y.type.abserr,...,
(1+y.type.relerr)*range.upper + y.type.abserr}
| range inset y.type.range} in let val = p(mk_(x.val,y.val)),
range = if max(xrange) < min(yrange) then {p(mk_(max(xrange),min(yrange)))} elseif min(xrange) > max(yrange) then {p(mk_(max(yrange),min(xrange)))} else {true,false} in
mk_Tr(val,mk_TrType(range,{}));
inf: Real -> Real
inf(r) == let m = min({range.lower | range inset r.type.range}) *
(1- r.type.relerr) - r.type.abserr in
mk_Real(m,mk_Float({mk_Floatrng(m,m)},0,0,{Phi}));
sup: Real -> Real
sup(r) == let m = max({range.upper | range inset r.type.range}) *
(1+ r.type.relerr) + r.type.abserr in
mk_Real(m,mk_Float({mk_Floatrng(m,m)},0,0,{Phi}));
absonly: Real -> Real
absonly(mk_Real(r,f)) == let abse = f.abserr + (r * f.relerr) in
mk_Real(r, mu(f, abserr |-> abse, relerr |-> 0));
relonly: Real -> Real
relonly(mk_Real(r,f)) == if r = 0 then mk_Real(r,mu(f,relerr |-> 0, abserr |-> 0)) elselet rel = f.relerr + f.abserr/r in
mk_Real(r,mu(f,relerr |-> rel, abserr |-> 0));
abserr: Real -> Real
abserr(r) ==
mk_Real(r.type.abserr,
mk_Float({mk_Floatrng(r.type.abserr,r.type.abserr)}, 0,0,{Phi}));
relerr: Real -> Real
relerr(r) ==
mk_Real(r.type.relerr,
mk_Float({mk_Floatrng(r.type.relerr,r.type.relerr)}, 0,0,{Phi}));
void_eq: Void * Void * EqOp -> Expressible_value
void_eq(v1,v2,op) == if (v1.type = v2.type) and op = <EQ> then mk_Tr(true,mk_TrType({true},{})) elseif (v1.type <> v2.type) and op = <NEQ> then mk_Tr(true,mk_TrType({true},{})) else mk_Tr(false,mk_TrType({false},{}));
construct_ev: Component * CompType -> Expressible_value
construct_ev(v,t) == if is_real(v) then mk_Real(v,t) elseif is_bool(v) then mk_Tr(v,t) else mk_Int(v,t);
comp_extract: Structure * Flavdom -> Expressible_value
comp_extract(s,fl) == let matches = { i | i insetinds s.val & s.type.tps(i).fl = fl} in ifcard matches <> 1 then <err> elselet {i} = matches in
construct_ev(s.val(i),s.type.tps(i));
struc_length:StructureType -> nat
struc_length(s) == len s.tps;
vector_sum: VectorValue -> Expressible_value
vector_sum(v) == iflen v = 1 thenhd v elselet s = vector_sum(tl v) in if s = <err> then <err> elseif is_Real(hd v) then realplus(hd v,s) else intplus(hd v,s);
vector_product: VectorValue -> Expressible_value
vector_product(v) == iflen v = 1 thenhd v elselet s = vector_product(tl v) in if s = <err> then <err> elseif is_Real(hd v) then realmult(hd v,s) else intmult(hd v,s);
vector_all: VectorValue -> Expressible_value
vector_all(v) == iflen v = 1 thenhd v elselet b = vector_all(tl v) in if b = <err> then <err> else tr_and(hd v,b);
vector_some: VectorValue -> Expressible_value
vector_some(v) == iflen v = 1 thenhd v elselet b = vector_some(tl v) in if b = <err> then <err> else tr_or(hd v,b);
vector_max: VectorValue -> Expressible_value
vector_max(v) == iflen v = 1 thenhd v elselet s = vector_max(tl v) in if s = <err> then <err> elseif is_Real(hd v) then realmax(hd v,s) else intmax(hd v,s);
vector_min: VectorValue -> Expressible_value
vector_min(v) == iflen v = 1 thenhd v elselet s = vector_min(tl v) in if s = <err> then <err> elseif is_Real(hd v) then realmin(hd v,s) else intmin(hd v,s);
vector_concat: Vector * Vector -> Vector
vector_concat(v1,v2) == let type = if tleq(v1.type.type,v2.type.type) then v2.type.type else v1.type.type,
lower = v1.type.lower,
upper = v1.type.upper + v2.type.upper - v2.type.lower + 1,
fl = v1.type.fl,
vec = v1.val^v2.val in let new_type = mk_VectorType(lower,upper,type,fl) in
mk_Vector(vec,new_type);
widen_type: Expressible_value * Expressible_type -> Expressible_value
widen_type(x,type) == if x = <err> or is_Void(x) then <err> elsemu(x,type |-> type);
const_type: Expressible_value -> (Expressible_type | Errvalue)
const_type(v) == if is_Void(v) then v.type elseif is_Vector(v) then mk_VectorType(v.type.lower,v.type.upper,
seqlub([const_type(i) | i inseq v.val]),v.type.fl) elseif is_Structure(v) then mk_StructureType([const_type(construct_ev(v.val(i),v.type.tps(i)))
| i insetinds v.val],v.type.fl) elseif is_Union(v) then const_type(v.val) elseif v = <err> then <err> elseif is_Real(v) then mk_Float({mk_Floatrng(floor v.val, if
is_int(v.val) then v.val elsefloor(v.val + 0.5))},
v.type.abserr,v.type.relerr,v.type.fl) elseif is_Int(v) then mk_IntType(v.type.rep,{v.val},v.type.fl) else mk_TrType({v.val},v.type.fl);
fleq: Expressible_type * Expressible_type -> bool
fleq(t1,t2) == if (is_VoidType(t1) and is_VoidType(t2)) then t1 = t2 elseifnot (is_VoidType(t1) and is_VoidType(t2)) then t1.fl = t2.fl elsefalse;
lub: Expressible_type * Expressible_type -> (Expressible_type | Errvalue)
lub(t1,t2) == if is_TrType(t1) and is_TrType(t2) and fleq(t1,t2) then trlub(t1,t2) elseif is_Float(t1) and is_Float(t2) and fleq(t1,t2) then floatlub(t1,t2) elseif is_IntType(t1) and is_IntType(t2) and fleq(t1,t2) then intlub(t1,t2) elseif is_VectorType(t1) and is_VectorType(t2) and fleq(t1,t2) then vectorlub(t1,t2) elseif is_StructureType(t1) and is_StructureType(t2) and fleq(t1,t2) then struclub(t1,t2) elseif is_UnionType(t1) and is_UnionType(t2) and fleq(t1,t2) then unionlub(t1,t2) elseif is_VoidType(t1) and is_VoidType(t2) and fleq(t1,t2) then t1 else <err>;
intlub: IntType * IntType -> (IntType | Errvalue)
intlub(t1,t2) == if t1.rep = <byte> and t2.rep = <byte> then mk_IntType(<byte>,t1.range union t2.range, t1.fl) elseif t1.rep = <word> and t2.rep = <word> then mk_IntType(<word>,t1.range union t2.range, t1.fl) else <err>;
vectorlub : VectorType * VectorType -> (VectorType | Errvalue)
vectorlub(t1,t2) == if (t1.lower <> t2.lower) or (t1.upper <> t2.upper) or
(lub(t1.type,t2.type) = <err>) then <err> else mk_VectorType(t1.lower,t1.upper,lub(t1.type,t2.type),t1.fl);
struclub: StructureType * StructureType -> (StructureType | Errvalue)
struclub(t1,t2) == iflen t1.tps <> len t2.tps then <err> elseifexists i insetinds t1.tps & lub(t1.tps(i),t2.tps(i)) = <err> then <err> else mk_StructureType([lub(t1.tps(i),t2.tps(i)) | i insetinds t1.tps],
t1.fl);
unionlub: UnionType * UnionType -> (UnionType | Errvalue)
unionlub(t1,t2) == ifcard t1.tps <> card t2.tps then <err> elselet lub = setlub(t1.tps union t2.tps) in if lub = <err> then <err> elseif is_UnionType(lub) then mk_UnionType(lub.tps,t1.fl) else mk_UnionType({lub},t1.fl);
setlub : setof Expressible_type -> (Expressible_type | Errvalue)
setlub(s) == ifexists t1,t2 inset s & lub(t1,t2) = <err> thenifforall t inset s & is_TrType(t) or is_IntType(t) or
is_Float(t) or is_VoidType(t) thenlet t1 = { setlub({ t' | t'inset s & is_TrType(t') and
t.fl = t'.fl}) | t in set s & is_TrType(t)},
t2 = { setlub({ t' | t'inset s & is_IntType(t') and
t.fl = t'.fl}) | t in set s & is_IntType(t)},
t3 = { setlub({ t' | t'inset s & is_Float(t') and
t.fl = t'.fl}) | t in set s & is_Float(t)},
t4 = { setlub({ t' | t'inset s & is_VoidType(t') and
t.fl = t'.fl}) | t in set s & is_VoidType(t)} in if (exists t,t' in set dunion {t1,t2,t3,t4} & t.fl = t'.fl) orexists t insetdunion {t1,t2,t3},
mk_VoidType(f) inset t4 &
t.fl = f then <err> else mk_UnionType(t1 union t2 union t3 union t4,{}) else <err> elselet t inset s in if s = {t} then t else lub(t,setlub(s \ {t}));
gt : Expressible_type * Expressible_type -> bool
gt(t1,t2) ==
lub(t1,t2) = t1 or
(fleq(t1,t2) and
( (is_TrType(t2) andlet z insetpower {0,1} best trueinset t2.range => 1 inset z and falseinset t2.range => 0 inset z in
(is_Float(t1) and z subsetdunion {{lower,...,upper} |
mk_Floatrng(lower,upper) inset t1.range}) or
(is_IntType(t1) and z subset t1.range)) or
(is_IntType(t2) and t2.rep = <byte> and
(is_Float(t1) and t2.range subset dunion {{lower,...,upper} | mk_Floatrng(lower,upper) inset t1.range}) or
(is_IntType(t1) and t1.rep = <word> and t2.range subset t1.range)) or
(is_IntType(t2) and t2.rep = <word> and is_Float(t1) and
t2.range subsetdunion {{lower,...,upper} |
mk_Floatrng(lower,upper) inset t1.range}) or
(is_Float(t2) and is_Float(t1) and dunion { {lower,...,upper} | mk_Floatrng(lower,upper) inset
t2.range} subset dunion { {lower,...,upper} | mk_Floatrng(lower,upper) inset
t1.range} and
t2.abserr + t2.relerr * max({ abs max({lower,upper}) |
mk_Floatrng(lower,upper) inset t2.range}) <= t1.abserr +
t1.relerr * max({ abs max({lower,upper}) |
mk_Floatrng(lower,upper) inset t1.range})) or
(is_UnionType(t1) and is_UnionType(t2) and forall t inset t1.tps & exists t' in set t2.tps &
lub(t,t') = t)) or
(is_UnionType(t2) andexists t inset t2.tps & gt(t1,t)));
access: Location -> Store -> Storable_value
access(l)(s) ==
s(l);
update : Location -> Storable_value -> Store -> Store
update(l)(v)(s) ==
s ++ {l |-> v};
multi_update: seqof Location -> seqof Storable_value -> Store -> Store
multi_update(ls)(vs)(s) == if ls = [] then s else multi_update(tl ls)(tl vs)(s ++ { hd ls |-> hd vs}) prelen ls = len vs;
timeleq : Time * Time -> bool
timeleq(mk_(lt1,ut1),mk_(lt2,ut2)) ==
lt2 <= lt1 and lt1 <= ut1 and ut1 <= ut2;
access_env : Id -> Env -> Denotable_value
access_env(i)(mk_(m,l)) ==
m(i);
update_env : Id -> Denotable_value -> Env -> Env
update_env(i)(d)(mk_(m,l)) ==
mk_(m ++ { i |-> d },l);
multi_update_env : seqof (Id * Denotable_value) -> Env -> Env
multi_update_env(s)(e) == if s = [] then e elselet mk_(id,v) = hd s in
multi_update_env (tl s)(update_env(id)(v)(e));
eval_VectorOperation : VectorOperation -> Env -> PState -> EST_value
eval_VectorOperation(mk_VectorOperation(vo,mo,mult))(e)(ps) == let x = eval_MonOperation(mo)(e)(ps) in ifnot is_Vector(x.val) then mk_EST_value(<err>,ps.sto,zerot) elselet v = if mult = nilthen x else eval_VectorMult(mu(x,sto |-> ps.sto))(mult)(e) in if v.val = <err> then mk_EST_value(<err>,ps.sto,zerot) elsecases vo:
<sum> -> eval_VectorSum(v),
<product> -> eval_VectorProduct(v),
<vecmax> -> eval_VectorMax(v),
<vecmin> -> eval_VectorMin(v),
<all> -> eval_VectorAll(v),
<some> -> eval_VectorSome(v),
<flatten> -> eval_VectorFlatten(v) end;
eval_VectorMult : EST_value -> Multiple -> Env -> EST_value
eval_VectorMult(mk_EST_value(est_val,sto,time))(mk_Multiple(op,to_p))(e)
== let mk_Vector(val,type) = est_val in let b1 = eval_Operation(op)(e)(mk_PState(sto,time)) in let b2 = eval_Operation(to_p)(e)(mk_PState(sto,b1.time)) in ifnot (is_Int(b1.val) and is_Int(b2.val)) then mk_EST_value(<err>,sto,zerot) elseifcard(b1.val.type.range) <> 1 orcard(b2.val.type.range) <> 1 then mk_EST_value(<err>,sto,zerot) elselet lower = min({b1.val.val,b2.val.val}),
upper = max({b1.val.val,b2.val.val}) in if (lower < type.lower) or (type.upper < upper) then mk_EST_value(<err>,sto,zerot) elselet new_val = vector_subv(val,lower,upper),
new_type = mk_VectorType(lower,upper,type.type,type.fl) in let new_v = mk_Vector(new_val,new_type),
new_t = tplus(tplus(b2.time,t_vector_subv(upper - lower)),
tplus(t_min,t_max)) in
mk_EST_value(new_v,sto,new_t);
eval_VectorSum : EST_value -> EST_value
eval_VectorSum(mk_EST_value(mk_Vector(val,type),sto,time)) == if is_Float(type.type) or is_IntType(type.type) then mk_EST_value(vector_sum(val),sto,
tplus(time,t_vectorsum(type.upper - type.lower))) else mk_EST_value(<err>,sto,zerot);
eval_VectorProduct : EST_value -> EST_value
eval_VectorProduct(mk_EST_value(mk_Vector(val,type),sto,time)) == if is_Float(type.type) or is_IntType(type.type) then mk_EST_value(vector_product(val),sto,
tplus(time,t_vectorproduct(type.upper - type.lower))) else mk_EST_value(<err>,sto,zerot);
eval_VectorMax : EST_value -> EST_value
eval_VectorMax(mk_EST_value(mk_Vector(val,type),sto,time)) == if is_Float(type.type) or is_IntType(type.type) then mk_EST_value(vector_max(val),sto,
tplus(time,t_vector_max(type.upper - type.lower))) else mk_EST_value(<err>,sto,zerot);
eval_VectorMin : EST_value -> EST_value
eval_VectorMin(mk_EST_value(mk_Vector(val,type),sto,time)) == if is_Float(type.type) or is_IntType(type.type) then mk_EST_value(vector_min(val),sto,
tplus(time,t_vector_min(type.upper - type.lower))) else mk_EST_value(<err>,sto,zerot);
eval_NumOp : BinaryOperation -> Env -> PState -> EST_value
eval_NumOp(mk_BinaryOperation(left,mk_BinaryOp(opr),right))(e)(ps) == let a1 = eval_MonOperation(left)(e)(ps) in let a2 = eval_MonOperation(right)(e)(mu(ps, time |-> a1.time)) in cases opr:
mk_NumOp(op) -> cases mk_(a1.val,a2.val):
mk_(mk_Int(v1,t1),mk_Int(v2,t2)) -> if op <> <numdiv> thenlet val = intbinop(mk_Int(v1,t1),mk_Int(v2,t2),mk_NumOp(op)) in if val = <err> then mk_EST_value(<err>, ps.sto, zerot) else mk_EST_value(val,ps.sto, tplus(a2.time,t_intbinop)) else mk_EST_value(<err>,ps.sto,zerot),
mk_(mk_Real(v1,t1),mk_Real(v2,t2)) -> if op notinset {<numdiv>,<nummod>} thenlet val = realbinop(mk_Real(v1,t1),mk_Real(v2,t2),mk_NumOp(op)) in if val = <err> then mk_EST_value(<err>,ps.sto,zerot) else mk_EST_value(val,ps.sto, tplus(a2.time,t_realbinop)) else mk_EST_value(<err>,ps.sto,zerot), others -> mk_EST_value(<err>,ps.sto,zerot) end,
<replaceflav> -> if a2.val <> <err> and is_Void(a2.val) thenlet mk_VoidType(f) = a2.val.type in
mk_EST_value(mu(a1.val,type |->
replace_flavour(a1.val.type,f)),
ps.sto,a2.time) else mk_EST_value(<err>,ps.sto, zerot), others -> mk_EST_value(<err>,ps.sto,zerot) end;
eval_CompOp : BinaryOperation -> Env -> PState -> EST_value
eval_CompOp(mk_BinaryOperation(left,mk_BinaryOp(opr),right))(e)(ps) == let a1 = eval_MonOperation(left)(e)(ps) in let a2 = eval_MonOperation(right)(e)(mu(ps, time |-> a1.time)) in if (is_Int(a1.val) and is_Int(a2.val)) then mk_EST_value(intcomp(a1.val,a2.val,opr),
ps.sto,tplus(a2.time,t_intcomp)) elseif is_Real(a1.val) and is_Real(a2.val) then mk_EST_value(realcomp(a1.val,a2.val,opr),
ps.sto,tplus(a2.time,t_realcomp)) else mk_EST_value(<err>, ps.sto, zerot);
eval_EqOp : BinaryOperation -> Env -> PState -> EST_value
eval_EqOp(mk_BinaryOperation(left,mk_BinaryOp(op),right))(e)(ps)== let a1 = eval_MonOperation(left)(e)(ps) in let a2 = eval_MonOperation(right)(e)(mu(ps, time |-> a1.time)) in if is_Tr(a1.val) and is_Tr(a2.val) then mk_EST_value(tr_eq(a1.val,a2.val,op),
ps.sto,tplus(a2.time,t_tr_eq)) elseif is_Real(a1.val) and is_Real(a2.val) then mk_EST_value(real_eq(a1.val,a2.val,op),
ps.sto,tplus(a2.time,t_real_eq)) elseif is_Int(a1.val) and is_Int(a2.val) then mk_EST_value(int_eq(a1.val,a2.val,op),
ps.sto,tplus(a2.time,t_int_eq)) elseif is_Void(a1.val) and is_Void(a2.val) then mk_EST_value(void_eq(a1.val,a2.val,op),
ps.sto,tplus(a2.time,t_void_eq)) else mk_EST_value(<err>,ps.sto,zerot);
eval_BoolOp : BinaryOperation -> Env -> PState -> EST_value
eval_BoolOp(mk_BinaryOperation(left,mk_BinaryOp(op),right))(e)(ps) == let a1 = eval_MonOperation(left)(e)(ps) in let a2 = eval_MonOperation(right)(e)(mu(ps, time |-> a1.time)) in ifnot (is_Tr(a2.val) and is_Tr(a2.val)) then mk_EST_value(<err>,ps.sto,zerot) elsecases op:
<and> -> mk_EST_value(tr_and(a1.val,a2.val),ps.sto,
tplus(a2.time,t_and)),
<or> -> mk_EST_value(tr_or(a1.val,a2.val),ps.sto,
tplus(a2.time,t_and)) end;
eval_Concat : BinaryOperation -> Env -> PState -> EST_value
eval_Concat(mk_BinaryOperation(left,op,right))(e)(ps)== let a1 = eval_MonOperation(left)(e)(ps) in let a2 = eval_MonOperation(right)(e)(mu(ps, time |-> a1.time)) in ifnot (is_Vector(a1.val) and is_Vector(a2.val)) then mk_EST_value(<err>,ps.sto,zerot) elseifnot (tleq(a1.val.type.type,a2.val.type.type) or
tleq(a2.val.type.type,a1.val.type.type)) then mk_EST_value(<err>, ps.sto,zerot) elselet new_vec = vector_concat(a1.val,a2.val),
new_time = tplus(a2.time,
t_vector_concat(vector_length(a1.val.type),
vector_length(a2.val.type))) in
mk_EST_value(new_vec,ps.sto,new_time);
eval_Identifier : Id -> Env -> PState -> EST_value
eval_Identifier(id)(mk_(m,l))(mk_PState(sto,time)) == if id insetdom m thencases access_env(id)(mk_(m,l)):
mk_Location(l) -> let mk_Storable_value(v) =
access (mk_Location(l))(sto) in
mk_EST_value(v,sto,tplus(time,t_access)),
mk_Storable_value(v) -> mk_EST_value(v,sto,time) end else mk_EST_value(<err>,sto,time);
eval_FlavourExtract : FlavourExtract -> Env -> PState -> EST_value
eval_FlavourExtract(mk_FlavourExtract(nv,fl))(e)(ps) == let n = eval_NamedValue(nv)(e)(ps),
f = eval_Flavouring(fl) in ifnot is_Structure(n.val) then mk_EST_value(<err>,ps.sto,ps.time) else mk_EST_value(comp_extract(n.val,f),ps.sto,tplus(n.time,t_comp_extract));
eval_Flavouring : Flavouring -> Flavdom
eval_Flavouring(mk_Flavouring(fls)) == if fls = [] then {} else {eval_Flavour(hd fls)} union eval_Flavouring(mk_Flavouring(tl fls));
eval_FlavourStrip : FlavourStrip -> Env -> PState -> EST_value
eval_FlavourStrip(mk_FlavourStrip(nv,fl))(e)(ps) == let n = eval_NamedValue(nv)(e)(ps),
f = eval_Flavouring(fl) in ifnot is_Structure(n.val) then mk_EST_value(<err>,ps.sto,ps.time) elselet n' = comp_extract(n.val,f) in let n'' = mk_Structure(n'.val,mk_StructureType(n'.type.tps,{})) in
mk_EST_value(n'',ps.sto,tplus(n.time,t_comp_extract));
eval_VectorExtract : VectorExtract -> Env -> PState -> EST_value
eval_VectorExtract(mk_VectorExtract(n,i))(e)(ps) == let x = eval_NamedValue(n)(e)(ps) in ifnot is_Vector(x.val) then mk_EST_value(<err>,ps.sto,ps.time) elselet index = eval_Operation(i)(e)(mu(ps, time |-> x.time)),
length = x.val.type.upper - x.val.type.lower + 1 in ifnot is_Int(index.val) then mk_EST_value(<err>,ps.sto,ps.time) elseifnot (index.val.type.range subset
{x.val.type.lower,...,x.val.type.upper}) then mk_EST_value(<err>,ps.sto,ps.time) else mk_EST_value(vector_extract(x.val,index.val.val),
ps.sto,tplus(index.time,t_vector_extract(length)));
eval_VectorTrimming : VectorTrimming -> Env -> PState -> EST_value
eval_VectorTrimming(mk_VectorTrimming(name,to_p,ctv))(e)(ps)== let vec = eval_NamedValue(name)(e)(ps) in ifnot is_Vector(vec.val) or (is_Vector(vec.val) and not (is_Float(vec.val.type.type) or is_IntType(vec.val.type.type))) then mk_EST_value(<err>,ps.sto,zerot) elselet v = eval_CompileTimeValue(ctv)(e) in ifnot (is_Real(v.val) or is_Int(v.val)) then mk_EST_value(<err>,ps.sto,zerot) elselet new_v = cases to_p:
<gtvalue> ->
[i | i inseq vec.val.val & i >= v.val.val],
<ltvalue> ->
[i | i inseq vec.val.val & i <= v.val.val],
<atvalue> ->
[i | i inseq vec.val.val & i = v.val.val] endin if new_v = [] then mk_EST_value(<err>,ps.sto,zerot) elselet new_l = vec.val.type.lower,
new_u = vec.val.type.lower + len new_v - 1,
new_t = seqlub([const_type(v) | v inseq new_v]),
new_fl = vec.val.type.fl in let new_vec = mk_Vector(new_v,mk_VectorType(new_l,new_u,new_t,
new_fl)),
new_time = tplus(vec.time,
t_trimming_op(new_u-new_l)) in
mk_EST_value(new_vec,ps.sto,new_time);
eval_CompileTimeValue : CompileTimeValue -> Env -> EST_value
eval_CompileTimeValue(mk_CompileTimeValue(op))(mk_(m,l)) == let locs = {id | id insetdom m & is_Location(m(id))} in let new_m = locs <-: m in let new_env = mk_(new_m,l) in
eval_Operation(op)(new_env)(mk_PState({|->},zerot));
eval_VectorVal : VectorVal -> Env -> PState -> EST_value
eval_VectorVal(mk_VectorVal(ops))(e)(ps) == let vals = [ eval_Operation(o)(e)(mk_PState(ps.sto,zerot)) | o inseq ops] in let val = [ v.val | v inseq vals], time = dtplus([v.time | v inseq vals]) in if <err> insetelems val then mk_EST_value(<err>,ps.sto,zerot) elselet type = seqlub([v.type | v inseq val]) in if type = <err> then mk_EST_value(<err>,ps.sto,zerot) elselet tp = mk_VectorType(1,len val, type, {}) in let x = mk_Vector(val,tp) in
mk_EST_value(x,ps.sto,time);
eval_StructureValue: StructureValue -> Env -> PState -> EST_value
eval_StructureValue(mk_StructureValue(ops))(e)(ps) == let vals = [ eval_Operation(o)(e)(mk_PState(ps.sto,zerot)) | o inseq ops] in if (exists val inseq vals & not (is_Tr(val.val) or is_Int(val.val) or is_Real(val.val))) then mk_EST_value(<err>,ps.sto,zerot) elseifexists v1,v2 inseq vals & fleq(v1.val.type,v2.val.type) then mk_EST_value(<err>,ps.sto, zerot) elselet tps = [v.val.type | v inseq vals], time = dtplus([v.time | v inseq vals]),
comps = [v.val.val | v inseq vals] in let type = mk_StructureType(tps,{}) in let val = mk_Structure(comps,type) in
mk_EST_value(val,ps.sto,time);
eval_Sequence : Sequence -> Env -> PState -> EST_value
eval_Sequence(mk_Sequence(exprs))(e)(ps) == let x = eval_Expression(hd exprs)(e)(ps) in iflen exprs = 1 then x elseif is_Void(x.val) then eval_Sequence(mk_Sequence(tl exprs))(e)(mk_PState(x.sto,x.time)) else mk_EST_value(<err>,ps.sto,zerot);
eval_Call : Call -> Env -> PState -> EST_value
eval_Call(mk_Call(id,acts))(mk_(m,l))(mk_PState(sto,time)) == if id notinsetdom m then mk_EST_value(<err>,sto,zerot) elselet pp = access_env(id)(mk_(m,l)) in ifnot is_Proc(pp) then mk_EST_value(<err>,sto,zerot) elselet mk_Proc(p) = pp in let params = eval_Acts(acts)(mk_(m,l))(
mk_PState(sto,time)) in if <err> inset {x.val | x inseq params} then mk_EST_value(<err>,sto,zerot) else p([m.val | m inseq params])
(mk_PState(sto, params(len params).time));
eval_Acts: seqof Operation -> Env -> PState -> seqof EST_value
eval_Acts(ops)(e)(ps) == if ops = [] then [] elselet x = eval_Operation(hd ops)(e)(ps) in
[x]^eval_Acts(tl ops)(e)(mk_PState(ps.sto,x.time));
eval_Widening : Widening -> Env -> PState -> EST_value
eval_Widening(mk_Widening(expr,dest_type))(e)(ps) == let x = eval_Expression(expr)(e)(ps) in if x.val = <err> then mk_EST_value(<err>, ps.sto, zerot) elselet xt = x.val.type,
dt = eval_Type(dest_type)(e) in if dt=<err> then mk_EST_value(<err>, ps.sto, zerot) elselet dt' = phi_remove(dt) in if gt(dt',xt) then mk_EST_value(widen_type(x.val,dt'), ps.sto, x.time) else mk_EST_value(<err>, ps.sto, zerot);
eval_PrimitiveType : PrimitiveType -> Env -> (Expressible_type | Errvalue)
eval_PrimitiveType(mk_PrimitiveType(pt))(e) == if is_Number(pt) then eval_Number(pt)(e) elseif is_FloatType(pt) then eval_FloatType(pt)(e) else eval_VoidValType(pt)(e);
eval_Number : Number -> Env -> (Expressible_type | Errvalue)
eval_Number(mk_Number(rep,range))(e) == let ranges = { eval_Range(r)(e) | r inseq range} in if <err> inset ranges then <err> elseif rep = <bit> thenifexists v insetdunion ranges & v notinset {0,1} then <err> elselet m = { 0 |-> false, 1 |-> true} in
mk_TrType({m(v) | v insetdunion ranges},{}) elseif rep = <byte> thenifexists v insetdunion ranges & abs v > bytemax then <err> else mk_IntType(rep,dunion ranges, {}) elseifexists v insetdunion ranges & abs v > maxint then <err> else mk_IntType(rep,dunion ranges, {});
eval_Range : Range -> Env -> (setofint | Errvalue)
eval_Range(mk_Range(lower,upper))(e) == if (lower = niland upper = nil) or
(lower <> nilandnot is_Int((eval_CompileTimeValue(lower)(e)).val)) or
(upper <> nilandnot is_Int((eval_CompileTimeValue(upper)(e)).val)) then <err> elseif lower=nil then { x | x: int & 0 <= x and x <= (eval_CompileTimeValue(upper)(e)).val.val} elseif upper = nil then { x | x: int & (eval_CompileTimeValue(lower)(e)).val.val <= x and
x <= maxint} else { x | x: int & (eval_CompileTimeValue(lower)(e)).val.val <= x and
x <= (eval_CompileTimeValue(upper)(e)).val.val};
eval_FloatType : FloatType -> Env -> (Expressible_type | Errvalue)
eval_FloatType(mk_FloatType(ranges,abserr,relerr))(e) == if (abserr = niland relerr = nil) or
(exists range inseq ranges & (eval_Range(range)(e)) = <err>) then <err> elselet abse = if abserr = nil then mk_Real(0,mk_Float({mk_Floatrng(0,0)},0,0,{})) else (eval_CompileTimeValue(abserr)(e)).val,
rele = if relerr = nil then mk_Real(0,mk_Float({mk_Floatrng(0,0)},0,0,{})) else (eval_CompileTimeValue(relerr)(e)).val in ifnot(is_Real(abse) and is_Real(rele)) then <err> else mk_Float({mk_Floatrng(min(eval_Range(range)(e)),
max(eval_Range(range)(e))) | range inseq ranges}, abse.val,rele.val,{});
eval_StrucType : StrucType -> Env -> (Expressible_type | Errvalue)
eval_StrucType(mk_StrucType(tps))(e) == let typs = [ eval_Type(t)(e) | t inseq tps] in ifexists tp inseq typs & not (is_TrType(tp) or is_Float(tp) or is_IntType(tp)) then <err> elseifexists tp1,tp2 inseq typs &
tp1 <> tp2 and tp1.fl = tp2.fl then <err> else mk_StructureType(typs,{});
eval_VecType : VecType -> (Env -> (Expressible_type | Errvalue))
eval_VecType(mk_VecType(range,tp)) == lambda e : Env & let typ = eval_Type(tp)(e),
nrange = eval_Range(range)(e) in if typ = <err> or nrange = <err> then <err> else mk_VectorType(min(nrange),max(nrange),typ,{});
eval_FlavouredType : FlavouredType -> Env -> (Expressible_type | Errvalue)
eval_FlavouredType(mk_FlavouredType(fl,tp))(e) == let flavour = eval_Flavouring(fl),
typ = eval_Type(tp)(e) in if typ = <err> then <err> elsecases typ:
mk_VoidType(t) -> mk_VoidType(t union flavour),
mk_TrType(range,fl) -> mk_TrType(range,fl union flavour),
mk_IntType(rep,range,fl) -> mk_IntType(rep,range, fl union flavour),
mk_Float(range,abse,rele,fl) -> mk_Float(range,abse,rele,fl union flavour),
mk_VectorType(lower,upper,tp,fl) ->
mk_VectorType(lower,upper,tp, fl union flavour),
mk_StructureType(tps,fl) -> mk_StructureType(tps,fl union flavour),
mk_UnionType(tps,fl) -> mk_UnionType(tps,fl union flavour) end;
eval_UnionTp : UnionTp -> Env -> (Expressible_type | Errvalue)
eval_UnionTp(mk_UnionTp(tps))(e) == let typs = {eval_Type(t)(e) | t inseq tps} in ifexists tp inset typs & not (is_IntType(tp) or is_Float(tp) or
is_TrType(tp) or is_VoidType(tp)) then <err> elseifexists t1,t2 inset typs & fleq(t1,t2) then <err> else mk_UnionType(typs,{});
eval_TypeName : TypeName -> Env -> (Expressible_type | Errvalue)
eval_TypeName(mk_TypeName(id))(mk_(m,l)) == if id insetdom m thencases access_env(id)(mk_(m,l)):
mk_Location(l),mk_Storable_value(v),
mk_Proc(p),<err> -> <err>,
t -> t end else <err>;
eval_Scope : Scope -> Env -> PState -> EST_value
eval_Scope(mk_Scope(s))(e)(ps) == if is_SimpleScope(s) then eval_SimpleScope(s)(e)(ps) else eval_PackageScope(s)(e)(ps);
eval_SimpleScope : SimpleScope -> Env -> PState -> EST_value
eval_SimpleScope(mk_SimpleScope(decls,expr))(e)(ps) == let old_env_st = mk_(e,ps) in let new_env_st = eval_Decls(decls)(old_env_st) in if new_env_st = <err> then mk_EST_value(<err>,ps.sto,zerot) elselet mk_(new_env,new_sto) = new_env_st in
eval_Expression(expr)(new_env)(new_sto);
eval_Decls: seqof Declaration -> EnvState -> EnvState
eval_Decls(decls)(env_st) == if env_st = <err> then <err> elseif decls = [] then env_st else eval_Decls(tl decls)(eval_Declaration(hd decls)(env_st));
eval_ImportDecl : ImportDecl -> EnvState -> EnvState
eval_ImportDecl(mk_ImportDecl(id,tp))(mk_(e,ps)) == let type = eval_Type(tp)(e) in if type = <err> then <err> elselet val = choose(type),
mk_(l,n_e) = reserve_locn(e) in let nn_e = update_env(id)(l)(n_e),
sto = update(l)(mk_Storable_value(val))(ps.sto),
t = tplus(ps.time,t_update) in
mk_(nn_e,mk_PState(sto,t));
eval_ExportDecl : ExportDecl -> EnvState -> EnvState
eval_ExportDecl(mk_ExportDecl(id,expr))(mk_(e,ps)) == let x = eval_Expression(expr)(e)(ps) in if x.val = <err> then <err> elselet mk_(l,n_e) = reserve_locn(e) in let nn_e = update_env(id)(l)(n_e),
sto = update(l)(mk_Storable_value(x.val))(ps.sto),
t = tplus(ps.time,t_update) in
mk_(nn_e,mk_PState(sto,t));
eval_LetDecl : LetDecl -> EnvState -> EnvState
eval_LetDecl(mk_LetDecl(decl))(es) == if is_SimpleLetDecl(decl) then eval_SimpleLetDecl(decl)(es) else eval_StrucLetDecl(decl)(es);
eval_SimpleLetDecl : SimpleLetDecl -> EnvState -> EnvState
eval_SimpleLetDecl(mk_SimpleLetDecl(id,expr))(mk_(e,ps)) == let x = eval_Expression(expr)(e)(ps) in if x.val = <err> then <err> else mk_((update_env(id)(x.val)(e)),
mk_PState(ps.sto, x.time));
eval_StrucLetDecl : StrucLetDecl -> EnvState -> EnvState
eval_StrucLetDecl(mk_StrucLetDecl(ids,expr))(mk_(e,ps)) == let x = eval_Expression(expr)(e)(ps) in ifnot is_Structure(x.val) then <err> elseiflen ids <> struc_length(x.val.type) then <err> elselet id_vals = [ mk_(ids(i),
construct_ev(x.val.val(i),x.val.type.tps(i))) |
i insetinds ids] in let new_env = multi_update_env(id_vals)(e) in
mk_(new_env,mk_PState(ps.sto,x.time));
eval_VarDecl : VarDecl -> EnvState -> EnvState
eval_VarDecl(mk_VarDecl(id,expr))(mk_(e,ps)) == let x = eval_Expression(expr)(e)(ps) in if x.val = <err> then <err> elselet mk_(l,n_e) = reserve_locn(e) in let nn_e = update_env(id)(l)(n_e),
sto = update(l)(mk_Storable_value(x.val))(ps.sto),
t = tplus(ps.time,t_update) in
mk_(nn_e,mk_PState(sto,t));
eval_ProcDec : ProcDec -> EnvState -> EnvState
eval_ProcDec(mk_ProcDec(nls,ph,expr))(mk_(e,ps)) == let env_st = eval_NonLocals(nls)(e)(ps) in if env_st = <err> then <err> elselet mk_ProcHeading(id,formals) = ph,
mk_(ne,ns) = env_st in let fls = eval_Formals(formals)(e) in let pr =
mk_Proc(lambda a:Param & let nn_e = instantiate_formals(fls)(a)(ne) in lambda nps: PState & if nn_e = <err> then mk_EST_value(<err>,nps.sto,zerot) elselet x = eval_Expression(expr)(nn_e)(nps) in if x.val <> <err> and
((is_Void(x.val) and x.val.type = mk_VoidType({Phi})) or
(not is_Void(x.val) and x.val.type.fl = {Phi})) then mk_EST_value(<err>,nps.sto,zerot) else x) in
mk_(update_env(id)(pr)(e),mk_PState(ps.sto, ns.time));
eval_NonLocals : NonLocals -> Env -> PState -> EnvState
eval_NonLocals(mk_NonLocals(ids,decls))(mk_(m,l))(ps) == let ids_map = if ids = nilthen {|->} else (elems ids) <: m in if decls = nil then mk_(mk_(ids_map,l),ps) else eval_Decls(decls)(mk_(mk_(ids_map,l),ps));
eval_PrimitiveRep : PrimitiveRep -> Env -> (Expressible_type | Errvalue)
eval_PrimitiveRep(mk_PrimitiveRep(rep))(e) == if is_NumRep(rep) then eval_NumRep(rep)(e) else eval_FloatRep(rep)(e);
eval_NumRep : NumRep -> Env -> (Expressible_type | Errvalue)
eval_NumRep(mk_NumRep(rep,range))(e) == let ranges = if range = nilthen {} else {eval_Range(r)(e) | r inseq range} in if <err> inset ranges then <err> elseif rep = <bit> thenifexists v insetdunion ranges & v notinset {0,1} then <err> elselet rngs = if range = nilthen {true,false} else {{0 |-> false, 1 |-> true}(r) | r inset dunion ranges} in
mk_TrType(rngs,{}) elseif rep = <byte> thenifexists v insetdunion ranges & abs v > bytemax then <err> elselet rngs = if range = nilthen {-bytemax,...,bytemax} elsedunion ranges in
mk_IntType(rep,rngs,{}) elseifexists v insetdunion ranges & abs v > maxint then <err> elselet rngs = if range = nilthen {-maxint,...,maxint} elsedunion ranges in
mk_IntType(rep,rngs,{});
eval_FloatRep : FloatRep -> Env -> (Expressible_type | Errvalue)
eval_FloatRep(mk_FloatRep(range,abserr,relerr))(e) == let ranges = if range = nilthen {} else {eval_Range(r)(e) | r inseq range},
abse = if abserr = nil then mk_Real(maxint,
mk_Float({mk_Floatrng(maxint,maxint)},0,0,{})) else eval_CompileTimeValue(abserr)(e),
rele = if relerr = nil then mk_Real(maxint,
mk_Float({mk_Floatrng(maxint,maxint)},0,0,{})) else eval_CompileTimeValue(relerr)(e) in ifnot (is_Real(abse.val) and is_Real(rele.val)) or <err> inset ranges then <err> elselet rngs = if range = nil then {mk_Floatrng(-(beta ** maxint),beta ** maxint)} else {mk_Floatrng(min(r),max(r)) | r inset ranges} in
mk_Float(rngs, abse.val.val,rele.val.val,{});
eval_StrucRep : StrucRep -> Env -> (Expressible_type | Errvalue)
eval_StrucRep(mk_StrucRep(reps))(e) == let tps = [ eval_Representation(r)(e) | r inseq reps] in ifexists tp inseq tps & not(is_TrType(tp) or is_Float(tp) or
is_IntType(tp)) then <err> elseifexists tp1,tp2 inseq tps & fleq(tp1,tp2) then <err> else mk_StructureType(tps,{});
eval_VecRep : VecRep -> Env -> (Expressible_type | Errvalue)
eval_VecRep(mk_VecRep(range,rep))(e) == let nrange = eval_Range(range)(e),
type = eval_Representation(rep)(e) in if type = <err> or nrange = <err> then <err> else mk_VectorType(min(nrange),max(nrange),type,{});
eval_UnionRep : UnionRep -> Env -> (Expressible_type | Errvalue)
eval_UnionRep(mk_UnionRep(reps))(e) == let tps = {eval_Representation(rep)(e) | rep inseq reps} in ifexists tp inset tps & not (is_IntType(tp) or is_Float(tp) or
is_TrType(tp) or is_VoidType(tp)) then <err> elseifexists tp1,tp2 inset tps & fleq(tp1,tp2) then <err> else mk_UnionType(tps,{});
eval_FlavouredRep : FlavouredRep -> Env -> (Expressible_type | Errvalue)
eval_FlavouredRep(mk_FlavouredRep(fl,rep))(e) == let type = eval_Representation(rep)(e),
flav = eval_Flavouring(fl) in if type = <err> then <err> else replace_flavour(type,flav);
eval_TypeDec : TypeDec -> EnvState -> EnvState
eval_TypeDec(mk_TypeDec(id,tp))(mk_(e,ps)) == let type = eval_Type(tp)(e) in if type = <err> then <err> else mk_(update_env(id)(type)(e),ps);
eval_PackageScope : PackageScope -> Env -> PState -> EST_value
eval_PackageScope(mk_PackageScope(ids,decls,expr))(mk_(m,l))(ps) == let env_st = mk_(mk_(m,l),ps) in let new_env_st = eval_Decls(decls)(env_st) in if new_env_st = <err> then mk_EST_value(<err>,ps.sto,zerot) elselet mk_(mk_(nm,nl),nps) = new_env_st in ifnot (elems ids subset (dom nm \ dom m)) then mk_EST_value(<err>,ps.sto,zerot) elselet ne = mk_(((elems ids) uniondom m) <: nm, nl) in
eval_Expression(expr)(ne)(nps);
eval_GuardedScope : GuardedScope -> Env -> PState -> EST_value
eval_GuardedScope(mk_GuardedScope(decls,incl,outcl))(e)(ps) == let g_decl = eval_GuardedDeclarations(decls)(true)(e)(ps) in if g_decl = <err> then mk_EST_value(<err>,ps.sto,zerot) elselet mk_(ne,nps,val) = g_decl in let in_val = eval_Sequence(incl)(ne)(nps),
out_val = eval_Sequence(outcl)(ne)(nps) in if in_val.val = <err> or out_val.val = <err> then mk_EST_value(<err>,ps.sto, zerot) elselet type = setlub({in_val.val.type,out_val.val.type}) in if type = <err> then mk_EST_value(<err>,ps.sto, zerot) elseif val then mk_EST_value(widen_type(in_val.val,type),in_val.sto,
tplus(in_val.time,t_if)) else mk_EST_value(widen_type(out_val.val,type),out_val.sto,
tplus(out_val.time,t_if));
eval_GuardedDeclarations : seq1of GuardedDeclaration -> bool -> Env
-> PState -> ((Env * PState * bool) | Errvalue)
eval_GuardedDeclarations(decls)(b)(e)(ps) == let gdcl = eval_GuardedDecl(hd decls)(e)(ps) in iflen decls = 1 then gdcl elseif gdcl = <err> then <err> elselet mk_(ne,nps,tr) = gdcl in
eval_GuardedDeclarations(tl decls)(b and tr)(ne)(nps);
eval_GuardedDecl : GuardedDeclaration -> Env -> PState -> ((Env *
PState * bool) | Errvalue)
eval_GuardedDecl(decl)(e)(ps) == if is_WhereDecl(decl) then eval_WhereDecl(decl)(e)(ps) elselet d = eval_Declaration(decl)(mk_(e,ps)) in if d = <err> then <err> elselet mk_(ne,nps) = d in
mk_(ne,nps,true);
eval_WhereDecl : WhereDecl -> Env -> PState -> ((Env * PState * bool) | Errvalue)
eval_WhereDecl(mk_WhereDecl(type,expr,id))(e)(ps) == let x = eval_Expression(expr)(e)(ps) in if x.val = <err> then <err> elselet t = eval_SkeletonType(type)(x.val.type)(e) in cases t:
<err> -> <err>, others -> let env = if id = nil then e else update_env(id)(x.val)(e) in let xt = const_type(x.val) in cases xt:
<err> -> <err>, others -> let val = gt(t,xt) in
mk_(env, mk_PState(ps.sto,x.time),val) end end;
eval_Assertion : Assertion -> Env -> PState -> EST_value
eval_Assertion(mk_Assertion(expr,tp))(e)(ps) == let x = eval_Expression(expr)(e)(ps) in if x.val = <err> then mk_EST_value(<err>,ps.sto,zerot) elselet type = eval_SkeletonType(tp)(x.val.type)(e) in if type = <err> then mk_EST_value(<err>,ps.sto,zerot) elselet xt = const_type(x.val) in cases xt:
<err> -> mk_EST_value(<err>,ps.sto,zerot), others -> ifnot (tleq(type,x.val.type) and tleq(xt,type)) then mk_EST_value(<err>,ps.sto,zerot) elselet val = widen_type(x.val, phi_remove(type)) in
mk_EST_value(val,x.sto,tplus(x.time,t_widen_type)) end;
eval_Conditional: Conditional -> Env -> PState -> EST_value
eval_Conditional(mk_Conditional(cond))(e)(ps) == if is_IfThenOnly(cond) then eval_IfThenOnly(cond)(e)(ps) elseif is_IfThenElse(cond) then eval_IfThenElse(cond)(e)(ps) else eval_CaseExpr(cond)(e)(ps);
eval_IfThenOnly : IfThenOnly -> Env -> PState -> EST_value
eval_IfThenOnly(mk_IfThenOnly(prop,action))(e)(ps) == let cond = eval_Expression(prop)(e)(ps),
aseq = eval_Sequence(action)(e)(mu(ps,time |-> tplus(cond.time,t_if))) in ifnot is_Tr(cond.val) ornot is_Void(aseq.val) then mk_EST_value(<err>,ps.sto,zerot) elseif cond.val.val then aseq else mk_EST_value(mk_Void(<nil>,mk_VoidType({})),ps.sto,
tplus(ps.time,tplus(cond.time,t_if)));
eval_IfThenElse : IfThenElse -> Env -> PState -> EST_value
eval_IfThenElse(mk_IfThenElse(prop,thenaction,elseaction))(e)(ps) == let cond = eval_Expression(prop)(e)(ps) in ifnot is_Tr(cond.val) then mk_EST_value(<err>,ps.sto,zerot) elselet then_x = eval_Sequence(thenaction)(e)(ps),
else_x = eval_Sequence(elseaction)(e)(ps) in let type = lub(then_x.val.type,else_x.val.type) in if type = <err> then mk_EST_value(<err>,ps.sto,zerot) elseif cond.val.val thenmu(then_x, val |-> widen_type(then_x.val,type), time |-> tplus(then_x.time,cond.time)) elsemu(else_x, val |-> widen_type(else_x.val,type), time |-> tplus(else_x.time,cond.time));
eval_CaseExpr : CaseExpr -> Env -> PState -> EST_value
eval_CaseExpr(mk_CaseExpr(expr,limbs,outlimb))(e)(ps) == let x = eval_Expression(expr)(e)(ps) in if x.val = <err> then mk_EST_value(<err>,ps.sto,zerot) elselet type_x = x.val.type in let ls = eval_Limbs(limbs)(x.val)(e)(mu(ps,time |-> x.time)) in let os = if outlimb = nil then [] elselet mk_(t,v) = ls(len ls) in
[mk_(type_x,eval_Sequence(outlimb)(e)(mu(ps,time
|-> v.time)))] in let pats = ls^os in ifexists mk_(t,v) inseq pats & v.val = <err> then mk_EST_value(<err>,ps.sto,zerot) elselet patlub = setlub({t | mk_(t,v) inseq pats}) in if patlub = <err> then mk_EST_value(<err>,ps.sto,zerot) elseif lub(type_x,patlub) <> patlub then mk_EST_value(<err>,ps.sto,zerot) elselet type = setlub({v.val.type | mk_(t,v) inseq pats}) in if type = <err> then mk_EST_value(<err>,ps.sto,zerot) elselet x_type = const_type(x.val) in let matches = [p | p inseq pats & let mk_(t,v) = p in
lub(x_type,t) = t] in let mk_(mt,mv) = hd matches in lettime =
dtplus([mv.time,t_const_type,t_widen_type]) in
mk_EST_value(widen_type(mv.val,type),mv.sto,time);
eval_Limb : CaseLimb -> Expressible_value -> Env -> PState ->
(Expressible_type * EST_value)
eval_Limb(mk_CaseLimb(test,sequ))(x)(e)(ps) == let t = eval_Tester(test)(x)(e)(ps) in if t = <err> then mk_(mk_VoidType({}),mk_EST_value(<err>,ps.sto,zerot)) elselet mk_(type,env,tm) = t in let val = eval_Sequence(sequ)(env)(mu(ps,time |-> tm)) in if val.val = <err> then mk_(mk_VoidType({}),mk_EST_value(<err>,ps.sto,zerot)) else mk_(type,val);
eval_Tester : Tester -> Expressible_value -> Env -> PState ->
((Expressible_type * Env * Time) | Errvalue)
eval_Tester(tester)(x)(e)(ps) == cases tester:
mk_SkeletonType(t) -> let nt = eval_SkeletonType(tester)(x.type)(e) in if nt = <err> then <err> else mk_(nt,e,ps.time),
mk_StrucTest(s) -> eval_StrucTest(tester)(x)(e)(ps),
mk_NonStrucTest(id,tp,fl) -> eval_NonStrucTest(tester)(x)(e)(ps) end;
eval_NumSkel : NumSkel -> Expressible_type -> Env ->
(Expressible_type | Errvalue)
eval_NumSkel(mk_NumSkel(ranges,errors))(x_type)(e) == ifnot (is_TrType(x_type) or is_IntType(x_type) or is_Float(x_type)) then <err> elselet rngs = if ranges = nil thenif is_Float(x_type) then {{l,...,u} | mk_Floatrng(l,u) inset x_type.range} else {x_type.range} else {eval_Range(r)(e) | r inseq ranges} in if <err> inset rngs then <err> elsecases x_type:
mk_TrType(range,fl) -> ifnot (dunion rngs subset {0,1}) then <err> else mk_TrType({{0 |->false, 1 |-> true}(v) | v insetdunion rngs},fl),
mk_IntType(rep,range,fl) -> if (rep = <byte> andexists v insetdunion rngs & abs v >= bytemax) or
(exists v insetdunion rngs & abs v >= maxint) then <err> else mk_IntType(rep,dunion rngs,fl),
mk_Float(rs,abse,rele,fl) -> ifexists v insetdunion rngs & abs v >= maxint then <err> else let abserr
= if errors.abserr = nil then abse else let v1 =
(eval_CompileTimeValue(errors.abserr)(e)).val in if v1 = <err> then <err> else v1.val,
relerr
= if errors.relerr = nil then rele else let v1 =
(eval_CompileTimeValue(errors.relerr)(e)).val in if v1 = <err> then <err> else v1.val in ifnot (is_real(abserr) and is_real(relerr)) then <err> else mk_Float({mk_Floatrng(min(r),max(r))
| r inset rngs},abserr,relerr,fl) end;
eval_StrucSkel : StrucSkel -> Expressible_type -> Env ->
(Expressible_type | Errvalue)
eval_StrucSkel(mk_StrucSkel(comps))(x_type)(e) == ifnot is_StructureType(x_type) then <err> elseif struc_length(x_type) <> len comps then <err> elselet t = [if comps(i) = <nil> then x_type.tps(i) else eval_SkeletonType(comps(i))(x_type.tps(i))(e) |
i insetinds comps] in ifexists tp inseq t & not (is_TrType(tp) or
is_IntType(tp) or is_Float(tp)) then <err> else mk_StructureType(t,x_type.fl);
eval_FlavSkel : FlavSkel -> Expressible_type -> Env ->
(Expressible_type | Errvalue)
eval_FlavSkel(mk_FlavSkel(skel,fl))(x_type)(e) == let t = eval_SkeletonType(skel)(x_type)(e),
f = eval_Flavouring(fl) in if t = <err> then <err> else replace_flavour(t,f);
eval_VecSkel : VecSkel -> Expressible_type -> Env ->
(Expressible_type | Errvalue)
eval_VecSkel(mk_VecSkel(skel))(x_type)(e) == let t = eval_SkeletonType(skel)(x_type)(e) in if t = <err> then <err> elsecases x_type:
mk_VectorType(l,u,tp,fl) -> mk_VectorType(l,u,t,fl), others -> <err> end;
eval_UnionSkel : UnionSkel -> Expressible_type -> Env ->
(Expressible_type | Errvalue)
eval_UnionSkel(mk_UnionSkel(skels))(x_type)(e) == let fls = { skel |-> fl | skel inseq skels, fl : Flavdom &
fl = cases skel:
mk_FlavSkel(skel,f) -> eval_Flavouring(f),
mk_FlavouredType(f,t) -> eval_Flavouring(f), others -> eval_Flavouring(skel) end} in ifcarddom fls <> cardrng fls then <err> elseif is_UnionType(x_type) thenlet x_fls = merge{
{ mk_VoidType(f) |-> f | mk_VoidType(f) inset x_type.tps},
{ mk_IntType(rep,range,fl) |-> fl |
mk_IntType(rep,range,fl) inset x_type.tps },
{ mk_TrType(range,fl) |-> fl |
mk_TrType(range,fl) inset x_type.tps },
{ mk_Float(rs,a,r,fl) |-> fl |
mk_Float(rs,a,r,fl) inset x_type.tps }} in ifnot (rng fls subsetrng x_fls) then <err> elselet tps =
{ cases skel:
mk_FlavSkel(s,f) -> eval_FlavSkel(skel)(tp)(e),
mk_FlavouredType(f,t) -> eval_FlavouredType(skel)(e), others -> eval_VoidValType(skel)(e) end | skel inseq skels, tp inset x_type.tps &
fls(skel) = x_fls(tp)} in ifexists tp inset tps & not (is_TrType(tp) or is_IntType(tp) or is_Float(tp) or is_VoidType(tp)) then <err> else mk_UnionType(tps,x_type.fl) elselet fl = if is_VoidType(x_type) then x_type else x_type.fl in if fl notinsetrng fls then <err> elselet skel = iota s insetelems skels & fls(s) = fl in cases skel:
mk_FlavSkel(s,f) -> eval_FlavSkel(skel)(x_type)(e),
mk_FlavouredType(f,t) -> eval_FlavouredType(skel)(e), others -> eval_VoidValType(skel)(e) end;
eval_NonStrucTest : NonStrucTest -> Expressible_value -> Env -> PState
-> ((Expressible_type * Env * Time) | Errvalue)
eval_NonStrucTest(mk_NonStrucTest(id,fl,skel))(x)(e)(ps) == let t = eval_SkeletonType(skel)(x.type)(e) in if t = <err> then <err> elselet t' = if fl = nil then t else replace_flavour(t,eval_Flavouring(fl)) in if id = nil then mk_(t',e,ps.time) else mk_(t',update_env(id)(x)(e), ps.time);
eval_StrucTest : StrucTest -> Expressible_value -> Env -> PState ->
((Expressible_type * Env * Time) | Errvalue)
eval_StrucTest(mk_StrucTest(tests))(x)(e)(ps) == ifnot is_Structure(x) then <err> elseif struc_length(x.type) <> len tests then <err> elselet xs = [ construct_ev(x.val(i),x.type.tps(i)) | i insetinds
x.val] in let ts = eval_Testseq(tests)(xs)(e)(ps) in if ts = <err> then <err> elselet mk_(tps,env,time) = ts in
mk_(mk_StructureType(tps,x.type.fl),env,time);
eval_Testseq : seqof (NonStrucTest | <nil>) -> seqof Expressible_value
-> Env -> PState -> ((seqof Expressible_type * Env
* Time) | Errvalue)
eval_Testseq(tests)(xs)(e)(ps) == if tests = [] then mk_([],e,ps.time) elselet t = ifhd tests = <nil> then mk_((hd xs).type, e, ps.time) else eval_NonStrucTest(hd tests)(hd xs)(e)(ps) in if t = <err> then <err> elselet mk_(tp,env,time) = t in let ts = eval_Testseq(tl tests)(tl xs) (env) (mu(ps,time |-> time)) in if ts = <err> then <err> elselet mk_(tps,n_env,n_time) = ts in
mk_([tp]^tps,n_env,n_time);
eval_OuterLoop : OuterLoop -> Env -> PState -> EST_value
eval_OuterLoop(mk_OuterLoop(oul))(e)(ps) == if is_OuterIntLoop(oul) then eval_OuterIntLoop(oul)(e)(ps) else eval_OuterVecLoop(oul)(e)(ps);
eval_OuterIntLoop : OuterIntLoop -> Env -> PState -> EST_value
eval_OuterIntLoop(mk_OuterIntLoop(mk_OverRange(id,range),actns))(e)(ps) == let nrange = eval_Range(range)(e) in if nrange = <err> then mk_EST_value(<err>,ps.sto,zerot) elselet vec_elems = [eval_Sequence(actns)(update_env(id)
(mk_Storable_value(mk_Int(i,mk_IntType(<word>,{i},{}))))(e))
(mu(ps,time |-> zerot)) | i inset nrange] in if <err> inset {x.val | x inseq vec_elems} then mk_EST_value(<err>,ps.sto,zerot) elselet type = seqlub([i.val.type | i inseq vec_elems]), time = dtplus([i.time | i inseq vec_elems]) in if type = <err> then mk_EST_value(<err>,ps.sto,zerot) elselet vec_val = if is_StructureType(type) or
is_VectorType(type) then [ v.val.val | v inseq vec_elems] else [ v.val | v inseq vec_elems] in
mk_EST_value(mk_Vector(vec_val,mk_VectorType(1,len
vec_val,type,{})),ps.sto, tplus(ps.time,time));
eval_OuterVecLoop : OuterVecLoop -> Env -> PState -> EST_value
eval_OuterVecLoop(mk_OuterVecLoop(ovs,actions))(e)(ps) == let idvs = eval_OverVectors(ovs)(e)(ps) in if idvs = <err> then mk_EST_value(<err>,ps.sto,zerot) elselet time1 = dtplus([ let mk_(id,v,t) = i in t | i inseq idvs]),
new_env = lambda i:nat &
(multi_update_env([ let mk_(id,v,t) = j in
mk_(id,vector_extract(v,i)) |
j inseq idvs]^( if ovs.cnt = nilthen [] else [mk_(ovs.cnt,i)]))(e)) in let vec_elems = [eval_Sequence(actions)(new_env(i))(mu(ps,time
|-> zerot)) | i insetlet mk_(i1,v,t) =
idvs(1) ininds (v.val)] in if <err> inset {x.val | x inseq vec_elems} then mk_EST_value(<err>,ps.sto,zerot) elselet type = seqlub([i.val.type | i inseq vec_elems]), time = dtplus([i.time | i inseq vec_elems]^[time1]) in if type = <err> then mk_EST_value(<err>,ps.sto,zerot) elselet new_tp = mk_VectorType(1,len vec_elems,type,{}) in let vec_val = if is_StructureType(type) or
is_VectorType(type) then [i.val.val | i inseq vec_elems] else [i.val | i inseq vec_elems] in let new_vec = mk_Vector(vec_val,new_tp) in
mk_EST_value(new_vec,ps.sto,tplus(ps.time,time));
eval_OverVectors : OverVectors -> Env -> PState -> (seq1of (Id * Vector * Time) | Errvalue)
eval_OverVectors(ovs)(e)(ps) == let indices = [ let mk_OverVector(id,val) = o in let x = eval_Operation(val)(e)(mu(ps,time |-> zerot)) in
mk_(id,x.val,x.time) | o inseq ovs.ovv] in ifexists i insetinds indices & let mk_(id,v,t) = indices(i) in not is_Vector(v) then <err> else indices;
eval_IntLoop : IntLoop -> Env -> PState -> EST_value
eval_IntLoop(mk_IntLoop(inc,actions))(e)(ps) == let idrng = eval_InnerControl(inc)(e)(ps) in if idrng = <err> then mk_EST_value(<err>,ps.sto,zerot) elselet mk_(id,range) = idrng in let f: EST_Iterate -> EST_Iterate
= lambda x: EST_Iterate & let new_env = update_env(id)(
mk_Storable_value(mk_Int(range(x.i),
mk_IntType(<word>,elems range,{}))))(e) in
eval_SeqIterate(actions)(new_env)(x) in let exi = (NIterate(f,(len range)))(mk_EST_Iterate(
mk_EST_value(mk_Void(<nil>,mk_VoidType({})), ps.sto,ps.time),1)) in
exi.expst;
eval_InnerControl : InnerControl -> Env -> PState -> ((Id * seqof int) | Errvalue)
eval_InnerControl(inc)(e)(ps) == cases inc:
mk_OverRange(cnt,range) -> let r = eval_Range(range)(e) in if r = <err> then <err> else mk_(cnt,[x | x inset r]),
mk_PartialRange(cnt,from_b,to_b,inc) -> let b1 = eval_Operation(from_b)(e)(ps),
b2 = eval_Operation(to_b)(e)(ps) in ifnot (is_Int(b1.val) and is_Int(b2.val)) then <err> elselet b3 = if inc = nil thenif b1.val.val <= b2.val.val then mk_Int(1,mk_IntType(<byte>,{1,-1},{})) else mk_Int(-1,mk_IntType(<byte>,{1,-1},{})) else (eval_Operation(inc)(e)(ps)).val in ifnot (is_Int(b3.val)) or
(is_Int(b3.val) and exists v1 inset b1.val.type.range,
v2 inset b2.val.type.range,
v3 inset b3.val.type.range & (v2-v1)*v3 < 0) then <err> elselet r = [ b1.val.val + alpha * b3.val | alpha inset
{0,...,floor(1+(b2.val.val-b1.val.val)/b3.val)} & abs (alpha * b3.val) <= abs (b2.val.val - b1.val.val)] in
mk_(cnt,r) end;
eval_SeqIterate : Sequence -> Env -> EST_Iterate -> EST_Iterate
eval_SeqIterate(sequ)(e)(exi) == if exi.expst.val = <err> thenmu(exi, i |-> exi.i + 1) elselet new_expst = eval_Sequence(sequ)(e)(mk_PState(exi.expst.sto,exi.expst.time)) in
mk_EST_Iterate(new_expst,exi.i + 1);
eval_VecLoop : VecLoop -> Env -> PState -> EST_value
eval_VecLoop(mk_VecLoop(ovs,actions))(e)(ps) == let indices = eval_OverVectors(ovs)(e)(ps) in if indices = <err> then mk_EST_value(<err>,ps.sto,zerot) elselettime = dtplus([let mk_(id,v,t) = i in t | i inseq indices]) in let f:EST_Iterate -> EST_Iterate
= lambda x:EST_Iterate & let env = multi_update_env(
[let mk_(id,v,t) = indices(i) in
mk_(id,vector_extract(v,x.i)) |i insetinds indices])(e),
new_expst = mu(x.expst, time |-> x.expst.time) in let new_env = if ovs.cnt = nilthen env else update_env(ovs.cnt)
(mk_Storable_value(mk_Int(x.i,mk_IntType(<word>,{x.i},{}))))(env) in
eval_SeqIterate(actions)(new_env)(mu(x,expst |-> new_expst)) in let mk_(-,v,-) = indices(1) in let exi = (NIterate(f,len v.val))(mk_EST_Iterate(mk_EST_value(
mk_Void(<nil>,mk_VoidType({})),
ps.sto,tplus(ps.time,time)),1)) in
exi.expst;
eval_TimeLoop : TimeLoop -> Env -> PState -> EST_value
eval_TimeLoop(mk_TimeLoop(time,actions))(e)(ps) == let t = eval_TimeInterval(time)(e),
x = eval_Sequence(actions)(e)(mu(ps,time |-> zerot)) in if t = <err> or x.val = <err> then mk_EST_value(<err>,ps.sto,zerot) elseifexists n:nat & timeleq(dtplus([x.time | i inset {1,...,n}]),t) thenlet its = iota n:nat &
timeleq(dtplus([x.time | i inset {1,...,n}]),t) and not (timeleq(dtplus([x.time | i inset {1,...,n+1}]),t)),
f:EST_value ->EST_value = lambda exs:EST_value &
eval_Sequence(actions)(e)(mk_PState(exs.sto,exs.time)) in
(Iterate(f,its))(mk_EST_value(mk_Void(<nil>,mk_VoidType({})),
ps.sto,ps.time)) else mk_EST_value(<err>,ps.sto,zerot);
eval_NvAssignment : NvAssignment -> Env -> PState -> EST_value
eval_NvAssignment(mk_NvAssignment(dest,expr))(e)(ps) == let l = access_env(dest)(e) in ifnot is_Location(l) then mk_EST_value(<err>,ps.sto,zerot) elselet x = eval_Expression(expr)(e)(ps) in if x.val = <err> then mk_EST_value(<err>,ps.sto,zerot) elseifcases x.val.type:
mk_VoidType(t) -> t = {Phi}, others -> x.val.type.fl = {Phi} end then mk_EST_value(<err>,ps.sto,zerot) elselet mk_Storable_value(dest_val) = access(l)(ps.sto) in if gt(dest_val.type,x.val.type) thenlet new_sto =
update(l)(mk_Storable_value(widen_type(x.val,dest_val.type)))(ps.sto) in
mk_EST_value(mk_Void(<nil>,mk_VoidType({})),new_sto,
tplus(tplus(ps.time,t_update),t_access)) else mk_EST_value(<err>,ps.sto,zerot);
eval_MultAssignment : MultAssignment -> Env -> PState -> EST_value
eval_MultAssignment(mk_MultAssignment(dest,mult,expr))(e)(ps) == let l = access_env(dest)(e) in ifnot is_Location(l) then mk_EST_value(<err>,ps.sto,zerot) elselet mk_Storable_value(v) = access(l)(ps.sto) in ifnot is_Vector(v) then mk_EST_value(<err>,ps.sto,zerot) elselet mk_Vector(val,type) = v in let v' =
eval_VectorMult(mk_EST_value(v,ps.sto,ps.time))(mult)(e) in let x = eval_Expression(expr)(e)(mk_PState(v'.sto,v'.time)) in if v'.val = <err> or not is_Vector(x.val) then mk_EST_value(<err>,ps.sto,zerot) elseif (x.val.type.upper - x.val.type.lower) <>
(v'.val.type.upper - v'.val.type.lower) or not gt(v.type.type,x.val.type.type) or cases x.val.type.type:
mk_VoidType(t) -> t = {Phi}, others -> x.val.type.fl = {Phi} end then mk_EST_value(<err>,ps.sto,zerot) elselet vleft = mk_Vector(vector_subv(val,type.lower,
v'.val.type.lower-1),mk_VectorType(type.lower,
v'.val.type.lower-1,type.type,type.fl)),
vmid = x.val,
vright = mk_Vector(vector_subv(val,v'.val.type.upper+1,
type.upper),mk_VectorType(v'.val.type.upper+1,
type.upper,type.type, type.fl)) in let new_vec = vector_concat(vector_concat(vleft,vmid),vright),
new_time = dtplus([x.time,t_vector_concat,
t_vector_concat, vector_subv,vector_subv]) in
mk_EST_value(mk_Void(<nil>,mk_VoidType({})),
update(l)(mk_Storable_value(new_vec))(ps.sto),
new_time);
eval_StrAssignment : StrAssignment -> Env -> PState -> EST_value
eval_StrAssignment(mk_StrAssignment(dest,expr))(e)(ps) == let ls = [access_env(d)(e) | d inseq dest] in ifexists l inseq ls & not is_Location(l) then mk_EST_value(<err>,ps.sto,zerot) elselet x = eval_Expression(expr)(e)(ps) in ifnot is_Structure(x.val) then mk_EST_value(<err>,ps.sto,zerot) elseiflen ls <> struc_length(x.val.type) then mk_EST_value(<err>,ps.sto,zerot) elselet nvals = [ access(l)(ps.sto) | l inseq ls] in let vals = [ let mk_Storable_value(v) = i in v | i inseq nvals] in let dest_tps = [v.type | v inseq vals],
x_tps = [i | i inseq x.val.type.tps] in ifexists i insetinds dest_tps & not gt(dest_tps(i),x_tps(i)) then mk_EST_value(<err>,ps.sto,zerot) elselet ys = [mk_Storable_value(construct_ev(x.val.val(i),
x.val.type.tps(i))) | i insetinds x.val.val],
new_t = dtplus([x.time,t_access,t_construct_ev,
t_multi_update(len ys)]) in
mk_EST_value(mk_Void(<nil>,mk_VoidType({})),
multi_update(ls)(ys)(ps.sto), new_t);
eval_TimedExpression : TimedExpression -> Env -> PState -> EST_value
eval_TimedExpression(mk_TimedExpression(texpr))(e)(ps) == if is_TimeTakes(texpr) then eval_TimeTakes(texpr)(e)(ps) else eval_TimeAssertion(texpr)(e)(ps);
eval_TimeTakes : TimeTakes -> Env -> PState -> EST_value
eval_TimeTakes(mk_TimeTakes(expr,time))(e)(ps) == let x = eval_Expression(expr)(e)(mu(ps, time |-> zerot)),
t = eval_TimeInterval(time)(e) in if x.val = <err> or t = <err> then mk_EST_value(<err>,ps.sto,zerot) elseif timeleq(x.time,t) thenmu(x,time |-> tplus(ps.time,x.time)) else mk_EST_value(<err>,ps.sto,zerot);
eval_TimeInterval : TimeInterval -> Env -> (Time | Errvalue)
eval_TimeInterval(time)(e) == let range = eval_Range(time)(e) in if range = <err> or min(range) < 0 then <err> else mk_(min(range),max(range));
eval_TimeAssertion:TimeAssertion -> Env -> PState -> EST_value
eval_TimeAssertion(mk_TimeAssertion(expr,time))(e)(ps) == let x = eval_Expression(expr)(e)(mu(ps, time |-> zerot)),
t = eval_TimeInterval(time)(e) in if x.val = <err> or t = <err> then mk_EST_value(<err>,ps.sto,zerot) elseif timeleq(t,x.time) thenmu(x,time |-> tplus(ps.time,t)) else mk_EST_value(<err>,ps.sto,zerot);
Iterate: (EST_value -> EST_value) * nat -> (EST_value ->
EST_value)
Iterate(f,n) == if n = 0 thenlambda x:EST_value & x elseif n = 1 then f else f comp (Iterate( f, n-1));
NIterate: (EST_Iterate -> EST_Iterate) * nat -> (EST_Iterate ->
EST_Iterate)
NIterate(f,n) == if n = 0 thenlambda x:EST_Iterate & x elseif n = 1 then f else f comp (NIterate( f, n-1))
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.47 Sekunden
(vorverarbeitet am 2026-04-30)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.