Implementation Defined Aspects and Pragmas
==========================================

This appendix lists all the aspects or pragmas specific to |GNATprove|.

.. index:: SPARK_Mode; rules

.. _Pragma_SPARK_Mode:

Aspect and Pragma ``SPARK_Mode``
--------------------------------

SPARK_Mode is a three-valued aspect. At least until we get to the
next paragraph, a SPARK_Mode of On, Off, or Auto is associated
with each Ada construct. Roughly, the meaning of the three values is the
following:

 * a value of On means that the construct is required to be in |SPARK|, and
   the construct will be analyzed by |GNATprove|.
 * a value of Off means that the construct will not be analyzed by
   |GNATprove|, and does not need to obey the |SPARK| restrictions. The
   construct also cannot be referenced from other parts that are required to
   be in |SPARK|.
 * a value of Auto means that the construct will not be analyzed, and
   |GNATprove| will infer whether this construct can be used in other |SPARK|
   parts or not.

As generic units are not directly analyzed by |GNATprove|, but only generic
instances are, the meaning of the three values is slightly different for
generic units:

 * a value of On means that instances can be in |SPARK|, depending on the
   parameters passed for the instantiation.
 * a value of Off means that instances cannot be in |SPARK|, independent of the
   parameters passed for the instantiation.
 * a value of Auto provides no information on whether instances can be in
   |SPARK| or not.

We now explain in more detail how the SPARK_Mode pragma works.

Some Ada constructs are said to have more than one "section".
For example, a declaration which requires a completion will have (at least)
two sections: the initial declaration and the completion. The SPARK_Modes
of the different sections of one entity may differ. In other words,
SPARK_Mode is not an aspect of an entity but rather of a section of an entity.

For example, if a subprogram declaration has a SPARK_Mode of On while
its body has a SPARK_Mode of Off, then an error would be generated if
the subprogram  took a parameter of a general access type but not if
the subprogram declared a local variable of a general
access type (recall that general access types are not in |SPARK|).

A package is defined to have 4 sections: its visible part, its private part,
its body declarations, and its body statements. A protected or task unit has
3 sections: its visible part, its private part, and its body.
Other declarations which require a completion have two sections, as noted
above; all other entities and constructs have only one section.

If the SPARK_Mode of a section of an entity is Off, then the SPARK_Mode
of a later section of that entity shall not be On. [For example, a subprogram
can have a SPARK declaration and a non-SPARK body, but not vice versa.]

If the SPARK_Mode of a section of an entity is Auto, then the SPARK_Mode
of a later section of that entity shall not be On, and it shall not be Off
unless that entity is a generic entity, or an instance of such a generic.
[This makes it possible to mark a later section of a generic unit as Off,
in cases where its initial section is Auto to allow instantiations to
have any value of SPARK_Mode.]

The SPARK_Mode aspect can be specified either via a pragma or via an
aspect_specification. In some contexts, only a pragma can be used
because of syntactic limitations. In those contexts where an
aspect_specification can be used, it has the same effect as a
corresponding pragma.

The form of a pragma SPARK_Mode is as follows:

.. code-block:: ada

   pragma SPARK_Mode [ (On | Off) ]

The form for the aspect_definition of a SPARK_Mode aspect_specification is
as follows:

.. code-block:: ada

   [ On | Off ]

For example:

.. code-block:: ada

   package P
      with SPARK_Mode => On
   is

The pragma can be used as a configuration pragma. The effect of
such a configuration pragma is described below in the rules for
determining the SPARK_Mode aspect value for an arbitrary section of an
arbitrary Ada entity or construct.

Pragma ``SPARK_Mode`` shall be used as a local pragma in only the following
contexts and has the described semantics:

.. csv-table::
   :header: "Pragma placement", "Affected construct", "Alternative aspect form"
   :widths: 3, 1, 1

   "Start of the visible declarations (preceded only by other pragmas) of a
   package declaration", "Visible part of the package", "As part of the
   package_specification"
   "Start of the visible declarations (preceded only by other pragmas) of a task
   or protected unit", "Visible part of the unit", "As part of the declaration"
   "Start of the private declarations of a package, a protected unit, or a task
   unit (only other pragmas can appear between the ``private`` keyword and the
   ``SPARK_Mode`` pragma)", "Private part", "None"
   "Immediately at the start of the declarations of a package body (preceded only
   by other pragmas)", "Body declarations of the package", "As part of the
   package_body"
   "Start of the elaboration statements of a package body (only other pragmas can
   appear between the ``begin`` keyword and the ``SPARK_Mode`` pragma)", "Body
   statements of the package", "None"
   "Start of the declarations of a protected or task body (preceded only by other
   pragmas)", "Body", "As part of the protected or task body"
   "After a subprogram declaration (with only other pragmas intervening). [This
   does not include the case of a subprogram whose initial declaration is via a
   subprogram_body_stub. Such a subprogram has only one section because a subunit
   is not a completion.]", "Subprogram's specification", "As part of the
   subprogram_declaration"
   "Start of the declarations of a subprogram body (preceded only by other
   pragmas)", "Subprogram's body", "As part of the subprogram_body"

A default argument of On is assumed for any SPARK_Mode pragma or
aspect_specification for which no argument is explicitly specified.

A SPARK_Mode of Auto can only be explicitly specified for a configuration
pragma; the cases in which a SPARK_Mode of Auto is implicitly specified are
described below. Roughly speaking, Auto indicates that it is left up to the
formal verification tools to determine whether or not a given construct is in
|SPARK|.

A SPARK_Mode pragma or aspect specification shall only apply to a
(section of a) package, generic package, subprogram, or
generic subprogram.

A SPARK_Mode of On shall only apply to a (section of a) library-level entity,
except for the case of SPARK_Mode specifications occurring within generic
instances. A SPARK_Mode of On applying to a non-library-level entity within a
generic instance has no effect.

The SPARK_Mode aspect value of an arbitrary section of an arbitrary
Ada entity or construct is then defined to be the following value
(except if this yields a result of Auto for a non-package; see below):

- If SPARK_Mode has been specified for the given section of the
  given entity or construct, then the specified value;

- else for the instance of a generic unit, follow the rules as for a
  declaration that would not be a generic instantiation; take the resulting
  value of SPARK_Mode if it is Auto or Off; otherwise, take the value of
  SPARK_Mode specified for the generic unit if any; otherwise the value is On.

- else for the private part of a public child unit whose parent unit's
  private part has a SPARK_Mode of Off, the SPARK_Mode is Off;

- else for the private part of a package or a protected or task unit,
  the SPARK_Mode of the visible part;

- else for a package body's statements, the SPARK_Mode of the
  package body's declarations;

- else for the first section (in the case of a package, the visible part)
  of a public child unit, the SPARK_Mode of the visible part of the
  parent unit;

- else for the first section (in the case of a package, the visible part)
  of a private child unit, the SPARK_Mode of the private part of the
  parent unit;

- else for any of the visible part or body declarations of a library
  unit package or either section of a library unit subprogram,
  if there is an applicable SPARK_Mode configuration pragma then the
  value specified by the pragma; if no such configuration pragma
  applies, then an implicit specification of Auto is assumed;

- else the SPARK_Mode of the enclosing section of the nearest enclosing
  package or subprogram;

- Corner case: the SPARK_Mode of the visible declarations of the
  limited view of a package is always Auto.

If the above computation yields a result of Auto for any construct
other than one of the four sections of a package, then a result of On
or Off is determined instead based on the legality (with respect to
the rules of |SPARK|) of the construct. The construct's SPARK_Mode is
On if and only if the construct is in |SPARK|. [A SPARK_Mode of Auto
is therefore only possible for (sections of) a package.]

