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};
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 ist noch experimentell.