<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Bluish Coder: spark</title>
 <link href="http://bluishcoder.co.nz/tag/spark/atom.xml" rel="self"/>
 <link href="http://bluishcoder.co.nz/"/>
 <updated>2020-07-10T16:25:05+12:00</updated>
 <id>http://bluishcoder.co.nz/</id>
 <author>
   <name>Bluishcoder</name>
   <email>admin@bluishcoder.co.nz</email>
 </author>

 
 <entry>
   <title>Installing GNAT and SPARK GPL Editions</title>
   <link href="http://bluishcoder.co.nz/2017/04/27/installing-gnat-and-spark-gpl-editions.html"/>
   <updated>2017-04-27T23:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2017/04/27/installing-gnat-and-spark-gpl-editions</id>
   <content type="html">&lt;p&gt;GNAT is an implementation of the &lt;a href=&quot;http://www.adacore.com/adaanswers/about/ada&quot;&gt;Ada programming language&lt;/a&gt;. &lt;a href=&quot;http://www.spark-2014.org/about&quot;&gt;SPARK&lt;/a&gt; is a restricted subset of Ada for formally verifying programs. It provide features comparable to languages like &lt;a href=&quot;http://rust-lang.org/&quot;&gt;Rust&lt;/a&gt; and &lt;a href=&quot;http://www.ats-lang.org/&quot;&gt;ATS&lt;/a&gt;. A recent &lt;a href=&quot;http://www.electronicdesign.com/industrial/rust-and-spark-software-reliability-everyone&quot;&gt;article comparing SPARK to Rust&lt;/a&gt; caught my eye and I decided to spend some time learnig Ada and SPARK. This post just outlines installing an implementation of both, a quick test to see if the installation worked, and some things to read to learn. I hope to post more later as I learn more.&lt;/p&gt;

&lt;h2&gt;Installation&lt;/h2&gt;

&lt;p&gt;Download GNAT GPL from &lt;a href=&quot;http://libre.adacore.com/download&quot;&gt;libre.adacore.com&lt;/a&gt;. Choose &quot;Free Software or Academic Development&quot; and click &quot;Build Your Download Package&quot;. Select the platform and click the checkboxes next to the required components. For my case I chose them all but &quot;GNAT Ada 2016&quot; and &quot;Spark 2016&quot; are the main ones I needed.&lt;/p&gt;

&lt;p&gt;To install Ada and SPARK from the downloaded tar file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ tar xvf AdaCore-Download-2017-04-27_0537.tar
$ cd x86_64-linux/adagpl-2016/gnatgpl
$ mkdir ~/ada
$ tar -xf gnat-gpl-2016-x86_64-linux-bin.tar.gz
$ cd gnat-gpl-2016-x86_64-linux-bin
$ ./doinstall
...answer prompts about where to install...
...for this example I used /home/username/gnat...
$ export PATH=/home/username/gnat/bin:$PATH

$ cd ../sparkgpl
$ tar -xf spark-gpl-2016-x86_64-linux-bin.tar.gz
$ cd spark-gpl-2016-x86_64-linux-bin
$ ./doinstall
...answer prompts about where to install...
...it should pick up the location used above...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Be aware that the install comes with its own &lt;code&gt;gcc&lt;/code&gt; and other utilities. By putting it first in the &lt;code&gt;PATH&lt;/code&gt; they are used over the systems versions.&lt;/p&gt;

&lt;h2&gt;Testing GNAT&lt;/h2&gt;

&lt;p&gt;The following is a &quot;Hello World&quot; application in Ada:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;with Ada.Text_IO; use Ada.Text_IO;
procedure Hello is
begin
  Put_Line (&quot;Hello World!&quot;);
end Hello;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It imports a package, &lt;code&gt;Ada.Text_IO&lt;/code&gt;, and uses it so the package contents can be used without prefixing them with the package name. A procedure called &lt;code&gt;Hello&lt;/code&gt; is created that outlines a line of text. If put in a file &lt;code&gt;hello.adb&lt;/code&gt; it can be compiled with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ gnatmake hello.adp
gnatbind -x hello.ali
gnatlink hello.ali

$ ./hello
Hello World!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Completely static executables can also be created:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ gnatmake hello.adb -bargs -static -largs -static
$ ldd hello
not a dynamic executable
$ ./hello
Hello World!
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Testing SPARK&lt;/h2&gt;

&lt;p&gt;I used an example taken from &lt;a href=&quot;http://www.spark-2014.org/entries/detail/spark-16-generating-counterexamples-for-failed-proofs&quot;&gt;Generating Counterexamples for failed Proofs&lt;/a&gt;. The SPARK checker, &lt;code&gt;gnatproof&lt;/code&gt;, requires a project file. This is the contents of &lt;code&gt;saturate.gpr&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;project Saturate is
   for Source_Dirs use (&quot;.&quot;);

   package Compiler is
      for Default_Switches (&quot;Ada&quot;) use (&quot;-gnatwa&quot;);
   end Compiler;
end Saturate;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It gives the project name, &lt;code&gt;Saturate&lt;/code&gt;, the location to search for source files (the current directory), and any compiler switches. The function to be implemented is a saturation function. It ensures a value given to it is in a specific range. In this case, a non-negative value less than or equal to 255. In file &lt;code&gt;saturate.ads&lt;/code&gt; we put the interface definition:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;with Interfaces;
use Interfaces;

