<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>Random Walks</title>
  <link rel="self" type="application/atom+xml" href="https://randomwalks.xyz/atom.xml"/>
  <link rel="alternate" type="text/html" href="https://randomwalks.xyz"/>
  <generator uri="https://www.getzola.org/">Zola</generator>
  <id>https://randomwalks.xyz/atom.xml</id>
  
  
  
  
  <entry xml:lang="en">
    <title>Jolt System Mismatch</title>
    <published>2026-06-19T00:00:00+00:00</published>
    <updated>2026-06-19T00:00:00+00:00</updated>
    
      <author><name>Ari</name></author>
    
    <link rel="alternate" type="text/html" href="https://randomwalks.xyz/blog/jolt-qed/csrrw-bug/"/>
    <id>https://randomwalks.xyz/blog/jolt-qed/csrrw-bug/</id>
    
    <content type="html" xml:base="https://randomwalks.xyz/blog/jolt-qed/csrrw-bug/">&lt;h2 id=&quot;jolt-implementation-of-csrrw&quot;&gt;Jolt Implementation Of CSRRW&lt;a class=&quot;zola-anchor&quot; href=&quot;#jolt-implementation-of-csrrw&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Jolt supports the writing of 6 control status registers, namely,
&lt;code&gt;mstatus, mtvec, mepc, mtval, mscratch, mcause&lt;&#x2F;code&gt;; and it treats the writing to each of these registers uniformly.&lt;&#x2F;p&gt;
&lt;p&gt;The assembly signature is &lt;code&gt;csrrw rd, csr, rs1&lt;&#x2F;code&gt; and the pseudocode of semantics in the Jolt expansion is roughly:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if rd = x0 then &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    [vreg_csr] &amp;lt;- [rs1] + 0 -- implemented via ADDI&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if rd = rs1 then &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tmp &amp;lt;- [rs1] + 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    [rd] &amp;lt;- [vreg_csr] + 0 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    [v_reg_csr] &amp;lt;- tmp + 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;else &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    [rd] &amp;lt;- [vreg_csr]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    [v_reg_csr] &amp;lt;- [rs1]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This can be verified against the Jolt &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;blob&#x2F;ef62afb010ebb78b8ddf9bacc963730890373611&#x2F;crates&#x2F;jolt-program&#x2F;src&#x2F;expand&#x2F;control_flow&#x2F;csrrw.rs#L10&quot;&gt;source code&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;

&lt;aside class=&quot;callout callout-remark&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;Problem&lt;&#x2F;div&gt;
  
  &lt;p&gt;The &lt;strong&gt;issue&lt;&#x2F;strong&gt; is that the RISC-V specification does not treat writes to control status registers uniformly.
Depending on the status register being written to, the logic differs.&lt;&#x2F;p&gt;
&lt;p&gt;For &lt;code&gt;mscratch, mcause, mtval&lt;&#x2F;code&gt;, the above logic agrees with the RISC-V specification.
For the remaining three, the spec asks that we first legalize the value in &lt;code&gt;rs1&lt;&#x2F;code&gt; before writing it to the control status register.&lt;&#x2F;p&gt;
&lt;p&gt;More details below.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;h2 id=&quot;mtvec&quot;&gt;mtvec&lt;a class=&quot;zola-anchor&quot; href=&quot;#mtvec&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;As per the Sail spec, which we checked to be correct&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-mtvec-docs-1&quot;&gt;&lt;a href=&quot;#fn-mtvec-docs&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, the value written to the contents of &lt;code&gt;mtvec&lt;&#x2F;code&gt; control status register is given by&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;writeReg mtvec (← (legalize_tvec (← readReg mtvec) value))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;which in simple speak is saying first apply the &lt;code&gt;legalize_tvec&lt;&#x2F;code&gt; function with inputs the &lt;code&gt;old_mtvec&lt;&#x2F;code&gt; value and &lt;code&gt;rs1_value&lt;&#x2F;code&gt; and then write the control status register.
The &lt;code&gt;legalize_tvec&lt;&#x2F;code&gt; function is given by&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; legalize_tvec&lt;&#x2F;span&gt;&lt;span&gt; (o : (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;)) (v : (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;)) : SailM (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; v := (Mk_Mtvec v) -- identity function.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  match&lt;&#x2F;span&gt;&lt;span&gt; (trapVectorMode_of_bits (_get_Mtvec_Mode v)) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  | TV_Direct =&amp;gt; (pure v) -- we &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;have&lt;&#x2F;span&gt;&lt;span&gt; to prove that we are &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;in&lt;&#x2F;span&gt;&lt;span&gt; TV_Direct&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  | TV_Vector =&amp;gt; (pure v) -- or TV_Vector &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  | _ =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      match&lt;&#x2F;span&gt;&lt;span&gt; xtvec_mode_reserved_behavior &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      | Xtvec_Fatal =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (reserved_behavior&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          (HAppend.hAppend &lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;Tried to write a reserved value (&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            (HAppend.hAppend (Int.repr (BitVec.toNatInt (_get_Mtvec_Mode v)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;              &amp;quot;) to the MODE field of xtvec.&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      | Xtvec_Ignore =&amp;gt; (pure (_update_Mtvec_Mode v (_get_Mtvec_Mode o))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Given the functional-language nature of Lean, the above might seem hard to parse, but all that’s going on is the following:&lt;&#x2F;p&gt;
&lt;p&gt;The match statement is saying: get the lowest two bits of &lt;code&gt;rs1_val&lt;&#x2F;code&gt;.
If that value is &lt;code&gt;00&lt;&#x2F;code&gt; or &lt;code&gt;01&lt;&#x2F;code&gt;, then &lt;code&gt;[vreg_csr] &amp;lt;- [rs1_val]&lt;&#x2F;code&gt;, as in Jolt.
Otherwise, grab the two least-significant bits of &lt;code&gt;mtvec&lt;&#x2F;code&gt;, overwrite &lt;code&gt;rs1_val&lt;&#x2F;code&gt;’s lowest two bits with them, and then write this updated value into &lt;code&gt;mtvec&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;randomwalks.xyz&#x2F;blog&#x2F;jolt-qed&#x2F;csrrw-bug&#x2F;.&#x2F;mtvec.svg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now for the Jolt code to be correct, we must &lt;em&gt;prove&lt;&#x2F;em&gt; that the lowest two bits of &lt;code&gt;rs1_val&lt;&#x2F;code&gt; are always either &lt;code&gt;00&lt;&#x2F;code&gt; or &lt;code&gt;01&lt;&#x2F;code&gt;.
But Jolt does &lt;strong&gt;not&lt;&#x2F;strong&gt; promise this.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mepc&quot;&gt;mepc&lt;a class=&quot;zola-anchor&quot; href=&quot;#mepc&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;The first step is to read the old &lt;code&gt;mepc&lt;&#x2F;code&gt; value.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; ((bne access_type CSRWrite) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            then&lt;&#x2F;span&gt;&lt;span&gt; (read_CSR csr) -- read csr (we take this branch)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;            else&lt;&#x2F;span&gt;&lt;span&gt; (pure (zeros (n := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;))) ) : SailM xlenbits )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;which for &lt;code&gt;mepc&lt;&#x2F;code&gt; — whose 12-bit address is &lt;code&gt;0x341&lt;&#x2F;code&gt; — results in the call&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  | &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0x341&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt; (get_xepc Machine)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;which in turn returns&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(align_pc (← readReg mepc))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So in simple speak: we read the current value in the &lt;code&gt;mepc&lt;&#x2F;code&gt; register, and then align it first:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; align_pc&lt;&#x2F;span&gt;&lt;span&gt; (addr : (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;)) : SailM (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; ((← (currentlyEnabled Ext_Zca)) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  then&lt;&#x2F;span&gt;&lt;span&gt; (pure (BitVec.update addr &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0 0&lt;&#x2F;span&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  else&lt;&#x2F;span&gt;&lt;span&gt; (pure (Sail.BitVec.updateSubrange addr &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1 0&lt;&#x2F;span&gt;&lt;span&gt; (zeros (n := (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt; -i (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; -i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;))))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So the old value read from &lt;code&gt;mepc&lt;&#x2F;code&gt; is not the value before update (as Jolt assumes), but that value with its low bit cleared.
Note that because this hart enables &lt;code&gt;Ext_Zca&lt;&#x2F;code&gt; (&lt;code&gt;hartSupports Ext_Zca =&amp;gt; true&lt;&#x2F;code&gt;), the &lt;em&gt;active&lt;&#x2F;em&gt; branch is &lt;code&gt;BitVec.update addr 0 0#1&lt;&#x2F;code&gt;, which clears &lt;strong&gt;bit 0 only&lt;&#x2F;strong&gt;; the &lt;code&gt;else&lt;&#x2F;code&gt; branch clearing bits &lt;code&gt;[1:0]&lt;&#x2F;code&gt; is reached only when &lt;code&gt;Zca&lt;&#x2F;code&gt; is disabled.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-zca-1&quot;&gt;&lt;a href=&quot;#fn-zca&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Similarly, before writing to &lt;code&gt;mepc&lt;&#x2F;code&gt;, we compute:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; target := (legalize_xepc rs1_value)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;where&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; legalize_xepc&lt;&#x2F;span&gt;&lt;span&gt; (v : (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;)) : (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; ((hartSupports Ext_Zca) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  then&lt;&#x2F;span&gt;&lt;span&gt; (BitVec.update v &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0 0&lt;&#x2F;span&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  else&lt;&#x2F;span&gt;&lt;span&gt; (Sail.BitVec.updateSubrange v &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1 0&lt;&#x2F;span&gt;&lt;span&gt; (zeros (n := (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt; -i (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; -i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So both the read (&lt;code&gt;align_pc&lt;&#x2F;code&gt;) and the write (&lt;code&gt;legalize_xepc&lt;&#x2F;code&gt;) clear &lt;code&gt;mepc&lt;&#x2F;code&gt;’s low bits, whereas Jolt copies &lt;code&gt;rs1_val&lt;&#x2F;code&gt; into the virtual register verbatim (&lt;code&gt;[vreg_csr] &amp;lt;- [rs1] + 0&lt;&#x2F;code&gt;, via &lt;code&gt;ADDI&lt;&#x2F;code&gt;) and later reads it back verbatim.&lt;&#x2F;p&gt;
&lt;p&gt;Now for the Jolt code to be correct, we must &lt;em&gt;prove&lt;&#x2F;em&gt; that every value written to &lt;code&gt;mepc&lt;&#x2F;code&gt; is already aligned — i.e. bit 0 of &lt;code&gt;rs1_val&lt;&#x2F;code&gt; is always &lt;code&gt;0&lt;&#x2F;code&gt; (or bits &lt;code&gt;[1:0]&lt;&#x2F;code&gt; are &lt;code&gt;00&lt;&#x2F;code&gt; when &lt;code&gt;Zca&lt;&#x2F;code&gt; is disabled).
But this guard does not exist in Jolt.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mstatus&quot;&gt;mstatus&lt;a class=&quot;zola-anchor&quot; href=&quot;#mstatus&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;This is also a bug, but the write is more complex, in that I have to parse the following Lean code to give you the clean algorithm.
I’ll do this in a couple of days.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-- v = [rs1]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-- o = [mstatus]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; legalize_mstatus&lt;&#x2F;span&gt;&lt;span&gt; (o : (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;)) (v : (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;)) : SailM (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; v := (Mk_Mstatus v) -- overwrite v &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; o ← &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (pure (_update_Mstatus_SIE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (_update_Mstatus_MIE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;          (_update_Mstatus_SPIE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            (_update_Mstatus_MPIE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              (_update_Mstatus_VS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                (_update_Mstatus_SPP&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  (_update_Mstatus_MPP&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    (_update_Mstatus_FS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                      (_update_Mstatus_XS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                        (_update_Mstatus_MPRV&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                          (_update_Mstatus_SUM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                            (_update_Mstatus_MXR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                              (_update_Mstatus_TVM&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                (_update_Mstatus_TW&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                  (_update_Mstatus_TSR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                    (_update_Mstatus_SPELP&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                      (_update_Mstatus_MPELP o&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; ((hartSupports Ext_Zicfilp) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                        then&lt;&#x2F;span&gt;&lt;span&gt; (_get_Mstatus_MPELP v)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                        else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                      (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; ((hartSupports Ext_Zicfilp) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                      then&lt;&#x2F;span&gt;&lt;span&gt; (_get_Mstatus_SPELP v)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                      else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                    (← &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                      if&lt;&#x2F;span&gt;&lt;span&gt; ((← (currentlyEnabled Ext_S)) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                      then&lt;&#x2F;span&gt;&lt;span&gt; (pure (_get_Mstatus_TSR v))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                      else&lt;&#x2F;span&gt;&lt;span&gt; (pure &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                  (← &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                    if&lt;&#x2F;span&gt;&lt;span&gt; ((← (currentlyEnabled Ext_U)) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                    then&lt;&#x2F;span&gt;&lt;span&gt; (pure (_get_Mstatus_TW v))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                    else&lt;&#x2F;span&gt;&lt;span&gt; (pure &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                (← &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                  if&lt;&#x2F;span&gt;&lt;span&gt; ((← (currentlyEnabled Ext_S)) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                  then&lt;&#x2F;span&gt;&lt;span&gt; (pure (_get_Mstatus_TVM v))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                  else&lt;&#x2F;span&gt;&lt;span&gt; (pure &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                              (← &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                if&lt;&#x2F;span&gt;&lt;span&gt; ((← (currentlyEnabled Ext_S)) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                then&lt;&#x2F;span&gt;&lt;span&gt; (pure (_get_Mstatus_MXR v))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                                else&lt;&#x2F;span&gt;&lt;span&gt; (pure &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                            (← &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                              if&lt;&#x2F;span&gt;&lt;span&gt; ((← (virtual_memory_supported ())) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                              then&lt;&#x2F;span&gt;&lt;span&gt; (pure (_get_Mstatus_SUM v))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                              else&lt;&#x2F;span&gt;&lt;span&gt; (pure &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                          (← &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                            if&lt;&#x2F;span&gt;&lt;span&gt; ((← (currentlyEnabled Ext_U)) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                            then&lt;&#x2F;span&gt;&lt;span&gt; (pure (_get_Mstatus_MPRV v))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                            else&lt;&#x2F;span&gt;&lt;span&gt; (pure &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;))) (extStatus_to_bits Off))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                      (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; ((hartSupports Ext_Zfinx) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                      then&lt;&#x2F;span&gt;&lt;span&gt; (extStatus_to_bits Off)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                      else&lt;&#x2F;span&gt;&lt;span&gt; (_get_Mstatus_FS v)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    (← &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                      if&lt;&#x2F;span&gt;&lt;span&gt; ((← (have_nominal_privLevel (_get_Mstatus_MPP v))) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                      then&lt;&#x2F;span&gt;&lt;span&gt; (pure (_get_Mstatus_MPP v))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                      else&lt;&#x2F;span&gt;&lt;span&gt; (pure (privLevel_to_bits (← (lowest_supported_privLevel ()))))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  (← &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                    if&lt;&#x2F;span&gt;&lt;span&gt; ((← (currentlyEnabled Ext_S)) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                    then&lt;&#x2F;span&gt;&lt;span&gt; (pure (_get_Mstatus_SPP v))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                    else&lt;&#x2F;span&gt;&lt;span&gt; (pure &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; ((hartSupports Ext_Zve32x) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                then&lt;&#x2F;span&gt;&lt;span&gt; (_get_Mstatus_VS v)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;                else&lt;&#x2F;span&gt;&lt;span&gt; 0b00#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt;)) (_get_Mstatus_MPIE v))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            (← &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;              if&lt;&#x2F;span&gt;&lt;span&gt; ((← (currentlyEnabled Ext_S)) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;              then&lt;&#x2F;span&gt;&lt;span&gt; (pure (_get_Mstatus_SPIE v))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;              else&lt;&#x2F;span&gt;&lt;span&gt; (pure &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;))) (_get_Mstatus_MIE v))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (← &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;          if&lt;&#x2F;span&gt;&lt;span&gt; ((← (currentlyEnabled Ext_S)) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;          then&lt;&#x2F;span&gt;&lt;span&gt; (pure (_get_Mstatus_SIE v))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;          else&lt;&#x2F;span&gt;&lt;span&gt; (pure &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; dirty :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (((extStatus_of_bits (_get_Mstatus_FS o)) == Dirty) || (((extStatus_of_bits (_get_Mstatus_XS o)) == Dirty) || ((extStatus_of_bits&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            (_get_Mstatus_VS o)) == Dirty)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  (pure (_update_Mstatus_SD o (bool_to_bit dirty)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;mret-issue&quot;&gt;MRET Issue&lt;a class=&quot;zola-anchor&quot; href=&quot;#mret-issue&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Sail’s MRET handler does not merely produce a target PC. It first mutates mstatus and cur_privilege, then reads mepc through prepare_xret_target
Machine, then execute_MRET writes nextPC..&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Before MRET&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Jolt:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  pc              = current pc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  nextPC          = old nextPC&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  cur_privilege   = Machine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mepc            = return target&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MPP     = Machine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MIE     = old MIE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MPIE    = old MPIE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MPRV    = old MPRV&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Sail:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  PC              = current pc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  nextPC          = old nextPC&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  cur_privilege   = Machine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mepc            = return target&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MPP     = Machine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MIE     = old MIE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MPIE    = old MPIE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MPRV    = old MPRV&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;After MRET&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Jolt:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  pc &#x2F; nextPC      = mepc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  cur_privilege    = Machine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mepc             = unchanged&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MPP      = Machine      &amp;lt;-- unchanged&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MIE      = old MIE      &amp;lt;-- unchanged&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MPIE     = old MPIE     &amp;lt;-- unchanged&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MPRV     = old MPRV     &amp;lt;-- unchanged&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Sail:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  nextPC           = mepc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  cur_privilege    = Machine      &amp;lt;-- old mstatus.MPP&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mepc             = unchanged&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MPP      = User         &amp;lt;-- mismatch (No way to get this to align)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MIE      = old MPIE     &amp;lt;-- mismatch unless old MIE = old MPIE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MPIE     = 1            &amp;lt;-- mismatch unless old MPIE = 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus.MPRV     = old MPRV     &amp;lt;-- unchanged because cur_privilege remains Machine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The problem here is there is &lt;strong&gt;NO&lt;&#x2F;strong&gt; way to tell sail that that privilege level will not be lowered to user, as Jolt says by writing 1 to bit 20 of the misa that user mode is enabled.
So if that is the case, the sail spec says we &lt;strong&gt;MUST&lt;&#x2F;strong&gt; reduce privilege when returning from a trap.
Unfortunately, jolt is &lt;strong&gt;always&lt;&#x2F;strong&gt; in Machine mode.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;&#x2F;jolt-qed&#x2F;LeanRV64D&#x2F;SysControl.lean:677&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;writeReg mstatus (Sail.BitVec.updateSubrange (← readReg mstatus) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;12 11&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  (privLevel_to_bits&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (← &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      if&lt;&#x2F;span&gt;&lt;span&gt; ((← (currentlyEnabled Ext_U)) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      then&lt;&#x2F;span&gt;&lt;span&gt; (pure User)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      else&lt;&#x2F;span&gt;&lt;span&gt; (pure Machine))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;references&quot;&gt;References&lt;a class=&quot;zola-anchor&quot; href=&quot;#references&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;All claims above can also be checked against the official RISC-V ISA docs&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.riscv.org&#x2F;reference&#x2F;isa&#x2F;v20260120&#x2F;priv&#x2F;machine.html#3-1-1-7-machine-trap-vector-base-address-mtvec-register&quot;&gt;mtvec&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.riscv.org&#x2F;reference&#x2F;isa&#x2F;v20260120&#x2F;priv&#x2F;machine.html#3-1-1-14-machine-exception-program-counter-mepc-register&quot;&gt;mepc&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-mtvec-docs&quot;&gt;
&lt;p&gt;Checked against the official RISC-V privileged ISA, which defines &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.riscv.org&#x2F;reference&#x2F;isa&#x2F;v20260120&#x2F;priv&#x2F;machine.html#3-1-1-7-machine-trap-vector-base-address-mtvec-register&quot;&gt;&lt;code&gt;mtvec&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; as a &lt;strong&gt;WARL&lt;&#x2F;strong&gt; register whose &lt;code&gt;MODE&lt;&#x2F;code&gt; field has only the &lt;code&gt;Direct&lt;&#x2F;code&gt; (&lt;code&gt;0b00&lt;&#x2F;code&gt;) and &lt;code&gt;Vectored&lt;&#x2F;code&gt; (&lt;code&gt;0b01&lt;&#x2F;code&gt;) encodings. &lt;a href=&quot;#fr-mtvec-docs-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-zca&quot;&gt;
&lt;p&gt;&lt;code&gt;Zca&lt;&#x2F;code&gt; enables 16-bit (compressed) instructions. See the official &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.riscv.org&#x2F;reference&#x2F;isa&#x2F;v20240411&#x2F;unpriv&#x2F;zc.html&quot;&gt;Zc* specification&lt;&#x2F;a&gt;. &lt;a href=&quot;#fr-zca-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
  </entry>
  
  
  
  <entry xml:lang="en">
    <title>Equivalence Statements And Assumptions</title>
    <published>2026-05-22T00:00:00+00:00</published>
    <updated>2026-05-22T00:00:00+00:00</updated>
    
      <author><name>Ari</name></author>
    
    <link rel="alternate" type="text/html" href="https://randomwalks.xyz/blog/jolt-qed/assumptions/"/>
    <id>https://randomwalks.xyz/blog/jolt-qed/assumptions/</id>
    
    <content type="html" xml:base="https://randomwalks.xyz/blog/jolt-qed/assumptions/">&lt;p&gt;The Jolt-qed project verifies, in Lean, that each Jolt bytecode expansion has the same effect as the RISC-V instruction it replaces.
