Order
module totally_ordered(t) = {
property [transitivity] (T:t < U & U < V) -> (T < V)
property [antisymmetry] ~(T:t < U & U < T)
property [totality] T:t < U | T = U | U < T
}
module totally_ordered_with_zero(t) = {
instantiate totally_ordered(t)
property 0 <= X:t
}
module unbounded_sequence = {
type t
action next(x:t) returns (y:t)
action prev(x:t) returns (y:t)
relation succ(X:t,Y:t)
object spec = {
property succ(X,Z) -> (X < Z & ~(X < Y & Y < Z))
instantiate totally_ordered(t)
after next {
assert x < y & (x < Y -> y <= Y);
assert succ(x,y)
}
before prev {
assert 0 < x
}
after prev {
assert y < x & (Y < x -> Y <= y);
assert succ(y,x)
}
}
object impl = {
interpret t -> int
definition succ(X,Y) = (Y = X + 1)
implement next {
y := x + 1
}
implement prev {
y := x - 1
}
}
isolate iso = impl,spec
attribute test = impl
}
module bounded_sequence(interp) = {
type t
action next(x:t) returns (y:t)
action prev(x:t) returns (y:t)
action is_max(x:t) returns (r:bool)
relation succ(X:t,Y:t)
object spec = {
property succ(X,Z) -> (X < Z & ~(X < Y & Y < Z))
instantiate totally_ordered(t)
before next {
assert exists S. S > x;
}
after next {
assert x < y & (x < Y -> y <= Y);
assert succ(x,y)
}
before prev {
assert 0 < x
}
after prev {
assert y < x & (Y < x -> Y <= y);
assert succ(y,x)
}
after is_max {
assert r <-> ~exists S. S > x
}
}
object impl = {
interpret t -> interp
definition succ(X,Y) = (Y = X + 1 & X < Y)
implement next {
y := x + 1
}
implement prev {
y := x - 1
}
implement is_max {
r := ~(x + 1 > x)
}
}
isolate iso = impl,spec
attribute test = impl
}
module order_iterator(range) = {
type t = struct {
is_end : bool,
val : range.t
}
definition (X < Y) = ~is_end(X) & is_end(Y)
| ~is_end(X) & ~is_end(Y) & val(X) < val(Y)
function done(X,Y) = is_end(Y) | X < val(Y)
function ahead(X,Y) = ~is_end(Y) & val(Y) < X
function between(X,V,Y) = ~done(V,X) & done(V,Y)
action create(x:range.t) returns (y:t)
action end returns (y:t)
object spec = {
after create {
assert ~is_end(y);
assert val(y) = x
}
after end {
assert is_end(y);
assert val(y) = 0
}
}
object impl = {
implement create {
is_end(y) := false;
val(y) := x
}
implement end {
is_end(y) := true;
val(y) := 0
}
}
isolate iso = impl,spec with range
attribute test = impl
}
module order_iterator_impl(range) = {
type t = struct {
is_end : bool,
val : range.t
}
definition (X < Y) = ~is_end(X) & is_end(Y)
| ~is_end(X) & ~is_end(Y) & val(X) < val(Y)
function done(X,Y) = is_end(Y) | X < val(Y)
function ahead(X,Y) = ~is_end(Y) & val(Y) < X
function between(X,V,Y) = ~done(V,X) & done(V,Y)
action create(x:range.t) returns (y:t)
action end returns (y:t)
implement create {
is_end(y) := false;
val(y) := x
}
implement end {
is_end(y) := true;
val(y) := 0
}
}
module sequence_iterator(range) = {
instantiate order_iterator(range)
action next(x:t) returns (x:t)
action prev(x:t) returns (x:t)
object spec = {
...
before next {
assert ~is_end(x)
}
after next {
assert X <= val(old x) & is_end(x)
| ~(val(old x) < Y & Y < val(x))
& val(old x) < val(x) & ~is_end(x)
}
before prev {
assert is_end(x) | exists X. X < val(x)
}
after prev {
assert ~is_end(x);
assert X <= val(x) & is_end(old x)
| ~(val(x) < Y & Y < val(old x))
& val(x) < val(old x) & ~is_end(old x)
}
}
object impl = {
...
implement next {
if range.is_max(val(x)) {
x := end
} else {
x := create(range.next(val(x)))
}
}
implement prev {
x := create(range.prev(val(x)))
}
}
}
¤
Queue
¤
module unbounded_queue(data) = {
instance index : unbounded_sequence
individual head : index.t
individual tail : index.t
function contents(X:index.t) : data
after init {
head := 0;
tail := 0;
}
derived empty = tail >= head
derived first = contents(tail)
action push(d:data) = {
contents(head) := d;
head := head.next;
}
action pop returns (res:data) = {
assert ~empty;
res := contents(tail);
tail := tail.next;
}
delegate pop
}