<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Lightning Talk: Supporting Software Sustainability with Lightweight Specifications</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Mistral Contrastin</string-name>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Matthew Danish</string-name>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Dominic Orchard y</string-name>
          <email>D.A.Orchard@kent.ac.uk</email>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Andrew Rice Computer Laboratory</string-name>
        </contrib>
        <contrib contrib-type="author">
          <string-name>University of Cambridge</string-name>
        </contrib>
        <contrib contrib-type="author">
          <string-name>UK firstname.lastname@cl.cam.ac.uk</string-name>
        </contrib>
      </contrib-group>
      <abstract>
        <p>-Lightweight specifications support software maintainability by providing a way to verify that any changes to a code base preserve certain program properties. We give two examples of lightweight specifications for numerical code: units-of-measure types which specify the physical units of numerical quantities in a program; and stencil specifications which describe the pattern of data access used in array computations. Not only can we automatically verify that a program correctly implements these requirements but specifications provide documentation for future developers. Specifications can also be inferred and generated automatically in some cases, further reducing programmer effort. We finish by identifying future potential specification techniques to ease the maintenance and comprehension of scientific code.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>I. INTRODUCTION</title>
      <p>Being able to comprehend and easily extend a code base
is central to software sustainability; inflexible and inscrutable
code is difficult to maintain, adapt, and debug in the future.
Frequently the intention of the original programmer is not clear
from the code alone. There may be an underlying
mathematical model from which the code is derived (e.g., numerical
computations in science), but the relationship between the
implementation and the model is rarely documented clearly.
Programmers often attempt to communicate their original
intention by commenting their code, providing informal
specifications and descriptions of the program. This approach is
often less than perfect: comments must be kept up-to-date with
the code they describe and an appropriate level of abstraction
must be used to provide effective information (rather than, say,
describing each operation line by line).</p>
      <p>
        This informal and manual commenting approach contrasts
with full program specification in which a formal and precise
mathematical description is provided for a program [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ]. This
is the precursor to automatic verification, where a verification
tool checks that a program behaves correctly with respect to
its specification. Full specification of scientific programs is
however challenging: specification languages are very different
to programming languages (requiring an additional skill set)
and writing specifications often requires an understanding of
the verification process; full specification requires significant
effort. This approach is simply not feasible for much of the
scientific community. Furthermore, it is currently unknown how
to effectively specify and verify many high-level numerical
properties of programs, such as convergence (some work in
this direction is by Boldo et al. [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ]).
      </p>
      <p>We believe lightweight specification and verification
provides an intermediate solution. Lightweight specifications
describe the behaviour of some aspects of a program, rather than
the whole. This reduces the burden on the programmer whilst
still aiding comprehension of the program by others. The
specification language can be designed to target a higher level
of abstraction than the code itself thereby producing useful
specifications which are both human- and machine-readable.
We advocate for including such lightweight specifications as
inline comments in the code so that the usual tool-chain
(compilers, IDEs, version control) is unaffected. The usual
verification benefits are provided: a program can be checked
for conformance to its lightweight specifications, and this also
ensures specifications are up-to-date with the code.</p>
    </sec>
    <sec id="sec-2">
      <title>II. EXAMPLE</title>
      <p>
        We give an example of two such lightweight specification
and verification techniques provided by our tool, CamFort,
for Fortran code base verification. Figure 1 shows an extract
of a Navier-Stokes fluid simulation (based on [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ]). The code
snippet is constrained by two kinds of specification:
1) The unit specifications (lines 1, 4, 7, 10, 13) specify the
units-of-measure of numerical quantities in the program,
ensuring that the units of variables are consistent. This
rules out a common source of bugs from mismatched units.
2) The stencil specifications (lines 16, 17) describe the
shape of the array access in the approximation computed
on line 21. They describe that, at each index(i, j), the
arrays f and g are accessed “backwards” to a depth of 1 in
the first and second dimensions respectively. This kind of
specification is especially useful when more complicated
access patterns are used, and frequently corresponds to
choices made when deriving a discrete approximation from
a continuous mathematical model.
      </p>
      <p>
        Note that lightweight specifications can be given selectively to