These equivalence theorems are not unconditional: they rely on explicit hypotheses about the RISC-V&#x2F;Jolt state, plus a small number of trusted edits to the generated RISC-V model so that it matches the Jolt CPU.
This post records those proof assumptions and trusted-code changes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;changes-to-the-trusted-risc-v-model&quot;&gt;Changes to the Trusted RISC-V Model&lt;a class=&quot;zola-anchor&quot; href=&quot;#changes-to-the-trusted-risc-v-model&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;The Lean RISC-V model lives in &lt;code&gt;LeanRV64D&#x2F;&lt;&#x2F;code&gt;, with the top-level entry point in &lt;code&gt;LeanRV64D.lean&lt;&#x2F;code&gt;.
It was generated by automatically transpiling the Sail specification of a RISC-V CPU to Lean&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-att-1&quot;&gt;&lt;a href=&quot;#fn-att&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.
The &lt;a href=&quot;https:&#x2F;&#x2F;randomwalks.xyz&#x2F;blog&#x2F;sail-to-lean&#x2F;&quot;&gt;Sail-to-Lean post&lt;&#x2F;a&gt; explains how we obtained this generated code.
We treat that generated model as trusted throughout the project, except for the two changes below.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;We say that the RISC-V CPU should not support misaligned memory addressing. We do this because Jolt does not support misaligned addressing, and it would be impossible to prove equivalence otherwise. The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;zkevm.ethereum.foundation&#x2F;blog&#x2F;zkevm-standards-v0-release&quot;&gt;Ethereum zkVM Standards v0&lt;&#x2F;a&gt; recommend that zk-VMs use &lt;code&gt;RV64IM+Zicclsm&lt;&#x2F;code&gt; as the target baseline, where &lt;code&gt;Zicclsm&lt;&#x2F;code&gt; is included to support misaligned loads and stores. We highlight this drawback off the bat.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;LeanRV64D&#x2F;PlatformConfig.lean:205-206&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-- WARNING: CHANGE IN TRANSPILED CODE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; plat_enable_misaligned_access&lt;&#x2F;span&gt;&lt;span&gt; : Bool := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Jolt does not support the Zicfiss and Zicfilp extensions. Leaving them on makes it impossible to prove equivalences about writing to control status registers.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;LeanRV64D&#x2F;Extensions.lean:714-717&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-- WARNING: (change to sail, Jolt does not support Zicfilp extension).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| Ext_Zicfilp =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-- WARNING: (change to sail, Jolt does not support Zicfiss extension).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| Ext_Zicfiss =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;These are the only changes we make to the generated RISC-V model.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;equivalence-statement-structure&quot;&gt;Equivalence Statement Structure&lt;a class=&quot;zola-anchor&quot; href=&quot;#equivalence-statement-structure&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Shown below is the equivalence statement for the &lt;code&gt;sra&lt;&#x2F;code&gt; instruction.
It says that running the Jolt instruction &lt;code&gt;sraProgram&lt;&#x2F;code&gt; with arguments &lt;code&gt;rd rs2 rs1&lt;&#x2F;code&gt; on the current Jolt state &lt;code&gt;js&lt;&#x2F;code&gt;, and then projecting down to the RISC-V state, is identical to running &lt;code&gt;sra rd rs2 rs1&lt;&#x2F;code&gt; on the RISC-V state of the current Jolt CPU.
In simple words, we could either run the original RISC-V instruction or run the Jolt expansion on the same starting state, and the effect is the same.
If we showed this for all RISC-V instructions, then we would show that Jolt faithfully simulates RISC-V.
Now to prove this theorem, we use an assumption bundle.
The goal of this post is to explain what an assumption bundle is.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Main program-level equivalence for `SRA`. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; sraProgramEqSailStatement&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;    (rs2 : regidx)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;    (rs1 : regidx)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;    (rd : regidx)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    (js : SailJoltState)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;    (_h : BinarySourceReadWithLinkedCSRs rs2 rs1 js) -- &amp;lt;--- Assumption bundle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;  : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop&lt;&#x2F;span&gt;&lt;span&gt; :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;  System.systemProjectResult&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;      ((JoltISA.execProgram (JoltISA.sraProgram rs2 rs1 rd)).run js) =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span&gt;    (execute_RTYPE rs2 rs1 rd rop.SRA).run js.sail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Assumption bundles are conjunctions of assumptions defined in &lt;code&gt;JoltBytecode&#x2F;Assumptions.lean&lt;&#x2F;code&gt; and collected in &lt;code&gt;JoltBytecode&#x2F;Bundles.lean&lt;&#x2F;code&gt;.
Each equivalence statement in Jolt-qed uses an assumption bundle.
Bundles describe exactly which assumptions were used to prove equivalence for a given instruction.
An assumption bundle is &lt;strong&gt;always&lt;&#x2F;strong&gt; made up of a list of assumptions&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-help-1&quot;&gt;&lt;a href=&quot;#fn-help&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This specific assumption bundle is made up of the two groups of assumptions shown below.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;abbrev&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; BinarySourceReadAssumptions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (rs2 rs1 : regidx) (js : SailJoltState) :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  Assumptions.BinarySourceReadAssumptions rs2 rs1 js.sail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;private structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; LinkedCSRRegisterAssumptions&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mstatus_matches : Assumptions.MstatusVRegMatchesSail js&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mtvec_matches : Assumptions.MtvecVRegMatchesSail js&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mscratch_matches : Assumptions.MscratchVRegMatchesSail js&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mepc_matches : Assumptions.MepcVRegMatchesSail js&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mcause_matches : Assumptions.McauseVRegMatchesSail js&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mtval_matches : Assumptions.MtvalVRegMatchesSail js&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We will explain what these mean below, but the takeaway message is that every equivalence theorem uses an assumption bundle.
Any assumption bundle can only be made up of core assumptions listed in &lt;code&gt;Assumptions.lean&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;assumptions&quot;&gt;Assumptions&lt;a class=&quot;zola-anchor&quot; href=&quot;#assumptions&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;For the rest of the document, we list every assumption used in Jolt.
If any assumption that is not listed here, or in &lt;code&gt;Assumptions.lean&lt;&#x2F;code&gt;, is used in a proof bundle, then that should be remedied immediately, and we should check whether the assumption is justified.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;privilege-is-always-machine&quot;&gt;Privilege Is Always Machine&lt;a class=&quot;zola-anchor&quot; href=&quot;#privilege-is-always-machine&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; CurPrivilegeMachine&lt;&#x2F;span&gt;&lt;span&gt; (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  value : s.regs.get? Register.cur_privilege =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    some (Privilege.Machine : RegisterType Register.cur_privilege)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In simple English, the value in &lt;code&gt;current_privilege&lt;&#x2F;code&gt; indicates that the Jolt CPU runs in machine mode all the time.
According to the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;blob&#x2F;main&#x2F;tracer&#x2F;src&#x2F;emulator&#x2F;cpu.rs:329-353&quot;&gt;Jolt Rust code base&lt;&#x2F;a&gt;, Jolt always runs in machine mode.
The above Lean code simply states that the value in the &lt;code&gt;cur_privilege&lt;&#x2F;code&gt; register is &lt;code&gt;Privilege.Machine&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mpp-bit-set-to-machine&quot;&gt;MPP Bit Set To Machine&lt;a class=&quot;zola-anchor&quot; href=&quot;#mpp-bit-set-to-machine&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MstatusMppMachine&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  value_eq :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _get_Mstatus_MPP (js.vregs JoltISA.mstatusVReg) =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      privLevel_to_bits Privilege.Machine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Jolt uses virtual register 39 to model the &lt;code&gt;mstatus&lt;&#x2F;code&gt; control status register of the Jolt CPU.
Based on the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;blob&#x2F;main&#x2F;tracer&#x2F;src&#x2F;instruction&#x2F;mret.rs#L7-L18&quot;&gt;Jolt source code&lt;&#x2F;a&gt;, Jolt always runs in machine mode, and the MPP bit of the status register is always set to &lt;code&gt;Machine&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;misa-user-enabled&quot;&gt;MISA User Enabled&lt;a class=&quot;zola-anchor&quot; href=&quot;#misa-user-enabled&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MisaUserEnabled&lt;&#x2F;span&gt;&lt;span&gt; (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  exists_value : ∃ misa : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    s.regs.get? Register.misa = some (misa : RegisterType Register.misa) ∧&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _get_Misa_U misa = &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Jolt initialises &lt;code&gt;misa&lt;&#x2F;code&gt; to &lt;code&gt;0x800000008014312f&lt;&#x2F;code&gt; based on &lt;code&gt;jolt&#x2F;tracer&#x2F;src&#x2F;emulator&#x2F;cpu.rs:399&lt;&#x2F;code&gt;.
The function &lt;code&gt;_get_Misa_U&lt;&#x2F;code&gt; reads bit 20 of the &lt;code&gt;misa&lt;&#x2F;code&gt; CSR, which, based on the written value, is 1.
According to the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.riscv.org&#x2F;reference&#x2F;isa&#x2F;v20260120&#x2F;priv&#x2F;machine.html&quot;&gt;RISC-V ISA&lt;&#x2F;a&gt;, having bit 20 set to 1 implies user mode is enabled.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mprv-bit&quot;&gt;MPRV Bit&lt;a class=&quot;zola-anchor&quot; href=&quot;#mprv-bit&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MstatusMprvZero&lt;&#x2F;span&gt;&lt;span&gt; (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  value : ∃ mval : RegisterType Register.mstatus,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    s.regs.get? Register.mstatus = some mval ∧&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _get_Mstatus_MPRV mval = &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;According to &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;blob&#x2F;main&#x2F;tracer&#x2F;src&#x2F;emulator&#x2F;mmu.rs:870-898&quot;&gt;Jolt&lt;&#x2F;a&gt;, the &lt;code&gt;MPRV&lt;&#x2F;code&gt; bit of the &lt;code&gt;mstatus&lt;&#x2F;code&gt; register is set to 0 in Jolt.
As a direct consequence of this, we get bare translation: virtual addresses are the same as physical addresses, which is also true in the Jolt code base.
In Lean, this is captured by the following three bare-translation theorems for loads, stores, and atomics.
We only show the theorem statements here; the proofs are in &lt;code&gt;JoltBytecode&#x2F;InstructionEquivalence&#x2F;ProofSupport&#x2F;BundleLemmas.lean&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;theorem&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; translateAddr_load_data_of_machine_mprv_zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (addr : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (s : SailState)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (hpriv : Assumptions.CurPrivilegeMachine s)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (hmprv : Assumptions.MstatusMprvZero s) :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    translateAddr (Virtaddr addr) (Load Data) s =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      .ok (Ok (physaddr.Physaddr addr, init_ext_ptw)) s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;theorem&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; translateAddr_store_data_of_machine_mprv_zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (addr : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (s : SailState)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (hpriv : Assumptions.CurPrivilegeMachine s)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (hmprv : Assumptions.MstatusMprvZero s) :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    translateAddr (Virtaddr addr) (Store Data) s =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      .ok (Ok (physaddr.Physaddr addr, init_ext_ptw)) s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;theorem&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; translateAddr_atomic_data_of_machine_mprv_zero&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (op : amoop) (addr : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (s : SailState)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (hpriv : Assumptions.CurPrivilegeMachine s)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (hmprv : Assumptions.MstatusMprvZero s) :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    translateAddr (Virtaddr addr) (Atomic (op, Data, Data)) s =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      .ok (Ok (physaddr.Physaddr addr, init_ext_ptw)) s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;zicfilp-extension&quot;&gt;Zicfilp Extension&lt;a class=&quot;zola-anchor&quot; href=&quot;#zicfilp-extension&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; ZicfilpDisabled&lt;&#x2F;span&gt;&lt;span&gt; (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  value : currentlyEnabled extension.Ext_Zicfilp s = .ok &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Jolt does not support the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.riscv.org&#x2F;reference&#x2F;isa&#x2F;v20260120&#x2F;priv&#x2F;priv-cfi.html&quot;&gt;Zicfilp extension&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mtvec&quot;&gt;Mtvec&lt;a class=&quot;zola-anchor&quot; href=&quot;#mtvec&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MtvecWriteDirectMode&lt;&#x2F;span&gt;&lt;span&gt; (value : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mode_eq : _get_Mtvec_Mode value = 0b00#&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The RISC-V ISA requires that we legalise values before writing to control and status registers.
&lt;a href=&quot;https:&#x2F;&#x2F;randomwalks.xyz&#x2F;blog&#x2F;jolt-qed&#x2F;csrrw-bug&#x2F;&quot;&gt;See this blog&lt;&#x2F;a&gt; for more details.
When writing the contents of &lt;code&gt;rs1&lt;&#x2F;code&gt; into the &lt;code&gt;mtvec&lt;&#x2F;code&gt; control and status register, if the value in &lt;code&gt;rs1&lt;&#x2F;code&gt; has the two least significant bits set to &lt;code&gt;00&lt;&#x2F;code&gt;, then we write &lt;code&gt;rs1&lt;&#x2F;code&gt;’s contents directly into &lt;code&gt;mtvec&lt;&#x2F;code&gt;.
Otherwise, we need to legalise the value.
The above assumption says the value in &lt;code&gt;rs1&lt;&#x2F;code&gt; will &lt;strong&gt;always&lt;&#x2F;strong&gt; have the lower two bits set to &lt;code&gt;00&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The ZeroOS&#x2F;Jolt boot path writes &lt;code&gt;_trap_handler&lt;&#x2F;code&gt; to &lt;code&gt;mtvec&lt;&#x2F;code&gt; with&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;csrw mtvec, t0&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;ZeroOS defines &lt;code&gt;_trap_handler&lt;&#x2F;code&gt; under &lt;code&gt;.align 2&lt;&#x2F;code&gt;, which gives 4-byte
alignment, so the lower two bits are &lt;code&gt;00&lt;&#x2F;code&gt;.
Evidence from ZeroOS source code is given below.&lt;&#x2F;p&gt;
&lt;p&gt;The ZeroOS boot code &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;LayerZero-Labs&#x2F;ZeroOS&#x2F;blob&#x2F;main&#x2F;platforms&#x2F;spike-platform&#x2F;src&#x2F;boot.rs#L13-L19&quot;&gt;writes&lt;&#x2F;a&gt;
to &lt;code&gt;mtvec&lt;&#x2F;code&gt;, and the trap handler definition is &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;LayerZero-Labs&#x2F;ZeroOS&#x2F;blob&#x2F;main&#x2F;crates&#x2F;zeroos-arch-riscv&#x2F;src&#x2F;trap.rs#L308-L316&quot;&gt;aligned&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;

&lt;aside class=&quot;callout callout-remark&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;Warning&lt;&#x2F;div&gt;
  
  &lt;p&gt;This assumption holds when we use the write to &lt;code&gt;mtvec&lt;&#x2F;code&gt; operation as it is meant to be used in Jolt.
If a malicious program were to write a different value to Jolt &lt;code&gt;mtvec&lt;&#x2F;code&gt;, Jolt does not have any mechanism to legalise the value. In that case, Jolt would not be following the RISC-V spec.
We will rely on the proof mechanism to catch this.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;h3 id=&quot;align-pc&quot;&gt;Align PC&lt;a class=&quot;zola-anchor&quot; href=&quot;#align-pc&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Jolt supports compressed instructions (&lt;code&gt;+c&lt;&#x2F;code&gt; &#x2F; RV64IMAC), &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;LayerZero-Research&#x2F;jolt&#x2F;blob&#x2F;main&#x2F;jolt-sdk&#x2F;src&#x2F;runtime&#x2F;trap.rs#L18-L34&quot;&gt;as seen here&lt;&#x2F;a&gt;, so we can only guarantee that the least significant bit of PC is 0.
The relevant assumption is that &lt;code&gt;mepc[0] = 0&lt;&#x2F;code&gt;.
Thus, the legalisation operation according to the specification is a no-op because the lowest bit is already cleared.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MepcReadAligned&lt;&#x2F;span&gt;&lt;span&gt; (value : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  value_eq : align_pc value s = .ok value s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is the write-side counterpart of &lt;code&gt;MepcReadAligned&lt;&#x2F;code&gt;: CSRRW writes the new
&lt;code&gt;rs1&lt;&#x2F;code&gt; value, so the assumption must be about that source value rather than only
the old stored &lt;code&gt;mepc&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MepcWriteLegalized&lt;&#x2F;span&gt;&lt;span&gt; (value : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  value_eq : legalize_xepc value = value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;legalise-mstatus&quot;&gt;Legalise MStatus&lt;a class=&quot;zola-anchor&quot; href=&quot;#legalise-mstatus&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MstatusWriteLegalized&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (old value : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  value_eq : legalize_mstatus old value s = .ok value s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Jolt does not legalise before writing to &lt;code&gt;mstatus&lt;&#x2F;code&gt;.
The evidence is in the Jolt CSR expansions: &lt;code&gt;CSRRW&lt;&#x2F;code&gt; writes &lt;code&gt;rs1&lt;&#x2F;code&gt; directly into the CSR virtual register, and &lt;code&gt;CSRRS&lt;&#x2F;code&gt; writes the OR of the old CSR value and &lt;code&gt;rs1&lt;&#x2F;code&gt;.
See &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;blob&#x2F;main&#x2F;crates&#x2F;jolt-program&#x2F;src&#x2F;expand&#x2F;control_flow&#x2F;csrrw.rs#L17-L63&quot;&gt;&lt;code&gt;csrrw.rs&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;blob&#x2F;main&#x2F;crates&#x2F;jolt-program&#x2F;src&#x2F;expand&#x2F;control_flow&#x2F;csrrs.rs#L26-L74&quot;&gt;&lt;code&gt;csrrs.rs&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;virtual-register-modelling&quot;&gt;Virtual Register Modelling&lt;a class=&quot;zola-anchor&quot; href=&quot;#virtual-register-modelling&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Here we are saying that certain virtual registers in Jolt correspond to the control status registers in the Sail state.
We could have written directly to the Sail registers in our Jolt semantics, but to be faithful to the Jolt expansion, we write the virtual registers and record that correspondence as an assumption.
The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;tree&#x2F;main&#x2F;crates&#x2F;jolt-program&#x2F;src&#x2F;expand&#x2F;allocator.rs&quot;&gt;Jolt code&lt;&#x2F;a&gt; confirms this.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Sail `mstatus` agrees with Jolt&amp;#39;s persistent `mstatus` virtual register. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MstatusVRegMatchesSail&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  value_eq :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    js.sail.regs.get? Register.mstatus =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      some (js.vregs JoltISA.mstatusVReg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Sail `mtvec` agrees with Jolt&amp;#39;s persistent trap-handler virtual register. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MtvecVRegMatchesSail&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  value_eq :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    js.sail.regs.get? Register.mtvec =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      some (js.vregs JoltISA.trapHandlerVReg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Sail `mscratch` agrees with Jolt&amp;#39;s persistent `mscratch` virtual register. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MscratchVRegMatchesSail&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  value_eq :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    js.sail.regs.get? Register.mscratch =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      some (js.vregs JoltISA.mscratchVReg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Sail `mepc` agrees with Jolt&amp;#39;s persistent `mepc` virtual register. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MepcVRegMatchesSail&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  value_eq :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    js.sail.regs.get? Register.mepc =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      some (js.vregs JoltISA.mepcVReg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Sail `mcause` agrees with Jolt&amp;#39;s persistent `mcause` virtual register. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; McauseVRegMatchesSail&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  value_eq :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    js.sail.regs.get? Register.mcause =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      some (js.vregs JoltISA.mcauseVReg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Sail `mtval` agrees with Jolt&amp;#39;s persistent `mtval` virtual register. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MtvalVRegMatchesSail&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  value_eq :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    js.sail.regs.get? Register.mtval =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      some (js.vregs JoltISA.mtvalVReg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;memory-assumptions&quot;&gt;Memory Assumptions&lt;a class=&quot;zola-anchor&quot; href=&quot;#memory-assumptions&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; DwordPresent&lt;&#x2F;span&gt;&lt;span&gt; (addr : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  bytes :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ∃ bytes : Fin &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt; → BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ∀ k : Fin &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;, s.mem.get? (addr.toNat + k.val) = some (bytes k)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Lean models memory as a hash map from natural numbers to 8-bit bitstrings.
The natural numbers are countably infinite, while the address space of any CPU is not.
Additionally, because memory is modelled as a hash map, Lean needs a hypothesis that the key already exists before it can retrieve the value.
This is a proof-engineering issue: the generated model represents memory as a partial map, so we must state that the relevant bytes are present.
Thus, the following assumption says that addresses can be read from memory and that they return valid bytes across the entire doubleword window.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;abbrev&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; LoadPmpOk&lt;&#x2F;span&gt;&lt;span&gt; (addr : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (width : Nat) (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop&lt;&#x2F;span&gt;&lt;span&gt; :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  phys_access_check (Load Data) Privilege.Machine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (physaddr.Physaddr addr) width &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span&gt; s = .ok none s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Machine-mode PMP accepts every explicit sub-load inside a memory window. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; LoadPmpOkWindow&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (base : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (width : Nat) (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ok :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ∀ offset accessWidth : Nat, offset + accessWidth ≤ width →&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      LoadPmpOk (base + BitVec.ofNat &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt; offset) accessWidth s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;abbrev&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; StorePmpOk&lt;&#x2F;span&gt;&lt;span&gt; (addr : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (width : Nat) (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop&lt;&#x2F;span&gt;&lt;span&gt; :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  phys_access_check (Store Data) Privilege.Machine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (physaddr.Physaddr addr) width &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span&gt; s = .ok none s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Machine-mode PMP accepts every explicit sub-store inside a memory window. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; StorePmpOkWindow&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (base : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (width : Nat) (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ok :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ∀ offset accessWidth : Nat, offset + accessWidth ≤ width →&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      StorePmpOk (base + BitVec.ofNat &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt; offset) accessWidth s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;abbrev&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; AtomicPmpOk&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (op : amoop) (addr : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (width : Nat) (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop&lt;&#x2F;span&gt;&lt;span&gt; :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  phys_access_check (Atomic (op, Data, Data)) Privilege.Machine&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (physaddr.Physaddr addr) width &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt; s = .ok none s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Machine-mode PMP accepts every explicit sub-AMO inside a memory window. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; AtomicPmpOkWindow&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (op : amoop) (base : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (width : Nat) (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ok :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ∀ offset accessWidth : Nat, offset + accessWidth ≤ width →&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      AtomicPmpOk op (base + BitVec.ofNat &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt; offset) accessWidth s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Jolt’s Rust MMU explicitly says memory protection is not implemented. These
predicates constrain the generated RISC-V model to the corresponding no-PMP-fault path.&lt;&#x2F;p&gt;
&lt;p&gt;Rust source: &lt;code&gt;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;blob&#x2F;main&#x2F;tracer&#x2F;src&#x2F;emulator&#x2F;mmu.rs#L17&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The above assumption says the entire doubleword block read by &lt;code&gt;LD&lt;&#x2F;code&gt; at physical address &lt;code&gt;addr&lt;&#x2F;code&gt; is not protected and can be read.
The same applies to writing to memory.
To prove equivalence, we need to tell the generated RISC-V model that the address is safe to read from or write to.
The generated RISC-V model uses different checks for &lt;code&gt;LD&lt;&#x2F;code&gt;, &lt;code&gt;SD&lt;&#x2F;code&gt;, and atomic operations, so we need three sets of assumptions that say the same thing.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;abbrev&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; NotReadableMmio&lt;&#x2F;span&gt;&lt;span&gt; (addr : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (width : Nat) (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop&lt;&#x2F;span&gt;&lt;span&gt; :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  within_mmio_readable (physaddr.Physaddr addr) width s = .ok &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; NotReadableMmioWindow&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (base : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (width : Nat) (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ok :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ∀ offset accessWidth : Nat, offset + accessWidth ≤ width →&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      NotReadableMmio (base + BitVec.ofNat &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt; offset) accessWidth s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;abbrev&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; NotWritableMmio&lt;&#x2F;span&gt;&lt;span&gt; (addr : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (width : Nat) (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop&lt;&#x2F;span&gt;&lt;span&gt; :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  within_mmio_writable (physaddr.Physaddr addr) width s = .ok &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Every explicit sub-store inside a memory window avoids writable MMIO. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; NotWritableMmioWindow&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (base : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (width : Nat) (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ok :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ∀ offset accessWidth : Nat, offset + accessWidth ≤ width →&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      NotWritableMmio (base + BitVec.ofNat &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt; offset) accessWidth s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Rust source: &lt;code&gt;tracer&#x2F;src&#x2F;emulator&#x2F;mmu.rs:139-213&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Jolt splits VM memory into reserved low-memory regions for advice, inputs,
outputs, panic, and termination, followed by ordinary RAM. These regions share
one VM address space and are mapped into the memory witness layout.
Ordinary RAM is backed by the emulator memory map, while advice&#x2F;input&#x2F;output are modelled by &lt;code&gt;JoltDevice&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Jolt does not support device MMIO such as UART, CLINT, PLIC, or disk; accesses to those ranges panic in the tracer. On the generated RISC-V side, memory operations can branch on memory-mapped device addresses, so the proof needs assumptions such as &lt;code&gt;NotReadableMmio&lt;&#x2F;code&gt; and &lt;code&gt;NotWritableMmio&lt;&#x2F;code&gt; to keep execution on the ordinary&#x2F;Jolt-supported memory path.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;register-assumptions&quot;&gt;Register Assumptions&lt;a class=&quot;zola-anchor&quot; href=&quot;#register-assumptions&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; XRegReadable&lt;&#x2F;span&gt;&lt;span&gt; (r : regidx) (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  exists_value : ∃ value : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;, rX_bits r s = .ok value s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; SailRegReadable&lt;&#x2F;span&gt;&lt;span&gt; (r : Register) (s : SailState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  exists_value : ∃ value : RegisterType r, s.regs.get? r = some value&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Assumptions for an instruction that reads one architectural source register. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; UnarySourceReadAssumptions&lt;&#x2F;span&gt;&lt;span&gt; (rs1 : regidx) (s : SailState) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  rs1_val : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  rs1_read : rX_bits rs1 s = .ok rs1_val s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Assumptions for an instruction that reads two architectural source registers. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; BinarySourceReadAssumptions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (rs2 rs1 : regidx) (s : SailState) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  rs1_val : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  rs1_read : rX_bits rs1 s = .ok rs1_val s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  rs2_val : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  rs2_read : rX_bits rs2 s = .ok rs2_val s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;These assumptions say that the Sail register file is readable.&lt;&#x2F;p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-att&quot;&gt;
&lt;p&gt;This translation was done by Galois and researchers at Cambridge University. See the Sail-to-Lean post for further details. &lt;a href=&quot;#fr-att-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-help&quot;&gt;
&lt;p&gt;We could not figure out a way to get the Lean kernel to enforce this in a clean manner without completely redoing the project.
So we do this manually by enforcing that each field uses something from the &lt;code&gt;Assumptions&lt;&#x2F;code&gt; namespace. If you, the reader, know a better way to do this, please reach out with a pull request. &lt;a href=&quot;#fr-help-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
  </entry>
  
  
  
  <entry xml:lang="en">
    <title>Jolt: Introduction</title>
    <published>2026-05-22T00:00:00+00:00</published>
    <updated>2026-05-22T00:00:00+00:00</updated>
    
      <author><name>Ari</name></author>
    
    <link rel="alternate" type="text/html" href="https://randomwalks.xyz/blog/jolt-qed/jolt-why/"/>
    <id>https://randomwalks.xyz/blog/jolt-qed/jolt-why/</id>
    
    <content type="html" xml:base="https://randomwalks.xyz/blog/jolt-qed/jolt-why/">&lt;h2 id=&quot;jolt-a-birds-eye-view&quot;&gt;Jolt - a Birds Eye View&lt;a class=&quot;zola-anchor&quot; href=&quot;#jolt-a-birds-eye-view&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;A user supplies a guest program&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-inlines-1&quot;&gt;&lt;a href=&quot;#fn-inlines&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; (a RISC-V elf) to Jolt.
