Seg3
include order
include collections
module segment2(domain,range,arr) = {
- Type
domainmust support arithmetic. - Type
arrmust be an array type over (domain,range).
This is a type of segments over arr
type this
action make(data:arr, begin:domain, end:domain) returns (seg:this)
function value(X:this,N:domain) : range
function first(X:this) : domain
function upper(X:this) : domain
specification {
Example:
var a := arr.empty
a := a.append(1);
a := a.append(2);
a := a.append(3);
a := a.append(4);
var s := segment.make(a,1,3);
assert s.value(1) = 2 & s.value(2) = 3; -- true
assert s.value(0) = 1; -- false
assert s.value(3) = 4; -- false
around make {
require 0 <= begin & begin <= end & end <= data.end
...
ensure begin <= N & N < end -> value(seg,N) = arr.value(data,N);
ensure first(seg) = begin;
ensure upper(seg) = end;
}
}
implementation {
We have to use arithmetic to prove the implementation, but this is within the decidable array property fragment.
Notice we use domain.impl to prove this isolate, so we get the arithmetic theory.
destructor offset(X:this) : domain
destructor elems(X:this) : arr
definition value(X,n:domain) = elems(X).value(n - offset(X))
definition first(X) = offset(X)
definition upper(x:this) = (elems(x).end) + offset(x)
implement make {
seg.offset := begin;
seg.elems := arr.empty;
var idx := begin;
while idx < end
invariant begin <= idx & idx <= end
invariant seg.offset = begin
invariant begin <= N & N < idx -> seg.value(N) = data.value(N)
invariant begin + seg.elems.end = idx
{
seg.elems := seg.elems.append(data.value(idx));
idx := idx.next;
};
}
}
isolate iso = this with domain.impl,arr
}
instance dom : unbounded_sequence
type rng
instance arr : array(dom,rng)
instance s : segment2(dom,rng,arr)
export s.make