From 736e690a8f4aa74b047a2780dde067f5d9c78d4e Mon Sep 17 00:00:00 2001
From: Regis Blanc <regwblanc@gmail.com>
Date: Mon, 23 Mar 2015 11:42:34 +0100
Subject: [PATCH] Describe the rest of XLang

---
 doc/xlang.rst | 103 ++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 88 insertions(+), 15 deletions(-)

diff --git a/doc/xlang.rst b/doc/xlang.rst
index 5089d8b93..e58675563 100644
--- a/doc/xlang.rst
+++ b/doc/xlang.rst
@@ -3,17 +3,17 @@
 XLang
 =====
 
-To complement the core PureScala language, the XLang module of Leon brings a
-few extensions to that core language.
+To complement the core :ref:`Pure Scala <purescala>` language, the XLang module
+of Leon brings a few extensions to that core language.
 
 These extensions are kept as an optional feature, that needs to be explicitly
 enabled from the command line with the option ``--xlang``. If you do not specify
 the option, Leon will reject any program making use of an XLang feature.
 
-Technically, these extensions are implemented using a translation to PureScala.
-This means They are not implemented in the back-end solving system of Leon, but
-parsed in the the front-end and eliminate early during the Leon pipelining
-process.
+Technically, these extensions are implemented using a translation to :ref:`Pure
+Scala <purescala>`. This means They are not implemented in the back-end
+solving system of Leon, but parsed in the the front-end and eliminate early
+during the Leon pipelining process.
 
 Imperative Code
 ---------------
@@ -42,9 +42,9 @@ The above example illustrates three new features introduced by XLang:
 You can use Scala variables with a few restrictions. The variables can only be
 declared and used locally in the same function, and inner functions cannot
 close over them. XLang introduces the possibility to use sequences of
-expressions (blocks) -- a feature not available in PureScala, where you're only
-option is a sequence of ``val`` which essentially introduce nested ``let``
-declarations.
+expressions (blocks) -- a feature not available in :ref:`Pure Scala
+<purescala>`, where you're only option is a sequence of ``val`` which
+essentially introduce nested ``let`` declarations.
 
 .. warning::
    Be careful when combining variables with nested functions from PureScala. Leon
@@ -93,19 +93,92 @@ as ``valid``.
 
 Leon internally handle loops as a function with a postcondition. For the end-user it
 means that Leon is only going to rely on the postcondition of the loop to prove properties
-of code relying on loops.
+of code relying on loops. Usually that invariant is too weak to prove anything remotely
+useful and you will need to anotate the loop with a stronger invariant.
+
+You can anotate a loop with an invariant as follows:
+
+.. code-block:: scala
+
+   var res = 0
+   var i = 0
+   (while(i < 10) {
+     res = res + i
+     i = i + 1
+   }) invariant(i >= 0 && res >= i)
+
+The strange syntax comes from some Scala magic in order to make the keyword
+``invariant`` a valid keyword. Leon is defining an implicit conversion from
+``Unit`` to an ``InvariantFunction`` object that provides an ``invariant``
+method. The ``invariant`` method takes a boolean expression as a parameter and
+its semantics is to hold at the following points during the execution of the loop:
+
+1. When first entering the loop: initialization.
+2. After each complete execution of the body.
+3. On exiting the loop.
+
+Leon will generate verification conditions ``invariant inductive`` and
+``invariant postcondition`` to verify points (2) and (3) above. It will also
+generate a ``precondition`` corresponding to the line of the while loop. This
+verification condition is used to prove the invariant on initialization of the
+loop.
 
 Arrays
 ******
 
-PureScala supports functional arrays, that is, the operations ``apply`` and ``updated`` which do
-not modify an array but only returns some result. In particular, ``updated`` returns a new copy
-of the array.
+PureScala supports functional arrays, that is, the operations ``apply`` and
+``updated`` which do not modify an array but only returns some result. In
+particular, ``updated`` returns a new copy of the array.
+
+.. code-block:: scala
+
+   def f(a: Array[Int]): Array[Int] = {
+     a(0).updated(0, a(1))
+   }
+
+However, using functional arrays is not the most natural way to work with
+arrays, and arrays are often used in imperative implementations of algorithms.
+XLang adds the usual ``update`` operation on arrays:
+
+.. code-block:: scala
 
-.. note::
-   some note comes here
+   val a = Array(1,2,3,4)
+   a(1) //2
+   a(1) = 10
+   a(1) //10
+
+There are some limitations with what you can do with arrays. Leon simply
+rewrite arrays using ``update`` operation as assignment of function arrays
+using ``updated``.  This leverages the built-in algorithm for functional array
+and rely on the elimination procedure for assignments. Concretely, it would
+transform the above on the following equivalent implementation:
+
+.. code-block:: scala
+
+   var a = Array(1,2,3,4)
+   a(1) //2
+   a = a.updated(1, 10)
+   a(1) //10
+
+Then Leon would apply the same process as for any other XLang program.
+
+Due to the way Leon handles side-effects, you cannot update arrays passed
+to a function as a parameter.
 
 Epsilon
 -------
 
+XLang introduces the ``epsilon`` keyword to express non-determinism. The
+concept is inspired from `Hilbert's epsilon calculus
+<http://en.wikipedia.org/wiki/Epsilon_calculus>`_. An ``epsilon`` expression
+takes a predicate as parameter and is defined to return a value that
+satisfies the predicate:
+
+.. code-block:: scala
+
+   def getInRange(from: Int, to: Int): Int = {
+     epsilon(n => from <= n && n <= to)
+   }
 
+You can use epsilon when you only know the interface of some function but
+cannot provide a concrete implementation.
-- 
GitLab