datatype Interval = Interval(lo: real, hi: real)
predicate contains(i: Interval, r: real) {
predicate empty(i: Interval) {
lemma empty_ok(i: Interval)
ensures empty(i) <==> !exists r :: contains(i, r)
assert contains(i, i.lo);
function min(r1: real, r2: real): real {
if r1 < r2 then r1 else r2
function max(r1: real, r2: real): real {
if r1 > r2 then r1 else r2
function intersect(i1: Interval, i2: Interval): Interval {
Interval(max(i1.lo, i2.lo), min(i1.hi, i2.hi))
lemma intersect_ok(i1: Interval, i2: Interval)
ensures forall r :: contains(intersect(i1, i2), r) <==> contains(i1, r) && contains(i2, r)
predicate overlap(i1: Interval, i2: Interval) {
!empty(intersect(i1, i2))
lemma overlap_ok(i1: Interval, i2: Interval)
ensures overlap(i1, i2) <==> exists r :: contains(i1, r) && contains(i2, r)
assert contains(i2, i1.lo);
assert contains(i1, i2.lo);
function union(i1: Interval, i2: Interval): Interval
Interval(min(i1.lo, i2.lo), max(i1.hi, i2.hi))
lemma union_ok(i1: Interval, i2: Interval)
ensures forall r :: contains(union(i1, i2), r) <==> contains(i1, r) || contains(i2, r)
lemma overlap_witness(i1: Interval, i2: Interval) returns (r: real)
ensures contains(i1, r) && contains(i2, r)