# Introduction¶

The Stainless verification framework aims to help developers build verified Scala software. It encourages using a small set of core Scala features, but provides unique automation functionality. In particular, Stainless can

verify statically that your program conforms to a given specification and that it cannot crash at run-time

provide useful counterexamples when an implementation does not satisfy its specification

verify that your program will terminate on all inputs

## Stainless and Scala¶

Stainless attempts to strike a delicate balance between the
convenience of use on the one hand and the simplicity of
reasoning on the other hand. Stainless supports verification
of Scala programs by applying a succession of semantic-preserving
transformations to the Pure Scala fragment until
it fits into the fragment supported by
Inox.
The Pure Scala fragment is at the core of
the functional programming paradigm and lies at the intersection
of functional languages such as Scala, Haskell, ML, and fragments
present in interactive theorem provers such as Isabelle and Coq. Thus,
if you do not already know Scala, learning the Stainless subset should
be easier as it is a smaller language. Moreover, thanks to the use of
`scalac`

front end, Stainless supports implicits and `for`

comprehensions (which also serve as a syntax for monads in Scala).
Stainless also comes with a simple library of useful data types, which
are designed to work well with automated reasoning and Stainless’s
language fragment.

In addition to this pure fragment, Stainless supports certain imperative features. Features thus introduced are handled by a translation into Pure Scala concepts. They are often more than just syntactic sugar, because some of them require significant modification of the original program, such as introducing additional parameters to a set of functions. As an intended aspect of its current design, Stainless’s language currently does not provide a default encoding of e.g. concurrency with a shared mutable heap, though it might support more manageable forms of concurrency in the future.

If you would like to use Stainless now, check the Installing Stainless section and follow Verifying and Compiling Examples and Tutorial. To learn more about the functionality that Stainless provides, read on below.

## Software Verification¶

The Stainless program verifier collects a list of top-level functions,
and verifies the *validity* of their *contracts*. Essentially, for each function,
it will (try to) prove that the postcondition always holds, assuming a given
precondition does hold. A simple example:

```
def factorial(n: BigInt): BigInt = {
require(n >= 0)
if(n == 0) {
BigInt(1)
} else {
n * factorial(n - 1)
}
} ensuring(res => res >= 0)
```

Stainless generates a `postcondition`

verification condition for the above
function, corresponding to the predicate parameter to the `ensuring`

expression. It attempts to prove it using a combination of an internal
algorithm and external automated theorem proving. Stainless will return one of the
following:

The postcondition is

`valid`

. In that case, Stainless was able to prove that for**any**input to the function satisfying the precondition, the postcondition will always hold.The postcondition is

`invalid`

. It means that Stainless disproved the postcondition and that there exists at least one input satisfying the precondition such that the postcondition does not hold. Stainless will always return a concrete counterexample, very useful when trying to understand why a function is not satisfying its contract.The postcondition is

`unknown`

. It means Stainless is unable to prove or find a counterexample. It usually happens after a timeout or an internal error occurring in the external theorem prover.

Stainless will also verify for each call site that the precondition of the invoked function cannot be violated.

Stainless supports verification of a significant part of the Scala language, described in Pure Scala and Imperative.

## Program Termination¶

A “verified” function in stainless is guaranteed to never crash, however, it can still lead to an infinite evaluation. Stainless therefore provides a termination checker that complements the verification of safety properties.

For each function in the program, Stainless will try to automatically infer a decreasing metric associated with this function to prove termination. The termination checker will then report one of the following:

The function

`terminates`

. In this case, Stainless was able to prove that for all inputs (satisfying the function’s precondition), evaluation of the function under those inputs is guaranteed to terminate.The function

`loops`

. In this case, Stainless was able to construct an input to the function such that evaluation under that input will be looping.The function

`maybe loops`

. In the case where recursive functions are passed around as first-class functions, Stainless will sometimes over-approximate the potential call sites and report loops that may never occur.Termination of the function is

`unknown`

. In this case, Stainless was neither able to prove nor disprove termination of the relevant function. Automated termination proving is a*hard*problem and such cases are thus to be expected.

In cases where automated termination checking fails, Stainless provides the user
with the ability to manually specify a measure under which termination should
occur through the `decreases`

construct. For example, the
McCarthy 91 function
can be shown terminating as follows:

```
def M(n: BigInt): BigInt = {
decreases(stainless.math.max(101 - n, 0))
if (n > 100) n - 10 else M(M(n + 11))
} ensuring (_ == (if (n > 100) n - 10 else BigInt(91)))
```

It is also possible to add a pre-condition (`require(...)`

) *before* `decreases`

.