Jolt runs this program, and writes any outputs on the output tape, along with a proof.
A proof is simply another program that the user runs to get output 0 or 1.
If the output of the proof is 1, then the user agrees&lt;&#x2F;p&gt;
&lt;h2 id=&quot;trace-to-polynomials&quot;&gt;Trace to Polynomials&lt;a class=&quot;zola-anchor&quot; href=&quot;#trace-to-polynomials&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-inlines&quot;&gt;
&lt;p&gt;Technically this statement is not strictly true. The input also allows some custom instructions that are not native RISC-V instructions. &lt;a href=&quot;#fr-inlines-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
  </entry>
  
  
  
  <entry xml:lang="en">
    <title>How to Model a CPU in Lean</title>
    <published>2026-05-22T00:00:00+00:00</published>
    <updated>2026-05-22T00:00:00+00:00</updated>
    
      <author><name>Ari</name></author>
    
    <link rel="alternate" type="text/html" href="https://randomwalks.xyz/blog/jolt-qed/state/"/>
    <id>https://randomwalks.xyz/blog/jolt-qed/state/</id>
    
    <content type="html" xml:base="https://randomwalks.xyz/blog/jolt-qed/state/">&lt;p&gt;To prove equivalence with a RISC-V CPU, we first need a RISC-V CPU modeled in Lean.
