singularity Wiki & Documentation Rss Feedhttp://www.codeplex.com/singularity/Wiki/View.aspx?title=Homesingularity Wiki Rss DescriptionNew Comment on "Documentation"https://singularity.codeplex.com/documentation?&ANCHOR#C31737Ironclad links broken.DoYouKnowSun, 21 Jun 2015 22:58:48 GMTNew Comment on "Documentation" 20150621105848PUpdated Wiki: Test clienthttps://singularity.codeplex.com/wikipage?title=Test client&version=1<div class="wikidoc">To run a client of the Ironclad app, do the following.<br /><br />First, in an administrative command prompt, create an ARP entry for the machine&#39;s Ethernet address by running this command with appropriate concrete values substituted:<br /><pre>
arp -s 10.1.2.3 90-e2-ba-4f-0c-5b
</pre><br />Next, start a serial port connection by running the following from cygwin:<br /><pre>
plink -sercfg 115200,8,n,1 -serial com3
</pre><br />Next, start the boot server and reboot the Ironclad server machine.<br /><br /></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:22:10 GMTUpdated Wiki: Test client 20141014112210PUpdated Wiki: Boot serverhttps://singularity.codeplex.com/wikipage?title=Boot server&version=1<div class="wikidoc">To allow our Ironclad machine to boot an Ironclad image, we use a boot server. This boot server serves as a DHCP/TFTP server for the Ironclad machine, so that when the Ironclad machine boots up it can obtain the image it needs. To set up a boot server, do the following:<br />
<ol><li>On the boot server, edit the file iron/boot/boot-cp.cmd to make sure you&#39;re serving the image you want. Comment out all but the iso_cp you want to use. Note that iso_cp is a directory.</li>
<li>From iron/boot, run boot-cp.cmd. This will start the boot server.</li>
<li>Start up the Ironclad machine. It should automatically boot using PXE and obtain the image. It&#39;s possible it will boot from an alternate PXE server on your network; if this happens, you might have to disconnect the switch from the network so your Ironclad machine can only reach your boot server.</li></ol>
<br />As of this writing, Ironclad has driver support only for a very specific model of Ethernet card.</div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:21:15 GMTUpdated Wiki: Boot server 20141014112115PUpdated Wiki: Tool componentshttps://singularity.codeplex.com/wikipage?title=Tool components&version=1<div class="wikidoc">This is a brief description of the component tools that comprise the Ironclad toolbox.<br />
<ul><li>Z3 is a generic SMT solver. Although SAT--boolean satisfiability--is an NP hard problem, it turns out good heuristics can solve many big problems quickly. Z3 is a big bag of such heuristics, plus &quot;Modulo Theories&quot; -- a layer that computes in super-boolean domains, like integer and real-valued arithmetic. We never interact directly with Z3, but its abilities (and limitations) underlie all of the verification tools we use.</li>
<li>Boogie is a verification-oriented programming language. It lets one write imperative code with modular Hoare-style contracts (requires and ensures). The Boogie tool maps Boogie programs (.bpl) into Z3 clauses.</li>
<li>Dafny is a high-level verification-oriented programming language, with features like object orientation (which we don&#39;t yet use), dynamic frames (which we should be using), and … some other reasons it&#39;s nicer than Boogie, which is why we use it. The Dafny.exe tool maps a Dafny program (.dfy) down to Boogie for verification, and can compile Dafny code to C# code, which can then be executed against the CLR.</li>
<li>Verve is a verified operating system, primarily of a garbage collector and microkernel. Its properties are specified in (trusted) Boogie. Other trusted Boogie specifies assumptions about the hardware, such as the behavior of x86 instructions. It is implemented in BoogieAsm (.basm*) and Beat (.beat*) code.</li>
<li>BoogieAsm is a subset of Boogie in which the only non-ghost (imperative) operations allowed are those specified in the trusted hardware spec. Thus, while Boogie allows x:=x+1, the same operation in BoogieAsm requires loading a register and using the add instruction. The trusted BoogieAsm tool enforces this constraint on .basm files to generate a Boogie file for verification, and also emits assembly code (stripped of the proof used by the Boogie verification) for consumption by masm, the standard macro assembler.</li>
<li>Beat is a macro assembly language over BoogieAsm. Programming in BoogieAsm involves long and ugly assembly idioms; Beat provides a cleaner, one-line abstraction to assembly instructions. The Beat tool transforms a Beat program into a BoogieAsm program which is then verified by trusted tools. No specs are written in Beat, so its transformation needn&#39;t be trusted.</li>
<li>The trusted DafnySpec tool translates a small subset of Dafny into Boogie. Trusting this tool enables us to write high-level app specs in Dafny.</li>
<li>The untrusted DafnyCC tool compiles a Dafny program into BoogieAsm modules. It works at the whole-program level to enforce that all methods have an implementation and that all implementations generate BoogieAsm verification obligations.</li>
<li>A complete Ironclad program, thus, is made from:
<ul><li>Trusted spec: Dafny application and hardware specs, transformed via DafnySpec into Boogie, plus Verve&#39;s Boogie hardware specs.</li>
<li>Untrusted implementation verified against those specs:
<ul><li>Dafny code compiled to BoogieAsm, plus</li>
<li>Verve&#39;s Beat code transformed to BoogieAsm, plus</li>
<li>Verve&#39;s raw BoogieAsm code,</li></ul></li></ul></li></ul>
all verified and emitted as an .asm file via BoogieAsm, assembled by masm, and linked into a Windows or standalone machine image.<br /></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:19:26 GMTUpdated Wiki: Tool components 20141014111926PUpdated Wiki: Event countershttps://singularity.codeplex.com/wikipage?title=Event counters&version=1<div class="wikidoc">SymDiff is useful in ensuring that a method isn&#39;t called with secret data. However, it doesn&#39;t, by default, ensure that the decision to call a method is based only on public data. If you have a method that requires this, you need to use an artificial event counter.<br /><br />For instance,<br /><pre>
ghost var {:readonly} event_counter:int;
ghost method MethodThatShouldntBeCalledBasedOnSecretData ()
requires public(event_counter);
ensures event_counter == old(event_counter) + 1;
</pre><br />Currently, we use two such event counters, one for reading from the network and one for writing to the network. One perspective is that this is one too many, and that we should use a single event counter for all such methods. So if you have such a method you use the network output counter, and eventually we&#39;ll change the network input method to also use that counter.<br /><br /></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:15:59 GMTUpdated Wiki: Event counters 20141014111559PUpdated Wiki: Using SymDiffhttps://singularity.codeplex.com/wikipage?title=Using SymDiff&version=2<div class="wikidoc">In Ironclad, we have a new way of specifying information-flow properties that takes some explaining. These information-flow properties are checked by a tool called SymDiff, which generally runs after DafnyCC has compiled and verified functional-correctness properties.<br /><br />If any device may leak information outside of the trusted part of the platform, its specification ensures that only public data may be leaked out that interface. Thus, if you ever try to output anything to, say, the network card, SymDiff is going to raise an alarm if you don&#39;t prove that it&#39;s public.<br /><br />The specification also says that data you read from untrusted parts of the platform is public. So you can prove data is public if you read it from, say, the network. But, most of the time, you&#39;ll want to do something to that data before you output it. If you can prove that your output derives only from public data, you&#39;ll be allowed to output it. But how do you prove such &quot;derivation&quot;?<br /><br />Suppose we have a set of expressions S that are known to be public, and we want to prove that another expression D is also public. We can do this by proving that, for any two program runs L and R in which each expression S takes on the same value in both runs, D also takes on the same value in both runs.<br /><br />We call these two runs L and R the &quot;left&quot; run and the &quot;right&quot; run. We use left(E) as the value that E takes on in the left run, and right(E) as the value that E takes on in the right run. So the axiom SymDiff applies is:<br /><pre>
public(S) &amp;&amp; (left(S) == right(S) ==&gt; left(D) == right(D)) ==&gt; public(D)
</pre><br />Indeed, viewed this way, you can think of public(X) as a synonym for left(X) == right(X). If this appears in a pre-condition, then SymDiff considers only pairs of runs in which X takes on the same value in both runs. If this appears in a post-condition, then SymDiff tries to prove that in any pair of runs considered, X takes on the same value.<br /><br />Unfortunately, SymDiff can only look at these relational invariants when they&#39;re pre-conditions, post-conditions, or loop invariants. So you can&#39;t, for instance, assert(public(X)).<br /><br />Sometimes you&#39;ll need to output data that can&#39;t be proven to be public. For instance, if you encrypt secret data using your private key, that encryption derives from the private key, which derives from randomness read from the trusted platform, which is obviously not public. However, you and I and the remote verifier know that the encryption scheme doesn&#39;t actually reveal anything about the key. So you&#39;ll need to convey that in an axiom that essentially forces SymDiff to accept something as public. For instance, you can write:<br /><pre>
method {:axiom} DeclassifyEncryption (m:seq&lt;int&gt;, k:RSAKey, e:seq&lt;int&gt;)
requires e == RSAEncrypt(m, k);
ensures public(e);
</pre><br />so you can encrypt something, call DeclassifyEncryption, then output the encryption on the network.<br /><br />Note the {:axiom} and the lack of a body. The lack of a body means that Dafny and DafnyCC will take all the post-conditions on faith. If this sounds dangerous, that&#39;s because it is, and for this reason the build system won&#39;t build an executable if there are any body-less methods. However, the :axiom directive tells the system it&#39;s OK to build an executable even though there&#39;s no body on this method.<br /><br /><a href="https://singularity.codeplex.com/wikipage?title=Event%20counters&referringTitle=Using%20SymDiff">Event counters</a></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:14:56 GMTUpdated Wiki: Using SymDiff 20141014111456PUpdated Wiki: Using SymDiffhttps://singularity.codeplex.com/wikipage?title=Using SymDiff&version=1<div class="wikidoc">In Ironclad, we have a new way of specifying information-flow properties that takes some explaining. These information-flow properties are checked by a tool called SymDiff, which generally runs after DafnyCC has compiled and verified functional-correctness properties.<br /><br />If any device may leak information outside of the trusted part of the platform, its specification ensures that only public data may be leaked out that interface. Thus, if you ever try to output anything to, say, the network card, SymDiff is going to raise an alarm if you don&#39;t prove that it&#39;s public.<br /><br />The specification also says that data you read from untrusted parts of the platform is public. So you can prove data is public if you read it from, say, the network. But, most of the time, you&#39;ll want to do something to that data before you output it. If you can prove that your output derives only from public data, you&#39;ll be allowed to output it. But how do you prove such &quot;derivation&quot;?<br /><br />Suppose we have a set of expressions S that are known to be public, and we want to prove that another expression D is also public. We can do this by proving that, for any two program runs L and R in which each expression S takes on the same value in both runs, D also takes on the same value in both runs.<br /><br />We call these two runs L and R the &quot;left&quot; run and the &quot;right&quot; run. We use left(E) as the value that E takes on in the left run, and right(E) as the value that E takes on in the right run. So the axiom SymDiff applies is:<br /><pre>
public(S) &amp;&amp; (left(S) == right(S) ==&gt; left(D) == right(D)) ==&gt; public(D)
</pre><br />Indeed, viewed this way, you can think of public(X) as a synonym for left(X) == right(X). If this appears in a pre-condition, then SymDiff considers only pairs of runs in which X takes on the same value in both runs. If this appears in a post-condition, then SymDiff tries to prove that in any pair of runs considered, X takes on the same value.<br /><br />Unfortunately, SymDiff can only look at these relational invariants when they&#39;re pre-conditions, post-conditions, or loop invariants. So you can&#39;t, for instance, assert(public(X)).<br /><br />Sometimes you&#39;ll need to output data that can&#39;t be proven to be public. For instance, if you encrypt secret data using your private key, that encryption derives from the private key, which derives from randomness read from the trusted platform, which is obviously not public. However, you and I and the remote verifier know that the encryption scheme doesn&#39;t actually reveal anything about the key. So you&#39;ll need to convey that in an axiom that essentially forces SymDiff to accept something as public. For instance, you can write:<br /><pre>
method {:axiom} DeclassifyEncryption (m:seq&lt;int&gt;, k:RSAKey, e:seq&lt;int&gt;)
requires e == RSAEncrypt(m, k);
ensures public(e);
</pre><br />so you can encrypt something, call DeclassifyEncryption, then output the encryption on the network.<br /><br />Note the {:axiom} and the lack of a body. The lack of a body means that Dafny and DafnyCC will take all the post-conditions on faith. If this sounds dangerous, that&#39;s because it is, and for this reason the build system won&#39;t build an executable if there are any body-less methods. However, the :axiom directive tells the system it&#39;s OK to build an executable even though there&#39;s no body on this method.<br /></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:14:36 GMTUpdated Wiki: Using SymDiff 20141014111436PUpdated Wiki: Debugginghttps://singularity.codeplex.com/wikipage?title=Debugging&version=1<div class="wikidoc">If you&#39;re having trouble understanding the error messages generated by Boogie on DafnyCC-generated code, try the following. Hand-edit the .bpl file to add {:expand} after the word &#39;implementation&#39; and before the name of the problematic method. Then, re-run boogie.exe on that file.<br /></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:13:48 GMTUpdated Wiki: Debugging 20141014111348PUpdated Wiki: Conservative sequence triggerhttps://singularity.codeplex.com/wikipage?title=Conservative sequence trigger&version=1<div class="wikidoc">If you run the Z3 axiom profiler, and it turns out to be thinking frequently about an axiom involving Seq<i>Index and Seq</i>Append, then you probably need this tip. Use the directive {:dafnycc_conservative_seq_triggers} on the affected method, and it should fix this problem.<br /></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:13:30 GMTUpdated Wiki: Conservative sequence trigger 20141014111330PUpdated Wiki: Mathematical _forall lemmashttps://singularity.codeplex.com/wikipage?title=Mathematical _forall lemmas&version=1<div class="wikidoc">Conveniently, many of the mathematical lemmas we&#39;ve proven in Libraries/Math/*.dfy have _forall variants that make them easy to invoke, like lemma<i>mul</i>is<i>distributive</i>forall(). Unfortunately, each of these _forall variants introduces a large number of potential facts, which may confuse Z3 and make it time out. This is particularly likely to happen for DafnyCC, so you should probably avoid using _forall lemmas in all but the shortest and simplest methods.<br /><br />The reason DafnyCC tends to be worse than Dafny at this is as follows. Dafny gives you quick feedback about whether it can prove things in a timely fashion. So you&#39;ll generally try various strategies until you find one that works. DafnyCC does not provide such quick feedback, so you won&#39;t really have an opportunity to try too many strategies. So while there may be a strategy using a _forall that will avoid a timeout, you may hit a personal human-frustration timeout trying to find such a strategy.<br /><br /></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:13:17 GMTUpdated Wiki: Mathematical _forall lemmas 20141014111317PUpdated Wiki: Calc hidinghttps://singularity.codeplex.com/wikipage?title=Calc hiding&version=1<div class="wikidoc">Normally, in Dafny, a calc hides everything except the outermost relationship. For instance, after the following code:<br /><pre>
calc {
a;
&lt; { assert Property1(); } b;
&lt; { lemma2(); } c;
&lt;= { lemma3(); d;
}
</pre><br />Dafny remembers a &lt; d but nothing else. However, DafnyCC doesn&#39;t quite forget everything else. It does forget all the stuff inside the intermediate explanations, e.g., it forgets the assertion of Property1() and it forgets all post-conditions of lemma2 and lemma3. However, it also remembers intermediate calc relationships. In the example above, those would be a &lt; b, b &lt; c, and c &lt;= d.<br /><br />This failure to forget can sometimes cause DafnyCC to know too many facts, and thus to time-out when trying to decide things. To get around this problem, you can nest the calc inside an outer calc that just proves the relationship you&#39;re interested in. For instance, for the above example, you could nest it as follows:<br /><pre>
calc {
a;
&lt;
calc {
a;
&lt; { assert Property1(); } b;
&lt; { lemma2(); } c;
&lt;= { lemma3(); d;
}
d;
}
</pre></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:12:20 GMTUpdated Wiki: Calc hiding 20141014111220PUpdated Wiki: Automatic inductionhttps://singularity.codeplex.com/wikipage?title=Automatic induction&version=1<div class="wikidoc">Regular Dafny can often infer inductive invariants, so you don&#39;t always have to state them. DafnyCC doesn&#39;t do this automatic inference, so you have to explicitly do the inductive assertions. Here&#39;s an illustrative example:<br /><br /><pre>
lemma AllIntegersAreKeen (j:int)
ensures IntegerIsKeen(j);
{
if j == 0 {
lemma_ZeroIsKeen();
}
else {
assert AllIntegersAreKeen(j-1); // DafnyCC requires this explicit invocation
lemma_KeennessForXImpliesKeennessForXPlusOne(j-1);
}
}
</pre></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:11:56 GMTUpdated Wiki: Automatic induction 20141014111156PUpdated Wiki: Null arrayshttps://singularity.codeplex.com/wikipage?title=Null arrays&version=1<div class="wikidoc">DafnyCC doesn&#39;t support setting an array reference to null, and will give an error if your code may ever set an array to null. However, this doesn&#39;t mean you can get away with leaving off pre-conditions that say arrays aren&#39;t null.<br /></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:11:39 GMTUpdated Wiki: Null arrays 20141014111139PUpdated Wiki: Arrays in datatypeshttps://singularity.codeplex.com/wikipage?title=Arrays in datatypes&version=1<div class="wikidoc">If you use a datatype that contains an array as one of its elements, DafnyCC can lose track of the fact that the array is allocated. This will lead to problems because most methods guarantee that they don&#39;t affect allocated parts of the heap (other than ones they explicitly modify). So if you call a method, DafnyCC may think that arrays sitting around in datatypes could have gotten modified by that method. The fix for this is to copy the array reference into a real (non-ghost variable). For instance:<br /><pre>
var da_ref := d.a; // copy array reference d.a so DafnyCC inserts a reminder here that d.a is allocated
</pre><br />The places to do this are: (1) at the beginning of a method, for every array in a datatype passed as a parameter, and (2) after calling a method, for every array in a datatype returned by that method.<br /><br /><br />An entirely separate issue related to arrays in datatypes is as follows. DafnyCC needs to know whether a function (not a method) depends on the heap. Its heuristic for this is to see if any of the parameters are arrays. So that means that if it has no array parameters, but one of its parameters is a datatype that includes an array, the heuristic will fail. For this reason, you have to put the directive {:heap} on the function if it accesses the heap but doesn&#39;t have any array parameters. If you don&#39;t do this, you&#39;ll probably get errors that talk about $absMem; this is a good sign that you need the {:heap} directive.<br /><br />Yet another issue is with opaque functions/predicates that operate on datatypes that contain arrays. When you call another procedure, it typically ensures that old locations in the heap remain the same, but because your function takes the entire heap as an argument, and it&#39;s opaque, Boogie can&#39;t tell that this implies the function still holds. You can call reveal_func(), but presumably you hid it for a reason. One solution is to, when you need to prove func holds, is to do:<br /><pre>
calc ==&gt; {
true;
{ reveal_func(); }
func(dt_containing_array);
}
</pre></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:11:25 GMTUpdated Wiki: Arrays in datatypes 20141014111125PUpdated Wiki: Sequence-based invariantshttps://singularity.codeplex.com/wikipage?title=Sequence-based invariants&version=1<div class="wikidoc">If you have a loop whose invariant takes in more and more of a sequence with each iteration, DafnyCC will typically need you to explicitly assert the relationship between the old sequence and the new sequence. For instance:<br /><pre>
while j &lt; |a|
invariant a[..j] == b[..j];
{
a[j] := b[j];
assert a[..j+1] == a[..j] + [a[j]]; // this line added for DafnyCC&#39;s sake
assert b[..j+1] == b[..j] + [b[j]]; // this line added for DafnyCC&#39;s sake
j := j + 1;
}
</pre><br />This also applies to sequences derived from arrays. For instance, in the example above, the reminders above are necessary whether a and b are sequences or arrays.<br /><br /><br /></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:10:52 GMTUpdated Wiki: Sequence-based invariants 20141014111052PUpdated Wiki: Using DafnyCChttps://singularity.codeplex.com/wikipage?title=Using DafnyCC&version=1<div class="wikidoc">The Visual Studio plugin and the dafny.exe command line both use the Dafny compiler to verify your code. However, that&#39;s not good enough for Ironclad, whose aim is to verify every assembly instruction that will execute on the system. So although the Dafny plugin and command-line tool are useful pre-build checks to see if your code is verifiable, passing either is no guarantee you&#39;ll satisfy DafnyCC, which is what the ultimate build process uses. Most of the time, it will, but here are some guidelines to get your code in shape to also pass DafnyCC.<br /><br /><a href="https://singularity.codeplex.com/wikipage?title=Sequence-based%20invariants&referringTitle=Using%20DafnyCC">Sequence-based invariants</a><br /><a href="https://singularity.codeplex.com/wikipage?title=Arrays%20in%20datatypes&referringTitle=Using%20DafnyCC">Arrays in datatypes</a><br /><a href="https://singularity.codeplex.com/wikipage?title=Null%20arrays&referringTitle=Using%20DafnyCC">Null arrays</a><br /><a href="https://singularity.codeplex.com/wikipage?title=Automatic%20induction&referringTitle=Using%20DafnyCC">Automatic induction</a><br /><a href="https://singularity.codeplex.com/wikipage?title=Calc%20hiding&referringTitle=Using%20DafnyCC">Calc hiding</a><br /><a href="https://singularity.codeplex.com/wikipage?title=Mathematical%20_forall%20lemmas&referringTitle=Using%20DafnyCC">Mathematical _forall lemmas</a><br /><a href="https://singularity.codeplex.com/wikipage?title=Conservative%20sequence%20trigger&referringTitle=Using%20DafnyCC">Conservative sequence trigger</a><br /><a href="https://singularity.codeplex.com/wikipage?title=Debugging&referringTitle=Using%20DafnyCC">Debugging</a></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:10:29 GMTUpdated Wiki: Using DafnyCC 20141014111029PUpdated Wiki: Mathematical propertieshttps://singularity.codeplex.com/wikipage?title=Mathematical properties&version=3<div class="wikidoc">Since a lot of programming is math, a lot of code proofs involve mathematical proofs. Dafny uses Z3 to prove things, and Z3 knows a lot about math, so often Dafny will just &quot;get&quot; a lot of mathematical assertions you make. But sometimes you may write something that seems obvious that Dafny can&#39;t prove. In this case, it&#39;s useful to include one or more of the files from Libraries/Math and invoke one of the many fundamental mathematical theorems we&#39;ve already found a way to convince Dafny of. For instance, if you want to use the fact that x * (y + z) == (x * y) + (x * z) , then you can just invoke<br /><pre>
lemma_mul_is_distributive_add(x, y, z);
</pre><br /></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:09:38 GMTUpdated Wiki: Mathematical properties 20141014110938PUpdated Wiki: Mathematical propertieshttps://singularity.codeplex.com/wikipage?title=Mathematical properties&version=2<div class="wikidoc">Since a lot of programming is math, a lot of code proofs involve mathematical proofs. Dafny uses Z3 to prove things, and Z3 knows a lot about math, so often Dafny will just &quot;get&quot; a lot of mathematical assertions you make. But sometimes you may write something that seems obvious that Dafny can&#39;t prove. In this case, it&#39;s useful to include one or more of the files from Libraries/Math and invoke one of the many fundamental mathematical theorems we&#39;ve already found a way to convince Dafny of. For instance, if you want to use the fact that x * (y + z) == (x * y) + (x * z) , then you can just invoke<br /><br />lemma<i>mul</i>is<i>distributive</i>add(x, y, z);<br /><br /></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:09:24 GMTUpdated Wiki: Mathematical properties 20141014110924PUpdated Wiki: Mathematical propertieshttps://singularity.codeplex.com/wikipage?title=Mathematical properties&version=1<div class="wikidoc">Since a lot of programming is math, a lot of code proofs involve mathematical proofs. Dafny uses Z3 to prove things, and Z3 knows a lot about math, so often Dafny will just &quot;get&quot; a lot of mathematical assertions you make. But sometimes you may write something that seems obvious that Dafny can&#39;t prove. In this case, it&#39;s useful to include one or more of the files from Libraries/Math and invoke one of the many fundamental mathematical theorems we&#39;ve already found a way to convince Dafny of. For instance, if you want to use the fact that x * (y <u> z) == (x * y) </u> (x * z), then you can just invoke<br /><br />lemma<i>mul</i>is<i>distributive</i>add(x, y, z);<br /><br /></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:08:55 GMTUpdated Wiki: Mathematical properties 20141014110855PUpdated Wiki: Writing Dafny Codehttps://singularity.codeplex.com/wikipage?title=Writing Dafny Code&version=2<div class="wikidoc">If you want to change one of the apps, you&#39;ll need to edit or write new code. Most of our code is written in Dafny, so this section gives you some Ironclad-specific advice about how to code in Dafny. This section assumes you already have some familiarity with Dafny, e.g., from reading the online tutorial at <a href="https://singularity.codeplex.com/wikipage?title=http%3a%2f%2frise4fun.com%2fDafny%2ftutorial%2fguide&referringTitle=Writing%20Dafny%20Code">http&#58;&#47;&#47;rise4fun.com&#47;Dafny&#47;tutorial&#47;guide</a>.<br /><br /><a href="https://singularity.codeplex.com/wikipage?title=Mathematical%20properties&referringTitle=Writing%20Dafny%20Code">Mathematical properties</a></div><div class="ClearBoth"></div>howellTue, 14 Oct 2014 23:08:42 GMTUpdated Wiki: Writing Dafny Code 20141014110842P