Information Technology Reference
In-Depth Information
case Cons(h1, t1 @ Cons(h2, t2)) (h1 h2) && isSorted(t1)
case
true
}
Thanks to the abstraction function and the invariant, we can concisely specify
an insert operation for sorted lists using a constraint:
def insert(l: List, v: Int) = {
require (isSorted(l))
choose { (x: List) isSorted(x) && (content(x) == content(l) ++ Set(v)) }
}
Our deductive synthesis procedure is able to translate this constraint into the
following complete implementation in under 9 seconds:
def insert(l: List, v: Int) = {
require (isSorted(l))
l match {
case Cons(head, tail)
if (v == head) {
l
} elseif (v < head) {
Cons(v, l)
} else {
insert(t, v)
}
case Nil
Cons(v, Nil)
}
}
However, as the complexity of the constraints increases, the deductive procedure
may run short of available time to translate a constraint into complete ecient
implementations. As an example, we can currently observe this limitation of
our system for a red-black tree benchmark. The following method describes the
insertion into a red-black tree. 1
def insert(t: Tree, v: Int) = {
require (isRedBlack(t))
choose { (x: Tree) isRedBlack(x) && (content(x) == content(t) ++ Set(v)) }
}
Instead of using synthesis (for which this example may present a challenge), we
can rely on the run-time constraint solving to execute the constraint. In such
scenario, the run-time waits until the argument t and the value v are known,
and finds a new tree value x such that the constraint holds. Thanks to our
constraint solver, which has a support recursive functions and also leverages
the Z3 SMT solver, this approach works well for small red-black trees. It is
therefore extremely useful for prototyping and testing and we have previously
1 We omit here the definition of the tree invariant for brevity, which is rather complex
[15,52], but still rather natural to describe using recursive functions.
Search WWH ::




Custom Search