зеркало из https://github.com/microsoft/ivy.git
91 строка
2.2 KiB
XML
91 строка
2.2 KiB
XML
#lang ivy1.7
|
|
|
|
include order
|
|
include collections
|
|
|
|
module segment(domain,range,arr) = {
|
|
|
|
# Requirements
|
|
|
|
# - Type `domain` must support arithmetic.
|
|
# - Type `arr` must be an array type over (`domain`,`range`).
|
|
|
|
# This is a type of segments over `arr`
|
|
|
|
type this
|
|
|
|
# We say segment_of(X,Y) if X is a segment of array Y from
|
|
# index begin to index end
|
|
|
|
relation segment_of(X:this,Y:arr,B:domain,E:domain)
|
|
|
|
# Extract a segment of an array, from a begin index to an end
|
|
# index
|
|
|
|
action make(data:arr, begin:domain, end:domain) returns (seg:this)
|
|
|
|
# Get element `n` of the segment.
|
|
|
|
# action get(seg:this, n:domain)
|
|
|
|
function value(X:this,N:domain) : range
|
|
|
|
specification {
|
|
|
|
# If X is a segment of Y over [B,E), then, for any n in [B,E), the nth
|
|
# element of X is the nth element of Y.
|
|
|
|
invariant segment_of(X,Y,B,E) & B <= N & N < E -> value(X,N) = arr.value(Y,N)
|
|
|
|
# When extracting a segment from an array, the range [begin,end) must
|
|
# describe a segment of the array. The return value is a segment representing
|
|
# that range [begin,end) of the array
|
|
|
|
around make {
|
|
require 0 <= begin & begin <= end & end <= data.end
|
|
...
|
|
segment_of(seg,data,begin,end) := true
|
|
}
|
|
}
|
|
|
|
implementation {
|
|
|
|
destructor offset(X:this) : domain
|
|
destructor elems(X:this) : arr
|
|
|
|
definition value(X,N) = elems(X).value(N + offset(X))
|
|
|
|
after init {
|
|
segment_of(X,Y,B,E) := false;
|
|
}
|
|
|
|
implement make {
|
|
seg.offset := begin;
|
|
seg.elems := arr.empty;
|
|
var idx := begin;
|
|
while idx < end
|
|
invariant begin <= idx
|
|
invariant begin <= N & N < idx -> seg.value(N) = arr.value(Y,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 : segment(dom,rng,arr)
|
|
|
|
export s.make
|
|
|
|
|
|
|