Translation from Stainless to Coq¶
Initially based on a project done by Bence Czipó, this translation is an early experimental stage.
The –coq option of Stainless replaces the standard verification checker (which uses Inox) by a translation to Coq. Each function from the *.scala file is translated to a Coq file, and obligations corresponding to assertions, preconditions, and postconditions are solved using predefined tactics in Coq.
Requirements¶
Coq 8.11.2
Coq Equations 1.2.2+8.11
These can be installed using opam as explained in the Equations README.md.
Usage of the Coq option¶
First, clone the Stainless repository. In the slc-lib directory, run ./configure and make.
Then, assuming the Stainless binary stainless-scalac
is in your path, run:
stainless-scalac --coq File.scala
on the file of your choice. As an example,
consider the test
function from the Arith.scala
file:
def test(a: BigInt, b: BigInt, c: BigInt): BigInt = {
require(a > b && c > BigInt(0))
c + a
}.ensuring( _ > c + b )
Running stainless-scalac --coq frontends/benchmarks/coq/Arith.scala
generates the file tmp/test.v
which contains the following Coq definition.
Definition test (a: Z) (b: Z) (c: Z) (contractHyp4: (ifthenelse (Z.gtb a b) bool
(fun _ => Z.gtb c (0)%Z )
(fun _ => false ) = true)) : {x___1: Z | (Z.gtb x___1 (Z.add c b) = true)} :=
Z.add c a.
Fail Next Obligation.
The coqc
executable in run on the file, and the status is reported by
Stainless. In the translation to Coq, the BigInt
type is encoded as Z
.
The precondition (require
) is encoded as an extra argument contractHyp4
,
and the postcondition is encoded as a refinement on the return type of test.
Here, the obligation related to the postcondition is solved automatically thanks
to the obligation tactic defined above in the tmp/test.v
file. The statement
Fail Next Obligation.
then succeeds because all obligations have been solved
(any command in Coq can be prefixed with Fail
, and the resulting command
succeeds when the original command fails).