In code where SPARK_Mode is On (also called "SPARK code"), the rules of
|SPARK| are enforced. In particular, such code shall not reference
non-SPARK entities, although such code may reference a SPARK declaration
with one or more non-SPARK subsequent sections (e.g., a package whose
visible part has a SPARK_Mode of On but whose private part has a SPARK_Mode
of Off; a package whose visible part has a SPARK_Mode of Auto may also be
referenced).

Code where SPARK_Mode is Off shall not enclose code where Spark_Mode is On.
However, if an instance of a generic unit is enclosed
by code where SPARK_Mode is Off and if any SPARK_Mode specifications occur
within the generic unit, then the corresponding SPARK_Mode specifications
occurring within the instance have no semantic effect. [In particular,
such an ignored SPARK_Mode specification could not violate the preceding
"Off shall not enclose On" rule because the SPARK_Mode of the
entire instance is Off. Similarly, such an ignored SPARK_Mode specification
could not violate the preceding rule that a SPARK_Mode specification
shall only apply to a (section of a) library-level entity.]

For purposes of the "Off shall not enclose On" rule just described, the
initial section of a child unit is considered to occur immediately
within either the visible part (for a public child unit) or the private
part (for a private child unit) of the parent unit. In addition, the private
part of a public child package is considered to occur immediately
within the private part of the parent unit. [This follows Ada's visibility
rules for child units. This means, for example, that if a parent unit's
private part has a SPARK_Mode of Off, then the private part of a
public child package shall not have a SPARK_Node of On. Note also that
a SPARK_Mode configuration pragma which applies only to the specification
(not the body) of a child unit is always ineffective; this is a consequence
of the rules given above for determining the SPARK_Mode of the first
section of a child unit.]

The rules for a protected
unit follow from the rules given for other constructs after notionally
rewriting the protected unit as a package.

A protected unit declaration such as

.. code-block:: ada

   protected type Prot
     with SPARK_Mode => On
   is
      procedure Op1 (X : in out Integer);
      procedure Op2;
      function Non_SPARK_Profile (X : in out Integer) return Boolean
        with SPARK_Mode => Off;
   private
      Aaa, Bbb : Integer := 0;
   end Prot;

can be thought of, for purposes of SPARK_Mode rules, as being
a lot like

.. code-block:: ada

   package Pkg
     with SPARK_Mode => On
   is
      type Prot is limited private;
      procedure Op1 (Obj : in out Prot; X : in out Integer);
      procedure Op2 (Obj : in out Prot);
      function Non_SPARK_Profile (Obj : Prot; Ptr : in out Integer) return Boolean
        with SPARK_Mode => Off;
   private
      type Prot is
        limited record
           Aaa, Bbb : Integer := 0;
        end record;
   end Pkg;

which is legal. The point is that a protected type which is
in |SPARK| can have protected operation whose declaration is not in |SPARK|.

SPARK_Mode is an implementation-defined Ada aspect; it is not (strictly
speaking) part of the |SPARK| language. It is used to notionally transform
programs which would otherwise not be in |SPARK| so that they can
be viewed (at least in part) as |SPARK| programs.

Note that if you would like to mark all your code in SPARK_Mode, the
simplest solution is to specify in your project file::

   package Builder is
      for Global_Configuration_Pragmas use "spark.adc";
   end Builder;

and provide a file `spark.adc` which contains::

   pragma SPARK_Mode;

.. index:: Annotate; Iterable; Iterable_For_Proof

.. _Aspect and Pragma Iterable:

Aspect and Pragma ``Iterable``
------------------------------

In |SPARK|, it is possible to allow quantification over any container type
using the ``Iterable`` aspect.
This aspect provides the primitives of a container type that will be used to
iterate over its content. For example, if we write:

.. code-block:: ada

   type Container is private with
     Iterable => (First       => First,
                  Next        => Next,
                  Has_Element => Has_Element);

where

.. code-block:: ada

   function First (S : Set) return Cursor;
   function Has_Element (S : Set; C : Cursor) return Boolean;
   function Next (S : Set; C : Cursor) return Cursor;

then quantification over containers can be done using the type ``Cursor``. For
example, we could state:

.. code-block:: ada

   (for all C in S => P (Element (S, C)))

to say that ``S`` only contains elements for which a property ``P`` holds. For
execution, this expression is translated as a loop using the provided ``First``,
``Has_Element``, and ``Next`` primitives. For proof, it is translated as a logic
quantification over every element of type ``Cursor``. To restrict the property
to cursors that are actually valid in the container, the provided function
``Has_Element`` is used. For example, the property stated above becomes:

.. code-block:: ada

   (for all C : Cursor => (if Has_Element (S, C) then P (Element (S, C))))

Like for the standard Ada iteration mechanism, it is possible to allow
quantification directly over the elements of the container by providing in
addition an ``Element`` primitive to the ``Iterable`` aspect. For example, if
we write:

.. code-block:: ada

   type Container is private with
     Iterable => (First       => First,
                  Next        => Next,
                  Has_Element => Has_Element
                  Element     => Element);

where

.. code-block:: ada

   function Element (S : Set; C : Cursor) return Element_Type;

then quantification over containers can be done directly on its elements. For
example, we could rewrite the above property into:

.. code-block:: ada

   (for all E of S => P (E))

For execution, quantification over elements of a container is translated as a
loop over its cursors. In the same way, for proof, quantification over elements
of a container is no more than syntactic sugar for quantification over its
cursors. For example, the above property is translated using quantification
over cursors :

.. code-block:: ada

   (for all C : Cursor => (if Has_Element (S, C) then P (Element (S, C))))

Depending on the application, this translation may be too low-level and
introduce an unnecessary burden on the automatic provers. As an example, let
us consider a package for functional sets:

.. code-block:: ada

  package Sets with SPARK_Mode is

    type Cursor is private;
    type Set (<>) is private with
      Iterable => (First       => First,
                   Next        => Next,
                   Has_Element => Has_Element,
                   Element     => Element);

    function Mem (S : Set; E : Element_Type) return Boolean with
      Post => Mem'Result = (for some F of S => F = E);

    function Intersection (S1, S2 : Set) return Set with
      Post => (for all E of Intersection'Result => Mem (S1, E) and Mem (S2, E))
        and (for all E of S1 =>
	         (if Mem (S2, E) then Mem (Intersection'Result, E)));

Sets contain elements of type ``Element_Type``. The most basic operation on sets
is membership test, here provided by the ``Mem`` subprogram. Every other
operation, such as intersection here, is then specified in terms of members.
Iteration primitives ``First``, ``Next``, ``Has_Element``, and ``Element``, that
take elements of a private type ``Cursor`` as an argument, are only provided for
the sake of quantification.

Following the scheme described previously, the postcondition of ``Intersection``
is translated for proof as:

.. code-block:: ada

  (for all C : Cursor =>
      (if Has_Element (Intersection'Result, C) then
             Mem (S1, Element (Intersection'Result, C))
         and Mem (S2, Element (Intersection'Result, C))))
  and
  (for all C1 : Cursor =>
      (if Has_Element (S1, C1) then
             (if Mem (S2, Element (S1, C1)) then
                   Mem (Intersection'Result, Element (S1, C1)))))

Using the postcondition of ``Mem``, this can be refined further into:

.. code-block:: ada

  (for all C : Cursor =>
      (if Has_Element (Intersection'Result, C) then
             (for some C1 : Cursor =>
                 Has_Element (S1, C1) and Element (Intersection'Result, C) = Element (S1, C1))
         and (for some C2 : Cursor =>
                 Has_Element (S2, C2) and Element (Intersection'Result, C) = Element (S2, C2))))
  and
  (for all C1 : Cursor =>
      (if Has_Element (S1, C1) then
             (if (for some C2 : Cursor =>
                 Has_Element (S2, C2) and Element (S1, C1) = Element (S2, C2)))
      then (for some C : Cursor => Has_Element (Intersection'Result, C)
               and Element (Intersection'Result, C) = Element (S1, C1))))