parts of the code as required, rather than being all or nothing.
CamFort has four modes of interaction with specifications:
!= stencil readOnce, backward(depth=1, dim=1) *
,! reflexive(dim=2) :: f
!= stencil readOnce, backward(depth=1, dim=2) *
,! reflexive(dim=1) :: g
do i = 1, imax
do j = 1, jmax
if (iand(flag(i,j), cf))
rhs(i,j) = ((f(i,j) - f(i-1,j)) / delx +
,! (g(i,j) - g(i,j-1)) / dely)
,! / del_t
end do; end do
2) inference: CamFort can infer specifications automatically,
giving useful information and reducing programmer effort.
For units-of-measure, a programmer need not specify the
units for each variable. For example, the unit specification
for rhs on line 10 need not be given. In infer mode,
CamFort infers and reports the units of all variables (whether
they have been given an explicit specification of not). For
stencil specifications, CamFort can infer specifications of
the shape of a large class of regular array access patterns.
3) synthesis: based on the above inference, CamFort can
further reduce programmer effort by inserting automatically
inferred specifications into the code where relevant. For
example, the specifications on lines 16, 17 can be inferred
and synthesised by CamFort entirely automatically without
any programmer effort.
4) suggestion: (just for units), CamFort can suggest a subset
of program variables that if given a specification manually
by the programmer provides enough information to
CamFort to infer the units-of-measure for all other variables.
The inference, synthesis, and suggestion features of CamFort
further support the lightweight nature of the specifications. In
a previous study, we sought to measure how much CamFort
reduces programmer effort via the inference and synthesis of
unit specifications [
        <xref ref-type="bibr" rid="ref8">8</xref>
        ]. We calculated the proportion of variable
declarations in a program that required a user-given
specification for CamFort to infer a units-of-measure specification for
the rest, as reported by the suggest mode. On a corpus of forty
small programs from a computational physics textbook, only
18% of variable declarations needed a user-given specification
in order to infer all others, i.e., an 82% effort saving compared
with giving a specification to all declarations [8, Fig. 6].
      </p>
      <p>
        For the full Navier-Stokes code, of which Figure 1 above
gave an excerpt, the latest version of CamFort suggests that
only 79 of the 262 variable declarations actually require a
usergiven specification to infer and synthesise units-of-measure for
the rest of the variables: a 70% saving in effort compared with
manually specifying the units of every variable [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ].
      </p>
      <p>Note that specifications can be declared once, given a name,
and reused many times, further reducing effort.</p>
    </sec>
    <sec id="sec-3">
      <title>III. DISCUSSION</title>
      <p>
        There are a variety of directions to explore for future
specifications. We give three examples that we are exploring.
1) Software contracts such as pre- and post-conditions,
assertions, and loop invariants can be added to check expected
ranges of values and program behaviour. Techniques for
inferring contracts are available [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ] which would ease the burden
on the programmer. 2) Test generation, e.g. QuickCheck [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ],
provides a way to generate program tests from user-supplied
properties of functions and methods. Test inputs are
automatically generated and applied, exposing counter examples.
3) Dependency specifications track how a piece of data
is used within a program. Long-lived (e.g., global) data is
common and specifications which restrict how the data is used
throughout the program would allow programmers to make
changes and be confident of their scope and influence.
      </p>
      <p>
        Lightweight specifications aid software maintainability and
reuse by providing high-level information to other developers
about the intention of the code. Automatically verifying their
correctness ensures that the code remains up-to-date with the
specification and can provide confidence in changes made
by new developers. Our open-source tool CamFort1 provides
implementations of stencil and units-of-measure specifications
(see [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ] for more). The synthesis and inference techniques it
provides show how tool support can further reduce the burden
of using specifications and verification systems.
      </p>
    </sec>
    <sec id="sec-4">
      <title>ACKNOWLEDGEMENTS</title>
      <p>This work was supported by the Engineering and Physical