function Saturate (Val : Unsigned_16) return Unsigned_16 with
  SPARK_Mode,
  Post =&amp;gt; Saturate&#39;Result &amp;lt;= 255 and then
         (if Val &amp;lt;= 255 then Saturate&#39;Result = Val);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The code first pulls the &lt;code&gt;Interfaces&lt;/code&gt; package into the current namespace. This provides unprefixed access to &lt;code&gt;Unsigned_16&lt;/code&gt;. It declares a function, &lt;code&gt;Saturate&lt;/code&gt;, that takes an &lt;code&gt;Unsigned_16&lt;/code&gt; as an argument and returns the same type. The &lt;code&gt;SPARK_Mode&lt;/code&gt; is an annotation that identifes code to be checked by SPARK. The &lt;code&gt;Post&lt;/code&gt; portion is a postcondition that the implementation of the function must adhere to. In this case the result must be less than 255 and if the given value is less than 255 then the result will be equal to the value.&lt;/p&gt;

&lt;p&gt;The implementation of the function is in a file &lt;code&gt;saturate.adb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function Saturate (Val : Unsigned_16) return Unsigned_16 with
  SPARK_Mode
is
begin
  return Unsigned_16&#39;Max (Val, 255);
end Saturate;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This calls the &lt;code&gt;Max&lt;/code&gt; function for &lt;code&gt;Unsigned_16&lt;/code&gt; types to return the maximum between the given value and 255. The code compiles with the Ada compiler:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ gnatmake saturate.adb
gcc -c saturate.adb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It fails however when running the SPARK checker:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ gnatprove -Psaturate 
Phase 1 of 2: generation of Global contracts ...
Phase 2 of 2: flow analysis and proof ...
saturate.ads:6:11: medium: postcondition might fail (e.g. when Saturate&#39;Result = 255 and Val = 0)
Summary logged in gnatprove/gnatprove.out
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This tells us that the postcondition might fail if the given value to the function is &lt;code&gt;0&lt;/code&gt; and the result is &lt;code&gt;255&lt;/code&gt;. This is because we are using &lt;code&gt;Max&lt;/code&gt; - given the value &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;Saturate&lt;/code&gt;, the &lt;code&gt;Max&lt;/code&gt; of &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;255&lt;/code&gt; is &lt;code&gt;255&lt;/code&gt;. The function result will be &lt;code&gt;255&lt;/code&gt;. The postcondition however states that the result should be equal to val - it should be &lt;code&gt;0&lt;/code&gt;. Changing the function call to &lt;code&gt;Min&lt;/code&gt; fixes it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ gnatprove -Psaturate 
Phase 1 of 2: generation of Global contracts ...
Phase 2 of 2: flow analysis and proof ...
Summary logged in gnatprove/gnatprove.out
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Having a postcondition that states what the result should be is probably unlikely in a lot of code. If the signature was the following, would SPARK find the error still?:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function Saturate (Val : Unsigned_16) return Unsigned_16 with
  SPARK_Mode,
  Post =&amp;gt; Saturate&#39;Result &amp;lt;= 255

$ gnatprove -Psaturate 
Phase 1 of 2: generation of Global contracts ...
Phase 2 of 2: flow analysis and proof ...
saturate.ads:6:11: medium: postcondition might fail,
         cannot prove Saturate&#39;Result &amp;lt;= 255 (e.g. when Saturate&#39;Result = 256)
Summary logged in gnatprove/gnatprove.out
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Apparently so. Now it identifies that the result can be 256. Other examples following different contracts on the function are &lt;a href=&quot;http://www.spark-2014.org/entries/detail/spark-16-generating-counterexamples-for-failed-proofs&quot;&gt;in the original article&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Documentation&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;http://docs.adacore.com/gnat_ugn-docs/html/gnat_ugn/gnat_ugn.html&quot;&gt;GNAT User&#39;s Guide for Native Platforms&lt;/a&gt; and &lt;a href=&quot;http://docs.adacore.com/spark2014-docs/html/ug/&quot;&gt;Spark 2014 User&#39;s Guide&lt;/a&gt; contains the instructions for the main tools. GNAT can &lt;a href=&quot;http://docs.adacore.com/gnat_ugn-docs/html/gnat_ugn/gnat_ugn/the_gnat_compilation_model.html#mixed-language-programming&quot;&gt;interface with C and C++&lt;/a&gt;. There is &lt;a href=&quot;http://libre.adacore.com/developers/documentation&quot;&gt;a full list of documentation here&lt;/a&gt;. Two useful books covering Ada and Spark:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.com/Building-High-Integrity-Applications-SPARK/dp/1107656842&quot;&gt;Building High Integrity Applications with SPARK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.com/Programming-Ada-2012-John-Barnes-ebook/dp/B00JXIIGMO&quot;&gt;Programming in Ada 2012&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Some technical papers that give a quick overview of Ada:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.adacore.com/knowledge/technical-papers/safe-and-secure-software-an-invitation-to-ada-2012/&quot;&gt;Safe and Secure Software - An Invitation to Ada 2012&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://libre.adacore.com/developers/technical-papers-single/ada-for-the-c-or-java-developer&quot;&gt;Ada for the C++ or Java Developer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I used the command line tools here but there is a &lt;code&gt;gps&lt;/code&gt; command which is a full graphical IDE which may be more approachable. I&#39;m looking forward to using Ada and SPARK and seeing how they compare to tools like Rust and ATS.&lt;/p&gt;
</content>
 </entry>
 
 
</feed>