Luckily for us, the teams at &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;opencompl&#x2F;sail-riscv-lean&quot;&gt;Galois&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;opencompl&#x2F;sail-riscv-lean&quot;&gt;Cambridge University&lt;&#x2F;a&gt; have done the hard work for us.
Given a Sail specification of a RISC-V CPU, they translated the Sail specification into non-executable Lean code suitable for theorem proving.
The details of how to get this code can be found &lt;a href=&quot;https:&#x2F;&#x2F;randomwalks.xyz&#x2F;blog&#x2F;sail-to-lean&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Our starting point will be to understand this transpilation.
At its core, a CPU is just a state machine whose state is described by the register file, memory, program counter, control&#x2F;status registers, and so on&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-risc-v-isa-1&quot;&gt;&lt;a href=&quot;#fn-risc-v-isa&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.
Instructions describe the ways the machine can transition between states.
Of course, there are also the mechanics of how a state transition physically works.
For example, on a silicon chip, the CPU emits an address on a bus, and the memory decoder reads this address, selects the matching memory cell, and drives its stored bits back onto the data bus where the CPU latches them into a register.
We will not focus on the mechanics of how state transitions happen on a physical chip or in software emulation.
Our concern is what happens before and after a state transition.
From here on, we refer to the trusted Sail-to-Lean transpilation as Sail code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;state&quot;&gt;State&lt;a class=&quot;zola-anchor&quot; href=&quot;#state&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;The RISC-V state, abbreviated as &lt;code&gt;SailState&lt;&#x2F;code&gt;, is given by:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;JoltBytecode&#x2F;JoltISA&#x2F;Core.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;abbrev&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; SailState&lt;&#x2F;span&gt;&lt;span&gt; := SequentialState RegisterType trivialChoiceSource&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here, &lt;code&gt;SequentialState&lt;&#x2F;code&gt; describes the full machine state from the Sail model.
It is parameterized&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-dep-1&quot;&gt;&lt;a href=&quot;#fn-dep&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; by the function &lt;code&gt;RegisterType : Register → Type&lt;&#x2F;code&gt; and a &lt;code&gt;ChoiceSource&lt;&#x2F;code&gt;.
The register file and memory are fields of the structure with details described below.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;.lake&#x2F;packages&#x2F;Sail&#x2F;Sail&#x2F;Sail.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;467&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; SequentialState&lt;&#x2F;span&gt;&lt;span&gt; (RegisterType : Register → &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Type&lt;&#x2F;span&gt;&lt;span&gt;) (c : ChoiceSource) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;468&lt;&#x2F;span&gt;&lt;span&gt;  regs : Std.ExtDHashMap Register RegisterType&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;469&lt;&#x2F;span&gt;&lt;span&gt;  choiceState : c.α&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;470&lt;&#x2F;span&gt;&lt;span&gt;  mem : Std.ExtHashMap Nat (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;471&lt;&#x2F;span&gt;&lt;span&gt;  tags : Unit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;472&lt;&#x2F;span&gt;&lt;span&gt;  cycleCount : Nat&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;473&lt;&#x2F;span&gt;&lt;span&gt;  sailOutput : Array String&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;regs&lt;&#x2F;code&gt; (line 468) models the register file with &lt;code&gt;Std.ExtDHashMap Register RegisterType&lt;&#x2F;code&gt; — a hash map where the keys are of type &lt;code&gt;Register&lt;&#x2F;code&gt; and the value type of the register &lt;em&gt;depends on the key&lt;&#x2F;em&gt;.
That is, if the key is &lt;code&gt;k : Register&lt;&#x2F;code&gt;, the corresponding value has type &lt;code&gt;RegisterType k&lt;&#x2F;code&gt;.
This is what makes it a &lt;em&gt;dependent&lt;&#x2F;em&gt; hash map rather than an ordinary one, and also why the state is declared with parameters &lt;code&gt;RegisterType&lt;&#x2F;code&gt; and &lt;code&gt;ChoiceSource&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;Register&lt;&#x2F;code&gt; is an inductive with ~180 variants — one for every named register in the RISC-V spec:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;LeanRV64D&#x2F;Defs.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1526&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;inductive&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Register&lt;&#x2F;span&gt;&lt;span&gt; : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Type where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1527&lt;&#x2F;span&gt;&lt;span&gt;  | hart_state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1528&lt;&#x2F;span&gt;&lt;span&gt;  | satp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1529&lt;&#x2F;span&gt;&lt;span&gt;  | PC&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1530&lt;&#x2F;span&gt;&lt;span&gt;  | nextPC&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1531&lt;&#x2F;span&gt;&lt;span&gt;  | x1 | x2 | x3 | ... | x31   -- general-purpose registers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1532&lt;&#x2F;span&gt;&lt;span&gt;  -- ... CSRs, vector registers, debug state, ~&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;180&lt;&#x2F;span&gt;&lt;span&gt; variants total ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;RegisterType&lt;&#x2F;code&gt; is the exact function&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-term-1&quot;&gt;&lt;a href=&quot;#fn-term&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; that tells the hash map what the type of the value is for each key:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;LeanRV64D&#x2F;Defs.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1708&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;abbrev&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; RegisterType&lt;&#x2F;span&gt;&lt;span&gt; : Register → &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Type&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1709&lt;&#x2F;span&gt;&lt;span&gt;  | .hart_state =&amp;gt; HartState&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1710&lt;&#x2F;span&gt;&lt;span&gt;  | .mhpmcounter =&amp;gt; (Vector (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1711&lt;&#x2F;span&gt;&lt;span&gt;  | .tlb =&amp;gt; (Vector (Option TLB_Entry) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt; ^ &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1712&lt;&#x2F;span&gt;&lt;span&gt;  | .PC =&amp;gt; (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1713&lt;&#x2F;span&gt;&lt;span&gt;  | .x1 =&amp;gt; (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;)   -- all x1–x31 map to BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1714&lt;&#x2F;span&gt;&lt;span&gt;  | .x2 =&amp;gt; (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1715&lt;&#x2F;span&gt;&lt;span&gt;  -- ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So &lt;code&gt;regs[.PC]&lt;&#x2F;code&gt; has type &lt;code&gt;RegisterType .PC = BitVec 64&lt;&#x2F;code&gt;, while &lt;code&gt;regs[.tlb]&lt;&#x2F;code&gt; has type &lt;code&gt;RegisterType .tlb = Vector (Option TLB_Entry) (2 ^ 6)&lt;&#x2F;code&gt;. Each register gets exactly the type it needs.
The general-purpose registers &lt;code&gt;x1-x31&lt;&#x2F;code&gt; are of type &lt;code&gt;BitVec 64&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;mem&lt;&#x2F;code&gt; field models byte-addressable memory as a hash map from &lt;code&gt;Nat&lt;&#x2F;code&gt; addresses to &lt;code&gt;BitVec 8&lt;&#x2F;code&gt; bytes.
The second parameter &lt;code&gt;c&lt;&#x2F;code&gt; has type &lt;code&gt;ChoiceSource&lt;&#x2F;code&gt;, a structure that provides a way to pick default values for primitive types.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;.lake&#x2F;packages&#x2F;Sail&#x2F;Sail&#x2F;Sail.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;291&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; ChoiceSource&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;292&lt;&#x2F;span&gt;&lt;span&gt;  (α : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Type&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;293&lt;&#x2F;span&gt;&lt;span&gt;  (nextState : Primitive → α → α)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;294&lt;&#x2F;span&gt;&lt;span&gt;  (choose : ∀ p : Primitive, α → p.reflect)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To define &lt;code&gt;SailState&lt;&#x2F;code&gt;, we use &lt;code&gt;trivialChoiceSource&lt;&#x2F;code&gt;, which is defined as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;.lake&#x2F;packages&#x2F;Sail&#x2F;Sail&#x2F;Sail.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;296&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; trivialChoiceSource&lt;&#x2F;span&gt;&lt;span&gt; : ChoiceSource &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;297&lt;&#x2F;span&gt;&lt;span&gt;  α := Unit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;298&lt;&#x2F;span&gt;&lt;span&gt;  nextState _ _ := ()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;299&lt;&#x2F;span&gt;&lt;span&gt;  choose p _ :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;300&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    match&lt;&#x2F;span&gt;&lt;span&gt; p &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;301&lt;&#x2F;span&gt;&lt;span&gt;    | .bool =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;302&lt;&#x2F;span&gt;&lt;span&gt;    | .bit =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;303&lt;&#x2F;span&gt;&lt;span&gt;    | .int =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;304&lt;&#x2F;span&gt;&lt;span&gt;    | .nat =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;305&lt;&#x2F;span&gt;&lt;span&gt;    | .string =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;306&lt;&#x2F;span&gt;&lt;span&gt;    | .fin _ =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;307&lt;&#x2F;span&gt;&lt;span&gt;    | .bitvector _ =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;More simply, this says that all default values are the expected ones.
Next, we describe how one steps the CPU or performs a state transition.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-sail-monad&quot;&gt;The Sail Monad&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-sail-monad&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Step transitions are modeled using Lean’s built-in error-state monad (&lt;code&gt;EStateM ε σ α&lt;&#x2F;code&gt;), with the &lt;a href=&quot;https:&#x2F;&#x2F;randomwalks.xyz&#x2F;blog&#x2F;jolt-qed&#x2F;state&#x2F;#errors&quot;&gt;error&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;randomwalks.xyz&#x2F;blog&#x2F;jolt-qed&#x2F;state&#x2F;#state&quot;&gt;state&lt;&#x2F;a&gt; types.
Under the hood &lt;code&gt;EStateM ε σ α&lt;&#x2F;code&gt; is just a function &lt;code&gt;σ → Result ε σ α&lt;&#x2F;code&gt; that takes a state and returns either &lt;code&gt;.ok v newState&lt;&#x2F;code&gt; or &lt;code&gt;.error e newState&lt;&#x2F;code&gt;, where &lt;code&gt;v : α&lt;&#x2F;code&gt; and &lt;code&gt;e : ε&lt;&#x2F;code&gt;.
See the &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;leanprover-community.github.io&#x2F;mathlib4_docs&#x2F;Init&#x2F;Control&#x2F;EState.html&quot;&gt;official &lt;code&gt;EStateM&lt;&#x2F;code&gt; documentation&lt;&#x2F;a&gt; for further details.&lt;&#x2F;p&gt;
&lt;p&gt;The Sail library defines a generic version called &lt;code&gt;PreSailM&lt;&#x2F;code&gt;, leaving the register types, choice source, and user-exception type as parameters:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;.lake&#x2F;packages&#x2F;Sail&#x2F;Sail&#x2F;Sail.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;479&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;abbrev&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; PreSailM&lt;&#x2F;span&gt;&lt;span&gt; (RegisterType : Register → &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Type&lt;&#x2F;span&gt;&lt;span&gt;) (c : ChoiceSource) (ue : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Type&lt;&#x2F;span&gt;&lt;span&gt;) :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;480&lt;&#x2F;span&gt;&lt;span&gt;  EStateM (Error ue) (SequentialState RegisterType c)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;SailM&lt;&#x2F;code&gt; is just &lt;code&gt;PreSailM&lt;&#x2F;code&gt; instantiated with the user-exception type &lt;code&gt;ue&lt;&#x2F;code&gt; as &lt;code&gt;exception&lt;&#x2F;code&gt; (so the error type &lt;code&gt;ε&lt;&#x2F;code&gt; becomes &lt;code&gt;Error exception&lt;&#x2F;code&gt;) and the state &lt;code&gt;σ&lt;&#x2F;code&gt; as &lt;code&gt;SailState&lt;&#x2F;code&gt; defined above.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;LeanRV64D&#x2F;Defs.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1928&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;abbrev&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; SailM&lt;&#x2F;span&gt;&lt;span&gt; := PreSailM RegisterType trivialChoiceSource exception&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice that &lt;code&gt;SailM&lt;&#x2F;code&gt; fixes the error type &lt;code&gt;ε&lt;&#x2F;code&gt; and state type &lt;code&gt;σ&lt;&#x2F;code&gt;, but says nothing about the result type &lt;code&gt;α&lt;&#x2F;code&gt;.
That is deliberate: &lt;code&gt;EStateM ε σ α&lt;&#x2F;code&gt; takes three type arguments, and here we have only supplied the first two.
&lt;code&gt;SailM&lt;&#x2F;code&gt; is therefore a function &lt;code&gt;Type → Type&lt;&#x2F;code&gt;.
The remaining &lt;code&gt;α&lt;&#x2F;code&gt; is filled in at each use site, giving a different “step computation that yields an &lt;code&gt;α&lt;&#x2F;code&gt;”:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SailM ExecutionResult   -- a full instruction step, yielding its execution result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SailM (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;)       -- a step that reads a register, yielding a &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;-bit word&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SailM Unit              -- a step run only &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; its effect on state&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So &lt;code&gt;SailM&lt;&#x2F;code&gt; is the “RISC-V step computation” constructor, and &lt;code&gt;SailM α&lt;&#x2F;code&gt; is “a step computation that produces an &lt;code&gt;α&lt;&#x2F;code&gt;”. This is the same currying you already use when you write &lt;code&gt;List&lt;&#x2F;code&gt; (a &lt;code&gt;Type → Type&lt;&#x2F;code&gt;) and only later &lt;code&gt;List Nat&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;errors&quot;&gt;Errors&lt;a class=&quot;zola-anchor&quot; href=&quot;#errors&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;These variants model all the ways the execution part of the fetch-decode-execute cycle can go wrong.
&lt;code&gt;Error&lt;&#x2F;code&gt; is from the Sail library:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;.lake&#x2F;packages&#x2F;Sail&#x2F;Sail&#x2F;Sail.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;351&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;inductive&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Error&lt;&#x2F;span&gt;&lt;span&gt; (ue : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Type&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;352&lt;&#x2F;span&gt;&lt;span&gt;  | Exit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;353&lt;&#x2F;span&gt;&lt;span&gt;  | Unreachable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;354&lt;&#x2F;span&gt;&lt;span&gt;  | OutOfMemoryRange (n : Nat)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;355&lt;&#x2F;span&gt;&lt;span&gt;  | Assertion (s : String)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;356&lt;&#x2F;span&gt;&lt;span&gt;  | User (e : ue)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;User&lt;&#x2F;code&gt; constructor wraps a user-exception type &lt;code&gt;ue&lt;&#x2F;code&gt;, which is instantiated with &lt;code&gt;exception&lt;&#x2F;code&gt; from the RISC-V model:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;LeanRV64D&#x2F;Defs.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;87&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;inductive&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; exception&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;88&lt;&#x2F;span&gt;&lt;span&gt;  | Error_not_implemented (_ : String)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;89&lt;&#x2F;span&gt;&lt;span&gt;  | Error_internal_error (_ : String)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;90&lt;&#x2F;span&gt;&lt;span&gt;  | Error_reserved_behavior (_ : String)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;executing-instructions&quot;&gt;Executing Instructions&lt;a class=&quot;zola-anchor&quot; href=&quot;#executing-instructions&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;With &lt;code&gt;SailM&lt;&#x2F;code&gt; defined above, to execute instructions we must provide two things:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The type for $\alpha$. For RISC-V instructions, $\alpha$ will invariably be &lt;code&gt;ExecutionResult&lt;&#x2F;code&gt;. This is the final output after execution.&lt;&#x2F;li&gt;
&lt;li&gt;Once $\alpha$ is defined, a full description of the state transition.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;execution-results-the-return-type-after-execution&quot;&gt;Execution Results: The Return Type After Execution&lt;a class=&quot;zola-anchor&quot; href=&quot;#execution-results-the-return-type-after-execution&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;LeanRV64D&#x2F;Defs.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1464&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;inductive&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; ExecutionResult&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1465&lt;&#x2F;span&gt;&lt;span&gt;  | Retire_Success (_ : Unit)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1466&lt;&#x2F;span&gt;&lt;span&gt;  | ExecuteAs (_ : instruction)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1467&lt;&#x2F;span&gt;&lt;span&gt;  | Enter_Wait (_ : WaitReason)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1468&lt;&#x2F;span&gt;&lt;span&gt;  | Illegal_Instruction (_ : Unit)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1469&lt;&#x2F;span&gt;&lt;span&gt;  | Virtual_Instruction (_ : Unit)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1470&lt;&#x2F;span&gt;&lt;span&gt;  | Trap (_ : (Privilege × ctl_result × xlenbits))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1471&lt;&#x2F;span&gt;&lt;span&gt;  | Memory_Exception (_ : (virtaddr × ExceptionType))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1472&lt;&#x2F;span&gt;&lt;span&gt;  | Ext_CSR_Check_Failure (_ : Unit)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1473&lt;&#x2F;span&gt;&lt;span&gt;  | Ext_ControlAddr_Check_Failure (_ : ext_control_addr_error)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1474&lt;&#x2F;span&gt;&lt;span&gt;  | Ext_DataAddr_Check_Failure (_ : ext_data_addr_error)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;1475&lt;&#x2F;span&gt;&lt;span&gt;  | Ext_XRET_Priv_Failure (_ : Unit)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the happy path, instructions return &lt;code&gt;RETIRE_SUCCESS&lt;&#x2F;code&gt; (which is &lt;code&gt;Retire_Success ()&lt;&#x2F;code&gt;).
To make this idea more concrete, we look at the actual execution of a native RISC-V instruction, &lt;code&gt;ADDIW&lt;&#x2F;code&gt;.
The opcode signature is &lt;code&gt;ADDIW rd, rs1, imm&lt;&#x2F;code&gt;.
In pseudocode, it computes:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# ADDIW rd, rs1, imm   (RV64I)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tmp = rs1 + sext(imm)        # 64-bit wrapping add of the sign-extended 12-bit imm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rd  = sext( tmp[31:0] )      # keep the low 32 bits, sign-extend back to 64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That is, the add is done in 64 bits but &lt;strong&gt;only the low 32 bits are kept&lt;&#x2F;strong&gt; and then sign-extended back to 64.
Below is the trusted Sail implementation of the pseudocode above.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;LeanRV64D&#x2F;InstsEnd.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;71658&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; execute_ADDIW&lt;&#x2F;span&gt;&lt;span&gt; (imm : (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;)) (rs1 : regidx) (rd : regidx) : SailM ExecutionResult := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;71659&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; result ← &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;span&gt; (pure ((← (rX_bits rs1)) + (sign_extend (m := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) imm))) -- m1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;71660&lt;&#x2F;span&gt;&lt;span&gt;  (wX_bits rd (sign_extend (m := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (Sail.BitVec.extractLsb result &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;31 0&lt;&#x2F;span&gt;&lt;span&gt;))) -- m2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;71661&lt;&#x2F;span&gt;&lt;span&gt;  (pure RETIRE_SUCCESS) -- m3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next we try and parse the above code.
It might look simple, but under the hood a lot is going, and understanding it is key for understanding our proof tactics later on.&lt;&#x2F;p&gt;

&lt;aside class=&quot;callout callout-remark&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;Remark&lt;&#x2F;div&gt;
  
  &lt;p&gt;We will not always discuss do notation in such detail, but we choose to do so here because all CPU implementations are written in do notation.
Thus, it’s important to get used to mentally translating do notation into function composition.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;h4 id=&quot;function-signature&quot;&gt;Function Signature&lt;a class=&quot;zola-anchor&quot; href=&quot;#function-signature&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;p&gt;The function signature says the inputs are a 12-bit immediate value &lt;code&gt;imm&lt;&#x2F;code&gt; and general-purpose source and destination registers &lt;code&gt;rs1&lt;&#x2F;code&gt; and &lt;code&gt;rd&lt;&#x2F;code&gt;, which are of type&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-gpr-1&quot;&gt;&lt;a href=&quot;#fn-gpr&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; &lt;code&gt;regidx&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;LeanRV64D&#x2F;Defs.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;inductive&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; regidx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;  | Regidx (_ : (BitVec (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; ( &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span&gt;  : Bool) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;then&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To parse the body, we need a little &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;leanprover.github.io&#x2F;functional_programming_in_lean&#x2F;monads&#x2F;do.html&quot;&gt;do notation&lt;&#x2F;a&gt;.
Lean is a functional language, but CPU execution is inherently stateful, so &lt;code&gt;do&lt;&#x2F;code&gt; notation lets us write imperative-looking code that the Lean elaborator desugars back into ordinary functional code.
The mental model is that each line of the block is a &lt;code&gt;SailM α&lt;&#x2F;code&gt; computation — and recall these are just functions: feed one the current state and it either returns &lt;code&gt;.ok&lt;&#x2F;code&gt; with a new value and state, or &lt;code&gt;.error&lt;&#x2F;code&gt; with an error value and state.
If a line errors, the computation short-circuits and the whole block returns that error; on success, the returned value is passed along to the next line.
Applying this to the whole body, the three &lt;code&gt;do&lt;&#x2F;code&gt; lines desugar into one nested &lt;code&gt;&amp;gt;&amp;gt;=&lt;&#x2F;code&gt; chain:&lt;&#x2F;p&gt;
&lt;h4 id=&quot;parsing-the-body&quot;&gt;Parsing The Body&lt;a class=&quot;zola-anchor&quot; href=&quot;#parsing-the-body&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;p&gt;We rewrite the outer &lt;code&gt;do&lt;&#x2F;code&gt; block as&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  result ← m1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  m2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  m3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here &lt;code&gt;m1&lt;&#x2F;code&gt;, &lt;code&gt;m2&lt;&#x2F;code&gt;, and &lt;code&gt;m3&lt;&#x2F;code&gt; are the monadic expressions marked in the code above.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;m1 := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;span&gt; (pure ((← (rX_bits rs1)) + (sign_extend (m := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) imm)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;m2 := wX_bits rd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        (sign_extend (m := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (Sail.BitVec.extractLsb result &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;31 0&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;m3 := pure RETIRE_SUCCESS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Following the guide on how to desugar &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;leanprover.github.io&#x2F;functional_programming_in_lean&#x2F;monads&#x2F;do.html&quot;&gt;do notation&lt;&#x2F;a&gt;, the first desugaring step gives:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;m1 &amp;gt;&amp;gt;= (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fun&lt;&#x2F;span&gt;&lt;span&gt; result =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    m2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    m3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A reminder that, a function &lt;code&gt;m : Type → Type&lt;&#x2F;code&gt; can be used as a monad only when Lean has a &lt;code&gt;Monad m&lt;&#x2F;code&gt; instance&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-monad-instance-1&quot;&gt;&lt;a href=&quot;#fn-monad-instance&quot;&gt;5&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; for it, which provides &lt;code&gt;pure&lt;&#x2F;code&gt; and &lt;code&gt;bind&lt;&#x2F;code&gt;.
The notation &lt;code&gt;a &amp;gt;&amp;gt;= f&lt;&#x2F;code&gt; is notation for &lt;code&gt;bind a f&lt;&#x2F;code&gt;, where &lt;code&gt;a : m α&lt;&#x2F;code&gt; and &lt;code&gt;f : α → m β&lt;&#x2F;code&gt;.
For &lt;code&gt;EStateM&lt;&#x2F;code&gt;, read &lt;code&gt;bind&lt;&#x2F;code&gt; as: run &lt;code&gt;a&lt;&#x2F;code&gt;; if it succeeds, pass its returned value to &lt;code&gt;f&lt;&#x2F;code&gt; to produce the next monadic computation.
The next desugaring step is as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;m1 &amp;gt;&amp;gt;= (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fun&lt;&#x2F;span&gt;&lt;span&gt; result =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  m2 &amp;gt;&amp;gt;= (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fun&lt;&#x2F;span&gt;&lt;span&gt; _ =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      m3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The next step is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;m1 &amp;gt;&amp;gt;= (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fun&lt;&#x2F;span&gt;&lt;span&gt; result =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  m2 &amp;gt;&amp;gt;= (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fun&lt;&#x2F;span&gt;&lt;span&gt; _ =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    m3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We expand only &lt;code&gt;m2&lt;&#x2F;code&gt; and &lt;code&gt;m3&lt;&#x2F;code&gt; first. As &lt;code&gt;m1&lt;&#x2F;code&gt; is itself a &lt;code&gt;do&lt;&#x2F;code&gt; block, we do expand that next individually, and then give you the combined version.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;m1 &amp;gt;&amp;gt;= (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fun&lt;&#x2F;span&gt;&lt;span&gt; result =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -- m2 expanded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  (wX_bits rd (sign_extend (m := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (Sail.BitVec.extractLsb result &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;31 0&lt;&#x2F;span&gt;&lt;span&gt;))) &amp;gt;&amp;gt;= (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fun&lt;&#x2F;span&gt;&lt;span&gt; _ =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      -- m3 expanded&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      pure RETIRE_SUCCESS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now parsing &lt;code&gt;m1&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;span&gt; (pure ((← (rX_bits rs1)) + (sign_extend (m := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) imm)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;as &lt;code&gt;m1&lt;&#x2F;code&gt; is a single statement it desugars to&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(pure ((← (rX_bits rs1)) + (sign_extend (m := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) imm)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The next desugaring step hoists the nested &lt;code&gt;←&lt;&#x2F;code&gt; out of the argument to &lt;code&gt;pure&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(rX_bits rs1) &amp;gt;&amp;gt;= (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fun&lt;&#x2F;span&gt;&lt;span&gt; rs1_value =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  pure (rs1_value + sign_extend (m := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) imm)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Putting the desugared &lt;code&gt;m1&lt;&#x2F;code&gt; back into the outer chain gives:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;((rX_bits rs1) &amp;gt;&amp;gt;= (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fun&lt;&#x2F;span&gt;&lt;span&gt; x =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  pure (x + sign_extend (m := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) imm)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)) &amp;gt;&amp;gt;= (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fun&lt;&#x2F;span&gt;&lt;span&gt; result =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  (wX_bits rd (sign_extend (m := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) (Sail.BitVec.extractLsb result &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;31 0&lt;&#x2F;span&gt;&lt;span&gt;))) &amp;gt;&amp;gt;= (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fun&lt;&#x2F;span&gt;&lt;span&gt; _ =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      pure RETIRE_SUCCESS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;rX_bits&lt;&#x2F;code&gt; is a monadic computation: given the current state, it returns a 64-bit value (the contents of register &lt;code&gt;rs1&lt;&#x2F;code&gt;)&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-populated-1&quot;&gt;&lt;a href=&quot;#fn-populated&quot;&gt;6&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; and threads the state unchanged. So the output is really &lt;code&gt;SailM (BitVec 64)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;sign_extend&lt;&#x2F;code&gt; just sign-extends the immediate value and returns a 64-bit value.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The next line, &lt;code&gt;wX_bits ...&lt;&#x2F;code&gt;, runs only if the first line succeeds all the way through. It is itself another bind: if we successfully write the sign-extended low 32 bits of &lt;code&gt;result&lt;&#x2F;code&gt; (that is, &lt;code&gt;sext(result[31:0])&lt;&#x2F;code&gt;) into the &lt;code&gt;rd&lt;&#x2F;code&gt; key of the register hash map, and that write succeeds&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;the final &lt;code&gt;pure RETIRE_SUCCESS&lt;&#x2F;code&gt; returns &lt;code&gt;RETIRE_SUCCESS&lt;&#x2F;code&gt; without changing the state further.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Thus, &lt;code&gt;wX_bits ...&lt;&#x2F;code&gt; is the &lt;em&gt;only&lt;&#x2F;em&gt; monadic computation that changes state.
We refer the reader to the &lt;a href=&quot;https:&#x2F;&#x2F;randomwalks.xyz&#x2F;blog&#x2F;jolt-qed&#x2F;state&#x2F;#read-and-write-chain&quot;&gt;Read and Write Chain&lt;&#x2F;a&gt; appendix for the full code blocks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;jolt-cpu&quot;&gt;Jolt CPU&lt;a class=&quot;zola-anchor&quot; href=&quot;#jolt-cpu&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;The Jolt CPU as modeled in Rust is shown below.
Most fields have an equivalent copy in the Sail state, so the Jolt state can and should be built on top of &lt;code&gt;SailState&lt;&#x2F;code&gt; with some extra fields.
For the purposes of proving expansion equivalence, this is enough&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-extend-1&quot;&gt;&lt;a href=&quot;#fn-extend&quot;&gt;7&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.
What we really need to model is the virtual registers and the virtual register allocation.
Jolt adds virtual registers and extra instructions.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;rust&quot; data-name=&quot;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;blob&#x2F;main&#x2F;tracer&#x2F;src&#x2F;emulator&#x2F;cpu.rs&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;203&lt;&#x2F;span&gt;&lt;span&gt;  #[derive(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Clone&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Debug&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;204&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  pub struct&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Cpu&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;205&lt;&#x2F;span&gt;&lt;span&gt;      clock&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;206&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;207&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      pub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;crate&lt;&#x2F;span&gt;&lt;span&gt;) privilege_mode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; PrivilegeMode&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;208&lt;&#x2F;span&gt;&lt;span&gt;      wfi&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;209&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      pub&lt;&#x2F;span&gt;&lt;span&gt; x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;i64&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; REGISTER_COUNT&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; Missing in Sail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;210&lt;&#x2F;span&gt;&lt;span&gt;      #[allow(dead_code)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;211&lt;&#x2F;span&gt;&lt;span&gt;      f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;f64&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 32&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;212&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      pub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;crate&lt;&#x2F;span&gt;&lt;span&gt;) pc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;213&lt;&#x2F;span&gt;&lt;span&gt;      csr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;u64&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; CSR_CAPACITY&lt;&#x2F;span&gt;&lt;span&gt;],&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;214&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      pub&lt;&#x2F;span&gt;&lt;span&gt; mmu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Mmu&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;215&lt;&#x2F;span&gt;&lt;span&gt;      reservation&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;216&lt;&#x2F;span&gt;&lt;span&gt;      is_reservation_set&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;217&lt;&#x2F;span&gt;&lt;span&gt;      reservation_width&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; ReservationWidth&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;218&lt;&#x2F;span&gt;&lt;span&gt;      _dump_flag&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;219&lt;&#x2F;span&gt;&lt;span&gt;      unsigned_data_mask&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;220&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;      &#x2F;&#x2F; pub trace: Vec&amp;lt;Cycle&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;221&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      pub&lt;&#x2F;span&gt;&lt;span&gt; trace_len&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; Missing in Sail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;222&lt;&#x2F;span&gt;&lt;span&gt;      executed_instrs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; u64&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; &amp;quot;real&amp;quot; RV64IMAC cycles&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;223&lt;&#x2F;span&gt;&lt;span&gt;      active_markers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; FnvHashMap&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;u32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; ActiveMarker&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;224&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      pub&lt;&#x2F;span&gt;&lt;span&gt; vr_allocator&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; VirtualRegisterAllocator&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; Missing in Sail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;225&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;      &#x2F;&#x2F;&#x2F; Call stack tracking (circular buffer)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;226&lt;&#x2F;span&gt;&lt;span&gt;      call_stack&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; VecDeque&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;CallFrame&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;227&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;      &#x2F;&#x2F;&#x2F; Advice tape for runtime advice system&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;228&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      pub&lt;&#x2F;span&gt;&lt;span&gt; advice_tape&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; AdviceTape&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; Not modeled in Lean&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;229&lt;&#x2F;span&gt;&lt;span&gt;      #[cfg(feature &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;field-inline&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;230&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      pub&lt;&#x2F;span&gt;&lt;span&gt; field_registers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; FieldRegisterFile&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;231&lt;&#x2F;span&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This gives us the following definition of Jolt state in Lean.
We do not model the virtual registers as a hash map; instead, we model them as a function from &lt;code&gt;BitVec 7 -&amp;gt; BitVec 64&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;JoltBytecode&#x2F;JoltISA&#x2F;Core.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; SailJoltState&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span&gt;  sail : SailState&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span&gt;  vregs : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt; → BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt; := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fun&lt;&#x2F;span&gt;&lt;span&gt; _ =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that we have duplication here.
The &lt;code&gt;sail&lt;&#x2F;code&gt; field already has the &lt;code&gt;regidx&lt;&#x2F;code&gt; for the general-purpose registers, and the first 32 slots of &lt;code&gt;vregs&lt;&#x2F;code&gt; are also the same.
To make proofs easier to manage, we directly use the Sail registers when writing to general-purpose registers, and block off writing to the first 32 registers.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;JoltBytecode&#x2F;JoltISA&#x2F;RegisterAccess.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;-- The general-purpose registers are &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;in&lt;&#x2F;span&gt;&lt;span&gt; the Sail hash map already,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;-- so we should never write to vr &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0-31&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;33&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; WritableVReg&lt;&#x2F;span&gt;&lt;span&gt; (vr : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop&lt;&#x2F;span&gt;&lt;span&gt; :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;34&lt;&#x2F;span&gt;&lt;span&gt;  ¬ vr.toNat &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;35&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;36&lt;&#x2F;span&gt;&lt;span&gt;-- We cannot write to the first &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt; registers, as we use xreg &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; them.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;37&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; writeVReg&lt;&#x2F;span&gt;&lt;span&gt; (vr : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;) (val : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) : JoltMonad Unit :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;38&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; vr.toNat &amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;39&lt;&#x2F;span&gt;&lt;span&gt;    throw (Error.Assertion &lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;writeVReg: architectural xreg address&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;40&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;41&lt;&#x2F;span&gt;&lt;span&gt;    modify &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fun&lt;&#x2F;span&gt;&lt;span&gt; js =&amp;gt; { js &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;with&lt;&#x2F;span&gt;&lt;span&gt; vregs := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fun&lt;&#x2F;span&gt;&lt;span&gt; r =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; r = vr &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt; val &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; js.vregs r }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;virtual-registers&quot;&gt;Virtual Registers&lt;a class=&quot;zola-anchor&quot; href=&quot;#virtual-registers&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Not all virtual registers are the same.
The figure below shows the classification of the different registers.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;randomwalks.xyz&#x2F;blog&#x2F;jolt-qed&#x2F;state&#x2F;.&#x2F;jolt-registers.svg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Virtual register allocation is modeled directly in the expansion.
The logic used in Jolt is as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Before an instruction executes, all registers from 40 to 47 are marked free.&lt;&#x2F;li&gt;
&lt;li&gt;When Jolt asks for a scratch virtual register, we return the lowest-indexed register marked free. For example, at the start, with all scratch registers marked free, the first free register is 40. Once this is returned, 40 is marked used until it is explicitly marked free again. The next free register is then 41, and so on.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We explicitly model this in &lt;code&gt;JoltBytecode&#x2F;JoltISA&#x2F;VirtualRegisters.lean&lt;&#x2F;code&gt;, with proof-side facts in &lt;code&gt;JoltBytecode&#x2F;InstructionEquivalence&#x2F;ProofSupport&#x2F;VirtualRegisters.lean&lt;&#x2F;code&gt;, so that expansion proofs can check that the allocator neither runs out of scratch virtual registers nor reuses one that is still live.&lt;&#x2F;p&gt;

&lt;aside class=&quot;callout callout-remark&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;Two sets of control&amp;#x2F;status registers&lt;&#x2F;div&gt;
  
  &lt;p&gt;It might seem confusing that some virtual registers represent control&#x2F;status registers, while there is also a separate field for CSRs.
This is because the Jolt CPU emulator is a fork of a RISC-V emulator.
This means that the emulator is able to emulate non-expanded vanilla RISC-V programs.
However, when reading a Jolt CPU program, control&#x2F;status register reads and writes are done via the virtual register file.
&lt;code&gt;ECALL&lt;&#x2F;code&gt;, &lt;code&gt;EBREAK&lt;&#x2F;code&gt;, &lt;code&gt;MRET&lt;&#x2F;code&gt;, &lt;code&gt;CSRRW&lt;&#x2F;code&gt;, &lt;code&gt;CSRRS&lt;&#x2F;code&gt;, and &lt;code&gt;CSRRC&lt;&#x2F;code&gt; are all expanded (as we show later).&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;h2 id=&quot;jolt-monad-stepping-the-cpu&quot;&gt;Jolt Monad (Stepping the CPU)&lt;a class=&quot;zola-anchor&quot; href=&quot;#jolt-monad-stepping-the-cpu&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;We step the Jolt CPU using the same &lt;code&gt;EStateM&lt;&#x2F;code&gt; infrastructure.
The only difference between this and the RISC-V CPU is that we use &lt;code&gt;SailJoltState&lt;&#x2F;code&gt; instead of &lt;code&gt;SailState&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;abbrev&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; JoltMonad&lt;&#x2F;span&gt;&lt;span&gt; (α : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Type&lt;&#x2F;span&gt;&lt;span&gt;) := EStateM (Error exception) SailJoltState α&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next, we define the instructions natively supported by the Jolt CPU: a subset of RISC-V instructions, plus a few new virtual instructions.
The source of truth is the Rust instruction definition in &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;blob&#x2F;main&#x2F;tracer&#x2F;src&#x2F;instruction&#x2F;mod.rs&quot;&gt;tracer&#x2F;src&#x2F;instruction&#x2F;mod.rs&lt;&#x2F;a&gt;.
These are modeled in Lean as the inductive type &lt;code&gt;JoltISA.Instr&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;JoltBytecode&#x2F;JoltISA&#x2F;Instruction.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;30&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;inductive&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Instr&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;  | NoOp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;  | ADDI (dst : Dst) (src : Src) (imm : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;33&lt;&#x2F;span&gt;&lt;span&gt;  | ANDI (dst : Dst) (src : Src) (imm : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;34&lt;&#x2F;span&gt;&lt;span&gt;  | ORI  (dst : Dst) (src : Src) (imm : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;35&lt;&#x2F;span&gt;&lt;span&gt;  | XORI (dst : Dst) (src : Src) (imm : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;36&lt;&#x2F;span&gt;&lt;span&gt;  | LUI  (dst : Dst) (imm : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;37&lt;&#x2F;span&gt;&lt;span&gt;  | JAL (dst : Dst) (imm : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;38&lt;&#x2F;span&gt;&lt;span&gt;  | BEQ (lhs rhs : Src) (imm : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;39&lt;&#x2F;span&gt;&lt;span&gt;  | ADD  (dst : Dst) (lhs rhs : Src)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;40&lt;&#x2F;span&gt;&lt;span&gt;  | SUB  (dst : Dst) (lhs rhs : Src)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;41&lt;&#x2F;span&gt;&lt;span&gt;  | MUL  (dst : Dst) (lhs rhs : Src)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;42&lt;&#x2F;span&gt;&lt;span&gt;  | VirtualMULI (dst : Dst) (src : Src) (imm : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;43&lt;&#x2F;span&gt;&lt;span&gt;  -- ... ~&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;55&lt;&#x2F;span&gt;&lt;span&gt; more opcodes, including the Virtual* family ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;44&lt;&#x2F;span&gt;&lt;span&gt;  | VirtualAssertMulUNoOverflow (lhs rhs : Src)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;45&lt;&#x2F;span&gt;&lt;span&gt;  | VirtualAssertLTE (lhs rhs : Src)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;46&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  deriving&lt;&#x2F;span&gt;&lt;span&gt; Repr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that unlike the RISC-V Cpu, these instructions can read&#x2F;write to both risc-v registers and virtual registers.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- An instruction source operand: either a virtual register or an&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;architectural Sail register. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;inductive&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Src&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  | vreg : VReg → Src&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  | xreg : regidx → Src&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  deriving&lt;&#x2F;span&gt;&lt;span&gt; Repr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- An instruction destination operand: either a virtual register or an&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;architectural Sail register. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;inductive&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Dst&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  | vreg : VReg → Dst&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  | xreg : regidx → Dst&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  deriving&lt;&#x2F;span&gt;&lt;span&gt; Repr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The inductive type above only lists the different instructions supported by the Jolt ISA.
It does not describe how the Jolt state changes when these instructions are executed.
We do that next.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;executing-jolt-instructions&quot;&gt;Executing Jolt Instructions&lt;a class=&quot;zola-anchor&quot; href=&quot;#executing-jolt-instructions&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;In &lt;code&gt;JoltBytecode&#x2F;JoltISA&#x2F;Semantics.lean&lt;&#x2F;code&gt; we define &lt;code&gt;execInstr&lt;&#x2F;code&gt;, a function that maps a &lt;code&gt;JoltISA.Instr&lt;&#x2F;code&gt; to a &lt;code&gt;JoltMonad ExecutionResult&lt;&#x2F;code&gt;.
That is, for each native or virtual Jolt instruction, it defines the state update function.
Remember, &lt;code&gt;JoltMonad&lt;&#x2F;code&gt; is just a function.
To execute the instruction, we have to “run” the function with a current state.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;JoltBytecode&#x2F;JoltISA&#x2F;Semantics.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;30&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; execInstr&lt;&#x2F;span&gt;&lt;span&gt; : Instr → JoltMonad ExecutionResult&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;  | .NoOp =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;      pure RETIRE_SUCCESS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;33&lt;&#x2F;span&gt;&lt;span&gt;  | .ADDI dst src imm =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;34&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      let&lt;&#x2F;span&gt;&lt;span&gt; x ← readSrc src&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;35&lt;&#x2F;span&gt;&lt;span&gt;      writeDst dst (x + sign_extend (m := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) imm)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;36&lt;&#x2F;span&gt;&lt;span&gt;      pure RETIRE_SUCCESS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;37&lt;&#x2F;span&gt;&lt;span&gt;  | .ANDI dst src imm =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;38&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      let&lt;&#x2F;span&gt;&lt;span&gt; x ← readSrc src&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;39&lt;&#x2F;span&gt;&lt;span&gt;      writeDst dst (x &amp;amp;&amp;amp;&amp;amp; sign_extend (m := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) imm)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;40&lt;&#x2F;span&gt;&lt;span&gt;      pure RETIRE_SUCCESS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;41&lt;&#x2F;span&gt;&lt;span&gt;  | .ORI dst src imm =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      let&lt;&#x2F;span&gt;&lt;span&gt; x ← readSrc src&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;43&lt;&#x2F;span&gt;&lt;span&gt;      writeDst dst (x ||| sign_extend (m := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) imm)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;44&lt;&#x2F;span&gt;&lt;span&gt;      pure RETIRE_SUCCESS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;45&lt;&#x2F;span&gt;&lt;span&gt;  -- ... remaining native and virtual instruction cases ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;46&lt;&#x2F;span&gt;&lt;span&gt;  | .VirtualAssertLTE lhs rhs =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;47&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      let&lt;&#x2F;span&gt;&lt;span&gt; x ← readSrc lhs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;48&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      let&lt;&#x2F;span&gt;&lt;span&gt; y ← readSrc rhs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;49&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      if&lt;&#x2F;span&gt;&lt;span&gt; x.toNat ≤ y.toNat &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;50&lt;&#x2F;span&gt;&lt;span&gt;        pure RETIRE_SUCCESS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;51&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;52&lt;&#x2F;span&gt;&lt;span&gt;        throw (Error.Assertion &lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;VirtualAssertLTE&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;You might ask: where did this execution logic come from?&lt;&#x2F;strong&gt;
For now, it is hand-translated from the Rust source code.
For each instruction, the process is as follows:&lt;&#x2F;p&gt;
&lt;p&gt;Find the corresponding &lt;code&gt;exec&lt;&#x2F;code&gt; block and model the Rust code in Lean. For example, here are the Lean semantics and Rust semantics side by side for &lt;code&gt;ADDI&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| .ADDI dst src imm =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; x ← readSrc src&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    writeDst dst (x + sign_extend (m := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) imm)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pure RETIRE_SUCCESS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;aside class=&quot;callout callout-box thm-box&quot;&gt;
  
  &lt;p&gt;This eyeballing of Rust and Lean code is prone to bugs. As a temporary solution, we always have an AI agent double-check the two code blocks. In the coming weeks, we will have an auto-translator from Rust to Lean for instruction execution semantics.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;rust&quot; data-name=&quot;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;blob&#x2F;main&#x2F;tracer&#x2F;src&#x2F;instruction&#x2F;addi.rs&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; exec&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span&gt;, cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;: &amp;amp;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Cpu&lt;&#x2F;span&gt;&lt;span&gt;, _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;: &amp;amp;mut&lt;&#x2F;span&gt;&lt;span&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;ADDI&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; RISCVInstruction&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;RAMAccess&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;        cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;write_register&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;operands&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;rd &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;as&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span&gt;            cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sign_extend&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;                cpu&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;x[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;operands&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;rs1 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;as&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;wrapping_add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;normalize_imm&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;operands&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;imm)),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span&gt;            ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span&gt;        );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As a result of the translation above, some natively supported instructions, such as &lt;code&gt;ADDI&lt;&#x2F;code&gt;, have both a Jolt execution and a trusted Sail execution.
We want them to agree on how they change Sail state.
This gives us an equivalence theorem for &lt;strong&gt;every&lt;&#x2F;strong&gt; Jolt instruction that is natively supported on a RISC-V CPU.
Continuing with the &lt;code&gt;ADDI&lt;&#x2F;code&gt; example, it looks like the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;JoltBytecode&#x2F;InstructionEquivalence&#x2F;Instructions&#x2F;Natives&#x2F;Addi.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;69&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Main native `ADDI` equivalence statement. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;70&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; addiInstrEqSailStatement&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;71&lt;&#x2F;span&gt;&lt;span&gt;    (imm : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;72&lt;&#x2F;span&gt;&lt;span&gt;    (rs1 rd : regidx)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;73&lt;&#x2F;span&gt;&lt;span&gt;    (js : SailJoltState)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;74&lt;&#x2F;span&gt;&lt;span&gt;    (_h : UnarySourceReadWithLinkedCSRs rs1 js) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop&lt;&#x2F;span&gt;&lt;span&gt; :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;75&lt;&#x2F;span&gt;&lt;span&gt;  System.systemProjectResult&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;76&lt;&#x2F;span&gt;&lt;span&gt;    ((JoltISA.execInstr (.ADDI (.xreg rd) (.xreg rs1) imm)).run js) =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;77&lt;&#x2F;span&gt;&lt;span&gt;    ((execute_ITYPE imm rs1 rd iop.ADDI).run js.sail)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The statement above translates to the following mathematical statement.

&lt;aside class=&quot;callout callout-theorem thm-numbered&quot;&gt;
  
  &lt;div class=&quot;thm-header&quot;&gt;&lt;span class=&quot;thm-label&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;thm-title&quot;&gt; — ADDI Equivalence Statement&lt;&#x2F;span&gt;&lt;&#x2F;div&gt;
  
  &lt;p&gt;Given a 12-bit immediate value &lt;code&gt;imm&lt;&#x2F;code&gt;, a readable source register &lt;code&gt;rs1&lt;&#x2F;code&gt;, a writable destination register &lt;code&gt;rd&lt;&#x2F;code&gt;, assumptions &lt;code&gt;h&lt;&#x2F;code&gt;, and an initial Jolt state &lt;code&gt;js&lt;&#x2F;code&gt;, running Jolt’s &lt;code&gt;ADDI&lt;&#x2F;code&gt; and projecting down to the Sail state gives the same state as running the trusted Sail &lt;code&gt;ADDI&lt;&#x2F;code&gt; on the input state &lt;code&gt;js.sail&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;&#x2F;p&gt;
&lt;p&gt;The exact assumption bundle used for &lt;code&gt;ADDI&lt;&#x2F;code&gt; is &lt;code&gt;UnarySourceReadWithLinkedCSRs rs1 js&lt;&#x2F;code&gt;, which bundles two sets of assumptions together.&lt;&#x2F;p&gt;
&lt;p&gt;The structure &lt;code&gt;UnarySourceReadAssumptions&lt;&#x2F;code&gt; just says we can read &lt;code&gt;rs1&lt;&#x2F;code&gt;.
As the register file is a hash map, this is a Lean implementation detail: we have to say that the key exists in the hash map.
The other structure is &lt;code&gt;LinkedCSRRegisterAssumptions&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;JoltBytecode&#x2F;Bundles.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Assumptions for an instruction that reads one architectural source register. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;30&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; UnarySourceReadAssumptions&lt;&#x2F;span&gt;&lt;span&gt; (rs1 : regidx) (js : SailJoltState) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;  rs1_val : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;  rs1_read : rX_bits rs1 js.sail = .ok rs1_val js.sail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;33&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;34&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Persistent CSR virtual registers agree with Sail&amp;#39;s architectural CSR state. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;35&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;private structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; LinkedCSRRegisterAssumptions&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;36&lt;&#x2F;span&gt;&lt;span&gt;  mstatus_matches : Assumptions.MstatusVRegMatchesSail js&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;37&lt;&#x2F;span&gt;&lt;span&gt;  mtvec_matches : Assumptions.MtvecVRegMatchesSail js&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;38&lt;&#x2F;span&gt;&lt;span&gt;  mscratch_matches : Assumptions.MscratchVRegMatchesSail js&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;39&lt;&#x2F;span&gt;&lt;span&gt;  mepc_matches : Assumptions.MepcVRegMatchesSail js&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;40&lt;&#x2F;span&gt;&lt;span&gt;  mcause_matches : Assumptions.McauseVRegMatchesSail js&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;41&lt;&#x2F;span&gt;&lt;span&gt;  mtval_matches : Assumptions.MtvalVRegMatchesSail js&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;42&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;43&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- One source-register read plus persistent CSR virtual-register agreement. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;44&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; UnarySourceReadWithLinkedCSRs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;45&lt;&#x2F;span&gt;&lt;span&gt;    (rs1 : regidx) (js : SailJoltState)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;46&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    extends&lt;&#x2F;span&gt;&lt;span&gt; UnarySourceReadAssumptions rs1 js,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;47&lt;&#x2F;span&gt;&lt;span&gt;      LinkedCSRRegisterAssumptions js&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It simply says that the virtual registers are equal to the Sail registers for the corresponding control&#x2F;status registers.&lt;&#x2F;p&gt;
&lt;p&gt;The only thing left to explain is &lt;code&gt;systemProjectResult&lt;&#x2F;code&gt;.
&lt;code&gt;systemProjectResult&lt;&#x2F;code&gt; removes the Jolt-specific state and keeps only the &lt;code&gt;sail&lt;&#x2F;code&gt; state, which can be compared with the RISC-V CPU.
Before we do that, we must map the virtual registers that represent control&#x2F;status registers in Jolt to the Sail control&#x2F;status registers.
Without this step, a program could arbitrarily write to these registers, and dropping &lt;code&gt;vregs&lt;&#x2F;code&gt; would make the Sail states appear to agree.
We need to tell Lean that those virtual registers represent the same values as the Sail registers.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;JoltBytecode&#x2F;InstructionEquivalence&#x2F;Instructions&#x2F;System&#x2F;Common.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;65&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Overlay Jolt&amp;#39;s persistent virtual CSR registers onto the generated Sail CSR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;66&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;register keys.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;67&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;68&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;This is only a proof projection: the Rust-faithful Jolt programs still write&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;69&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;Jolt virtual registers, and the Sail specification still reads&#x2F;writes generated&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;70&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;Sail registers. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;71&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; systemProject&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) : SailState :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;72&lt;&#x2F;span&gt;&lt;span&gt;  { js.sail &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;73&lt;&#x2F;span&gt;&lt;span&gt;    regs :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;74&lt;&#x2F;span&gt;&lt;span&gt;      ((((((js.sail.regs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;75&lt;&#x2F;span&gt;&lt;span&gt;        |&amp;gt;.insert Register.mtvec (js.vregs JoltISA.trapHandlerVReg))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;76&lt;&#x2F;span&gt;&lt;span&gt;        |&amp;gt;.insert Register.mscratch (js.vregs JoltISA.mscratchVReg))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;77&lt;&#x2F;span&gt;&lt;span&gt;        |&amp;gt;.insert Register.mepc (js.vregs JoltISA.mepcVReg))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;78&lt;&#x2F;span&gt;&lt;span&gt;        |&amp;gt;.insert Register.mcause (js.vregs JoltISA.mcauseVReg))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;79&lt;&#x2F;span&gt;&lt;span&gt;        |&amp;gt;.insert Register.mtval (js.vregs JoltISA.mtvalVReg))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;80&lt;&#x2F;span&gt;&lt;span&gt;        |&amp;gt;.insert Register.mstatus (js.vregs JoltISA.mstatusVReg)) }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;81&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;82&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Project a Jolt run result through `systemProject`, preserving the result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;83&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;value and error shape while materializing virtual CSRs in the Sail state. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;84&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; systemProjectResult&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;85&lt;&#x2F;span&gt;&lt;span&gt;    (r : EStateM.Result (Error exception) SailJoltState α) :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;86&lt;&#x2F;span&gt;&lt;span&gt;    EStateM.Result (Error exception) SailState α :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;87&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  match&lt;&#x2F;span&gt;&lt;span&gt; r &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;88&lt;&#x2F;span&gt;&lt;span&gt;  | .ok a js&amp;#39; =&amp;gt; .ok a (systemProject js&amp;#39;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;89&lt;&#x2F;span&gt;&lt;span&gt;  | .error e js&amp;#39; =&amp;gt; .error e (systemProject js&amp;#39;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And that’s it: for every natively supported instruction, we have to prove that this statement is true.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;expansions&quot;&gt;Expansions&lt;a class=&quot;zola-anchor&quot; href=&quot;#expansions&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;We’ve handled natively supported RISC-V instructions.
What about instructions like &lt;code&gt;LW&lt;&#x2F;code&gt;, where the RISC-V instruction is handled as a sequence of Jolt instructions rather than as one native &lt;code&gt;execInstr&lt;&#x2F;code&gt; step?
These instructions are modeled by expansion programs.
An expansion program is a value of the inductive type &lt;code&gt;Program&lt;&#x2F;code&gt;, made from composing Jolt instructions, as defined below.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;JoltBytecode&#x2F;JoltISA&#x2F;Instruction.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;192&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Structured Jolt bytecode programs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;193&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;194&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;`instr i next` means: execute `i`; if it retires successfully, continue with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;195&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;`next`; otherwise return the non-retire result immediately. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;196&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;inductive&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Program&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;197&lt;&#x2F;span&gt;&lt;span&gt;  | done (result : ExecutionResult)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;198&lt;&#x2F;span&gt;&lt;span&gt;  | instr (instr : Instr) (next : Program)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;199&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  deriving&lt;&#x2F;span&gt;&lt;span&gt; Repr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So a program is either finished, with a final &lt;code&gt;ExecutionResult&lt;&#x2F;code&gt;, or it is one instruction followed by the rest of the program.
In plain English, a program is just the composition of instruction steps: run this instruction, then run the next instruction, and so on until the program ends.
For example, a tiny program with two instructions looks like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; tinyProgram&lt;&#x2F;span&gt;&lt;span&gt; (rd rs1 : regidx) : Program :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  .instr (.ADDI (.xreg rd) (.xreg rs1) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;) &amp;lt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  .instr (.ANDI (.xreg rd) (.xreg rd) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;255&lt;&#x2F;span&gt;&lt;span&gt;) &amp;lt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  .done RETIRE_SUCCESS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;|&lt;&#x2F;code&gt; symbol is just Lean sugar that lets us write this composition without a pile of parentheses.
Without &lt;code&gt;&amp;lt;|&lt;&#x2F;code&gt;, the same program is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; tinyProgram&lt;&#x2F;span&gt;&lt;span&gt; (rd rs1 : regidx) : Program :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  .instr (.ADDI (.xreg rd) (.xreg rs1) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    (.instr (.ANDI (.xreg rd) (.xreg rd) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;255&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      (.done RETIRE_SUCCESS))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This represents the expansion:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ADDI x[rd], x[rs1], 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ANDI x[rd], x[rd], 255&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For &lt;code&gt;LW&lt;&#x2F;code&gt;, the Lean model of the Jolt expansion lives in &lt;code&gt;JoltBytecode&#x2F;JoltISA&#x2F;Expansions&#x2F;Load.lean&lt;&#x2F;code&gt; as &lt;code&gt;JoltISA.lwProgram&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;JoltBytecode&#x2F;JoltISA&#x2F;Expansions&#x2F;Load.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;116&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Rust&amp;#39;s RV64 `LW::inline_sequence`. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;117&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; lwProgram&lt;&#x2F;span&gt;&lt;span&gt; (imm : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;) (rs1 rd : regidx) : Program :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;118&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; v0 := loadV0For rd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;119&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; v1 := loadV1For rd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;120&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; tmp := loadInlineTmpFor rd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;121&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; dst := loadDstFor rd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;122&lt;&#x2F;span&gt;&lt;span&gt;  .instr (.VirtualAssertWordAlignment rs1 imm (ExceptionType.E_Load_Addr_Align ())) &amp;lt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;123&lt;&#x2F;span&gt;&lt;span&gt;  .instr (.ADDI (.vreg v0) (.xreg rs1) imm) &amp;lt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;124&lt;&#x2F;span&gt;&lt;span&gt;  .instr (.ANDI (.vreg v1) (.vreg v0) (-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt; : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;)) &amp;lt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;125&lt;&#x2F;span&gt;&lt;span&gt;  .instr (.LD .normal (.vreg v1) (.vreg v1) &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) &amp;lt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;126&lt;&#x2F;span&gt;&lt;span&gt;  slliBlock (.vreg v0) (.vreg v0) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span&gt; : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;) &amp;lt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;127&lt;&#x2F;span&gt;&lt;span&gt;  srlBlock (.vreg v1) (.vreg v1) (.vreg v0) tmp &amp;lt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;128&lt;&#x2F;span&gt;&lt;span&gt;  .instr (.VirtualSignExtendWord dst (.vreg v1)) &amp;lt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;129&lt;&#x2F;span&gt;&lt;span&gt;  .done RETIRE_SUCCESS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We make use of some helper functions like &lt;code&gt;loadV0For&lt;&#x2F;code&gt; to model virtual register allocation.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;JoltBytecode&#x2F;JoltISA&#x2F;Expansions&#x2F;Load.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;36&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Rust source `rd = x0` rewrite destination for side-effecting load&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;37&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;expansions. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;38&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; loadDstFor&lt;&#x2F;span&gt;&lt;span&gt; (rd : regidx) : Dst :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;39&lt;&#x2F;span&gt;&lt;span&gt;  sideEffectingRdZeroDst rd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;40&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;41&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Rust load `v0`, shifted when `rd = x0` consumes the first temporary. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; loadV0For&lt;&#x2F;span&gt;&lt;span&gt; (rd : regidx) : VReg :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;43&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; isX0 rd &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt; inlineTmp1 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; loadV0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;44&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;45&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Rust load `v1`, shifted when `rd = x0` consumes the first temporary. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;46&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; loadV1For&lt;&#x2F;span&gt;&lt;span&gt; (rd : regidx) : VReg :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;47&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; isX0 rd &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt; inlineTmp2 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; loadV1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;48&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;49&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Recursive load scratch, shifted when `rd = x0` consumes the first&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;50&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;temporary. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;51&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; loadInlineTmpFor&lt;&#x2F;span&gt;&lt;span&gt; (rd : regidx) : VReg :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;52&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; isX0 rd &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt; inlineTmp3 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt; loadInlineTmp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The reason they look somewhat complex is that we also need to model the side effect of the case where &lt;code&gt;rd=x0&lt;&#x2F;code&gt;.
In that case Jolt swaps &lt;code&gt;rd&lt;&#x2F;code&gt; for the first free virtual register, and this means the downstream virtual register allocation changes by an offset of 1.
These helpers help represent that in a clean manner.
So far, this only says how to build a program. We still need to say how to run one.&lt;&#x2F;p&gt;

&lt;aside class=&quot;callout callout-remark&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;What are these blocks?&lt;&#x2F;div&gt;
  
  &lt;p&gt;One might notice that we said a program is built by composing instructions.
However, the two lines &lt;code&gt;slliBlock&lt;&#x2F;code&gt; and &lt;code&gt;srlBlock&lt;&#x2F;code&gt; are not themselves instructions.
This is because Jolt does not support &lt;code&gt;SLLI&lt;&#x2F;code&gt; and &lt;code&gt;SRL&lt;&#x2F;code&gt; natively either, so they are expanded too.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;JoltBytecode&#x2F;JoltISA&#x2F;Expansions&#x2F;ALU.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;71&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Rust `SLLI::inline_sequence`: multiply by the immediate power of two. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;72&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; slliBlock&lt;&#x2F;span&gt;&lt;span&gt; (dst : Dst) (src : Src) (shamt : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span&gt;) (tail : Program) : Program :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;73&lt;&#x2F;span&gt;&lt;span&gt;  .instr (.VirtualMULI dst src (slliMultiplier shamt)) tail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;74&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;75&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;&#x2F;-- Rust `SRL::inline_sequence`: compute the right-shift bitmask in a scratch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;76&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;virtual register, then run `VirtualSRL` with that bitmask. -&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;77&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; srlBlock&lt;&#x2F;span&gt;&lt;span&gt; (dst : Dst) (value shift : Src) (scratch : VReg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;78&lt;&#x2F;span&gt;&lt;span&gt;    (tail : Program) : Program :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;79&lt;&#x2F;span&gt;&lt;span&gt;  .instr (.VirtualShiftRightBitmask (.vreg scratch) shift) &amp;lt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;80&lt;&#x2F;span&gt;&lt;span&gt;  .instr (.VirtualSRL dst value (.vreg scratch)) tail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With the block notation, we just write the programs cleanly.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;p&gt;The Rust expansion is given below, and we can see that it lines up with the Lean &lt;code&gt;lwProgram&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;rust&quot; data-name=&quot;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;blob&#x2F;main&#x2F;crates&#x2F;jolt-program&#x2F;src&#x2F;expand&#x2F;memory&#x2F;lw.rs&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;pub&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;in crate::&lt;&#x2F;span&gt;&lt;span&gt;expand)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; expand_lw&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    instruction&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;SourceInstructionRow&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Result&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;ExpandedInstructionSequence&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; ExpansionError&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    let mut&lt;&#x2F;span&gt;&lt;span&gt; asm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; ExpansionBuilder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;instruction);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;11&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; v0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; asm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;allocate&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; asm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;allocate&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;13&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;    &#x2F;&#x2F; RAM is accessed at doubleword granularity here. The word alignment&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;15&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;    &#x2F;&#x2F; assertion is still required by the source `LW` semantics.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;    asm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;expand_address&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;        SourceInstructionKind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;VirtualAssertWordAlignment&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;        reg&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;rs1&lt;&#x2F;span&gt;&lt;span&gt;(instruction)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;19&lt;&#x2F;span&gt;&lt;span&gt;        instruction&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;operands&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;imm,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;20&lt;&#x2F;span&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;21&lt;&#x2F;span&gt;&lt;span&gt;    asm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;expand_i&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;22&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;        SourceInstructionKind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;ADDI&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;23&lt;&#x2F;span&gt;&lt;span&gt;        v0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;operand&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;24&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;        reg&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;rs1&lt;&#x2F;span&gt;&lt;span&gt;(instruction)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;25&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;        format_i_imm&lt;&#x2F;span&gt;&lt;span&gt;(instruction&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;operands&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;imm),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;26&lt;&#x2F;span&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;27&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;    &#x2F;&#x2F; v1 = containing doubleword address, v0 = byte offset within it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;28&lt;&#x2F;span&gt;&lt;span&gt;    asm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;expand_i&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;29&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;        SourceInstructionKind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;ANDI&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;30&lt;&#x2F;span&gt;&lt;span&gt;        v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;operand&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;31&lt;&#x2F;span&gt;&lt;span&gt;        v0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;operand&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;        format_i_imm&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;33&lt;&#x2F;span&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;34&lt;&#x2F;span&gt;&lt;span&gt;    asm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;expand_i&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;SourceInstructionKind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;LD&lt;&#x2F;span&gt;&lt;span&gt;, v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;operand&lt;&#x2F;span&gt;&lt;span&gt;(), v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;operand&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;35&lt;&#x2F;span&gt;&lt;span&gt;    asm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;expand_i&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;SourceInstructionKind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;SLLI&lt;&#x2F;span&gt;&lt;span&gt;, v0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;operand&lt;&#x2F;span&gt;&lt;span&gt;(), v0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;operand&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;36&lt;&#x2F;span&gt;&lt;span&gt;    asm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;expand_r&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;37&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;        SourceInstructionKind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;SRL&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;38&lt;&#x2F;span&gt;&lt;span&gt;        v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;operand&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;39&lt;&#x2F;span&gt;&lt;span&gt;        v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;operand&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;40&lt;&#x2F;span&gt;&lt;span&gt;        v0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;operand&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;41&lt;&#x2F;span&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;42&lt;&#x2F;span&gt;&lt;span&gt;    asm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;expand_i&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;43&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;        SourceInstructionKind&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;VirtualSignExtendWord&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;44&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;            jolt_riscv&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;instructions&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;VirtualSignExtendWord&lt;&#x2F;span&gt;&lt;span&gt;(()),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;45&lt;&#x2F;span&gt;&lt;span&gt;        ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;46&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;        reg&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;rd&lt;&#x2F;span&gt;&lt;span&gt;(instruction)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;?&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;47&lt;&#x2F;span&gt;&lt;span&gt;        v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;operand&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;48&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;        0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;49&lt;&#x2F;span&gt;&lt;span&gt;    );&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;50&lt;&#x2F;span&gt;&lt;span&gt;    asm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;release&lt;&#x2F;span&gt;&lt;span&gt;(v0);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;51&lt;&#x2F;span&gt;&lt;span&gt;    asm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;release&lt;&#x2F;span&gt;&lt;span&gt;(v1);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;52&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;53&lt;&#x2F;span&gt;&lt;span&gt;    asm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;finalize&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;54&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;executing-expanded-programs&quot;&gt;Executing Expanded Programs&lt;a class=&quot;zola-anchor&quot; href=&quot;#executing-expanded-programs&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Execution of a program is much like the execution of a single Jolt instruction.
Given a program, instead of a single Jolt instruction, we return a state transition function.
If the program is already complete, then execution just returns the result.
Otherwise, it takes the instruction and the rest of the program, steps the current Jolt instruction, and on successful execution, executes the rest.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;JoltBytecode&#x2F;JoltISA&#x2F;Semantics.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;413&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; execProgram&lt;&#x2F;span&gt;&lt;span&gt; : Program → JoltMonad ExecutionResult&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;414&lt;&#x2F;span&gt;&lt;span&gt;  | .done result =&amp;gt; pure result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;415&lt;&#x2F;span&gt;&lt;span&gt;  | .instr instr rest =&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;416&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;      match&lt;&#x2F;span&gt;&lt;span&gt; ← execInstr instr &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;417&lt;&#x2F;span&gt;&lt;span&gt;      | .Retire_Success () =&amp;gt; execProgram rest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;418&lt;&#x2F;span&gt;&lt;span&gt;      -- If any instruction does not complete successfully,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;419&lt;&#x2F;span&gt;&lt;span&gt;      -- &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;return&lt;&#x2F;span&gt;&lt;span&gt; Result.ok result s&amp;#39; and &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;span&gt; not run the rest of the program.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;420&lt;&#x2F;span&gt;&lt;span&gt;      | result =&amp;gt; pure result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If the instruction traps, errors, or otherwise returns a non-retire result, execution stops and that result is returned.
We will also prove that this program leaves the Sail state exactly as it would be after running the trusted Sail &lt;code&gt;LW&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;JoltBytecode&#x2F;InstructionEquivalence&#x2F;Instructions&#x2F;LoadFamily&#x2F;LW_main.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;398&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; lwProgramEqSailStatement&lt;&#x2F;span&gt;&lt;span&gt; (imm : BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;12&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;399&lt;&#x2F;span&gt;&lt;span&gt;    (rs1 rd : regidx)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;400&lt;&#x2F;span&gt;&lt;span&gt;    (js : SailJoltState)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;401&lt;&#x2F;span&gt;&lt;span&gt;    (_h : LoadProgramEqSailAssumptions imm rs1 js) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop&lt;&#x2F;span&gt;&lt;span&gt; :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;402&lt;&#x2F;span&gt;&lt;span&gt;    System.systemProjectResult&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;403&lt;&#x2F;span&gt;&lt;span&gt;      ((JoltISA.execProgram (JoltISA.lwProgram imm rs1 rd)).run js) =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;404&lt;&#x2F;span&gt;&lt;span&gt;    (execute_LOAD imm rs1 rd &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;false 4&lt;&#x2F;span&gt;&lt;span&gt;).run js.sail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The statement above translates to the following mathematical statement.

&lt;aside class=&quot;callout callout-theorem thm-numbered&quot;&gt;
  
  &lt;div class=&quot;thm-header&quot;&gt;&lt;span class=&quot;thm-label&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;thm-title&quot;&gt; — LW Equivalence Statement&lt;&#x2F;span&gt;&lt;&#x2F;div&gt;
  
  &lt;p&gt;Given a 12-bit immediate value &lt;code&gt;imm&lt;&#x2F;code&gt;, a readable source register &lt;code&gt;rs1&lt;&#x2F;code&gt;, a writable destination register &lt;code&gt;rd&lt;&#x2F;code&gt;, assumptions &lt;code&gt;h&lt;&#x2F;code&gt;, and an initial Jolt state &lt;code&gt;js&lt;&#x2F;code&gt;, running Jolt’s expanded &lt;code&gt;LW&lt;&#x2F;code&gt; program and projecting down to the Sail state gives the same state as running the trusted Sail &lt;code&gt;LW&lt;&#x2F;code&gt; on the input state &lt;code&gt;js.sail&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;&#x2F;p&gt;
&lt;p&gt;In upcoming posts, we will dive into the details of assumptions in theorem statements and how to go about proving these statements.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;appendices&quot;&gt;Appendices&lt;a class=&quot;zola-anchor&quot; href=&quot;#appendices&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;read-and-write-chain&quot;&gt;Read and Write Chain&lt;a class=&quot;zola-anchor&quot; href=&quot;#read-and-write-chain&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;LeanRV64D&#x2F;Regs.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;696&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; rX_bits&lt;&#x2F;span&gt;&lt;span&gt; (app_0 : regidx) : SailM (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;697&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; .Regidx i := app_0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;698&lt;&#x2F;span&gt;&lt;span&gt;  (rX (Regno (BitVec.toNatInt i)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;699&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;700&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; wX_bits&lt;&#x2F;span&gt;&lt;span&gt; (typ_0 : regidx) (data : (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;)) : SailM Unit := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;701&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; .Regidx i : regidx := typ_0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;702&lt;&#x2F;span&gt;&lt;span&gt;  (wX (Regno (BitVec.toNatInt i)) data)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;LeanRV64D&#x2F;Regs.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;618&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; rX&lt;&#x2F;span&gt;&lt;span&gt; (app_0 : regno) : SailM (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;) := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;619&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; .Regno r := app_0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;620&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; v ← (( &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;621&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    match&lt;&#x2F;span&gt;&lt;span&gt; r &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;622&lt;&#x2F;span&gt;&lt;span&gt;    | &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt; (pure zero_reg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;623&lt;&#x2F;span&gt;&lt;span&gt;    | &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt; readReg x1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;624&lt;&#x2F;span&gt;&lt;span&gt;    | &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt; readReg x2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;625&lt;&#x2F;span&gt;&lt;span&gt;    -- ... x3 through x30 ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;626&lt;&#x2F;span&gt;&lt;span&gt;    | _ =&amp;gt; readReg x31 ) : SailM regtype )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;627&lt;&#x2F;span&gt;&lt;span&gt;  (pure (regval_from_reg v))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;LeanRV64D&#x2F;Regs.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;656&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; wX&lt;&#x2F;span&gt;&lt;span&gt; (typ_0 : regno) (in_v : (BitVec &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;64&lt;&#x2F;span&gt;&lt;span&gt;)) : SailM Unit := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;657&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; .Regno r : regno := typ_0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;658&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; v := (regval_into_reg in_v)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;659&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  match&lt;&#x2F;span&gt;&lt;span&gt; r &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;660&lt;&#x2F;span&gt;&lt;span&gt;  | &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt; (pure ())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;661&lt;&#x2F;span&gt;&lt;span&gt;  | &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt; writeReg x1 v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;662&lt;&#x2F;span&gt;&lt;span&gt;  | &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span&gt; =&amp;gt; writeReg x2 v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;663&lt;&#x2F;span&gt;&lt;span&gt;  -- ... x3 through x30 ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;664&lt;&#x2F;span&gt;&lt;span&gt;  | _ =&amp;gt; writeReg x31 v&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;665&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; ((r != &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;) : Bool)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;666&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  then&lt;&#x2F;span&gt;&lt;span&gt; (xreg_write_callback (Regidx (to_bits (l := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;) r)) in_v)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;667&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  else&lt;&#x2F;span&gt;&lt;span&gt; (pure ())&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;.lake&#x2F;packages&#x2F;Sail&#x2F;Sail&#x2F;Sail.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;530&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; writeReg&lt;&#x2F;span&gt;&lt;span&gt; (r : Register) (v : RegisterType r) : PreSailM RegisterType c ue PUnit :=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;531&lt;&#x2F;span&gt;&lt;span&gt;  modify &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fun&lt;&#x2F;span&gt;&lt;span&gt; s =&amp;gt; { s &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;with&lt;&#x2F;span&gt;&lt;span&gt; regs := s.regs.insert r v }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;.lake&#x2F;packages&#x2F;Sail&#x2F;Sail&#x2F;Sail.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;534&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; readReg&lt;&#x2F;span&gt;&lt;span&gt; (r : Register) : PreSailM RegisterType c ue (RegisterType r) := &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;535&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; .some s := (← get).regs.get? r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;536&lt;&#x2F;span&gt;&lt;span&gt;    | throw .Unreachable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;537&lt;&#x2F;span&gt;&lt;span&gt;  pure s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;csr-assumptions&quot;&gt;CSR Assumptions&lt;a class=&quot;zola-anchor&quot; href=&quot;#csr-assumptions&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;lean&quot; data-name=&quot;JoltBytecode&#x2F;Assumptions.lean&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;107&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MstatusVRegMatchesSail&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;108&lt;&#x2F;span&gt;&lt;span&gt;  value_eq :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;109&lt;&#x2F;span&gt;&lt;span&gt;    js.sail.regs.get? Register.mstatus =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;110&lt;&#x2F;span&gt;&lt;span&gt;      some (js.vregs JoltISA.mstatusVReg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;111&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;112&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MtvecVRegMatchesSail&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;113&lt;&#x2F;span&gt;&lt;span&gt;  value_eq :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;114&lt;&#x2F;span&gt;&lt;span&gt;    js.sail.regs.get? Register.mtvec =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;115&lt;&#x2F;span&gt;&lt;span&gt;      some (js.vregs JoltISA.trapHandlerVReg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;116&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;117&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MscratchVRegMatchesSail&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;118&lt;&#x2F;span&gt;&lt;span&gt;  value_eq :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;119&lt;&#x2F;span&gt;&lt;span&gt;    js.sail.regs.get? Register.mscratch =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;120&lt;&#x2F;span&gt;&lt;span&gt;      some (js.vregs JoltISA.mscratchVReg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;121&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;122&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MepcVRegMatchesSail&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;123&lt;&#x2F;span&gt;&lt;span&gt;  value_eq :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;124&lt;&#x2F;span&gt;&lt;span&gt;    js.sail.regs.get? Register.mepc =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;125&lt;&#x2F;span&gt;&lt;span&gt;      some (js.vregs JoltISA.mepcVReg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;126&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;127&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; McauseVRegMatchesSail&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;128&lt;&#x2F;span&gt;&lt;span&gt;  value_eq :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;129&lt;&#x2F;span&gt;&lt;span&gt;    js.sail.regs.get? Register.mcause =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;130&lt;&#x2F;span&gt;&lt;span&gt;      some (js.vregs JoltISA.mcauseVReg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;131&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;132&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;structure&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; MtvalVRegMatchesSail&lt;&#x2F;span&gt;&lt;span&gt; (js : SailJoltState) : &lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;Prop where&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;133&lt;&#x2F;span&gt;&lt;span&gt;  value_eq :&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;134&lt;&#x2F;span&gt;&lt;span&gt;    js.sail.regs.get? Register.mtval =&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot; style=&quot;color: #1B1F234D;&quot;&gt;135&lt;&#x2F;span&gt;&lt;span&gt;      some (js.vregs JoltISA.mtvalVReg)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-risc-v-isa&quot;&gt;
&lt;p&gt;See the RISC-V ISA for a detailed description of state. &lt;a href=&quot;#fr-risc-v-isa-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-dep&quot;&gt;
&lt;p&gt;More formally, the state is defined as a dependent inductive type with one constructor. So to fully define the state, one must &lt;em&gt;specify&lt;&#x2F;em&gt; a term of the function type &lt;code&gt;RegisterType&lt;&#x2F;code&gt; and a term of &lt;code&gt;ChoiceSource&lt;&#x2F;code&gt;. &lt;a href=&quot;#fr-dep-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-term&quot;&gt;
&lt;p&gt;Or, in Lean terms, the term of type &lt;code&gt;Register → Type&lt;&#x2F;code&gt;. &lt;a href=&quot;#fr-term-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-gpr&quot;&gt;
&lt;p&gt;For our purposes, &lt;code&gt;regidx&lt;&#x2F;code&gt; behaves just like a &lt;code&gt;BitVec 5&lt;&#x2F;code&gt;, but is given its own name to record that this particular 5-bit vector is a &lt;em&gt;general-purpose register index&lt;&#x2F;em&gt;. Here the condition is &lt;code&gt;false&lt;&#x2F;code&gt;, so the &lt;code&gt;if&lt;&#x2F;code&gt; reduces through the &lt;code&gt;else&lt;&#x2F;code&gt; branch to &lt;code&gt;5&lt;&#x2F;code&gt;, and &lt;code&gt;regidx&lt;&#x2F;code&gt; is just &lt;code&gt;Regidx (BitVec 5)&lt;&#x2F;code&gt;.
This aligns with the RISC-V spec that there are $2^5 = 32$ general-purpose registers. &lt;a href=&quot;#fr-gpr-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-monad-instance&quot;&gt;
&lt;p&gt;In simple terms, this means &lt;code&gt;pure&lt;&#x2F;code&gt; and &lt;code&gt;bind&lt;&#x2F;code&gt; have been implemented for &lt;code&gt;m&lt;&#x2F;code&gt;. &lt;a href=&quot;#fr-monad-instance-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-populated&quot;&gt;
&lt;p&gt;As the register file is a hash map, Lean requires a proof that the key already exists in the hash map. Without this proof, we are unable to get the bits inside the hash map, and the computation errors as shown in the appendices.
Of course, in a real physical CPU, the register file is not a hash map and we do not have to say that general-purpose register &lt;code&gt;x&lt;&#x2F;code&gt; exists. So although not shown here, to prove theorems we will have a general assumption that the general-purpose registers can be read. &lt;a href=&quot;#fr-populated-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-extend&quot;&gt;
&lt;p&gt;This state may change as we model other parts of Jolt and decide whether to include the remaining Rust fields. &lt;a href=&quot;#fr-extend-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
  </entry>
  
  
  
  <entry xml:lang="en">
    <title>Sail RISC-V Into Lean</title>
    <published>2026-03-22T00:00:00+00:00</published>
    <updated>2026-03-22T00:00:00+00:00</updated>
    
      <author><name>Ari</name></author>
    
    <link rel="alternate" type="text/html" href="https://randomwalks.xyz/blog/sail-to-lean/"/>
    <id>https://randomwalks.xyz/blog/sail-to-lean/</id>
    
    <content type="html" xml:base="https://randomwalks.xyz/blog/sail-to-lean/">
&lt;aside class=&quot;callout callout-caution&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;Caution&lt;&#x2F;div&gt;
  
  &lt;p&gt;These notes re-cap the steps required to transplile the RISC-V sail specification to Lean.&lt;&#x2F;p&gt;
&lt;p&gt;NOTE: As confirmed from the original documentation, only the non-computable Lean code builds and compiles cleanly.
Some work is still needed to get the executable CPU to work.
I do not imagine a whole lot, but as of the date of writing this, the executable build is not clean.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;p&gt;Tested on:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;macOS (Apple Silicon)&lt;&#x2F;li&gt;
&lt;li&gt;Intel CPU Arch Linux (TODO:)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;step-0-clone-both-repos&quot;&gt;Step 0: Clone Both Repos&lt;a class=&quot;zola-anchor&quot; href=&quot;#step-0-clone-both-repos&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Here I’ve forked the two repositories with the hope of eventually fixing the executable issue.
But there’s nothing special about my fork right now. Cloning the original repos will also work.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; clone git@github.com:abiswas3&#x2F;sail-riscv.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; clone git@github.com:abiswas3&#x2F;sail.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;parent&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── sail&#x2F;                  # Sail compiler (transpiler) -- clone from github.com&#x2F;rems-project&#x2F;sail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└── sail-riscv&#x2F;            # This repo -- RISC-V ISA model written in Sail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;step-1-install-system-dependencies&quot;&gt;Step 1: Install System Dependencies&lt;a class=&quot;zola-anchor&quot; href=&quot;#step-1-install-system-dependencies&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;

&lt;aside class=&quot;callout callout-warning&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;Note To Reader&lt;&#x2F;div&gt;
  
  &lt;p&gt;I do not particularly understand the Sail DSL, nor am I an expert ocaml programmer.
These steps mostly follow the &lt;code&gt;README.md&lt;&#x2F;code&gt;’s in the repo, a bit of googling and some Claude code help.
Hopefully with time, I will be able to write a better version of what the hell is going on.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;h3 id=&quot;macos-homebrew&quot;&gt;macOS (Homebrew)&lt;a class=&quot;zola-anchor&quot; href=&quot;#macos-homebrew&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;xcode-select&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --install&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;    # if not already done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;brew&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; install opam gmp z3 pkgconf cmake&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;arch-linux&quot;&gt;Arch Linux&lt;a class=&quot;zola-anchor&quot; href=&quot;#arch-linux&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; pacman&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -S&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; opam&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;        # OCaml package manager -- needed to fetch and install Sail&amp;#39;s OCaml dependencies&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; pacman&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -S&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; gmp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;         # GNU Multiple Precision arithmetic library -- Sail uses it internally for big integer arithmetic&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; pacman&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -S&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; z3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;          # SMT solver from Microsoft Research -- Sail calls Z3 during type-checking to prove&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;                           #   arithmetic constraints on dependent types (e.g. that bitvector widths are correct)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; pacman&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -S&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; cmake&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;       # build system generator -- sail-riscv uses CMake to orchestrate the Sail-to-Lean code generation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; pacman&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -S&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; base-devel&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;  # C compiler, make, binutils, etc. -- OCaml&amp;#39;s runtime is written in C and some opam&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;                           #   packages have C bindings (e.g. GMP). Also provides C++ compiler which sail-riscv&amp;#39;s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;                           #   CMake build needs for the emulator harness, even if you only want Lean output.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; pacman&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -S&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; pkgconf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;     # pkg-config implementation -- CMake uses it to locate system libraries like GMP&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;both-platforms-initialize-opam-one-time&quot;&gt;Both Platforms: Initialize opam (one-time)&lt;a class=&quot;zola-anchor&quot; href=&quot;#both-platforms-initialize-opam-one-time&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Run the following code from anywhere – opam stores its state in &lt;code&gt;~&#x2F;.opam&#x2F;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;TODO:&lt;&#x2F;strong&gt; ocaml crash course&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;opam&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; init&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;                 # follow prompts, say yes to shell setup&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;eval&lt;&#x2F;span&gt;&lt;span&gt; $(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;opam&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; env&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;          # or restart your shell&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;opam init&lt;&#x2F;code&gt; creates the &lt;code&gt;~&#x2F;.opam&#x2F;&lt;&#x2F;code&gt; directory, downloads the OCaml package registry, and
installs a default OCaml compiler.
&lt;code&gt;eval $(opam env)&lt;&#x2F;code&gt; sets shell environment variables (&lt;code&gt;PATH&lt;&#x2F;code&gt;, &lt;code&gt;OCAML_TOPLEVEL_PATH&lt;&#x2F;code&gt;, etc.) so that your shell can find the OCaml tools and
libraries that opam installed.
You need to run &lt;code&gt;eval $(opam env)&lt;&#x2F;code&gt; in each new shell session, or let opam’s shell hook do it automatically (it offers to set this up during
&lt;code&gt;opam init&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-2-build-and-install-the-sail-compiler-locally&quot;&gt;Step 2: Build and Install the Sail Compiler Locally&lt;a class=&quot;zola-anchor&quot; href=&quot;#step-2-build-and-install-the-sail-compiler-locally&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;You should be in the &lt;code&gt;parent&#x2F;&lt;&#x2F;code&gt; directory (the one containing both &lt;code&gt;sail&#x2F;&lt;&#x2F;code&gt; and &lt;code&gt;sail-riscv&#x2F;&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;The Sail compiler is a single binary called &lt;code&gt;sail&lt;&#x2F;code&gt;.
On its own, it can only parse and type-check Sail code.
To actually generate output for a specific language (Lean, C++, Coq, etc.), it needs a &lt;strong&gt;backend plugin&lt;&#x2F;strong&gt; loaded at startup.&lt;&#x2F;p&gt;

&lt;aside class=&quot;callout callout-box thm-box&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;What The Hell Is A Plugin&lt;&#x2F;div&gt;
  
  &lt;p&gt;Note that I do not understand ocaml’s plugin infrastructure properly.
I had to ask Calude and this is what it gave me:&lt;&#x2F;p&gt;
&lt;p&gt;A plugin is a &lt;code&gt;.cmxs&lt;&#x2F;code&gt; file – an OCaml shared library (see &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ocaml.org&#x2F;manual&#x2F;5.2&#x2F;native.html#s:native:dynlink&quot;&gt;OCaml manual on native plugins&lt;&#x2F;a&gt;).
When &lt;code&gt;sail&lt;&#x2F;code&gt; starts, it scans a known directory for &lt;code&gt;.cmxs&lt;&#x2F;code&gt; files and loads them.
Each plugin registers new command-line flags.
For example, loading &lt;code&gt;sail_plugin_lean.cmxs&lt;&#x2F;code&gt; adds the &lt;code&gt;--lean&lt;&#x2F;code&gt; flag to the &lt;code&gt;sail&lt;&#x2F;code&gt; binary.
There is no separate “lean binary” – it’s all one &lt;code&gt;sail&lt;&#x2F;code&gt; binary with plugins extending its capabilities.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;p&gt;&lt;strong&gt;dune&lt;&#x2F;strong&gt; is OCaml’s build system (like &lt;code&gt;make&lt;&#x2F;code&gt; or &lt;code&gt;cargo&lt;&#x2F;code&gt;).
It reads build instructions from &lt;code&gt;dune&lt;&#x2F;code&gt; files in the source tree.
Below, we use three commands. Each is explained with what it does and what it produces:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; sail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;2a-install-ocaml-dependencies&quot;&gt;2a. Install OCaml dependencies&lt;a class=&quot;zola-anchor&quot; href=&quot;#2a-install-ocaml-dependencies&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;opam&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; install .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --deps-only&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Reads the &lt;code&gt;.opam&lt;&#x2F;code&gt; files in the sail repo and installs all required OCaml libraries
into the current opam switch. Does not build sail itself.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2b-build-the-compiler-and-plugins&quot;&gt;2b. Build the compiler and plugins&lt;a class=&quot;zola-anchor&quot; href=&quot;#2b-build-the-compiler-and-plugins&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;dune&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --release&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Compiles everything in the sail repo. Produces build artifacts under &lt;code&gt;_build&#x2F;&lt;&#x2F;code&gt;, including:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_build&#x2F;default&#x2F;src&#x2F;bin&#x2F;sail.exe&lt;&#x2F;code&gt; – the core sail binary&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;_build&#x2F;default&#x2F;src&#x2F;sail_lean_backend&#x2F;sail_plugin_lean.cmxs&lt;&#x2F;code&gt; – the Lean plugin&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;At this point the binary exists but doesn’t know where to find its plugins.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2c-install-into-a-local-prefix&quot;&gt;2c. Install into a local prefix&lt;a class=&quot;zola-anchor&quot; href=&quot;#2c-install-into-a-local-prefix&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;dune&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; install&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --prefix&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; _local_install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Copies the binary, plugins, and standard library files into a structured directory:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_local_install&#x2F;bin&#x2F;sail&lt;&#x2F;code&gt; – the sail binary&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;_local_install&#x2F;share&#x2F;libsail&#x2F;plugins&#x2F;sail_plugin_lean.cmxs&lt;&#x2F;code&gt; – the Lean plugin&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;_local_install&#x2F;share&#x2F;sail&#x2F;lib&#x2F;&lt;&#x2F;code&gt; – Sail’s standard library (prelude, etc.)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This is what “installing a plugin” means concretely: copying the &lt;code&gt;.cmxs&lt;&#x2F;code&gt; file into the
&lt;code&gt;share&#x2F;libsail&#x2F;plugins&#x2F;&lt;&#x2F;code&gt; directory where the &lt;code&gt;sail&lt;&#x2F;code&gt; binary knows to look for it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; ..&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;verify-the-lean-backend-is-loaded&quot;&gt;Verify the Lean backend is loaded&lt;a class=&quot;zola-anchor&quot; href=&quot;#verify-the-lean-backend-is-loaded&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAIL_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;sail&#x2F;_local_install&#x2F;share&#x2F;sail&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; sail&#x2F;_local_install&#x2F;bin&#x2F;sail&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --help&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; grep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; lean&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;SAIL_DIR&lt;&#x2F;code&gt; tells the sail binary where to find its standard library and plugins.
You should see &lt;code&gt;--lean&lt;&#x2F;code&gt; and related flags listed. If you don’t, the plugin file is
not in the expected &lt;code&gt;share&#x2F;libsail&#x2F;plugins&#x2F;&lt;&#x2F;code&gt; directory – re-run &lt;code&gt;dune install&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-3-configure-the-sail-riscv-build&quot;&gt;Step 3: Configure the sail-riscv Build&lt;a class=&quot;zola-anchor&quot; href=&quot;#step-3-configure-the-sail-riscv-build&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;From the parent directory (or from &lt;code&gt;sail-riscv&#x2F;&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; sail-riscv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAIL_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;realpath&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; ..&#x2F;sail&#x2F;_local_install&#x2F;share&#x2F;sail&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cmake&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -S&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -B&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;  -DCMAKE_BUILD_TYPE=RelWithDebInfo \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;  -DSAIL_BIN=$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;realpath&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; ..&#x2F;sail&#x2F;_local_install&#x2F;bin&#x2F;sail&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Key variables:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SAIL_DIR&lt;&#x2F;code&gt; – points to the installed Sail share directory. This is where the
compiler finds its standard library, include files, and plugins.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;SAIL_BIN&lt;&#x2F;code&gt; – path to the locally-installed sail binary.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;&#x2F;strong&gt; Both paths must be &lt;strong&gt;absolute&lt;&#x2F;strong&gt;. CMake runs &lt;code&gt;sail --dir&lt;&#x2F;code&gt; internally
to locate the Sail library directory, and the sail binary echoes back whatever
&lt;code&gt;SAIL_DIR&lt;&#x2F;code&gt; was set to. If that’s a relative path like &lt;code&gt;..&#x2F;sail&#x2F;...&lt;&#x2F;code&gt;, CMake
resolves it relative to the build directory (&lt;code&gt;build&#x2F;&lt;&#x2F;code&gt;), not the source directory,
causing “Cannot find source file” errors for the C runtime files.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-4-generate-lean-code&quot;&gt;Step 4: Generate Lean Code&lt;a class=&quot;zola-anchor&quot; href=&quot;#step-4-generate-lean-code&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Two variants can be generated. Both take a few minutes (the Sail compiler
type-checks the full model, calling Z3 to solve arithmetic constraints).&lt;&#x2F;p&gt;

&lt;aside class=&quot;callout callout-warning&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;Warning&lt;&#x2F;div&gt;
  
  &lt;p&gt;I also do not understand any of the Z3 stuff right now.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;h3 id=&quot;noncomputable-for-theorem-proving&quot;&gt;Noncomputable (for theorem proving)&lt;a class=&quot;zola-anchor&quot; href=&quot;#noncomputable-for-theorem-proving&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAIL_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;realpath&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; ..&#x2F;sail&#x2F;_local_install&#x2F;share&#x2F;sail&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;  cmake&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --target&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; generated_lean_rv64d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Output: &lt;code&gt;build&#x2F;model&#x2F;Lean_RV64D&#x2F;&lt;&#x2F;code&gt; (~155 &lt;code&gt;.lean&lt;&#x2F;code&gt; files)&lt;&#x2F;p&gt;
&lt;p&gt;This version uses &lt;code&gt;noncomputable&lt;&#x2F;code&gt; sections, suitable for interactive proof in Lean.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;executable-for-running-theorem-provin-theorem-provingg&quot;&gt;Executable (for running + theorem provin + theorem provingg)&lt;a class=&quot;zola-anchor&quot; href=&quot;#executable-for-running-theorem-provin-theorem-provingg&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAIL_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;realpath&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; ..&#x2F;sail&#x2F;_local_install&#x2F;share&#x2F;sail&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;  cmake&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --target&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; generated_lean_executable_rv64d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Output: &lt;code&gt;build&#x2F;model&#x2F;Lean_RV64D_executable&#x2F;&lt;&#x2F;code&gt; (~155 &lt;code&gt;.lean&lt;&#x2F;code&gt; files)&lt;&#x2F;p&gt;
&lt;p&gt;This version generates computable code that can be built and executed with &lt;code&gt;lake build&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rv32-variants&quot;&gt;RV32 Variants&lt;a class=&quot;zola-anchor&quot; href=&quot;#rv32-variants&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Replace &lt;code&gt;rv64d&lt;&#x2F;code&gt; with &lt;code&gt;rv32d&lt;&#x2F;code&gt; in the target names for 32-bit:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;generated_lean_rv32d&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;generated_lean_executable_rv32d&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;step-5-build-the-generated-lean-code-optional&quot;&gt;Step 5: Build the Generated Lean Code (Optional)&lt;a class=&quot;zola-anchor&quot; href=&quot;#step-5-build-the-generated-lean-code-optional&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Each output directory contains a &lt;code&gt;lakefile.toml&lt;&#x2F;code&gt; and &lt;code&gt;lean-toolchain&lt;&#x2F;code&gt;. To compile:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; build&#x2F;model&#x2F;Lean_RV64D&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;          # or Lean_RV64D_executable&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;lake&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; update&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;lake&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; build&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The generated Lean requires a specific Lean toolchain version (specified in
&lt;code&gt;lean-toolchain&lt;&#x2F;code&gt;) and the &lt;code&gt;lean-sail&lt;&#x2F;code&gt; support library (fetched automatically by &lt;code&gt;lake&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rebuilding-after-sail-compiler-changes&quot;&gt;Rebuilding After Sail Compiler Changes&lt;a class=&quot;zola-anchor&quot; href=&quot;#rebuilding-after-sail-compiler-changes&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Since you’re running from source, after modifying the Sail compiler:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# 1. Rebuild and reinstall the compiler&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; ..&#x2F;sail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;dune&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --release&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;dune&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; install&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --prefix&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; _local_install&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# 2. Clean stale outputs and re-generate Lean (from sail-riscv)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;cd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; ..&#x2F;sail-riscv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;rm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; -rf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; build&#x2F;model&#x2F;Lean_RV64D build&#x2F;model&#x2F;Lean_RV64D_executable&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAIL_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;realpath&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; ..&#x2F;sail&#x2F;_local_install&#x2F;share&#x2F;sail&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;  cmake&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --target&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; generated_lean_rv64d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SAIL_DIR&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;$(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;realpath&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; ..&#x2F;sail&#x2F;_local_install&#x2F;share&#x2F;sail&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;  cmake&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; build&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --target&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; generated_lean_executable_rv64d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;troubleshooting&quot;&gt;Troubleshooting&lt;a class=&quot;zola-anchor&quot; href=&quot;#troubleshooting&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Cannot find source file: ..&#x2F;sail&#x2F;_local_install&#x2F;share&#x2F;sail&#x2F;lib&#x2F;elf.c&lt;&#x2F;code&gt;&lt;&#x2F;strong&gt;: You used
relative paths for &lt;code&gt;SAIL_DIR&lt;&#x2F;code&gt;. CMake resolves paths relative to the build directory,
not where you ran the command. Use &lt;code&gt;$(realpath ..&#x2F;sail&#x2F;_local_install&#x2F;share&#x2F;sail)&lt;&#x2F;code&gt; to
get an absolute path.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;--lean&lt;&#x2F;code&gt; flag not found&lt;&#x2F;strong&gt;: The plugin wasn’t installed. Make sure you ran
&lt;code&gt;dune install --prefix _local_install&lt;&#x2F;code&gt; and that &lt;code&gt;SAIL_DIR&lt;&#x2F;code&gt; points to the
&lt;code&gt;_local_install&#x2F;share&#x2F;sail&lt;&#x2F;code&gt; directory (not the repo root or &lt;code&gt;lib&#x2F;&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;sail: command not found&lt;&#x2F;code&gt; during cmake&lt;&#x2F;strong&gt;: You need to pass &lt;code&gt;-DSAIL_BIN=&lt;&#x2F;code&gt; pointing
to your local install, and set &lt;code&gt;SAIL_DIR&lt;&#x2F;code&gt; as an environment variable.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Plugin load error (&lt;code&gt;symbol not found&lt;&#x2F;code&gt;)&lt;&#x2F;strong&gt;: Version mismatch between the sail binary
and the plugin. Run &lt;code&gt;dune build --release &amp;amp;&amp;amp; dune install --prefix _local_install&lt;&#x2F;code&gt;
again to rebuild both from the same source.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CMake cache error about mismatched source directory&lt;&#x2F;strong&gt;: Delete &lt;code&gt;build&#x2F;&lt;&#x2F;code&gt; and
reconfigure: &lt;code&gt;rm -rf build &amp;amp;&amp;amp; cmake -S . -B build ...&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;what-gets-generated&quot;&gt;What Gets Generated&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-gets-generated&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;The Sail compiler translates the entire RISC-V ISA model into Lean definitions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Instruction encodings&#x2F;decodings&lt;&#x2F;li&gt;
&lt;li&gt;Instruction semantics&lt;&#x2F;li&gt;
&lt;li&gt;CSR definitions&lt;&#x2F;li&gt;
&lt;li&gt;Memory model&lt;&#x2F;li&gt;
&lt;li&gt;Exception handling&lt;&#x2F;li&gt;
&lt;li&gt;Extension support (M, A, F, D, C, V, etc.)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The noncomputable version is for reasoning about the spec in Lean’s type theory.
The executable version can simulate RISC-V binaries.&lt;&#x2F;p&gt;
</content>
  </entry>
  
  
  
  <entry xml:lang="en">
    <title>Anatomy Of A Jolt Sumcheck</title>
    <published>2025-12-01T00:00:00+00:00</published>
    <updated>2026-02-17T00:00:00+00:00</updated>
    
      <author><name>Ari</name></author>
    
    <link rel="alternate" type="text/html" href="https://randomwalks.xyz/blog/streaming-sumchecks/"/>
    <id>https://randomwalks.xyz/blog/streaming-sumchecks/</id>
    
    <content type="html" xml:base="https://randomwalks.xyz/blog/streaming-sumchecks/">
&lt;aside class=&quot;callout callout-remark&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;(Update) 2026-08-14&lt;&#x2F;div&gt;
  
  &lt;p&gt;Jolt has changed so much since writing this post was written, the code is no longer in main.
Still the post remains valid if one were to understand how to implement streaming sum-checks.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;p&gt;This write-up talks about this &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;a16z&#x2F;jolt&#x2F;pull&#x2F;1114&quot;&gt;PR&lt;&#x2F;a&gt; which introduces a generalised sum-check API, adapted to accommodate an implementation of Jolt that uses $O(1)$ memory&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-d-1&quot;&gt;&lt;a href=&quot;#fn-d&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-trace&quot;&gt;The Trace&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-trace&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Before we describe the API, it will be useful to briefly re-cap how Jolt works.
At the heart of the Jolt prover is the sumcheck algorithm.
Given some polynomial $g$ and a set $S$ with sufficient structure&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-e-1&quot;&gt;&lt;a href=&quot;#fn-e&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;, the sum-check algorithm enables a prover to convince a verifier that it computed $\sum_{x \in S} g(x)$ honestly.
The end goal of the Jolt prover is to convince an honest verifier that it ran some guest program&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-c-1&quot;&gt;&lt;a href=&quot;#fn-c&quot;&gt;3&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; correctly.
It does so via many sum-check algorithms.
Therefore for the whole setup to work, the polynomials involved in these sumchecks must be in some way related to the execution of said program.
As such honest proving begins with emulation of the given RISC-V program – which we refer to as the trace.
This is a fancy way of saying that the prover runs the program, and stores succinctly as a list the machine state before and after each instruction.
This list is what we refer to as the trace.
And it is this trace from which we will construct the sum-check polynomials in Jolt.
See the emulation post for a fully worked out description of the emulation from an actual albeit useless program written in Rust.
For example, consider the following program with just two instructions.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;00001117&lt;&#x2F;span&gt;&lt;span&gt;    auipc  &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;sp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0x1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # sp = PC + (0x1 &amp;lt;&amp;lt; 12) = 0x80000000 + 0x1000 = 0x80001000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;12010113&lt;&#x2F;span&gt;&lt;span&gt;    addi   &lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;sp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;sp&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;288&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # sp = 0x80001000 + 288 = 0x80001120&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After doing some initial setup of all the values of registers and memory, the emulation looks like the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Cycle&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; AUIPC&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2147483648&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;  &#x2F;&#x2F; = 0x80000000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    operands&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; FormatU&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;            &#x2F;&#x2F; x2 = sp (stack pointer)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        imm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;        &#x2F;&#x2F; = 0x1000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    register_state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        rd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2147487744&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;  &#x2F;&#x2F; sp: 0 → 0x80001000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Cycle&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; ADDI&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    RISCVCycle&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        instruction&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; ADDI&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2147483652&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;  &#x2F;&#x2F; = 0x80000004 (Program counter)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            operands&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; FormatI&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                rd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;            &#x2F;&#x2F; sp (based on mapping above)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                rs1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;           &#x2F;&#x2F; sp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                imm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 288&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;         &#x2F;&#x2F; = 0x120&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            virtual_sequence_remaining&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; None&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            is_first_in_sequence&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            is_compressed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        register_state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; RegisterStateFormatI&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            rd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;                2147487744&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; new value in rd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;                2147488032&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; old value in rd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            rs1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; 2147487744&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; value in rs1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ram_access&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; (),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; no ram access&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    },&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For the purposes of this post, this is the mental model we will have when referring to the trace.
It is a giant vector of length $T$, and location $t \in [T]$ stores the machine state before and after the $t$’th instruction.&lt;&#x2F;p&gt;

&lt;aside class=&quot;callout callout-remark&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;A Lie In Service Of The Truth&lt;&#x2F;div&gt;
  
  &lt;p&gt;Throughout this post we will assume that we can store the entire trace in memory, and iterating through the trace is free. This is clearly not true, and we will fix this at a later date.
But for the purposes of this post, this assumption allows us to abstract away important implementation details that currently remain unimplemented, and prove that we can indeed implement any Jolt sumcheck with $O(1)$ memory.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;h2 id=&quot;correctness-as-constraint-satisfaction&quot;&gt;Correctness As Constraint Satisfaction&lt;a class=&quot;zola-anchor&quot; href=&quot;#correctness-as-constraint-satisfaction&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Now with the trace&#x2F;emulation in hand, we ask - what does it mean for a program to be executed correctly?
One way to define correctness would be to say at every cycle, the machine state is consistent with the program specification.
As a concrete example, consider loading and storing to memory.
In RISC-V assembly loads&#x2F;store instructions look like the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lb   rd, offset(rs1)   &lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # Load byte (sign-extended)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lh   rd, offset(rs1)   &lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # Load halfword (sign-extended)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lw   rd, offset(rs1)   &lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # Load word (sign-extended)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ld   rd, offset(rs1)   &lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # Load doubleword (RV64)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lbu  rd, offset(rs1)   &lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # Load byte unsigned&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lhu  rd, offset(rs1)   &lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # Load halfword unsigned&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lwu  rd, offset(rs1)   &lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # Load word unsigned (RV64)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sb   rs2, offset(rs1)  &lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # Store byte&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sh   rs2, offset(rs1)  &lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # Store halfword&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sw   rs2, offset(rs1)  &lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # Store word&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sd   rs2, offset(rs1)  &lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; # Store doubleword (RV64)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So if the instruction has the &lt;code&gt;Load&lt;&#x2F;code&gt; flag set to 1 or &lt;code&gt;Store&lt;&#x2F;code&gt; flag set to 1, then the address from which we read&#x2F;write must be equal to value in &lt;code&gt;rs1 + offset&lt;&#x2F;code&gt;.
Using propositional logic we write:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if { Instruct has Load OR Store } then ( RamAddress ) == ( Rs1Value + Imm )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The same thing expressed as algebraic constraints:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(Load + Store) * (RamAddress - (Rs1Value + Imm)) = 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For a program to be correctly executed, for every time step $t \in \lbrace 0,1 \rbrace^{\log T}$, the above constraint must be satisfied.
Of course for a program to be correct, it is not sufficient to just satisfy the above constraint.
There are many more constraints.
In the &lt;code&gt;OuterSpartan&lt;&#x2F;code&gt; sumcheck we write down 20 such constraints, express these constraints as the evaluations of two polynomials $\widetilde{A}$ and $\widetilde{B}$, and represent constraint satisfaction as a sumcheck.
More details follow.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-outer-spartan-polynomials&quot;&gt;The Outer Spartan Polynomials&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-outer-spartan-polynomials&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;There are 20 constraints for each time step $t \in \lbrace 0,1\rbrace^{\log T}$.
Each constraint will be of form&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;Term 1 * Term 2 = 0&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here &lt;code&gt;Term 1&lt;&#x2F;code&gt; will be represented by $A$ and &lt;code&gt;Term 2&lt;&#x2F;code&gt; will be represented by $B$.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Indexing&lt;&#x2F;strong&gt;: We divide the 20 constraints into 2 groups.
We refer to each constraint using two digits&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-a-1&quot;&gt;&lt;a href=&quot;#fn-a&quot;&gt;4&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; $(b,y)$ where $b \in \lbrace 0,1\rbrace$ is the selector index, and $y\in \lbrace -4, \ldots, 5\rbrace$ refers to one of the 10 constraints in group $b$.
For example,&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;$(0,-4)$ refers to constraint 1,&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;$(0, -3)$ refers to constraint 2,&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;…&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;$(1, 5)$ refers to the 20th constraint and so on.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;example-constraint-1&quot;&gt;Example : Constraint 1&lt;a class=&quot;zola-anchor&quot; href=&quot;#example-constraint-1&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Let $z_t[\text{LOAD}], z_t[\text{STORE}] \in \lbrace 0,1\rbrace$ denote boolean flags that denote whether the $t$’th instruction contains a LOAD or a STORE instruction.
For a given time step $t \in \lbrace 0,1\rbrace^{\log T}$, using information from the trace, we write a table of evaluations with the following indexing logic:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;$A(t, 0 , -4) = z_t[\text{LOAD}] + z_t[\text{STORE}]$&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;$B(t, 0, -4) = (\text{RamAddress} - (\text{Rs1Value} + \text{Imm}))$&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;That is satisfying constraint 1 for time step $t$ is equivalent to checking if $A(t, 0, -4) \times B(t, 0, -4) = 0$.
The remaining 19 constraints give us evaluations $A(X_t, X_b, Y)$ and $B(X_t, X_b, Y)$ for $Y \in \lbrace -4, \ldots, 5\rbrace, X_b \in \lbrace 0,1\rbrace, X_t \in \lbrace 0,1\rbrace^{\log T}$.
The picture you have in mind is the following
&lt;img src=&quot;https:&#x2F;&#x2F;randomwalks.xyz&#x2F;blog&#x2F;streaming-sumchecks&#x2F;trave_to_poly.svg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Satisfying all constraints is just saying the following:&lt;&#x2F;p&gt;
&lt;div class=&quot;math-display&quot;&gt;
$$
\widetilde{A}(x_t, x_b, y) \times \widetilde{B}(x_t, x_b,  y) = \vec{0} \quad \forall x_t \in \{0,1\}^{\log T}, \forall x_b \in \{0,1\}, \forall y \in \{-4, ..., 5\}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;where $\widetilde{U}$ denotes the multilinear extension of a vector $U$.&lt;&#x2F;p&gt;

&lt;aside class=&quot;callout callout-definition thm-numbered&quot;&gt;
  
  &lt;div class=&quot;thm-header&quot;&gt;&lt;span class=&quot;thm-label&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;thm-title&quot;&gt; — Notation&lt;&#x2F;span&gt;&lt;&#x2F;div&gt;
  
  &lt;ul&gt;
&lt;li&gt;$\widetilde{U}$ denotes the &lt;strong&gt;multilinear extension&lt;&#x2F;strong&gt; (MLE) of $U$: the unique multilinear polynomial agreeing with $U$ on all Boolean inputs.&lt;&#x2F;li&gt;
&lt;li&gt;$\eq{\tau}{x}$ is the &lt;strong&gt;equality polynomial&lt;&#x2F;strong&gt;, evaluating to 1 when $\tau = x$ on the Boolean hypercube and 0 otherwise.&lt;&#x2F;li&gt;
&lt;li&gt;$\mathcal{L}_a(X)$ is the &lt;strong&gt;Lagrange basis polynomial&lt;&#x2F;strong&gt; for point $a$ in a domain $D$: the unique polynomial of degree $|D|-1$ satisfying $\mathcal{L}_a(a) = 1$ and $\mathcal{L}_a(d) = 0$ for all other $d \in D$.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;

&lt;&#x2F;aside&gt;

&lt;p&gt;Now we do the thing we have done since the beginning of time.
We want to make sure the LHS of the above system of equations equals the RHS as polynomials.
So we sample $(\TauTime | \tau_{b} | \TauConstraints) \samples \ChallengeSet^{\log T+2}$ and check if the following sumcheck holds:&lt;&#x2F;p&gt;
&lt;div class=&quot;math-display&quot;&gt;
$$\sum_{x_t \in \{0,1\}^{\log T}} \sum_{x_b \in \{0,1\}} \sum_{y \in \{-4,...,5\}} \eq{\tau_t}{x_t} \cdot \eq{\tau_{b}}{x_b} \cdot \Lagrange{y}{\TauConstraints} \cdot \widetilde{A}(x_t, x_b, y) \, \widetilde{B}(x_t, x_b, y) = 0 $$
&lt;&#x2F;div&gt;
&lt;p&gt;By Schwartz-Zippel, with high probability if the above test passes, then the verifier can be happy that the prover was honest.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;review-of-the-linear-sumcheck-implementation&quot;&gt;Review Of The Linear Sumcheck Implementation&lt;a class=&quot;zola-anchor&quot; href=&quot;#review-of-the-linear-sumcheck-implementation&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;As described above in the picture, in order to get $\widetilde{A}(x_t, x_b, y)$ and $\widetilde{B}(x_t, x_b, y)$ we need to process the $t$’th location of the trace.
As soon as we process every location of the trace once, we can store $\widetilde{A}$ and $\widetilde{B}$ in memory.
This requires $T \times 2 \times 20$ field elements worth of memory.
If we could afford this, we can bin the trace once and for all.
We have every bit of information needed to complete the sum-check algorithm.
This is almost how the current implementation of the linear &lt;code&gt;OuterSpartan&lt;&#x2F;code&gt; sumcheck looks.
Except there’s a special first round, which we describe below.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;A special handling of round involving variable $Y$ involving 10 constraints per time step and group index.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Remember in each round of the sum-check the prover sends to the verifier a univariate polynomial, and the verifier responds with a challenge $r \samples \ChallengeSet$ sampled from the challenge set.
We iterate through the entire trace, &lt;strong&gt;but&lt;&#x2F;strong&gt; we do &lt;strong&gt;NOT&lt;&#x2F;strong&gt; compute and store $\widetilde{A}$ and $\widetilde{B}$ in memory.
Instead we store in memory the following univariate polynomial, which is the prover’s first round message.&lt;&#x2F;p&gt;
&lt;div class=&quot;math-display&quot;&gt;
$$s(\textcolor{pink}{Y}) \Def \sum_{x_t \in \{0,1\}^{\log T}} \sum_{x_b \in \{0,1\}} \eq{\tau_t}{x_t} \cdot \eq{\tau_{b}}{x_b} \cdot \Lagrange{\TauConstraints}{\textcolor{pink}{Y}} \cdot A(x_t, x_b, \textcolor{pink}{Y}) \, B(x_t, x_b , \textcolor{pink}{Y})$$
&lt;&#x2F;div&gt;
&lt;p&gt;This takes $O(1)$ field elements worth of storage as there are only $10$ constraints per group.
&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;blob&#x2F;c20fe3c0234ea3a328dbbd3d7f717f64599ff579&#x2F;jolt-core&#x2F;src&#x2F;zkvm&#x2F;spartan&#x2F;outer.rs#L117&quot;&gt;See&lt;&#x2F;a&gt; for the evaluation points that represent the above polynomial.
We refer to these evaluations as the &lt;code&gt;skip_window&lt;&#x2F;code&gt; in the code.&lt;&#x2F;p&gt;

&lt;aside class=&quot;callout callout-remark&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;Remark&lt;&#x2F;div&gt;
  
  &lt;p&gt;&lt;strong&gt;NOTE:&lt;&#x2F;strong&gt; This phase will remain exactly the same in the current “streaming” implementation as well.
Remember we assumed streaming the trace was free, and storing $O(1)$ field elements for a univariate polynomial does not break anyone’s memory bank.
We include this round in this post for completeness.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;p&gt;After this round, the prover has received challenge $r_y$ to bind to variable $Y$.
What we describe next refers to the &lt;code&gt;OuterRemainingSumcheck&lt;&#x2F;code&gt; in Jolt.
The sumcheck is divided into 2 phases:&lt;&#x2F;p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;A setup phase which materialises the polynomials – this is the &lt;code&gt;gen&lt;&#x2F;code&gt; constructor.&lt;&#x2F;li&gt;
&lt;li&gt;The remaining communication rounds (which are standard).&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h3 id=&quot;setup-phase&quot;&gt;Setup Phase&lt;a class=&quot;zola-anchor&quot; href=&quot;#setup-phase&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;We iterate over the entire trace one more time, and now materialise polynomials $\widetilde{A}, \widetilde{B}$ with $r_y$ bound to variable $Y$.
This takes $2T$ field elements worth of space.&lt;&#x2F;p&gt;
&lt;p&gt;More specifically for every $(x_{\log T}, \dots, x_{1}, x_b) \in \lbrace 0,1\rbrace^{\log T + 1}$, we store&lt;&#x2F;p&gt;
&lt;div class=&quot;math-display&quot;&gt;
$$\widetilde{A}(x_{\log T}, \dots, x_{1}, x_b, r_y) = \sum_{y \in \{-4, \dots, 5\}} \Lagrange{\tau_y}{y}\, \widetilde{A}(x_{\log T}, \dots, x_{1}, x_b, y)$$
&lt;&#x2F;div&gt;
&lt;p&gt;and&lt;&#x2F;p&gt;
&lt;div class=&quot;math-display&quot;&gt;
$$\widetilde{B}(x_{\log T}, \dots, x_{1}, x_b, r_y)= \sum_{y \in \{-4, \dots, 5\}} \Lagrange{\tau_y}{y}\, \widetilde{B}(x_{\log T}, \dots, x_{1}, x_b, y)$$
&lt;&#x2F;div&gt;
&lt;p&gt;This storing of partially bound sumcheck polynomials in memory is what we refer to as materialising.&lt;&#x2F;p&gt;
&lt;p&gt;While we’re materialising $\widetilde{A}$ and $\widetilde{B}$, we might as well prepare ourselves to also compute the prover’s messages for the first round of the sum-check algorithm.
This process where we materialise the polynomials of the sum-check &lt;strong&gt;and&lt;&#x2F;strong&gt; also compute the messages for the next round is referred to as &lt;code&gt;fused&lt;&#x2F;code&gt; materialisation in the code.
This is exactly what &lt;code&gt;compute_first_quadratic_evals_and_bound_polys&lt;&#x2F;code&gt; (&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;blob&#x2F;c20fe3c0234ea3a328dbbd3d7f717f64599ff579&#x2F;jolt-core&#x2F;src&#x2F;zkvm&#x2F;spartan&#x2F;outer.rs#L297&quot;&gt;described here&lt;&#x2F;a&gt;) does.&lt;&#x2F;p&gt;
&lt;p&gt;Here &lt;code&gt;t0&lt;&#x2F;code&gt; and &lt;code&gt;t_inf&lt;&#x2F;code&gt; refer to evaluations of the following quadratic polynomial.&lt;&#x2F;p&gt;
&lt;div class=&quot;math-display&quot;&gt;
$$t(\textcolor{pink}{X_b}) \Def \sum_{x_t \in \{0,1\}^{\log T}}\sum_{y \in \{-4, \dots, 5\}}  \eq{\tau_t}{x_t} \cdot \Lagrange{r_y}{y} \cdot \widetilde{A}(x_t ,\textcolor{pink}{X_b}, y) \, \widetilde{B}(x_t, \textcolor{pink}{X_b}, y) $$
&lt;&#x2F;div&gt;
&lt;p&gt;The final polynomial that the prover must send is the following:&lt;&#x2F;p&gt;
&lt;p&gt;$s(X_b) \Def \Lagrange{\tau_y}{r_0} \cdot t(\textcolor{pink}{X_b}) \cdot  \eq{\tau_{b}}{\textcolor{pink}{X_b}}$&lt;&#x2F;p&gt;
&lt;p&gt;which is exactly what the following snippet of code on Line 1430 of &lt;code&gt;jolt-core&#x2F;src&#x2F;zkvm&#x2F;spartan&#x2F;outer.rs&lt;&#x2F;code&gt; computes.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;split_eq_poly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;gruen_poly_deg_3&lt;&#x2F;span&gt;&lt;span&gt;(t0, t_inf, previous_claim)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;the-remaining-rounds&quot;&gt;The Remaining Rounds&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-remaining-rounds&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;With $\widetilde{A}$ and $\widetilde{B}$ materialised, the remaining rounds are standard. The mental picture is the following:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;randomwalks.xyz&#x2F;blog&#x2F;streaming-sumchecks&#x2F;Linear_sumcheck.svg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;At each bind the length of the representation of $\widetilde{A}$ and $\widetilde{B}$ shrinks by half.
And the next prover message can be computed from the bound and materialised polynomials.
The &lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;blob&#x2F;c20fe3c0234ea3a328dbbd3d7f717f64599ff579&#x2F;jolt-core&#x2F;src&#x2F;zkvm&#x2F;spartan&#x2F;outer.rs#L387&quot;&gt;code&lt;&#x2F;a&gt; is described here.&lt;&#x2F;p&gt;
&lt;p&gt;In conclusion, the linear sum-check with a special first round required that we stream the trace twice.
The second time of doing so – we materialised the polynomials with only $r_0$ bound to $Y$.
Once we materialise, we never have to look at the trace ever again – for at least this sum-check.
But this came at the cost of storing $2T$ field elements in memory per polynomial.
If $T$ is large, on the order of billions, then this is too expensive.&lt;&#x2F;p&gt;

&lt;aside class=&quot;callout callout-remark&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;Remark&lt;&#x2F;div&gt;
  
  &lt;p&gt;In this world where iterating through the trace is free, we could &lt;strong&gt;never&lt;&#x2F;strong&gt; materialise any polynomial and always just stream the trace every round (like we did in the first round).
That would take close to no memory at all.
While this is true, streaming the trace is actually not free, and we want to avoid it as many times as possible.
We only assume it’s free to make the memory accounting work for this post.
Eventually, we will have to implement a memory efficient way to stream the trace – but that is not terribly hard, and will soon be implemented.
In what follows, we make a compromise of sometimes streaming instead of always streaming, but this will allow us to store fewer things.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;h2 id=&quot;the-streaming-generalisation&quot;&gt;The Streaming Generalisation&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-streaming-generalisation&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;To describe the streaming sum-check we need to first describe what we mean by a sum-check schedule.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A schedule classifies every round of the sum-check as being a &lt;code&gt;window_start&lt;&#x2F;code&gt; round or not.
For example the sum-check involving 16 rounds of interaction below can be scheduled as shown below.
Rounds 0, 3, 6, 9, 10, …, 15 are all window starts.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;randomwalks.xyz&#x2F;blog&#x2F;streaming-sumchecks&#x2F;stream_schedule.svg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;For every round, we have a notion of width or the number of unbound variables. This is given by the distance of current round from the next window start (or the end if there is no more window starts).
So in the above example, round 0 has window width 3, round 1 has width 2, round 2 has width 1, and round 3 has width 3 again, round 4 has width 2 and so on.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Out of all the rounds that are marked as &lt;code&gt;window_start&lt;&#x2F;code&gt; rounds, exactly &lt;strong&gt;one&lt;&#x2F;strong&gt; round is marked as special, and we call it the switchover point. This switchover point will mark the round at which we &lt;strong&gt;materialise&lt;&#x2F;strong&gt; the polynomials from the trace and store it in memory. In the example above, the switch over round is the 10th round given by round index 9. The width of this round is one in the above example (but it doesn’t have to be such).&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;At this point it should be somewhat clear that the later we materialise, the more variables would be bound by verifier challenges, hence the memory representation of the materialised polynomial will be smaller.
However, the later we materialise, it means we would have to stream the entire trace to compute prover messages more times.
There is an inherent tradeoff here that cannot be avoided.
The rough sketch of the algorithm is as follows:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;If a round $i \in \lbrace 0, \ldots, n-1\rbrace$ is the start of a window with width $w$ – we need to stream over the entire trace to generate and store a multivariate polynomial $t$ with $w$ variables. This requires storing $W:=(d+1)^w$ evaluations of $t$ in memory, where $d$ is the degree of $t$.  This degree $d$, $w$-variate polynomial is what is referred to as &lt;code&gt;t_grid&lt;&#x2F;code&gt; or the streaming data structure. As $d$ and $w$ will be small constants, storing &lt;code&gt;t_grid&lt;&#x2F;code&gt; in memory is essentially free.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Once we store $t$ in memory, we can compute all prover messages needed for the next $w$ rounds of sum-check, without streaming the trace again. If this is not immediately clear, we work out an example below.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;On receiving a verifier challenge $r$ for the current round, we shrink the size of $t$ by a factor of $d+1$ (just as in the case of the linear-sum-check) where $d$ is the degree of $t$. The factor is 2 if $t$ is multilinear.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;In the last round of the given window the size of $t$ should reduce to 1.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The next round is either the start of a new window or it’s the switchover point. If it’s the former, we repeat the process described above. That is, we stream the trace again, and compute $t$ from the trace.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If the round $\hat{t} \in [n]$ is the switch-over point, we stream over the trace and store multilinear polynomials $\widetilde{A}(\textcolor{orange}{r_y, r_b, r_1, \ldots, r_{\hat{t}-1}}, X_{\hat{t}}, \ldots, X_{\log T})$ and $\widetilde{B}(\textcolor{orange}{r_y, r_b, r_1, \ldots, r_{\hat{t}-1}}, X_{\hat{t}}, \ldots, X_{\log T})$. Note that as we are materialising later, the size of these polynomials is much smaller than if we materialised in the first or second round.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Once again we compute $t$ to answer the prover’s messages. But crucially, this time we do it from the materialised polynomials above. We no longer need to stream the trace.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If the above description is all too abstract, let’s work through an actual example, and then finally look at the code snippets.
For this sum-check the degree of $t$ will be $d=2$ always.
In the example schedule above, the window width is $w=3$ for round 0.
The streaming data structure to compute is the following:&lt;&#x2F;p&gt;
&lt;div class=&quot;math-display&quot;&gt;
$$\begin{align*}
t&#x27;(\textcolor{pink}{X_2, X_1, X_b}) = \sum_{y \in \{-4, \dots, 5\}}\sum_{x_{15}..x_{3} \in \{0,1\}^{13}} &amp;A(x_{15}...x_3 , \textcolor{pink}{X_2, X_1, X_b},\, y) \\
&amp;\cdot B(x_{15}...x_3,\textcolor{pink}{X_2, X_1, X_b},\, y)\, \Lagrange{y}{r_y} \\[10pt] &amp;\cdot\text{eq}(\tau_{15}..\tau_3; x_{15}...x_3)
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Thus, we need $(d+1)^w = 3^3 = 27$ evaluations to represent $t$.
In Jolt we evaluate $t$ at $\lbrace 0,1, \infty\rbrace^{w}$ and the data structure that stores these evaluations is called &lt;code&gt;t_grid&lt;&#x2F;code&gt;, which is what we describe as the streaming data structure.
This is exactly what &lt;code&gt;compute_evaluation_grid_from_trace&lt;&#x2F;code&gt; computes.
The next stage is to compute $t(0)$ and $t(\infty)$ where&lt;&#x2F;p&gt;
&lt;div class=&quot;math-display&quot;&gt;
$$
t(\textcolor{pink}{X_b}) = \sum_{x_2, x_1 \in \{0,1\}^2 } t&#x27;(x_2, x_1, \textcolor{pink}{X_b})\,\,\text{eq}(\tau_2, \tau_1; x_2, x_1)
$$
&lt;&#x2F;div&gt;
&lt;p&gt;This is what &lt;code&gt;compute_t_evals&lt;&#x2F;code&gt; computes.&lt;&#x2F;p&gt;

&lt;aside class=&quot;callout callout-remark&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;Remark&lt;&#x2F;div&gt;
  
  &lt;p&gt;Throughout this post when we write $\eq{\tau}{x}$, we assume it’s implemented using the Dao-Thaler split-eq optimisation. Thus the memory representation of the $\eq{}{}$ polynomials is never an issue.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;p&gt;Finally the prover’s message is given by
$$
s(\textcolor{pink}{X_b}) = t(\textcolor{pink}{X_b}),\text{eq}(\tau_b, \textcolor{pink}{X_b})
$$&lt;&#x2F;p&gt;

&lt;aside class=&quot;callout callout-remark&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;Prover Messages Are Always Computed From `t_grid`&lt;&#x2F;div&gt;
  
  &lt;p&gt;It is important to note that in every round of the sum-check the prover’s messages will be computed using the streaming data structure &lt;code&gt;t_grid&lt;&#x2F;code&gt;.
We will shortly see that once the current &lt;code&gt;t_grid&lt;&#x2F;code&gt; gets exhausted we will re-compute it.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;


&lt;aside class=&quot;callout callout-remark&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;A Note About Evaluating At Infinity&lt;&#x2F;div&gt;
  
  &lt;p&gt;For a univariate polynomial $p$, $p(\infty)$ is equal to the coefficient associated with the highest degree term of the polynomial.
For example, if $p$ is linear i.e $p(X) = aX + b$, we have $p(\infty) = a$.&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;p&gt;This completes the first round message the prover sends.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;binding-in-the-streaming-phase&quot;&gt;Binding in the streaming phase&lt;a class=&quot;zola-anchor&quot; href=&quot;#binding-in-the-streaming-phase&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h4&gt;
&lt;p&gt;Note as $t’$ is multivariate, we are sorted for the next $w$ rounds, till we bind all $w$ of its variables.
In the example above, we can answer 3 rounds of prover messages using &lt;code&gt;t_grid&lt;&#x2F;code&gt; only.
Binding is exactly the same as the linear version but we do it for the multi-quadratic polynomial and is done by &lt;code&gt;t_prime_poly.bind(r_j, BindingOrder::LowToHigh)&lt;&#x2F;code&gt;
(&lt;a rel=&quot;noopener noreferrer external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;abiswas3&#x2F;jolt&#x2F;blob&#x2F;feat&#x2F;streaming-prover-merged&#x2F;jolt-core&#x2F;src&#x2F;poly&#x2F;multiquadratic_poly.rs&quot;&gt;method&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;After binding in round 0 we go from  $t’(X_2, X_1, X_b)$ to $t’(X_2, X_1, \textcolor{orange}{r_b})$.
Then at the end of round 1 we are left with $t’(X_2, \textcolor{orange}{r_1, r_b})$ and after round 2 i.e 3 rounds of sum-check we are left with $t’( \textcolor{orange}{r_2, r_1, r_b})$.
Hereafter, we must stream the trace again – and we will as round 3 is a window start.&lt;&#x2F;p&gt;
&lt;p&gt;Additionally as the challenges come in, we also build a data structure called &lt;code&gt;r_grid&lt;&#x2F;code&gt; which looks like the following&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	[1]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	[(1-rb), rb] &#x2F;&#x2F; eq(r_b, x_b)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	[(1-rb)(1-r1), rb(1-r1), (1-rb)r1, rbr1] &#x2F;&#x2F; eq(r_1, r_b, x_1, x_b)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;aside class=&quot;callout callout-remark&quot;&gt;
  
  &lt;div class=&quot;callout-title&quot;&gt;Remark&lt;&#x2F;div&gt;
  
  &lt;p&gt;We will see shortly that we only need to store &lt;code&gt;r_grid&lt;&#x2F;code&gt; up to the switch-over point.
The total amount of storage needed is $2^{\hat{t}}$ where $\hat{t} \in [n]$ is the switchover point of the sum-check and $n$ is the number of rounds of the sum-check.
If $\hat{t}$ is large, we can always use the split-eq technique for &lt;code&gt;r_grid&lt;&#x2F;code&gt; (this is not currently needed).&lt;&#x2F;p&gt;

&lt;&#x2F;aside&gt;

&lt;p&gt;The last line of &lt;code&gt;r_grid&lt;&#x2F;code&gt; helps us compute $\text{eq}(\textcolor{orange}{r_{w-1},…, r_b}, x_{w-1},…, x_{b})$ which is useful when we recompute &lt;code&gt;t_grid&lt;&#x2F;code&gt; in the first round of the next window.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;next-window-start&quot;&gt;Next Window Start&lt;a class=&quot;zola-anchor&quot; href=&quot;#next-window-start&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Now we still have not hit a switchover point, so nothing is materialised yet, so we once again compute the grid from the trace.
Additionally, as we are not in the first round anymore, we have to deal with the verifier challenges – so the equations for computing the grid are the following.&lt;&#x2F;p&gt;
&lt;div class=&quot;math-display&quot;&gt;
$$\begin{align*}
t(\textcolor{pink}{X_5, X_4, X_3}) &amp;= \sum_{x_{15}..x_{6}, x_{2}, x_{1}, x_{b} \in \{0,1\}^{13}}\sum_{y \in \{-4, \dots, 5\}}  \widetilde{A}(x_{15}...x_6,  \textcolor{pink}{X_5, X_4, X_3}, x_2, x_1, x_b, y) \\
&amp;\qquad \cdot \widetilde{B}(x_{15}\dots x_6 ,\textcolor{pink}{X_5, X_4, X_3}, x_2, x_1, x_b, y) \\[10pt]
&amp;\qquad \cdot\text{eq}(\tau_{15}\dots\tau_6;\, x_{15}\dots x_6) \, \\[10pt]
&amp;\qquad \cdot \text{eq}(\textcolor{orange}{r_2, r_1, r_b}, x_{2}, x_{1}, x_{b})
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Notice how &lt;code&gt;r_grid&lt;&#x2F;code&gt; becomes useful in the last line.
This process continues till we hit the switch over point.
Also observe that the RHS of the above equations actually visits every cell of the trace exactly once.
Hence we keep banging on about streaming the trace.&lt;&#x2F;p&gt;
&lt;p&gt;At this point we have only used $\max\lbrace(d+1)^{\hat{w}}, 2^{\hat{t}}\rbrace$ field elements worth of memory, where $\hat{t}$ is the switch-over point and $\hat{w}$ is the maximum window width for a round.
$d=2$ for this sumcheck.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;switch-over-point&quot;&gt;Switch Over Point&lt;a class=&quot;zola-anchor&quot; href=&quot;#switch-over-point&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Finally we get to the switchover point.
&lt;code&gt;t_grid&lt;&#x2F;code&gt; is exhausted once again.
We stream through the trace one last time to materialise the bound polynomials.&lt;&#x2F;p&gt;
&lt;p&gt;We now store for each $X_{15}…X_9 \in \lbrace 0,1\rbrace^{7}$&lt;&#x2F;p&gt;
&lt;div class=&quot;math-display&quot;&gt;
$$\begin{align*}
&amp; \widetilde{A}(\textcolor{pink}{X_{15}...X_9}, \textcolor{orange}{r_8, ..., r_b, r_y}) \\[10pt]
&amp;= \sum_{x_8...x_b \in \{0,1\}^9}\sum_{y \in \{-4, \dots, 5\}} \widetilde{A}(\textcolor{pink}{X_{15}, ..., X_9}, x_8...x_b, y)\,\text{eq}(\textcolor{orange}{r_8..r_b}, x_8...x_b)\, \Lagrange{r_y}{y}
\end{align*}
$$

$$\begin{align*}
&amp; \widetilde{B}(\textcolor{pink}{X_{15}...X_9}, \textcolor{orange}{r_8, ..., r_b, r_y}) \\[10pt]
&amp;= \sum_{x_8...x_b \in \{0,1\}^9}\sum_{y \in \{-4, \dots, 5\}} \widetilde{B}(\textcolor{pink}{X_{15}, ..., X_9}, x_8...x_b, y)\,\text{eq}(\textcolor{orange}{r_8..r_b}, x_8...x_b)\, \Lagrange{r_y}{y}
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;&#x2F;strong&gt;: This stores only $2^7$ field elements worth of storage (much fewer than the linear sumcheck setup).
The method &lt;code&gt;fused_materialise_polynomials_general_with_multiquadratic&lt;&#x2F;code&gt; computes the above polynomials and stores them in memory.
Note that as we have the polynomials at hand already, we also compute the grid now.
In the schedule given above, the grid size is just 1, thus we only need to store&lt;&#x2F;p&gt;
&lt;div class=&quot;math-display&quot;&gt;
$$
\begin{align*}
t(\textcolor{pink}{X_9}) =  \sum_{x_{15},\dots,x_{10} \in \{0,1\}^{6}} &amp; \widetilde{A}(x_{15}, \dots, x_{10}, \textcolor{pink}{X_9}, \textcolor{orange}{r_8, \dots, r_1, r_b, r_y})\\[10pt]
&amp;\cdot \widetilde{B}(x_{15}, \dots, x_{10}, \textcolor{pink}{X_9}, \textcolor{orange}{r_8, \dots, r_1, r_b, r_y}) \\[10pt]
&amp;  \cdot \eq{\tau_{15}, \dots, \tau_{10}}{ x_{15}, \dots, x_{10}} \\[10pt]
\end{align*}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;Finally the prover message is&lt;&#x2F;p&gt;
&lt;div class=&quot;math-display&quot;&gt;
$$s(\textcolor{pink}{X_9}) = t(\textcolor{pink}{X_9})\,\, \eq{\tau_9}{\textcolor{pink}{X_9}}\,\,\eq{\tau_8, \dots, \tau_b}{\textcolor{orange}{r_{8}, \dots, r_{b}}}\,\,\Lagrange{\tau_y}{\textcolor{orange}{r_y}}
$$
&lt;&#x2F;div&gt;
&lt;p&gt;From here onwards, whenever we need to compute the grid, we never look at the trace.
We can directly do it from the materialised polynomials $\widetilde{A}$ and $\widetilde{B}$.
This is what &lt;code&gt;compute_evaluation_grid_from_polynomials_parallel&lt;&#x2F;code&gt; computes.&lt;&#x2F;p&gt;
&lt;p&gt;From here on after the switchover point we &lt;strong&gt;NEVER&lt;&#x2F;strong&gt; touch the trace again.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;actual-code&quot;&gt;Actual Code&lt;a class=&quot;zola-anchor&quot; href=&quot;#actual-code&quot; aria-label=&quot;Link to this section&quot;&gt;#&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Below we describe what the &lt;code&gt;compute_message&lt;&#x2F;code&gt; method of the generalised sumcheck looks like.
The following snippet of code executes the logic described above, based on the round classification.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; compute_message&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;&amp;amp;mut&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span&gt;, round&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; usize&lt;&#x2F;span&gt;&lt;span&gt;, previous_claim&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; F&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; UniPoly&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;F&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; num_unbound_vars&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;schedule&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;num_unbound_vars&lt;&#x2F;span&gt;&lt;span&gt;(round);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; The size of the streaming data structure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;schedule&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;is_switch_over_point&lt;&#x2F;span&gt;&lt;span&gt;(round) {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; Check if it&amp;#39;s time materialise the sum-check polynomials&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;        self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;materialise_polynomials_from_trace&lt;&#x2F;span&gt;&lt;span&gt;(num_unbound_vars);&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; Materialise bound polynomials A and B&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    else if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;schedule&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;is_window_start&lt;&#x2F;span&gt;&lt;span&gt;(round) {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; Window start&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;schedule&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;before_switch_over_point&lt;&#x2F;span&gt;&lt;span&gt;(round) {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt; &#x2F;&#x2F; Need to compute streaming data structure from trace&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;compute_evaluation_grid_from_trace&lt;&#x2F;span&gt;&lt;span&gt;(num_unbound_vars);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;            &#x2F;&#x2F; Have materialised polynomials, no need to stream the trace anymore&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;            self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;compute_evaluation_grid_from_polynomials_parallel&lt;&#x2F;span&gt;&lt;span&gt;(num_unbound_vars);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;    &#x2F;&#x2F; This part remains unchanged -- from the linear sum-check&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; (t_prime_0, t_prime_inf)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;compute_t_evals&lt;&#x2F;span&gt;&lt;span&gt;(num_unbound_vars);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;    self&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;split_eq_poly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;gruen_poly_deg_3&lt;&#x2F;span&gt;&lt;span&gt;(t_prime_0, t_prime_inf, previous_claim)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-d&quot;&gt;
&lt;p&gt;This statement is strictly not true. In the current implementation, as a consequence of the process by which we construct the polynomials, we still need $O(T)$ memory, where $T$ is the number of instructions in the guest program (both virtual and real). But in this post we make a few simplifying assumptions, by which the statement does ring true. &lt;a href=&quot;#fr-d-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-e&quot;&gt;
&lt;p&gt;It is not so important to be formal about what we mean by sufficient structure here. If $g \in \Field[x_1, \dots, x_n]$, then we can just pretend $H = \lbrace 0,1\rbrace^n$. &lt;a href=&quot;#fr-e-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-c&quot;&gt;
&lt;p&gt;A program is just a sequence of RISC-V instructions. &lt;a href=&quot;#fr-c-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-a&quot;&gt;
&lt;p&gt;We choose those indices for $y$ instead of bit string or the set $\lbrace 0, \ldots, 9\rbrace$ for computational reasons, the details of which we don’t discuss here (maybe for a separate post). &lt;a href=&quot;#fr-a-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
  </entry>
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
</feed>