Sciences Research Council (EP/M026124/1).</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>S.</given-names>
            <surname>Boldo</surname>
          </string-name>
          ,
          <string-name>
            <surname>F.</surname>
          </string-name>
          <article-title>Cle´ment,</article-title>
          <string-name>
            <surname>J-C. Filliaˆtre</surname>
            , M. Mayero, G. Melquiond, and
            <given-names>P.</given-names>
          </string-name>
          <string-name>
            <surname>Weis</surname>
          </string-name>
          .
          <article-title>Wave equation numerical resolution: a comprehensive mechanized proof of a C program</article-title>
          .
          <source>Journal of Automated Reasoning</source>
          ,
          <volume>50</volume>
          (
          <issue>4</issue>
          ):
          <fpage>423</fpage>
          -
          <lpage>456</lpage>
          ,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>K.</given-names>
            <surname>Claessen</surname>
          </string-name>
          and
          <string-name>
            <surname>J. Hughes.</surname>
          </string-name>
          <article-title>QuickCheck: a lightweight tool for random testing of Haskell programs</article-title>
          .
          <source>ACM SIGPLAN Notices</source>
          ,
          <volume>46</volume>
          (
          <issue>4</issue>
          ):
          <fpage>53</fpage>
          -
          <lpage>64</lpage>
          ,
          <year>2011</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>M.</given-names>
            <surname>Contrastin</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Rice</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Danish</surname>
          </string-name>
          , and
          <string-name>
            <given-names>D.</given-names>
            <surname>Orchard</surname>
          </string-name>
          .
          <article-title>Research data supporting “Lightning Talk: Supporting Software Sustainability with Lightweight Specifications”</article-title>
          . http://dx.doi.org/10.17863/CAM.1190.
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>M.</given-names>
            <surname>Contrastin</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Rice</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Danish</surname>
          </string-name>
          , and
          <string-name>
            <given-names>D.</given-names>
            <surname>Orchard</surname>
          </string-name>
          .
          <article-title>Units-of-Measure Correctness in Fortran Programs</article-title>
          .
          <source>Computing in Science &amp; Engineering</source>
          ,
          <volume>18</volume>
          (
          <issue>1</issue>
          ):
          <fpage>102</fpage>
          -
          <lpage>107</lpage>
          ,
          <year>2016</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>M.</given-names>
            <surname>Griebel</surname>
          </string-name>
          ,
          <string-name>
            <given-names>T.</given-names>
            <surname>Dornsheifer</surname>
          </string-name>
          , and
          <string-name>
            <given-names>T.</given-names>
            <surname>Neunhoeffer</surname>
          </string-name>
          .
          <article-title>Numerical simulation in fluid dynamics: a practical introduction</article-title>
          , volume
          <volume>3</volume>
          .
          <source>Society for Industrial Mathematics</source>
          ,
          <year>1997</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>K.</given-names>
            <surname>Hinsen</surname>
          </string-name>
          .
          <article-title>Writing software specifications</article-title>
          .
          <source>Computing in Science &amp; Engineering</source>
          ,
          <volume>17</volume>
          (
          <issue>3</issue>
          ):
          <fpage>54</fpage>
          -
          <lpage>61</lpage>
          ,
          <year>2015</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>F.</given-names>
            <surname>Logozzo</surname>
          </string-name>
          .
          <article-title>Technology for Inferring Contracts from Code</article-title>
          .
          <source>In Proceedings of SigADA High Integrity Language Technology (HILT</source>
          <year>2013</year>
          ). ACM,
          <year>November 2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>D.</given-names>
            <surname>Orchard</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Rice</surname>
          </string-name>
          , and
          <string-name>
            <given-names>O.</given-names>
            <surname>Oshmyan</surname>
          </string-name>
          .
          <article-title>Evolving Fortran types with inferred units-of-measure</article-title>
          .
          <source>Journal of Computational Science</source>
          ,
          <volume>9</volume>
          :
          <fpage>156</fpage>
          -
          <lpage>162</lpage>
          ,
          <year>2015</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>