<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/notes/default.xsl"?>
<fr:tree xmlns:fr="http://www.forester-notes.org" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xml="http://www.w3.org/XML/1998/namespace" root="false" base-url="/notes/">
  <fr:frontmatter>
    <fr:authors />
    <fr:date>
      <fr:year>2025</fr:year>
      <fr:month>11</fr:month>
      <fr:day>23</fr:day>
    </fr:date>
    <fr:uri>https://kaierikniermann.github.io/notes/001a/</fr:uri>
    <fr:display-uri>001a</fr:display-uri>
    <fr:route>/notes/001a/</fr:route>
    <fr:title text="Blog posts">Blog posts</fr:title>
  </fr:frontmatter>
  <fr:mainmatter>
    <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
      <fr:frontmatter>
        <fr:authors />
        <fr:date>
          <fr:year>2025</fr:year>
          <fr:month>11</fr:month>
          <fr:day>23</fr:day>
        </fr:date>
        <fr:uri>https://kaierikniermann.github.io/notes/001b/</fr:uri>
        <fr:display-uri>001b</fr:display-uri>
        <fr:route>/notes/001b/</fr:route>
        <fr:title text="Understanding recursors with Lean4">Understanding recursors with Lean4</fr:title>
        <fr:taxon>Blog</fr:taxon>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:date>
              <fr:year>2025</fr:year>
              <fr:month>11</fr:month>
              <fr:day>23</fr:day>
            </fr:date>
            <fr:title text="The recursor for natural numbers">The recursor for natural numbers</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>
    Before we define recursors, let's first introduce the idea of an inductive type. We'll do this by examining how lean defines natural numbers.
  </html:p>
            <html:pre class="code-block language-lean">
              <html:code class="language-lean">
    inductive Nat where
    | zero : Nat
    | succ (n : Nat) : Nat
  </html:code>
            </html:pre>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:date>
              <fr:year>2025</fr:year>
              <fr:month>11</fr:month>
              <fr:day>23</fr:day>
            </fr:date>
            <fr:title text="The recursor for natural numbers">The recursor for natural numbers</fr:title>
          </fr:frontmatter>
          <fr:mainmatter><html:p>
    Before we define recursors, let's first introduce the idea of an inductive type. We'll do this by examining how lean defines natural numbers.
  </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
    inductive Nat where
    | zero : Nat
    | succ (n : Nat) : Nat
  </html:code></html:pre><html:p>
    The idea here being that we can construct natural numbers by either using the constructor <html:code>zero</html:code> to get <html:code>0</html:code>, or by applying the constructor <html:code>succ</html:code> to an existing natural number to get its successor. For example, we can construct <html:code>3</html:code> as follows:
  </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
    def three : Nat := Nat.succ (Nat.succ (Nat.succ Nat.zero))
  </html:code></html:pre><html:p>
    We can equivalently express this definition using the type formation and term introduction rules:
  </html:p>
  
    
    <fr:resource hash="c76ba9ca452e4efa0a2374728195a21a"><fr:resource-content><html:img src="/notes/c76ba9ca452e4efa0a2374728195a21a.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=Form-Nat]{}{
      \mathbb {N} : \texttt {type}
    }
    \and  
    \inferrule *[right=Intro-Zero]{}{
      0 : \mathbb {N}
    }
    \and 
    \inferrule *[right=Intro-Succ]{
      n : \mathbb {N}
    }{
      \texttt {succ}\ n : \mathbb {N}
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
    While this explanation for inductive types usually gives most people I think enough intuition to understand the basic notions of how to use them to construct something like natural numbers, I think it kind of misses the deeper idea of what an inductive type and by extension a recursor really is. To attempt to explain this we'll take a look into some categorical semantics behind inductive types.
  </html:p><fr:tree show-metadata="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>23</fr:day></fr:date><fr:uri>https://kaierikniermann.github.io/notes/001c/</fr:uri><fr:display-uri>001c</fr:display-uri><fr:route>/notes/001c/</fr:route><fr:title text="Natural Number Object (NNO)">Natural Number Object (NNO)</fr:title><fr:taxon>Definition</fr:taxon></fr:frontmatter><fr:mainmatter><html:p>
  We assume that <fr:tex display="inline"><![CDATA[\mathcal  L]]></fr:tex> is a category with a <fr:link href="/notes/001d/" title="Terminal Object (Category Theory)" uri="https://kaierikniermann.github.io/notes/001d/" display-uri="001d" type="local">terminal object</fr:link> <fr:tex display="inline"><![CDATA[1]]></fr:tex>. This category has a <html:em>natural number object</html:em> (NNO) if there exists an object <fr:tex display="inline"><![CDATA[\mathbb {N}]]></fr:tex> together with two morphisms:
</html:p><html:ul><html:li><fr:tex display="inline"><![CDATA[0 : 1 \to  \mathbb {N}]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[s : \mathbb {N} \to  \mathbb {N}]]></fr:tex></html:li></html:ul><html:p>
  such that, given any global element <fr:tex display="inline"><![CDATA[z : 1 \to  X]]></fr:tex> and any morphism <fr:tex display="inline"><![CDATA[f : X \to  X]]></fr:tex>, there exists a unique morphism <fr:tex display="inline"><![CDATA[u : \mathbb {N} \to  X]]></fr:tex> such that the following diagram commutes:
</html:p>
 
  
  <html:figure><fr:resource hash="451ab9726be7ca6a5fa1653caf21d4c5"><fr:resource-content><html:img src="/notes/451ab9726be7ca6a5fa1653caf21d4c5.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
   
   % String-diagram specific extensions live here. Add diagram tweaks without
 % re-running the full base preamble (to avoid duplicate definitions).

   
  
   \usepackage{eulervm}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{amsmath, amsthm, amsfonts}
  \usepackage{tikz, tikz-cd, mathtools, amssymb, stmaryrd}
  \usetikzlibrary{arrows.meta, shapes, positioning, calc, decorations.pathreplacing, backgrounds, fit, matrix, spath3}

  % A TikZ style for curved arrows of a fixed height, due to AndréC.
  \tikzset{curve/.style={settings={#1},to path={(\tikztostart)
        .. controls ($(\tikztostart)!\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
        and ($(\tikztostart)!1-\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
    .. (\tikztotarget)\tikztonodes}},
    settings/.code={\tikzset{quiver/.cd,#1}
    \def\pv##1{\pgfkeysvalueof{/tikz/quiver/##1}}},
  quiver/.cd,pos/.initial=0.35,height/.initial=0}

  % A TikZ style for shortening paths without the poor behaviour of `shorten <' and `shorten >'.
  \tikzset{between/.style n args={2}{/tikz/spath/at end path construction={
        \tikzset{spath/split at keep middle={current}{#1}{#2}}
  }}}

  % TikZ arrowhead/tail styles.
  \tikzset{tail reversed/.code={\pgfsetarrowsstart{tikzcd to}}}
  \tikzset{2tail/.code={\pgfsetarrowsstart{Implies[reversed]}}}
  \tikzset{2tail reversed/.code={\pgfsetarrowsstart{Implies}}}
  % TikZ arrow styles.
  \tikzset{no body/.style={/tikz/dash pattern=on 0 off 1mm}}


  ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[
  \begin {tikzcd}
    1 \arrow [r, "0"] \arrow [dr, "z"'] & \mathbb {N} \arrow [d, "u"] \arrow [r, "s"] & \mathbb {N} \arrow [d, "u"] \\
    & X \arrow [r, "f"'] & X
  \end {tikzcd}
]]></fr:resource-source></fr:resource></html:figure>
 
</fr:mainmatter></fr:tree><html:p>
    While at first this definition seems a bit needlessly abstract, it actually captures what the inductive type of natural numbers really is. The basic thing to recognize is that the two morphisms (just think of them as functions for now) in reality don't have anything to do with natural numbers directly. Instead, they act as a kind of blueprint for how we can use the properties or constraints of natural numbers to make anything. Here on a high level we can describe the two functions / constructors as follows:
  </html:p><html:ul><html:li><fr:tex display="inline"><![CDATA[0 : 1 \to  \mathbb {N}]]></fr:tex> - The represents the abstract idea of having some starting point or base case. Within natural numbers this is represented by <html:code>0</html:code>, but in reality it denotes an abstract concept of having a starting point.
    </html:li>
    <html:li><fr:tex display="inline"><![CDATA[s : \mathbb {N} \to  \mathbb {N}]]></fr:tex> - This represents the abstract idea of being able to build upon existing things to create new things. Within natural numbers this is represented by the successor function.
    </html:li></html:ul><html:p>
    Now this might quite fairly still seem a bit confusing and abstract. How can we <html:em>use properties</html:em> to <html:em>make anything?</html:em>. To describe this more formally lets constrain ourselves to the category of sets, <fr:tex display="inline"><![CDATA[\mathbf {Set}]]></fr:tex>. If you are unfamiliar with category theory it's sufficient to think of this as just a collection of all kinds of sets and functions between them.
  </html:p><fr:tree show-metadata="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>23</fr:day></fr:date><fr:uri>https://kaierikniermann.github.io/notes/001e/</fr:uri><fr:display-uri>001e</fr:display-uri><fr:route>/notes/001e/</fr:route><fr:title text="Natural Number Object (NNO) in Set">Natural Number Object (NNO) in Set</fr:title><fr:taxon>Example</fr:taxon></fr:frontmatter><fr:mainmatter><html:p>
  In the category <html:strong>Set</html:strong>, the natural number object (NNO) can be represented by the set of natural numbers <fr:tex display="inline"><![CDATA[\mathbb {N} = \{0, 1, 2, 3, \ldots \}]]></fr:tex>. If we take some arbitrary other set <fr:tex display="inline"><![CDATA[X]]></fr:tex> with some point <fr:tex display="inline"><![CDATA[x : 1 \to  X]]></fr:tex> (which can be identified with an element of <fr:tex display="inline"><![CDATA[X]]></fr:tex>) and some function <fr:tex display="inline"><![CDATA[f : X \to  X]]></fr:tex>, we can define a unique function <fr:tex display="inline"><![CDATA[u : \mathbb {N} \to  X]]></fr:tex> as follows:
</html:p><fr:tex display="block"><![CDATA[
  u(n) = \begin {cases}
  x & \text {if } n = 0 \\
  f^n(x) & \text {if } n \geq  0
  \end {cases}
]]></fr:tex></fr:mainmatter></fr:tree><html:p>
    So in plain English what this is saying is that given any set <fr:tex display="inline"><![CDATA[X]]></fr:tex> where we have some starting point <fr:tex display="inline"><![CDATA[x \in  X]]></fr:tex> and some way of building upon existing elements of <fr:tex display="inline"><![CDATA[X]]></fr:tex> (the function <fr:tex display="inline"><![CDATA[f : X \to  X]]></fr:tex>), we can use the properties of natural numbers to create a unique function <fr:tex display="inline"><![CDATA[u : \mathbb {N} \to  X]]></fr:tex> that maps natural numbers to elements of <fr:tex display="inline"><![CDATA[X]]></fr:tex> in a way that respects our starting point and building function. A natural next question to have might be
  </html:p><html:blockquote>
    But what does it mean to <html:em>respect</html:em> the starting point and building function?
  </html:blockquote><html:p>
    Here I'd fast say intuitively you can just imagine construct which has some notion of a start and some way of building upon existing things. For example let's imagine the following graph:
  </html:p><fr:tex display="block"><![CDATA[
    a \to  b \to  c \to  d \to  e \to  \ldots 
  ]]></fr:tex><html:p>
    Clearly here with have:
  </html:p><html:ul><html:li><html:strong>Starting point</html:strong>: Our start here is the node <fr:tex display="inline"><![CDATA[a]]></fr:tex>.
    </html:li>
    <html:li><html:strong>Building function</html:strong>: Our building function i.e. successor mechanism here is just following the arrows to the next node.
    </html:li></html:ul><html:p>
    So our two morphisms then are:
  </html:p><html:ul><html:li><fr:tex display="inline"><![CDATA[x : 1 \to  X]]></fr:tex> where <fr:tex display="inline"><![CDATA[x]]></fr:tex> maps to <fr:tex display="inline"><![CDATA[a]]></fr:tex>.
    </html:li>
    <html:li><fr:tex display="inline"><![CDATA[f : X \to  X]]></fr:tex> where <fr:tex display="inline"><![CDATA[f]]></fr:tex> maps each node to the next node along the arrow. That is
      <html:pre class="code-block language-lean"><html:code class="language-lean">
        f(a) = b
        f(b) = c
        f(c) = d
        f(d) = e
        ...
      </html:code></html:pre></html:li></html:ul><html:p>
    Creating a minimal replica of this in Lean we could do something like:
  </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
    inductive Node where
    | start : Node           -- this will play the role of “a”
    | next  : Node → Node

    def succNode (v : Node) : Node :=
      Node. next v

    def natToNode : ℕ → Node
      | 0       =&gt; Node.start
      | n + 1   =&gt; succNode (natToNode n)
  </html:code></html:pre><html:p>
    So we can see our function <fr:tex display="inline"><![CDATA[u : \mathbb {N} \to  X]]></fr:tex> here is represented by <html:code>natToNode</html:code>. Where the function maps <html:code>0</html:code> to <html:code>a</html:code> and each successor natural number to the next node along the arrow.
  </html:p><html:p>
    Something you might notice here is that if our <html:code>natToNode</html:code> function is replaced by just an identity, i.e.:
  </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
    def natToNat : ℕ → ℕ
      | 0       =&gt; 0
      | n + 1   =&gt; n + 1
  </html:code></html:pre><html:p>
    Then we get just the natural numbers themselves as defined by their properties. This is precisely what's expressed by the earlier commutative diagram we say. The two arrows:
  </html:p><fr:tex display="block"><![CDATA[
    1 \xrightarrow {0} \mathbb {N}
    \quad  \text { and } \quad  \mathbb {N} \xrightarrow {s} \mathbb {N}
  ]]></fr:tex><html:p>
    Are just the natural numbers defined by their properties. So in a sense the natural numbers are the most basic instantiation of their own properties. So now a fair thing to wonder is:
  </html:p><html:blockquote>
    So what does this have to do with recursers?
  </html:blockquote><html:p>
    Well the key insight here is that our functions <html:code>natToNat</html:code> and <html:code>natToNode</html:code> both <html:em>are our recursers</html:em> for the natural numbers. A recursor is just a function that allows us to define functions <html:em>out of</html:em> an inductive type by specifying how to handle each constructor of the inductive type. So equivalently we can express our recursor for natural numbers as:
  </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
    def recNat {C : Type} (z : C) (s : C → C) : ℕ → C
      | 0       =&gt; z
      | n + 1   =&gt; s (recNat z s n)
  </html:code></html:pre><html:p>
    If we examine the actual type signature generated by <html:code>#check Nat.rec</html:code> we have:
    </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
      «Nat».rec.{u}
      {motive : ℕ → Sort u}
      (zero : motive «Nat».zero)
      (succ : (n : ℕ)
        → motive n
        → motive n.succ)
      (t : ℕ) : motive t
    </html:code></html:pre><html:p>
      In our examples above we can see that the <html:code>motive</html:code> is just the type we are mapping to (either <fr:tex display="inline"><![CDATA[\mathbb {N}]]></fr:tex> or <fr:tex display="inline"><![CDATA[X]]></fr:tex>), the <html:code>zero</html:code> is our starting point (either <html:code>0</html:code> or <html:code>a</html:code>) and the <html:code>succ</html:code> is our building function (either the successor function or following the arrows). So using the recursor we can rewrite our earlier <html:code>natToNat</html:code> and <html:code>natToNode</html:code> functions as:
    </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
      def natToNat : ℕ → ℕ :=
        Nat.rec
          0                 -- | 0     =&gt; 0
          (fun n =&gt; n + 1)  -- | n + 1 =&gt; n + 1

      def natToNode : ℕ → Node :=
        Nat.rec
          Node.start            -- | 0     =&gt; Node.start
          (fun n =&gt; succNode n) -- | n + 1 =&gt; succNode (natToNode n)
    </html:code></html:pre></fr:mainmatter>
        </fr:tree>
        <html:p>
    This for the most part covers the basic idea of recursors for the sake of brevity I won't go into more instances of recursors for other inductive types though conceptually they work the same way. You specify how to handle each constructor of the inductive type and the recursor gives you a function that maps from the inductive type to whatever type you specified.
  </html:p>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:date>
              <fr:year>2025</fr:year>
              <fr:month>11</fr:month>
              <fr:day>23</fr:day>
            </fr:date>
            <fr:title text="The connection to induction">The connection to induction</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>
      A very important property of recursors emerges when we make the motive dependent. To elaborate on what that means let's first consider the situation of simple stepwise induction.
    </html:p>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>23</fr:day>
                </fr:date>
                <fr:uri>https://kaierikniermann.github.io/notes/001f/</fr:uri>
                <fr:display-uri>001f</fr:display-uri>
                <fr:route>/notes/001f/</fr:route>
                <fr:title text="Stepwise (Mathematical) Induction">Stepwise (Mathematical) Induction</fr:title>
                <fr:taxon>Definition</fr:taxon>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
  Stepwise (mathematical/natural/ordinary) induction is a proof technique used to establish the truth of a statement <fr:tex display="inline"><![CDATA[P(n)]]></fr:tex> for all natural numbers <fr:tex display="inline"><![CDATA[n \in  \mathbb {N}]]></fr:tex>. The process involves two main steps:
</html:p>
                <html:ol><html:li><html:strong>Base Case:</html:strong> Prove that the statement <fr:tex display="inline"><![CDATA[P(0)]]></fr:tex> is true.
  </html:li>
  <html:li><html:strong>Inductive Step:</html:strong> Assume that the statement <fr:tex display="inline"><![CDATA[P(k)]]></fr:tex> is true for some arbitrary natural number <fr:tex display="inline"><![CDATA[k \in  \mathbb {N}]]></fr:tex> (this assumption is called the <html:em>inductive hypothesis</html:em>). Then, using this assumption, prove that the statement <fr:tex display="inline"><![CDATA[P(k + 1)]]></fr:tex> is also true.
  </html:li></html:ol>
                <html:p>
  If both the base case and the inductive step are successfully proven, we can conclude that the statement <fr:tex display="inline"><![CDATA[P(n)]]></fr:tex> holds for all natural numbers <fr:tex display="inline"><![CDATA[n \in  \mathbb {N}]]></fr:tex>. The concise formulation of this can be given by the induction principle.
</html:p>
                <fr:tex display="block"><![CDATA[
  (P(0) \land  \forall  k \in  \mathbb {N}.\ (P(k) \to  P(k + 1))) \to  \forall  n \in  \mathbb {N}.\ P(n)
]]></fr:tex>
              </fr:mainmatter>
            </fr:tree>
            <html:p>
      Something we can notice here just by superficial observation alone is that this seems to look an awful lot like the recursor for natural numbers we defined earlier. In fact, it <html:em>is</html:em> an application of the recursor for natural numbers for the <html:em>dependent</html:em> motive <fr:tex display="inline"><![CDATA[P : \mathbb {N} \to  \texttt {Prop}.]]></fr:tex>. To make this a little more concrete let's define a simple property over natural numbers:
    </html:p>
            <html:pre class="code-block language-lean">
              <html:code class="language-lean">
      def P (n : ℕ) : Prop := n + 0 = n
    </html:code>
            </html:pre>
            <html:p>
      Now its important to note that in an abstract sense this is no different from any other function from natural numbers to some type. The dependency comes into play when we try to use the recursor i.e. the properties of naturals with this motive.
    </html:p>
            <html:pre class="code-block language-lean">
              <html:code class="language-lean">
      def natToProp (n : ℕ) : (P n) :=
        Nat.rec
          (motive := P)
          (by simp [P])                    -- base case: P 0
          (fun n ih =&gt; by simp [P])        -- inductive step: P n → P (n+1)
          n
    </html:code>
            </html:pre>
            <html:p>
      A few things we can observe here:
    </html:p>
            <html:ul><html:li>
        The recursor here represents a <html:em>dependent</html:em> function, which is to say that the return type of the function depends on the input value. Contrasting this to the earlier case where the return type was always just <fr:tex display="inline"><![CDATA[\mathbb {N}]]></fr:tex> or <fr:tex display="inline"><![CDATA[X]]></fr:tex>.
      </html:li>
      <html:li><html:strong>Base case</html:strong> - Importantly here as opposed to providing a function that returns some value of type <fr:tex display="inline"><![CDATA[C]]></fr:tex> for the base case, we instead provide a proof that the property <fr:tex display="inline"><![CDATA[P(0)]]></fr:tex> holds.
      </html:li>
      <html:li><html:strong>Inductive step</html:strong> - Similarly for the inductive step we provide a function that takes an arbitrary natural number <fr:tex display="inline"><![CDATA[n]]></fr:tex> and a proof that <fr:tex display="inline"><![CDATA[P(n)]]></fr:tex> holds (the inductive hypothesis) and returns a proof that <fr:tex display="inline"><![CDATA[P(n + 1)]]></fr:tex> holds.
      </html:li></html:ul>
            <html:p>
      If we view this through the lens of the Curry-Howard correspondence it quite nicely illustrates how our proof here is just a program which constructs witnesses (valid proofs) for each natural number that the property <fr:tex display="inline"><![CDATA[P(n)]]></fr:tex> holds. In the same way that our earlier recursor provided elements on the correct type, this dependent recursor provides proofs on the correct property. As this application of a recursor to a proposition represents said proposition being true for all natural numbers, we can equivalently use this within a theorem.
    </html:p>
            <html:pre class="code-block language-lean">
              <html:code class="language-lean">
      theorem add_zero (n : ℕ) : n + 0 = n := natToProp n
    </html:code>
            </html:pre>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:date>
              <fr:year>2025</fr:year>
              <fr:month>11</fr:month>
              <fr:day>23</fr:day>
            </fr:date>
            <fr:title text="Case Study: Evaluating arithmetic expressions">Case Study: Evaluating arithmetic expressions</fr:title>
          </fr:frontmatter>
          <fr:mainmatter><html:p>
      As a little kind of case study I want to give an example of an inductive type (and its recursor) that most people become familiar with; in a sense; as early as primary school: the operational semantics of binary operators. We'll start by defining some basic syntax for arithmetic expressions:
    </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
      inductive BinOp where
      | add : BinOp
      | sub : BinOp
      | mul : BinOp
      | div : BinOp

      inductive Expr where
      | const : ℕ → Expr
      | binop : BinOp → Expr → Expr → Expr
    </html:code></html:pre><html:p>
      So here we have defined a simple language of arithmetic expressions consisting of natural number constants and binary operations. This provides us with the means to construct expressions like:
    </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
      #check Expr.binop BinOp.add (Expr.const 10) (Expr.const 20)
    </html:code></html:pre><html:p>
      If we want to actually define the semantics of how to evaluate these expressions we'll need to define a set of rewrite rules that describe how we can take an expression and reduce it to a value i.e. evaluate it. To evaluate an expression we want to traverse the expression tree and whenever we encounter a binary operation with two constant operands we want to apply the operation and replace the entire sub-expression with the resulting constant. We express this as 3 rewrite rules:
    </html:p><html:ul><html:li><html:strong>Left Evaluation</html:strong>: If the left operand of a binary operation can be reduced, then we reduce it.
      </html:li>
      <html:li><html:strong>Right Evaluation</html:strong>: If the left operand is a constant and the right operand can be reduced, then we reduce the right operand.
      </html:li>
      <html:li><html:strong>Operation Evaluation</html:strong>: If both operands are constants, we apply the binary operation and replace the entire sub-expression with the resulting constant.
      </html:li></html:ul><html:pre class="code-block language-lean"><html:code class="language-lean">
      def eval_op : BinOp → (Nat → Nat → Nat)
      | .add =&gt; Nat.add
      | .sub =&gt; Nat.sub
      | .mul =&gt; Nat.mul
      | .div =&gt; Nat.div

      inductive Step : Expr -&gt; Expr -&gt; Prop
      | ST_BinOp1 (op : BinOp)
          (e₁ e₁' e₂ : Expr)
          (h : Step e₁ e₁') :
          Step (Expr.binop op e₁ e₂)
               (Expr.binop op e₁' e₂)
      | ST_BinOp2 (op : BinOp)
          (v₁ : Nat)
          (e₂ e₂' : Expr)
          (h : Step e₂ e₂') :
          Step (Expr.binop op (Expr.const v₁) e₂)
               (Expr.binop op (Expr.const v₁) e₂')
      | ST_BinOpConst (op : BinOp) (v₁ v₂ : Nat) :
          Step (Expr.binop op (Expr.const v₁) (Expr.const v₂))
               (Expr.const (eval_op op v₁ v₂))
    </html:code></html:pre><html:p>
      Since expressions can naturally require multiple evaluations steps it makes sense to define a multistep evaluation relation as the reflexive transitive closure of the single step evaluation relation defined above. This we can define as:
    </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
      abbrev MultiStep := Relation.ReflTransGen Step

      -- helper notation to express multi-step evaluation
      notation:50 e " -&gt;ⁿ " e' =&gt;  MultiStep e e'
    </html:code></html:pre><html:p>
      Let's also define a small helper syntax and macro to make it easier to write arithmetic expressions:
    </html:p>
      
      <fr:tree show-metadata="false" expanded="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>23</fr:day></fr:date><fr:title text="A small arithmetic expression grammar">A small arithmetic expression grammar</fr:title></fr:frontmatter><fr:mainmatter><html:pre class="code-block language-lean"><html:code class="language-lean">
          declare_syntax_cat arithTm

          -- atoms
          syntax num                      : arithTm
          syntax "(" arithTm ")"          : arithTm

          -- multiplicative level (higher precedence)
          syntax:70 arithTm:70 "*" arithTm:71 : arithTm
          syntax:70 arithTm:70 "/" arithTm:71 : arithTm

          -- additive level (lower precedence)
          syntax:60 arithTm:60 "+" arithTm:61 : arithTm
          syntax:60 arithTm:60 "-" arithTm:61 : arithTm

          syntax "ex{" arithTm "}" : term

          macro_rules
            -- numerals
            | `(ex{ $n:num }) =&gt;
                `(Expr.const $n)

            -- parentheses
            | `(ex{ ($t:arithTm) }) =&gt;
                `(ex{$t})

            -- addition
            | `(ex{ $e₁:arithTm + $e₂:arithTm }) =&gt;
                `(Expr.binop BinOp.add (ex{$e₁}) (ex{$e₂}))

            -- subtraction
            | `(ex{ $e₁:arithTm - $e₂:arithTm }) =&gt;
                `(Expr.binop BinOp.sub (ex{$e₁}) (ex{$e₂}))

            -- multiplication
            | `(ex{ $e₁:arithTm * $e₂:arithTm }) =&gt;
                `(Expr.binop BinOp.mul (ex{$e₁}) (ex{$e₂}))

            -- division
            | `(ex{ $e₁:arithTm / $e₂:arithTm }) =&gt;
                `(Expr.binop BinOp.div (ex{$e₁}) (ex{$e₂}))
        </html:code></html:pre></fr:mainmatter></fr:tree>
    <fr:tree show-metadata="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>23</fr:day></fr:date><fr:title text="Describing arithmetic evaluation">Describing arithmetic evaluation</fr:title></fr:frontmatter><fr:mainmatter><html:p>
        Now say that we wanted to evaluate the expression <fr:tex display="inline"><![CDATA[((2 * 3) + 4)]]></fr:tex> on a high level what we would do is rewrite the multiplication to <fr:tex display="inline"><![CDATA[6 + 4]]></fr:tex> and then rewrite that to <fr:tex display="inline"><![CDATA[10]]></fr:tex>. Expressing this in lean we have:
      </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
        example : -- ((2 * 3) + 4) -&gt;ⁿ 10
        ex{ ((2 * 3) + 4) } -&gt;ⁿ ex{ 10 } :=
          .trans (rw_lhs (rw_const .mul 2 3)) (rw_const .add 6 4)
      </html:code></html:pre><html:p>
        Here we say that the expression <fr:tex display="inline"><![CDATA[((2 * 3) + 4)]]></fr:tex> after multiple steps evaluates to <fr:tex display="inline"><![CDATA[10]]></fr:tex> by first rewriting the left-hand side multiplication to <fr:tex display="inline"><![CDATA[6 + 4]]></fr:tex> and then rewriting that to <fr:tex display="inline"><![CDATA[10]]></fr:tex>. And we chain these operations together using the <html:code>.trans</html:code> constructor of the multistep evaluation relation. Now the question becomes, how do we define these rewrite steps? Intuitively we can imagine evaluation as being described by the following sort of graph
      </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
        +(lhs [op] rhs)
        |
        +-+(rw_lhs) -&gt;ⁿ lhs' [op] rhs    (1) reduce lhs some number of steps
          |
          +-+(rw_rhs) -&gt;ⁿ lhs [op] rhs'  (2) reduce rhs some number of steps
            |
            +- (rw_const) -&gt; value       (3) reduce both to a constant value
      </html:code></html:pre><html:p>
        The idea of each rule being that:
      </html:p><html:ul><html:li><html:strong>rw_lhs</html:strong>: If the left-hand side can be reduced some number of steps we can reduce it while keeping the right-hand side the same. This corresponds to the <html:code>ST_BinOp1</html:code> rule defined earlier.
        </html:li>
        <html:li><html:strong>rw_rhs</html:strong>: If the left-hand side is a constant we can reduce the right-hand side some number of steps while keeping the left-hand side the same. This corresponds to the <html:code>ST_BinOp2</html:code> rule defined earlier.
        </html:li>
        <html:li><html:strong>rw_const</html:strong>: If both sides are constants we can apply the binary operation and reduce the entire expression to a single constant value. This corresponds to the <html:code>ST_BinOpConst</html:code> rule defined earlier.
        </html:li></html:ul><html:p>
        As these rules are defined over the structure of multistep evaluation our implementation of them will naturally be in terms of the inductive structure of a multistep relationship:
      </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
        lemma rw_lhs (lhs_rw : lhs -&gt;ⁿ lhs') :
          (lhs [op] rhs) -&gt;ⁿ (lhs' [op] rhs) :=
        match lhs_rw with
        | .refl       =&gt; .refl
        | .tail S₁ S₂ =&gt; (rw_lhs S₁).tail (.ST_BinOp1 S₂)

        lemma rw_rhs (rhs_rw : rhs -&gt;ⁿ rhs') :
          ((.const lhs) [op] rhs) -&gt;ⁿ ((.const lhs) [op] rhs') :=
        match rhs_rw with
        | .refl       =&gt; .refl
        | .tail S₁ S₂ =&gt; (rw_rhs S₁).tail (.ST_BinOp2 S₂)

        lemma rw_const (op : BinOp) (lhs rhs : Nat) :
          ((.const lhs) [op] (.const rhs)) -&gt;ⁿ .const (eval_op op lhs rhs) :=
        .single (.ST_BinOpConst op lhs rhs)
      </html:code></html:pre><html:p>
        Alternatively we can specify the left and right rewrite rules using the recursor or or head induction principle for multistep evaluation:
      </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
        lemma rw_rhs' (rhs_rw : rhs -&gt;ⁿ rhs') :
          ((.const lhs) [op] rhs) -&gt;ⁿ ((.const lhs) [op] rhs') :=
        .rec
          (refl := .refl)
          (tail := by
            intro _ _ _ hcb ih
            exact ih.tail (.ST_BinOp2 hcb)
          ) rhs_rw

        lemma rw_rhs'' (rhs_rw : rhs -&gt;ⁿ rhs') :
          ((.const lhs) [op] rhs) -&gt;ⁿ ((.const lhs) [op] rhs') :=
        .head_induction_on
          (refl := .refl)
          (head := by
            intro _ _ hac _ ih
            exact ih.head (.ST_BinOp2 hac)
          ) rhs_rw
      </html:code></html:pre><html:p>
        The motive function here is inferred by Lean via the Lemma, which allos us to avoid having to explicitly specify it. Other than this we can see that the recursors again simply correspond to providing methods to describe what to do for each of the constructors.
      </html:p></fr:mainmatter></fr:tree><fr:tree show-metadata="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>23</fr:day></fr:date><fr:title text="Recursors describe usage">Recursors describe usage</fr:title></fr:frontmatter><fr:mainmatter><html:p>
        So at this point you might, I think fairly ask yourself:
      </html:p><html:blockquote>
        Wait why are you spending so much time on this random example for recursors?
      </html:blockquote><html:p>
        The main reason is that to me it provides one of the most grounded direct examples of what it means for a recursor function to <html:em>eliminate</html:em> a term of an inductive type. In general in type theory we say that <html:em>term elimination</html:em> represents the natural deduction rules for <html:em>how to use</html:em> terms of a given type. Applied to our example we can see that these recursors precisely correspond to the rules of how we evaluate i.e. <html:em>use</html:em> arithmetic expressions.
      </html:p><html:p>
        Each rewrite rule describes how we can take an expression and reduce it step by step until we reach a final value. So in a sense the recursor here <html:em>eliminates</html:em> the expression by providing a systematic way to break it down into its constituent parts and evaluate it. This is precisely the essence of what recursors do in type theory; they provide a way to systematically deconstruct and utilize terms of inductive types according to their defined structure and properties.
      </html:p></fr:mainmatter></fr:tree><fr:tree show-metadata="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>23</fr:day></fr:date><fr:title text="Proving correct evaluation">Proving correct evaluation</fr:title></fr:frontmatter><fr:mainmatter><html:p>
        One of the wonderful things we then naturally get from these recursors is that we can use them to describe how a correct evaluation works. So given our evaluation function:
      </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
        @[simp]
        def eval : Expr -&gt; Nat
          | Expr.const n =&gt; n
          | Expr.binop op e₁ e₂ =&gt;
              let v₁ := eval e₁
              let v₂ := eval e₂
              eval_op op v₁ v₂
      </html:code></html:pre><html:p>
        We can use the recursors describing the rewrite rules to show that this evaluation function for our expressions both yields a constant and that we have some sequence of reduction steps (application of rewrite rules) to get to said constant. Or expressed formally:
      </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
        (e : Expr) : -- for any expression e
          (∃ v : Nat), -- there exists a value v
            (eval e = v) ∧ (e -&gt;ⁿ (.const v))
            -- such that eval e = v and e reduces to the constant v
      </html:code></html:pre><html:p>
        The proof of this statement works by induction on the structure of the expression <html:code>e</html:code> if our expression represents a constant then the proof is trivial as we can just take the value of the constant itself. If our expression represents a binary operation then same as we showed for the concrete example we just apply our recursors to first rewrite the lhs, then the rhs and finally apply the operation to get the final constant value. In full the proof looks like:
      </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
        theorem eval_correct (e : Expr) :
        ∃ v : Nat, (eval e = v) ∧ (e -&gt;ⁿ (.const v)) := by
        induction e with
        | const n =&gt; exists n
        | binop op lhs rhs eval_lhs eval_rhs =&gt;
          rcases eval_lhs with ⟨lhs_v, ⟨rhs_is_v, lhs_rw⟩⟩
          rcases eval_rhs with ⟨rhs_v, ⟨lhs_is_v, rhs_rw⟩⟩
          simp [rhs_is_v, lhs_is_v]

          exact
            (rw_lhs lhs_rw).trans (
              (rw_rhs rhs_rw).trans (
                rw_const op lhs_v rhs_v
              )
            )
      </html:code></html:pre><html:p>
        In other words our proof for describing that our evaluation function is correct amounts to essentially simulating or describing quite literally how the evaluation works step by step using the recursors we defined earlier. To see precisely how <html:code>rcases</html:code> works here I'd recommend to paste the code into a Lean environment and examine the types of each of the intermediate values.
      </html:p></fr:mainmatter></fr:tree></fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
      <fr:frontmatter>
        <fr:authors />
        <fr:date>
          <fr:year>2025</fr:year>
          <fr:month>11</fr:month>
          <fr:day>28</fr:day>
        </fr:date>
        <fr:uri>https://kaierikniermann.github.io/notes/002r/</fr:uri>
        <fr:display-uri>002r</fr:display-uri>
        <fr:route>/notes/002r/</fr:route>
        <fr:title text="Type universes in Lean4">Type universes in Lean4</fr:title>
        <fr:taxon>Blog</fr:taxon>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:date>
              <fr:year>2025</fr:year>
              <fr:month>11</fr:month>
              <fr:day>28</fr:day>
            </fr:date>
            <fr:title text="A brief overview">A brief overview</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>28</fr:day>
                </fr:date>
                <fr:title text="Universe hierarchy">Universe hierarchy</fr:title>
              </fr:frontmatter>
              <fr:mainmatter><html:p>
      In Lean4, types are organized into a hierarchy of <html:em>universes</html:em> (also referred to as <html:em>sorts</html:em>). Each universe is associated with a <html:em>level</html:em>, which is a natural number. The <fr:tex display="inline"><![CDATA[\texttt {Sort}]]></fr:tex> operator constructs a universe from a given level. To avoid things like Girard's paradox, Lean4 employs a stratified type system where each universe can only contain types from lower universes, we have the following hierarchy <fr:link href="/notes/baanen-bentkamp-blanchette-holzl-limperg-hitchhikers-2024/" title="The Hitchhiker’s Guide to Logical Verification (2024 Desktop Edition)" uri="https://kaierikniermann.github.io/notes/baanen-bentkamp-blanchette-holzl-limperg-hitchhikers-2024/" display-uri="baanen-bentkamp-blanchette-holzl-limperg-hitchhikers-2024" type="local">(1)</fr:link>:
    </html:p><fr:tex display="block"><![CDATA[
      \begin {align*}
      \texttt {Prop} : \texttt {Type 0} : \texttt {Type 1} : \texttt {Type 2} : \cdots  \\
      \texttt {Sort 0} : \texttt {Sort 1} : \texttt {Sort 2} : \texttt {Sort 3} : \cdots 
      \end {align*}
    ]]></fr:tex><html:p><fr:tex display="inline"><![CDATA[\texttt {Sort}]]></fr:tex> has two main aliases used in Lean4: <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> and <fr:tex display="inline"><![CDATA[\texttt {Type u}]]></fr:tex>. Here, <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> (which is equivalent to <fr:tex display="inline"><![CDATA[\texttt {Sort 0}]]></fr:tex>) is the universe of logical propositions, while <fr:tex display="inline"><![CDATA[\texttt {Type u}]]></fr:tex> (which is equivalent to <fr:tex display="inline"><![CDATA[\texttt {Sort (u + 1)}]]></fr:tex>) represents a universe of types at level <fr:tex display="inline"><![CDATA[u]]></fr:tex>. So we can say:
    </html:p><fr:tex display="block"><![CDATA[
      \texttt {Type u} \equiv  \texttt {Sort (u + 1)}
    ]]></fr:tex><fr:tex display="block"><![CDATA[
      \texttt {Prop} \equiv  \texttt {Sort 0}
    ]]></fr:tex><html:p>
      In general we can express the hierarchy for any universe level <fr:tex display="inline"><![CDATA[u]]></fr:tex> as follows:
    </html:p>
  
    
    <fr:resource hash="a3c29f626bfeab7896c406c2972da4df"><fr:resource-content><html:img src="/notes/a3c29f626bfeab7896c406c2972da4df.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
      \inferrule *[right=Sort]{}{
        \Gamma  \vdash  \texttt {Sort u} : \texttt {Sort (u + 1)}
      }
    \end {mathpar}]]></fr:resource-source></fr:resource>
  
</fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>28</fr:day>
                </fr:date>
                <fr:title text="Predicative universes">Predicative universes</fr:title>
              </fr:frontmatter>
              <fr:mainmatter><html:p>
      Except propositions, a type in a universe at level <fr:tex display="inline"><![CDATA[u]]></fr:tex> cannot quantify over types from strictly larger universes unless the whole result is lifted to a larger universe. In the case of types we have:
    </html:p>
  
    
    <fr:resource hash="6421c48de3f29311e497b41a79a808fd"><fr:resource-content><html:img src="/notes/6421c48de3f29311e497b41a79a808fd.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
      \inferrule *[right=ArrowType]{
        \Gamma  \vdash  \sigma  : \texttt {Type u} \\
        \Gamma  , x : \sigma  \vdash  \tau [x] : \texttt {Type v}
      }{
        \Gamma  \vdash  (x : \sigma ) \to  \tau [x] : \texttt {Type (max u v)}
      }
    \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
      To demonstrate some valid instance of this inference rule lets consider the following lean examples:
    </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
      example (α : Type 1) (β : Type 2) : Type 2 := α → β
      example (α : Type 2) (β : Type 1) : Type 2 := α → β
    </html:code></html:pre><html:p>
      Both of the above examples are valid because the resulting type is lifted to the maximum universe level of the input types. In general, we say that the behavior of the <fr:tex display="inline"><![CDATA[\texttt {Type}]]></fr:tex> universes is called <html:strong>predicative</html:strong> meaning that objects <html:em>may not</html:em> be defined in terms of quantifiers ranging over that same object.
    </html:p></fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>28</fr:day>
                </fr:date>
                <fr:title text="Impredicative universes">Impredicative universes</fr:title>
              </fr:frontmatter>
              <fr:mainmatter><html:p>
      We can observe that a function type's universe is determined by the universes of its argument and return types. However, in the case of propositions we have a different behavior:
    </html:p>
  
    
    <fr:resource hash="01b9da1304665deaca41d0e69e7e2b67"><fr:resource-content><html:img src="/notes/01b9da1304665deaca41d0e69e7e2b67.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
      \inferrule *[right=ArrowProp]{
        \Gamma  \vdash  \sigma  : \texttt {Sort u} \\ 
        \Gamma  , x : \sigma  \vdash  \tau [x] : \texttt {Prop}
      }{
        \Gamma  \vdash  (\forall  x : \sigma , \tau [x]) : \texttt {Prop}
      }
    \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
      Predicates, which are functions that return propositions, may have argument types in any universe, but the function itself remains in the <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> universe. This behavior is called <html:strong>impredicative</html:strong> meaning that objects <html:em>may</html:em> be defined in terms of quantifiers ranging over that same object. The rule <fr:tex display="inline"><![CDATA[\textsc {ArrowProp}]]></fr:tex> means that expressions such <fr:tex display="inline"><![CDATA[\forall  a : \texttt {Prop}, a \to  a]]></fr:tex>, which quantify over all propositions (including themselves), yield a proposition, that is:
    </html:p><fr:tex display="block"><![CDATA[
      (\forall  a : \texttt {Prop},\ a \to  a) : \texttt {Prop}
    ]]></fr:tex><html:p>
      We can see some more examples of quantifying both over propositions and types as follows:
    </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
      /-- Quantifying over propositions yields a proposition -/
      example : Prop := ∀ (P : Prop) (p1 p2 : P), p1 = p2

      /-- Proposition quantifying over all type stays in Prop -/
      example : Prop := ∀ (α : Type), ∀ (x : α), x = x
      example : Prop := ∀ (α : Type 5), ∀ (x : α), x = x
    </html:code></html:pre></fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>28</fr:day>
                </fr:date>
                <fr:title text="The general rule">The general rule</fr:title>
              </fr:frontmatter>
              <fr:mainmatter><html:p>
      We can combine these two rules to get a more general rule for function types that return types in any universe:
    </html:p>
  
    
    <fr:resource hash="0701b5f9a243365e0125751bf06c9e91"><fr:resource-content><html:img src="/notes/0701b5f9a243365e0125751bf06c9e91.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
      \inferrule *[right=Arrow]{
        \Gamma  \vdash  \sigma  : \texttt {Sort u} \\ 
        \Gamma  , x : \sigma  \vdash  \tau [x] : \texttt {Sort v}
      }{
        \Gamma  \vdash  (x : \sigma ) \to  \tau [x] : \texttt {Sort (imax u v)}
      }
    \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
      Here the function type's universe is determined by the (impredicative max) <html:strong>imax</html:strong> of the universes of its argument and return types, where <fr:tex display="inline"><![CDATA[\texttt {imax}]]></fr:tex> is defined as follows:
    </html:p><fr:tex display="block"><![CDATA[
      \texttt {imax}(u, v) = \begin {cases}
      0 & \text {if } v = 0 \\
      \texttt {max}(u, v) & \text {otherwise}
      \end {cases}
    ]]></fr:tex></fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>28</fr:day>
                </fr:date>
                <fr:title text="The level grammar">The level grammar</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
      We can describe the level grammar via the following inductive type:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      inductive Level
      | zero : Level
      | succ : Level → Level
      | max  : Level → Level → Level
      | imax : Level → Level → Level
    </html:code>
                </html:pre>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:date>
              <fr:year>2025</fr:year>
              <fr:month>11</fr:month>
              <fr:day>28</fr:day>
            </fr:date>
            <fr:title text="Universe Binding">Universe Binding</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>28</fr:day>
                </fr:date>
                <fr:title text="Explicit">Explicit</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
      We can define functions and types that are <html:strong>universe polymorphic</html:strong> by introducing universe levels either <html:em>explicitly</html:em> or <html:em>implicitly</html:em>. An explicit universe level is specified directly in the definition, while an implicit universe level is inferred by Lean4. For example:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
        /-- Explicit universe level -/
        def map.{u v} {α : Type u} {β : Type v} 
            (f : α → β) : List α → List β :=
          | []       ⇒ []
          | x :: xs  =&gt; f x :: map f xs
      </html:code>
                </html:pre>
                <html:p>
      Here the map is declared with explicit universe levels <fr:tex display="inline"><![CDATA[u]]></fr:tex> and <fr:tex display="inline"><![CDATA[v]]></fr:tex> and instantiates the polymorphic <fr:tex display="inline"><![CDATA[\texttt {List}]]></fr:tex>. We can also define the same function with implicit universe levels as follows:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
        universe u v
        def map {α : Type u} {β : Type v} 
            (f : α → β) : List α → List β := ...
      </html:code>
                </html:pre>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>28</fr:day>
                </fr:date>
                <fr:title text="Implicit">Implicit</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
      By default in Lean4 the option <fr:tex display="inline"><![CDATA[\texttt {autoImplicit}]]></fr:tex> is set to true, meaning that our universe levels will be inferred automatically meaning that we can simply write:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
        def map {α : Type u} {β : Type v} 
            (f : α → β) : List α → List β := ...
      </html:code>
                </html:pre>
                <html:p>
      Importantly automatic implicit parameter inference <html:em>only works</html:em> if the universe is mentioned in the header preceding the assignment, i.e:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
        /-- Bad: unknown universe u -/
        def L := List (Type u)
        /-- Good: universe u mentioned in header -/
        def L.{u} := List (Type u)
      </html:code>
                </html:pre>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>28</fr:day>
                </fr:date>
                <fr:title text="Implicit + fresh">Implicit + fresh</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
      We can also go even further with implicit universes by allowing Lean4 to generate fresh universe levels for us. This is done by omitting the universe annotation and replacing it with a * suffix:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      /-- Fresh implicit universe levels -/
      def map {α : Type*} {β : Type*} 
          (f : α → β) : List α → List β := ...
    </html:code>
                </html:pre>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:date>
              <fr:year>2025</fr:year>
              <fr:month>11</fr:month>
              <fr:day>28</fr:day>
            </fr:date>
            <fr:title text="Universe Lifting">Universe Lifting</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>
    Sometimes we may want to explicitly lift a type from one universe to a higher universe. Lean4 provides lifting operators which are wrappers around terms of a type that reside in a higher universe. There are two main lifting operators:
  </html:p>
            <html:ul><html:li><fr:tex display="inline"><![CDATA[\texttt {PLift}]]></fr:tex>: Lifts a proposition from <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex> (i.e. <fr:tex display="inline"><![CDATA[\texttt {Sort 1}]]></fr:tex>).
    </html:li>
    <html:li><fr:tex display="inline"><![CDATA[\texttt {ULift}]]></fr:tex>: Lifts a type from <fr:tex display="inline"><![CDATA[\texttt {Type u}]]></fr:tex> to any number of levels.
    </html:li></html:ul>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>28</fr:day>
                </fr:date>
                <fr:title text="PLift">PLift</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
      The <fr:tex display="inline"><![CDATA[\texttt {PLift}]]></fr:tex> operator is used to lift propositions into the first type universe. It is defined as follows:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      structure PLift (α : Sort u) : Type u where
        /-- Wraps a proof/value to increase its type's universe lvl -/
        up ::
        /-- Extracts a wrapped proof/value from a lifted prop/type. -/
        down : α
    </html:code>
                </html:pre>
                <html:p>
      Some simple examples:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      #check False       -- False : Prop
      #check PLift False -- PLift False : Type
      #check Nat         -- Nat : Type
      #check PLift Nat   -- PLift Nat : Type 1

      example : PLift Prop        := PLift.up True
      example : Prop              := (PLift.down (PLift.up False))
      example : List (PLift True) := [.up (by trivial), .up (by decide)]
    </html:code>
                </html:pre>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>28</fr:day>
                </fr:date>
                <fr:title text="ULift">ULift</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
      The <fr:tex display="inline"><![CDATA[\texttt {ULift}]]></fr:tex> operator is used to lift types to higher universes. It is defined as follows:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      structure ULift.{r, s} (α : Type s) : Type (max s r) where
        /-- Wraps a value to increase its type's universe level. -/
        up ::
        /-- Extracts a wrapped value from a universe-lifted type. -/
        down : α
    </html:code>
                </html:pre>
                <html:p>
      Some simple examples:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      #check Nat               -- Nat : Type
      #check ULift Nat         -- ULift Nat : Type 1
      #check ULift (ULift Nat) -- ULift (ULift Nat) : Type 2

      example : ULift Nat        := ULift.up 42
      example : List (ULift Nat) := [.up 1, .up 2, .up 3]
    </html:code>
                </html:pre>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:date>
              <fr:year>2025</fr:year>
              <fr:month>11</fr:month>
              <fr:day>28</fr:day>
            </fr:date>
            <fr:title text="Example: Preorder Category">Example: Preorder Category</fr:title>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>
    A <html:em>preorder relation</html:em> is a binary relation that is <html:strong>reflexive</html:strong> and <html:strong>transitive</html:strong>. In Lean this is expressed as follows:
  </html:p>
            <html:pre class="code-block language-lean">
              <html:code class="language-lean">
    class Preorder (α : Type*) extends LE α, LT α where
      le_refl   : ∀ a : α, a ≤ a
      le_trans  : ∀ a b c : α, a ≤ b → b ≤ c → a ≤ c
      lt := fun a b =&gt; a ≤ b ∧ ¬b ≤ a
      lt_iff_le_not_ge : ∀ a b : α, a &lt; b ↔ a ≤ b ∧ ¬b ≤ a := by intros; rfl
  </html:code>
            </html:pre>
            <html:p>
    We can already see here that the preorder relation uses implicit universe polymorphism via the <fr:tex display="inline"><![CDATA[\texttt {Type*}]]></fr:tex> annotation. We can now construct a small category from a preorder relation as follows:
  </html:p>
            <html:pre class="code-block language-lean">
              <html:code class="language-lean">
    open CategoryTheory

    instance {α : Type u} [Preorder α] : SmallCategory α where
      Hom a b          := ULift &lt;| PLift (a ≤ b)
      id a             := .up &lt;| .up &lt;| le_refl a
      comp {a b c} f g := .up &lt;| .up &lt;| (le_trans f.down.down g.down.down)
  </html:code>
            </html:pre>
            <html:p>
    Let's break this down part by part starting with the homomorphism:
  </html:p>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>28</fr:day>
                </fr:date>
                <fr:title text="Arrows">Arrows</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
      For the case of the category definition, Lean fundamentally uses quivers to represent the homs between objects. Now before showing how lean defines them lets I think try and do it ourselves. So in this instance in an abstract sense we want the relationship <fr:tex display="inline"><![CDATA[\leq ]]></fr:tex> to represent our morphism or arrow between two objects, so in a sense the following two are equivalent:
    </html:p>
                <fr:tex display="block"><![CDATA[
      a \leq  b \equiv  a \xrightarrow {\leq } b
    ]]></fr:tex>
                <html:p>
      So in the most straightforward sense what we can do is define any kind of "container" to represent our source and target objects under some label, we can define this naively as follows:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      class Graph (Obj : Type) where
        arrow (source : Obj) (target : Obj) : Type
    </html:code>
                </html:pre>
                <html:p>
      Now let's try to define an instance of such a graph on a preorder relation in which our objects simply live in <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex>:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      instance {α : Type} [Preorder α] : Graph α where
        arrow a b := a ≤ b -- arrow from a to b is the relation a ≤ b
    </html:code>
                </html:pre>
                <html:p>
      Here we are declaring an instance, this instance takes
      <html:ul><html:li>
          An <html:strong>implicit type parameter</html:strong> <fr:tex display="inline"><![CDATA[\alpha ]]></fr:tex> which is the type of our objects at the universe level 0.
        </html:li>
        <html:li>
          A <html:strong>type class constraint</html:strong> <fr:tex display="inline"><![CDATA[\texttt {[Preorder α]}]]></fr:tex> which ensures that the type <fr:tex display="inline"><![CDATA[\alpha ]]></fr:tex> has a preorder relation defined on it. In other words it guarantees that the relation <fr:tex display="inline"><![CDATA[\leq ]]></fr:tex> is reflexive and transitive for all elements of type <fr:tex display="inline"><![CDATA[\alpha ]]></fr:tex>.
        </html:li></html:ul>
      And we provide the necessary implementation for the <fr:tex display="inline"><![CDATA[\texttt {arrow}]]></fr:tex> function by setting it to be the preorder relation <fr:tex display="inline"><![CDATA[\leq ]]></fr:tex>. But what you will notice is that we have a problem here, namely that our preorder relation lives in the universe <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> as it's obviously a logical relation, but our graph arrows need to live in <fr:tex display="inline"><![CDATA[\texttt {Type}]]></fr:tex> (i.e. <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex>). 
    </html:p>
                <html:p>
      A first thought might be to just set the arrow type to be <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> directly, in our definition of the class <fr:tex display="inline"><![CDATA[\texttt {Graph}]]></fr:tex> though this is rather restrictive as it means that any graph we wish to define can only ever have arrows representing propositions, what if we want to have arrows represent other types such as functions or numbers?
    </html:p>
                <html:p>
      One way to approach this is to use the <fr:tex display="inline"><![CDATA[\texttt {PLift}]]></fr:tex> operator to lift our preorder relation from <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex> as follows:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      instance {α : Type} [Preorder α] : Graph α where
        arrow a b := PLift (a ≤ b) -- lift relation to Type 0
    </html:code>
                </html:pre>
                <html:p>
      While this does work, and often is probably a reasonable way to go about things, much of Lean's mathlib employs universe polymorphic types to define various kinds of structures. Thus parameterizing over some universe level <fr:tex display="inline"><![CDATA[u]]></fr:tex> we define our polymorphic instance as:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      instance {α : Type u} [Preorder α] : Graph α where
        arrow a b := PLift (a ≤ b) 
    </html:code>
                </html:pre>
                <html:p>
      But now we naturally run into another issue, namely that the class for our graph is now no longer universe polymorphic which leads to a universe level mismatch. The most straightforward fix here is to simply make the objects in the graph universe polymorphic as well:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      class Graph (Obj : Type u) where -- now polymorphic over u
        arrow (source : Obj) (target : Obj) : Type
    </html:code>
                </html:pre>
                <html:p>
      But this leads to another question, what level should the arrows live in? We've already seen that arrows can represent various different kinds of things different from the types of objects themselves, (e.g. <fr:tex display="inline"><![CDATA[2 \leq  3]]></fr:tex> is a proposition but clearly 2 and 3 are numbers). Now one approach is to simply leave the arrows in <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex> but this already is mildly annoying as it forces us to lift any arrows that don't naturally live in <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex>. Furthermore, we've already seen that having the type stuck at Prop is also not nice, so what we can do is make the arrows' universe polymorphic as well, though over a different universe level <fr:tex display="inline"><![CDATA[v]]></fr:tex> motivated by the aforementioned situation of different levels of arrows and objects:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      class Graph (Obj : Type u) where
        arrow (source : Obj) (target : Obj) : Sort v

      instance {α : Type u} [Preorder α] : Graph α where
        arrow a b := a ≤ b -- now lives in Sort 0 (i.e. Prop)
    </html:code>
                </html:pre>
                <html:p>
      But hold up, why are we lifting in the definition of the instance for the SmallCategory? Let's take a look at all the relevant type signatures:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      -- Quiver 
      -- (V : Type u) where

      -- CategoryStruct
      -- (obj : Type u) : Type max u (v + 1) extends Quiver.{v + 1} obj

      -- Category 
      -- (obj : Type u) : Type max u (v + 1) extends CategoryStruct.{v} obj 

      -- SmallCategory
      -- (obj : Type u) : Type (u + 1) extends Category.{u} obj 
    </html:code>
                </html:pre>
                <html:p>
      Let's break this down step by step starting first with the relationship between CategoryStruct and Quiver, for the sake of simplicity i'll abstract away some exact names and make all universes explicit:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      variable {α : Type m} [Preorder α] (a b c : α)

      class Box.{u, v} (obj : Type u) where
        pair : obj → obj → Sort v

      class A.{u, v} (obj : Type u) 
        : Type max u (v + 1) extends (Box.{u, v + 1} obj) where
    </html:code>
                </html:pre>
                <html:p>
      I think an interesting question I first had here is with the extension of <fr:tex display="inline"><![CDATA[\texttt {Box}]]></fr:tex> in <fr:tex display="inline"><![CDATA[\texttt {A}]]></fr:tex> why might you want to increase the universe level of the arrows by one? The main reason this is done in general is to essentially constrain the <fr:tex display="inline"><![CDATA[v]]></fr:tex> to never be zero. The implication of this being that our extended class <fr:tex display="inline"><![CDATA[\texttt {A}]]></fr:tex> can never have any pairs which live in <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex>.
    </html:p>
                <html:p>
      A good follow up to this might be, why would you not want things to live in <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex>? In the most general sense some reasons are:
    </html:p>
                <html:ul><html:li><fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> is <html:em>proof irrelevant</html:em>: In Lean, propositions are considered proof irrelevant, meaning that all proofs of a given proposition are treated as equal. This can lead to loss of information when you want to be able to distinguish between different morphisms or in our simplified example pairs.
      </html:li>
      <html:li><fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> is <html:em>not computational</html:em>: Propositions in Lean are not computationally relevant, meaning that they do not have computational content. If you want to perform computations or extract algorithms from your morphisms or pairs, having them in <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> would prevent that.
      </html:li>
      <html:li><fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> has <html:em>limited structure</html:em>: Propositions in Lean do not have the same rich structure as types in higher universes. If you need to work with morphisms or pairs that have additional structure (like being functions, sets, etc.), you would want them to live in a higher universe.
      </html:li></html:ul>
                <html:p>
      As an example we can consider the following:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      -- @classname disables universe inference for that class
      variable (a₁ : @A.{m, v} α)
      #check (a₁.pair a b : Sort (v + 1)) -- Box.pair a b : Type v
    </html:code>
                </html:pre>
                <html:p>
      We can see here that the pair now lives in <fr:tex display="inline"><![CDATA[\texttt {Sort (v + 1)}]]></fr:tex>, meaning that if we had <fr:tex display="inline"><![CDATA[v = 0]]></fr:tex> then our pairs would now live in <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex>. A natural byproduct of this choice - having arrows live in <fr:tex display="inline"><![CDATA[\texttt {Sort (v + 1)}]]></fr:tex> - is that the type of the structure itself must now live in the largest universe such that it can contain both the objects and the arrows. This is why we have the type signature <fr:tex display="inline"><![CDATA[\texttt {Type max u (v + 1)}]]></fr:tex> for <fr:tex display="inline"><![CDATA[\texttt {A}]]></fr:tex>. Equivalently we can expand this as:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      -- since Type u = Sort (u + 1) and Type (v + 1) = Sort (v + 2)
      Sort (max (u + 1) (v + 2)) 
    </html:code>
                </html:pre>
                <html:p>
      If we then create similarly abstract versions for the Category class (B) and SmallCategory class (C) we have:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      class B.{u, v} (obj : Type u) 
        : Type max u (v + 1) extends A.{u, v} obj where

      class C.{u} (obj : Type u) 
        : Type (u + 1) extends B.{u, u} obj where 
      --                        ^ can also type B.{u} (inferres v = u)
    </html:code>
                </html:pre>
                <html:p>
      We can see here that our SmallCategory (C) now constrains the arrows to live in the same universe as the objects by setting <fr:tex display="inline"><![CDATA[v = u]]></fr:tex> in the extension of <fr:tex display="inline"><![CDATA[\texttt {B}]]></fr:tex>. Thus, if we construct our pair, we have:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      variable (c : @C.{m} α)
      #check (c.pair a b : Sort (m + 1)) -- Box.pair a b : Type m
    </html:code>
                </html:pre>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>28</fr:day>
                </fr:date>
                <fr:title text="Identity morphism">Identity morphism</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
      Next up let's look at the identity morphism:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      id a := .up &lt;| .up &lt;| le_refl a
    </html:code>
                </html:pre>
                <html:p>
      The identity is defined as a function that quantifies over all objects <fr:tex display="inline"><![CDATA[a]]></fr:tex> in our category and returns an arrow from <fr:tex display="inline"><![CDATA[a]]></fr:tex> to <fr:tex display="inline"><![CDATA[a]]></fr:tex>. Naturally we then first want to construct our arrow, the identity arrow from <fr:tex display="inline"><![CDATA[a]]></fr:tex> to <fr:tex display="inline"><![CDATA[a]]></fr:tex> is simply the reflexivity property of the preorder relation <fr:tex display="inline"><![CDATA[\leq ]]></fr:tex>, that is <fr:tex display="inline"><![CDATA[a \leq  a]]></fr:tex> which we can get via <fr:tex display="inline"><![CDATA[\texttt {le\_refl a}]]></fr:tex>. However since our arrows live in <fr:tex display="inline"><![CDATA[\texttt {Type m}]]></fr:tex>, we need to lift our relation twice, first using <fr:tex display="inline"><![CDATA[\texttt {PLift.up}]]></fr:tex> to lift it from <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex>, and then again using <fr:tex display="inline"><![CDATA[\texttt {ULift.up}]]></fr:tex> to lift it from <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {Type m}]]></fr:tex>. A note to make for people unfamiliar with the syntax here, the following pieces of code are equivalent:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      -- .up &lt;| .up &lt;| le_refl a == ULift.up (PLift.up (le_refl a))
    </html:code>
                </html:pre>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>28</fr:day>
                </fr:date>
                <fr:title text="Composition">Composition</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
      Finally let's look at the composition of arrows:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      comp {a b c} f g := .up &lt;| .up &lt;| (le_trans f.down.down g.down.down)
    </html:code>
                </html:pre>
                <html:p>
      The lifting portion here follows the same reasoning as the identity morphism, we need to lift the resulting relation from <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {Type m}]]></fr:tex>. The actual composition is done via the transitivity property of the preorder relation <fr:tex display="inline"><![CDATA[\leq ]]></fr:tex>. The thing is here that our input arrows <fr:tex display="inline"><![CDATA[f]]></fr:tex> and <fr:tex display="inline"><![CDATA[g]]></fr:tex> are both lifted types corresponding to:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      f : ULift (PLift (a ≤ b))
      g : ULift (PLift (b ≤ c))
    </html:code>
                </html:pre>
                <html:p>
      Thus to extract the actual preorder relations we need to use the <fr:tex display="inline"><![CDATA[\texttt {down}]]></fr:tex> method twice, first to go from <fr:tex display="inline"><![CDATA[\texttt {ULift}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {PLift}]]></fr:tex>, and then again to go from <fr:tex display="inline"><![CDATA[\texttt {PLift}]]></fr:tex> to the actual relation in <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex>. Once we have the two relations extracted we can then apply the transitivity property <fr:tex display="inline"><![CDATA[\texttt {le\_trans}]]></fr:tex> to get the composed relation <fr:tex display="inline"><![CDATA[a \leq  c]]></fr:tex> (which we then lift back up).
    </html:p>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
      <fr:frontmatter>
        <fr:authors />
        <fr:date>
          <fr:year>2025</fr:year>
          <fr:month>11</fr:month>
          <fr:day>29</fr:day>
        </fr:date>
        <fr:uri>https://kaierikniermann.github.io/notes/002u/</fr:uri>
        <fr:display-uri>002u</fr:display-uri>
        <fr:route>/notes/002u/</fr:route>
        <fr:title text="A simple Bool category in Lean4">A simple Bool category in Lean4</fr:title>
        <fr:taxon>Blog</fr:taxon>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:date>
              <fr:year>2025</fr:year>
              <fr:month>11</fr:month>
              <fr:day>27</fr:day>
            </fr:date>
            <fr:uri>https://kaierikniermann.github.io/notes/002m/</fr:uri>
            <fr:display-uri>002m</fr:display-uri>
            <fr:route>/notes/002m/</fr:route>
            <fr:title text="Category">Category</fr:title>
            <fr:taxon>Definition</fr:taxon>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>
  There are a few ways you can define a <html:em>category</html:em>. In the most basic intuitive sense a category consists of a collection of things called <html:em>objects</html:em> and binary relationships (or transitions) between those objects called <html:em>morphisms</html:em> (or <html:em>arrows</html:em>). We can combine these relationships by <html:em>composing</html:em> them, and for each object there is an <html:em>identity morphism</html:em> that acts as a neutral element for composition. <fr:link href="/notes/nlab-category/" title="category" uri="https://kaierikniermann.github.io/notes/nlab-category/" display-uri="nlab-category" type="local">(1)</fr:link></html:p>
            <html:p>
  In the context of <fr:link href="/notes/002l/" title="Quiver" uri="https://kaierikniermann.github.io/notes/002l/" display-uri="002l" type="local"><html:em>quivers</html:em></fr:link> a category can be defined as a quiver with a rule saying for how we can compose two edges that fit together to get a new edge. Furthermore, each vertex (object) has an edge starting and ending at that vertex (the identity morphism). The classical definition is something like this:
</html:p>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>27</fr:day>
                </fr:date>
                <fr:title text="The data">The data</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
    A <html:em>category</html:em> <fr:tex display="inline"><![CDATA[C]]></fr:tex> consists of:
  </html:p>
                <html:ul><html:li>
      A collection (or <html:em>class</html:em> <fr:link href="/notes/johnson-yau-2d-categories-2020/" title="2-Dimensional Categories" uri="https://kaierikniermann.github.io/notes/johnson-yau-2d-categories-2020/" display-uri="johnson-yau-2d-categories-2020" type="local">(2)</fr:link>) of <html:strong>objects</html:strong>, denoted as <fr:tex display="inline"><![CDATA[\text {Ob}(C)]]></fr:tex> or <fr:tex display="inline"><![CDATA[C_0]]></fr:tex>.
    </html:li>
    <html:li>
      A collection (or <html:em>set</html:em> <fr:link href="/notes/johnson-yau-2d-categories-2020/" title="2-Dimensional Categories" uri="https://kaierikniermann.github.io/notes/johnson-yau-2d-categories-2020/" display-uri="johnson-yau-2d-categories-2020" type="local">(2)</fr:link>) of <html:strong>morphisms</html:strong> (or <html:em>arrows</html:em>), denoted <fr:tex display="inline"><![CDATA[C_1]]></fr:tex> or <fr:tex display="inline"><![CDATA[C(x, y)]]></fr:tex> for <fr:tex display="inline"><![CDATA[x, y \in  \text {Ob}(C)]]></fr:tex>.
      <html:ul><html:li>
          For every morphism <fr:tex display="inline"><![CDATA[f \in  C(x, y)]]></fr:tex>, there are two associated objects: the <html:em>source</html:em> (or <html:em>domain</html:em>) <fr:tex display="inline"><![CDATA[x]]></fr:tex> and the <html:em>target</html:em> (or <html:em>co-domain</html:em>) <fr:tex display="inline"><![CDATA[y]]></fr:tex>. In standard function notation, we write <fr:tex display="inline"><![CDATA[f: x \to  y]]></fr:tex> where <fr:tex display="inline"><![CDATA[x = \text {dom}(f)]]></fr:tex> and <fr:tex display="inline"><![CDATA[y = \text {cod}(f)]]></fr:tex>. NLab has a nice convention where it denotes the source <fr:tex display="inline"><![CDATA[s]]></fr:tex> of a morphism as <fr:tex display="inline"><![CDATA[s(f)]]></fr:tex> and the target <fr:tex display="inline"><![CDATA[t]]></fr:tex> as <fr:tex display="inline"><![CDATA[t(f)]]></fr:tex>.
        </html:li>
        <html:li>
          For every pair of morphisms <fr:tex display="inline"><![CDATA[f \in  C(x, y)]]></fr:tex> and <fr:tex display="inline"><![CDATA[g \in  C(y, z)]]></fr:tex> (s.t. <fr:tex display="inline"><![CDATA[t(f) = s(g)]]></fr:tex> i.e. the morphisms type check), there is a <html:strong>composition</html:strong> morphism <fr:tex display="inline"><![CDATA[g \circ  f \in  C(x, z)]]></fr:tex>. Written out we can denote this as:
          <fr:tex display="block"><![CDATA[
            C(x, y) \times  C(y, z) \to  C(x, z)
          ]]></fr:tex>
          in diagrammatic order this is often written as <fr:tex display="inline"><![CDATA[f; g]]></fr:tex> we can equivalently use a more graphical notation:
          
 
  
  <html:figure><fr:resource hash="d8323ce59463aa832587ad5330c42c75"><fr:resource-content><html:img src="/notes/d8323ce59463aa832587ad5330c42c75.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
   
   % String-diagram specific extensions live here. Add diagram tweaks without
 % re-running the full base preamble (to avoid duplicate definitions).

   
  
   \usepackage{eulervm}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{amsmath, amsthm, amsfonts}
  \usepackage{tikz, tikz-cd, mathtools, amssymb, stmaryrd}
  \usetikzlibrary{arrows.meta, shapes, positioning, calc, decorations.pathreplacing, backgrounds, fit, matrix, spath3}

  % A TikZ style for curved arrows of a fixed height, due to AndréC.
  \tikzset{curve/.style={settings={#1},to path={(\tikztostart)
        .. controls ($(\tikztostart)!\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
        and ($(\tikztostart)!1-\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
    .. (\tikztotarget)\tikztonodes}},
    settings/.code={\tikzset{quiver/.cd,#1}
    \def\pv##1{\pgfkeysvalueof{/tikz/quiver/##1}}},
  quiver/.cd,pos/.initial=0.35,height/.initial=0}

  % A TikZ style for shortening paths without the poor behaviour of `shorten <' and `shorten >'.
  \tikzset{between/.style n args={2}{/tikz/spath/at end path construction={
        \tikzset{spath/split at keep middle={current}{#1}{#2}}
  }}}

  % TikZ arrowhead/tail styles.
  \tikzset{tail reversed/.code={\pgfsetarrowsstart{tikzcd to}}}
  \tikzset{2tail/.code={\pgfsetarrowsstart{Implies[reversed]}}}
  \tikzset{2tail reversed/.code={\pgfsetarrowsstart{Implies}}}
  % TikZ arrow styles.
  \tikzset{no body/.style={/tikz/dash pattern=on 0 off 1mm}}


  ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[
          \[\begin {tikzcd}[column sep=small]
            x && y && z
            \arrow ["f", from=1-1, to=1-3]
            \arrow ["{f;g}", curve={height=-18pt}, from=1-1, to=1-5]
            \arrow ["g", from=1-3, to=1-5]
          \end {tikzcd}\]
        ]]></fr:resource-source></fr:resource></html:figure></html:li>
        <html:li>
          For every object <fr:tex display="inline"><![CDATA[x \in  \text {Ob}]]></fr:tex> there is an <html:strong>identity morphism</html:strong>:
          <fr:tex display="block"><![CDATA[
            (\text {id}_x : x \to  x) \in  C(x, x)
          ]]></fr:tex></html:li></html:ul>
      Note: Some additional notations for morphisms include <fr:tex display="inline"><![CDATA[\text {hom}(x, y)]]></fr:tex>, <fr:tex display="inline"><![CDATA[\text {hom}_C(x, y)]]></fr:tex> or <fr:tex display="inline"><![CDATA[C_1(x, y)]]></fr:tex>. Additionally, people use the notation <fr:tex display="inline"><![CDATA[\text {Mor(C)}]]></fr:tex> to denote the following disjoint union
      <fr:tex display="block"><![CDATA[
        \text {Mor}(C) = \bigsqcup _{x, y \in  \text {Ob}(C)} C(x, y)
      ]]></fr:tex>
      Which just expresses the idea that the collection of all morphisms in a category is made up of the morphisms between each pair of objects.
    </html:li></html:ul>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>27</fr:day>
                </fr:date>
                <fr:title text="The axioms">The axioms</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
    The above are often called <html:strong>data</html:strong> of a category. In addition to this data, a category must satisfy the following <html:strong>axioms</html:strong> or (<html:em>conditions</html:em>):
  </html:p>
                <html:ul><html:li>
      Morphisms need to be <html:strong>associative</html:strong> which means that for every triple of morphisms <fr:tex display="inline"><![CDATA[f \in  C(w, x)]]></fr:tex>, <fr:tex display="inline"><![CDATA[g \in  C(x, y)]]></fr:tex>, and <fr:tex display="inline"><![CDATA[h \in  C(y, z)]]></fr:tex> the following holds:
      <fr:tex display="block"><![CDATA[
        h \circ  (g \circ  f) = (h \circ  g) \circ  f
      ]]></fr:tex></html:li>
    <html:li>
      For each morphism <fr:tex display="inline"><![CDATA[f \in  C(x, y)]]></fr:tex> the identity morphisms act as <html:strong>neutral elements</html:strong> for composition:
      <fr:tex display="block"><![CDATA[
        \text {id}_y \circ  f = f = f \circ  \text {id}_x
      ]]></fr:tex>
      This is also known as the <html:em>left</html:em> and <html:em>right</html:em> <html:strong>unit laws</html:strong> or just <html:strong>unity</html:strong> in general.
    </html:li></html:ul>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>27</fr:day>
                </fr:date>
                <fr:title text="Remarks">Remarks</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:ul>
                  <html:li>
      A category such as the one described above is often also called a 1-category to distinguish it from higher categories such as 2-categories, n-categories.
    </html:li>
                </html:ul>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:date>
              <fr:year>2025</fr:year>
              <fr:month>11</fr:month>
              <fr:day>29</fr:day>
            </fr:date>
            <fr:uri>https://kaierikniermann.github.io/notes/002s/</fr:uri>
            <fr:display-uri>002s</fr:display-uri>
            <fr:route>/notes/002s/</fr:route>
            <fr:title text="Isomorphism (morphisms)">Isomorphism (morphisms)</fr:title>
            <fr:taxon>Definition</fr:taxon>
          </fr:frontmatter>
          <fr:mainmatter>
            <html:p>
  A morphism <fr:tex display="inline"><![CDATA[f : X \to  Y]]></fr:tex> is called an <html:strong>Isomorphism</html:strong> if there exists a morphism <fr:tex display="inline"><![CDATA[g : Y \to  X]]></fr:tex> such that the following hold <fr:link href="/notes/johnson-yau-2d-categories-2020/" title="2-Dimensional Categories" uri="https://kaierikniermann.github.io/notes/johnson-yau-2d-categories-2020/" display-uri="johnson-yau-2d-categories-2020" type="local">(1)</fr:link>:
</html:p>
            <fr:tex display="block"><![CDATA[
  g \circ  f = 1_X
  \quad 
  f \circ  g = 1_Y
]]></fr:tex>
            <html:p>
  Sometimes an isomorphism is also denoted
</html:p>
            <fr:tex display="block"><![CDATA[
  X \xrightarrow {\cong } Y
]]></fr:tex>
          </fr:mainmatter>
        </fr:tree>
        <fr:tree show-metadata="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:date>
              <fr:year>2025</fr:year>
              <fr:month>11</fr:month>
              <fr:day>29</fr:day>
            </fr:date>
            <fr:title text="The category">The category</fr:title>
            <fr:taxon>Example</fr:taxon>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>29</fr:day>
                </fr:date>
                <fr:title text="The data">The data</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
      We want to start off by defining the data of our category. On a high level we want to define a category with two objects, <fr:tex display="inline"><![CDATA[\texttt {true}]]></fr:tex> and <fr:tex display="inline"><![CDATA[\texttt {false}]]></fr:tex>. Starting with the object representation we have:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      /-- A wrapper type to make a custom category on Bool -/
      structure BoolCat : Type where
        val : Bool
      deriving DecidableEq, Repr

      /-- The two objects -/
      def BoolCat.tt : BoolCat := ⟨true⟩
      def BoolCat.ff : BoolCat := ⟨false⟩
    </html:code>
                </html:pre>
                <html:p>
      Next we want to define the morphisms between these objects. For each pair of objects we express 3 kinds of morphisms: the identity morphism, a morphism from <fr:tex display="inline"><![CDATA[\texttt {false}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {true}]]></fr:tex>, <fr:tex display="inline"><![CDATA[\texttt {false}]]></fr:tex>from <fr:tex display="inline"><![CDATA[\texttt {true}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {false}]]></fr:tex>. We can express this in Lean as follows:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      /-- Morphisms: we allow identity on each, plus iso between them -/
      inductive BCHom : BoolCat → BoolCat → Type
        | id (b : BoolCat) : BCHom b b
        | swap : BCHom BoolCat.tt BoolCat.ff
        | swapInv : BCHom BoolCat.ff BoolCat.tt
    </html:code>
                </html:pre>
                <html:p>
      Formally what this describes is a kind of piecewise function:
    </html:p>
                <fr:tex display="block"><![CDATA[
      \text {f}(x, y) =
      \begin {cases}
      1_x &: x \to  x & \texttt {if } x = y \\
      \texttt {swap} &: \text {tt} \to  \text {ff} & \texttt {if } x = \text {tt} \land  y = \text {ff} \\
      \texttt {swapInv} &: \text {ff} \to  \text {tt} & \texttt {if } x = \text {ff} \land  y = \text {tt}
      \end {cases}
    ]]></fr:tex>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>29</fr:day>
                </fr:date>
                <fr:title text="Composition and Category instance">Composition and Category instance</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
      Now we have some notion of objects and morphisms between them, we can move on to defining composition of morphisms.
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      def comp : {X Y Z : BoolCat} → BCHom Y Z → BCHom X Y → BCHom X Z
        | _, _, _, id _, f =&gt; f
        | _, _, _, f, id _ =&gt; f
        | _, _, _, swapInv, swap =&gt; id _
        | _, _, _, swap, swapInv =&gt; id _
    </html:code>
                </html:pre>
                <html:p>
      This defines composition by pattern matching on the possible morphism combinations. Note that we have to explicitly handle the cases where we compose <fr:tex display="inline"><![CDATA[\texttt {swap}]]></fr:tex> and <fr:tex display="inline"><![CDATA[\texttt {swapInv}]]></fr:tex> to get the identity morphism on the respective objects. To construct our category we have to provide proofs for the category axioms, namely associativity and identity.
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      @[simp] theorem id_comp' {X Y : BoolCat} (f : BCHom X Y) 
          : comp (id Y) f = f := by
        cases f &lt;;&gt; rfl

      @[simp] theorem comp_id' {X Y : BoolCat} (f : BCHom X Y) 
          : comp f (id X) = f := by
        cases f &lt;;&gt; rfl

      theorem assoc'  (f : BCHom W X) (g : BCHom X Y) (h : BCHom Y Z) :
          comp h (comp g f) = comp (comp h g) f := by
        cases f &lt;;&gt; cases g &lt;;&gt; cases h &lt;;&gt; rfl
    </html:code>
                </html:pre>
                <html:p>
      With all this in place we can finally define our category instance:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      instance : Category BoolCat where
        -- The data
        Hom     := BCHom
        id      := BCHom. id
        comp    := fun f g =&gt; BCHom. comp g f

        -- Category laws
        id_comp := fun f     =&gt; BCHom.comp_id' f
        comp_id := fun f     =&gt; BCHom.id_comp' f
        assoc   := fun f g h =&gt; BCHom.assoc' f g h
    </html:code>
                </html:pre>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>29</fr:day>
                </fr:date>
                <fr:title text="Isomorphisms in the Bool category">Isomorphisms in the Bool category</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
      Since we clearly see that the morphisms <fr:tex display="inline"><![CDATA[\texttt {swap}]]></fr:tex> and <fr:tex display="inline"><![CDATA[\texttt {swapInv}]]></fr:tex> are inverses of each other, we can construct an isomorphism between the two objects <fr:tex display="inline"><![CDATA[\texttt {tt}]]></fr:tex> and <fr:tex display="inline"><![CDATA[\texttt {ff}]]></fr:tex> as follows:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      def ttFfIso : BoolCat.tt ≅ BoolCat.ff where
        hom := BCHom.swap
        inv := BCHom.swapInv
        hom_inv_id := rfl
        inv_hom_id := rfl
    </html:code>
                </html:pre>
                <html:p>
      We can see that lean uses a similar notation for isomorphism as we do in our notes, namely the <fr:tex display="inline"><![CDATA[\texttt {≅}]]></fr:tex> symbol between the two objects. We can see that an isomorphism consists of a <fr:tex display="inline"><![CDATA[\texttt {hom}]]></fr:tex> and an <fr:tex display="inline"><![CDATA[\texttt {inv}]]></fr:tex> morphism along with proofs that composing them in either order yields the respective identity morphism. In Lean4 its defined as follows:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      structure Iso {C : Type u} [Category.{v} C] (X Y : C) where
        /-- The forward direction of an isomorphism. -/
        hom : X ⟶ Y
        /-- The backwards direction of an isomorphism. -/
        inv : Y ⟶ X
        /-- Composition is the identity on the source. -/
        hom_inv_id : hom ≫ inv = 𝟙 X := by cat_disch
        /-- Composition, in reverse, is the identity on the target. -/
        inv_hom_id : inv ≫ hom = 𝟙 Y := by cat_disch

      ...

      /-- Notation for an isomorphism in a category. -/
      infixr:10 " ≅ " =&gt; Iso 
    </html:code>
                </html:pre>
                <html:p>
      We can check out some properties of our isomorphism like so:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      -- Verify it's an isomorphism
      #check ttFfIso           -- BoolCat.tt ≅ BoolCat.ff
      #check ttFfIso.hom       -- BoolCat.tt ⟶ BoolCat.ff
      #check ttFfIso.inv       -- BoolCat.ff ⟶ BoolCat.tt
    </html:code>
                </html:pre>
                <html:p>
      Furthermore we can also show the identity isomorphism <fr:tex display="inline"><![CDATA[tt \cong  tt]]></fr:tex>:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      -- Every object is isomorphic to itself (trivially)
      def ttSelfIso : BoolCat.tt ≅ BoolCat.tt := Iso.refl _

      #check ttSelfIso -- BoolCat.tt ≅ BoolCat.tt
    </html:code>
                </html:pre>
                <html:p>
      Finally for the sake of completeness we can also demonstrate the isomorphism laws in examples as so:
    </html:p>
                <html:pre class="code-block language-lean">
                  <html:code class="language-lean">
      -- The isomorphism laws
      example : ttFfIso.hom ≫ ttFfIso.inv = 𝟙 BoolCat.tt 
        := ttFfIso.hom_inv_id

      example : ttFfIso.inv ≫ ttFfIso.hom = 𝟙 BoolCat.ff 
        := ttFfIso.inv_hom_id
    </html:code>
                </html:pre>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
  </fr:mainmatter>
  <fr:backmatter>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="References">References</fr:title>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>nLab authors</fr:author>
            </fr:authors>
            <fr:date>
              <fr:year>2025</fr:year>
              <fr:month>11</fr:month>
              <fr:day>1</fr:day>
            </fr:date>
            <fr:uri>https://kaierikniermann.github.io/notes/nlab-category/</fr:uri>
            <fr:display-uri>nlab-category</fr:display-uri>
            <fr:route>/notes/nlab-category/</fr:route>
            <fr:title text="category">category</fr:title>
            <fr:taxon>Reference</fr:taxon>
            <fr:meta name="external">https://ncatlab.org/nlab/show/category</fr:meta>
            <fr:meta name="ENTRYTYPE">misc</fr:meta>
            <fr:meta name="ID">nlab:category</fr:meta>
          </fr:frontmatter>
          <fr:mainmatter />
        </fr:tree>
        <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>Baanen, Anne, Bentkamp, Alexander, Blanchette, Jasmin, Holzl, Johannes, Limperg, Jannis</fr:author>
            </fr:authors>
            <fr:date>
              <fr:year>2024</fr:year>
              <fr:month>3</fr:month>
              <fr:day>28</fr:day>
            </fr:date>
            <fr:uri>https://kaierikniermann.github.io/notes/baanen-bentkamp-blanchette-holzl-limperg-hitchhikers-2024/</fr:uri>
            <fr:display-uri>baanen-bentkamp-blanchette-holzl-limperg-hitchhikers-2024</fr:display-uri>
            <fr:route>/notes/baanen-bentkamp-blanchette-holzl-limperg-hitchhikers-2024/</fr:route>
            <fr:title text="The Hitchhiker’s Guide to Logical Verification (2024 Desktop Edition)">The Hitchhiker’s Guide to Logical Verification (2024 Desktop Edition)</fr:title>
            <fr:taxon>Reference</fr:taxon>
            <fr:meta name="note">Desktop edition</fr:meta>
            <fr:meta name="external">https://raw.githubusercontent.com/lean-forward/logical_verification_2024/main/hitchhikers_guide_2024_desktop.pdf</fr:meta>
            <fr:meta name="publisher">Lean Forward</fr:meta>
            <fr:meta name="ENTRYTYPE">book</fr:meta>
            <fr:meta name="ID">baanen_bentkamp_blanchette_holzl_limperg_hitchhikers_2024</fr:meta>
          </fr:frontmatter>
          <fr:mainmatter />
        </fr:tree>
        <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
          <fr:frontmatter>
            <fr:authors>
              <fr:author>Johnson, Niles, Yau, Donald</fr:author>
            </fr:authors>
            <fr:date>
              <fr:year>2020</fr:year>
              <fr:month>6</fr:month>
              <fr:day>17</fr:day>
            </fr:date>
            <fr:uri>https://kaierikniermann.github.io/notes/johnson-yau-2d-categories-2020/</fr:uri>
            <fr:display-uri>johnson-yau-2d-categories-2020</fr:display-uri>
            <fr:route>/notes/johnson-yau-2d-categories-2020/</fr:route>
            <fr:title text="2-Dimensional Categories">2-Dimensional Categories</fr:title>
            <fr:taxon>Reference</fr:taxon>
            <fr:meta name="external">https://arxiv.org/abs/2002.06055v3</fr:meta>
            <fr:meta name="eprint">2002.06055</fr:meta>
            <fr:meta name="ENTRYTYPE">misc</fr:meta>
            <fr:meta name="ID">johnson_yau_2d_categories_2020</fr:meta>
          </fr:frontmatter>
          <fr:mainmatter />
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Context">Context</fr:title>
      </fr:frontmatter>
      <fr:mainmatter>
        <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
          <fr:frontmatter>
            <fr:authors />
            <fr:uri>https://kaierikniermann.github.io/notes/index/</fr:uri>
            <fr:display-uri>index</fr:display-uri>
            <fr:route>/notes/index/</fr:route>
            <fr:title text="Kai Erik Niermann">Kai Erik Niermann</fr:title>
            <fr:meta name="institution">Vrije Universiteit Amsterdam</fr:meta>
            <fr:meta name="position">Student</fr:meta>
          </fr:frontmatter>
          <fr:mainmatter>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>22</fr:day>
                </fr:date>
                <fr:uri>https://kaierikniermann.github.io/notes/0002/</fr:uri>
                <fr:display-uri>0002</fr:display-uri>
                <fr:route>/notes/0002/</fr:route>
                <fr:title text="Course Notes">Course Notes</fr:title>
                <fr:meta name="description">Course Notes</fr:meta>
              </fr:frontmatter>
              <fr:mainmatter>
                <html:p>
  This is a collection of notes for various courses I have taken.
</html:p>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:date>
                      <fr:year>2025</fr:year>
                      <fr:month>11</fr:month>
                      <fr:day>22</fr:day>
                    </fr:date>
                    <fr:uri>https://kaierikniermann.github.io/notes/0003/</fr:uri>
                    <fr:display-uri>0003</fr:display-uri>
                    <fr:route>/notes/0003/</fr:route>
                    <fr:title text="All VFS Quiz Solutions">All VFS Quiz Solutions</fr:title>
                    <fr:taxon>VU-VFS-2025</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <html:p>
  This is an explanation and solution to all quizzes in the VFS lectures. By default, I have the solutions minimized, but you can expand them by clicking on the upper part of the solution box (i.e. just click the solution section).
</html:p>
                    <fr:tree show-metadata="false" expanded="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>11</fr:month>
                          <fr:day>22</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/0004/</fr:uri>
                        <fr:display-uri>0004</fr:display-uri>
                        <fr:route>/notes/0004/</fr:route>
                        <fr:title text="Lecture 1 - Propositional Logic">Lecture 1 - Propositional Logic</fr:title>
                        <fr:taxon>VU-VFS-2025</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>22</fr:day>
                            </fr:date>
                            <fr:title text="Syntax">Syntax</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0005/</fr:uri>
                                <fr:display-uri>0005</fr:display-uri>
                                <fr:route>/notes/0005/</fr:route>
                                <fr:title text="Syntax">Syntax</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Using BNF notation, the syntax of propositional logic can be defined as follows:
</html:p>
 
  
  <html:figure><fr:resource hash="e8fe66989c999aaf2a9551442e29166b"><fr:resource-content><html:img src="/notes/e8fe66989c999aaf2a9551442e29166b.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
   
   % String-diagram specific extensions live here. Add diagram tweaks without
 % re-running the full base preamble (to avoid duplicate definitions).

   
  
   \usepackage{eulervm}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{amsmath, amsthm, amsfonts}
  \usepackage{tikz, tikz-cd, mathtools, amssymb, stmaryrd}
  \usetikzlibrary{arrows.meta, shapes, positioning, calc, decorations.pathreplacing, backgrounds, fit, matrix, spath3}

  % A TikZ style for curved arrows of a fixed height, due to AndréC.
  \tikzset{curve/.style={settings={#1},to path={(\tikztostart)
        .. controls ($(\tikztostart)!\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
        and ($(\tikztostart)!1-\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
    .. (\tikztotarget)\tikztonodes}},
    settings/.code={\tikzset{quiver/.cd,#1}
    \def\pv##1{\pgfkeysvalueof{/tikz/quiver/##1}}},
  quiver/.cd,pos/.initial=0.35,height/.initial=0}

  % A TikZ style for shortening paths without the poor behaviour of `shorten <' and `shorten >'.
  \tikzset{between/.style n args={2}{/tikz/spath/at end path construction={
        \tikzset{spath/split at keep middle={current}{#1}{#2}}
  }}}

  % TikZ arrowhead/tail styles.
  \tikzset{tail reversed/.code={\pgfsetarrowsstart{tikzcd to}}}
  \tikzset{2tail/.code={\pgfsetarrowsstart{Implies[reversed]}}}
  \tikzset{2tail reversed/.code={\pgfsetarrowsstart{Implies}}}
  % TikZ arrow styles.
  \tikzset{no body/.style={/tikz/dash pattern=on 0 off 1mm}}


  ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[
  \begin {align*}
    \text {Atom} \quad  \alpha  &::= p \mid  q \mid  r \mid  \top  \mid  \bot  \\
    \text {Literal} \quad  l &::= \alpha  \mid  \neg  \alpha  \\
    \text {Formula} \quad  F &::= l \mid  \neg  F  \mid  (F \land  F) \mid  (F \lor  F) \mid  (F \to  F) \mid  (F \leftrightarrow  F)
  \end {align*}
]]></fr:resource-source></fr:resource></html:figure>
 
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0006/</fr:uri>
                                <fr:display-uri>0006</fr:display-uri>
                                <fr:route>/notes/0006/</fr:route>
                                <fr:title text="Evaluating Syntax">Evaluating Syntax</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:ol><html:li><html:strong>Is <fr:tex display="inline"><![CDATA[p]]></fr:tex> an atom?</html:strong></html:li>
  <html:li><html:strong>Is <fr:tex display="inline"><![CDATA[p]]></fr:tex> a literal?</html:strong></html:li>
  <html:li><html:strong>Is <fr:tex display="inline"><![CDATA[p]]></fr:tex> a formula?</html:strong></html:li>
  <html:li><html:strong>What about <fr:tex display="inline"><![CDATA[\neg  p]]></fr:tex>?</html:strong></html:li>
  <html:li><html:strong>What about <fr:tex display="inline"><![CDATA[\neg  \neg  p]]></fr:tex>?</html:strong></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>22</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      Yes, <fr:tex display="inline"><![CDATA[p]]></fr:tex> is an atom.
    </html:li>
    <html:li>
      Yes, <fr:tex display="inline"><![CDATA[p]]></fr:tex> is a literal. Literals are either atoms or negated atoms, and since <fr:tex display="inline"><![CDATA[p]]></fr:tex> is an atom, it is also a literal.
    </html:li>
    <html:li>
      Yes, <fr:tex display="inline"><![CDATA[p]]></fr:tex> is a formula. Formulas can be literals, and since <fr:tex display="inline"><![CDATA[p]]></fr:tex> is a literal, it is also a formula.
    </html:li>
    <html:li><fr:tex display="inline"><![CDATA[\neg  p]]></fr:tex> is not an atom, but it is a literal (as it is a negated atom) and therefore also a formula.
    </html:li>
    <html:li><fr:tex display="inline"><![CDATA[\neg  \neg  p]]></fr:tex> is a formula, since the inner negation <fr:tex display="inline"><![CDATA[\neg  p]]></fr:tex> is a literal and any additional negation applied promotes it to a formula. In other words only <html:em>negated atoms</html:em> are literals but <html:em>negated literals</html:em> are formulas. This is especially important when we later discuss Negation Normal Form (NNF). 
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>22</fr:day>
                            </fr:date>
                            <fr:title text="Semantics &amp; Intepretations">Semantics &amp; Intepretations</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0007/</fr:uri>
                                <fr:display-uri>0007</fr:display-uri>
                                <fr:route>/notes/0007/</fr:route>
                                <fr:title text="Semantics">Semantics</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  We can define the semantic inference rules for propositional logic formulas under interpretations as follows inductively, starting with the base cases:
</html:p>
  
    
    <fr:resource hash="028beb2256956745cbd6c6d092a67ec4"><fr:resource-content><html:img src="/notes/028beb2256956745cbd6c6d092a67ec4.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule *[right=Atom-$\top $]{
    I(p) = \top 
  }{
    I \models  p
  }
  \and 
  \inferrule *[right=Atom-$\bot $]{
    I(p) = \bot 
  }{
    I \not \models  p
  }
  \and 
  \inferrule *[right=True]{
  }{
    I \models  \top 
  }
  \and 
  \inferrule *[right=False]{
  }{
    I \not \models  \bot 
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
  Moving on to the inductive case we have
</html:p>
  
    
    <fr:resource hash="6b58c468fd4a9e74c51788f18b2ea6bb"><fr:resource-content><html:img src="/notes/6b58c468fd4a9e74c51788f18b2ea6bb.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule *[right=Neg-$\top $]{
    I \models  \neg  F
  }{
    I \not \models  F
  }
  \and 
  \inferrule *[right=Conj-$\top $]{
    I \models  F_1 \quad  I \models  F_2
  }{
    I \models  F_1 \land  F_2
  }
  \and 
  \inferrule *[right=Disj-$\top $]{
    I \models  F_1 \quad  \text {or} \quad  I \models  F_2
  }{
    I \models  F_1 \lor  F_2
  }
  \and 
  \inferrule *[right=Imp-$\top $]{
    I \not \models  F_1 \quad  \text {or} \quad  I \models  F_2
  }{
    I \models  F_1 \to  F_2
  }
  \and 
  \inferrule *[right=Contr-$\top $]{
    I \models  F \\ I \not \models  F
  }{
    I \models  \bot 
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
  Similarly, the rules for when an interpretation does not satisfy a formula are as follows:
</html:p>
  
    
    <fr:resource hash="6be5095cad00657a1d9244ee3cab2d11"><fr:resource-content><html:img src="/notes/6be5095cad00657a1d9244ee3cab2d11.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule *[right=Neg-$\bot $]{
    I \not \models  \neg  F
  }{
    I \models  F
  }
  \and 
  \inferrule *[right=Conj-$\bot $]{
    I \not \models  F_1 \quad  \text {or} \quad  I \not \models  F_2
  }{
    I \not \models  F_1 \land  F_2
  }
  \and 
  \inferrule *[right=Disj-$\bot $]{
    I \not \models  F_1 \\ I \not \models  F_2
  }{
    I \not \models  F_1 \lor  F_2
  }
  \and 
  \inferrule *[right=Imp-$\bot $]{
    I \models  F_1 \\ I \not \models  F_2
  }{
    I \not \models  F_1 \to  F_2
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0008/</fr:uri>
                                <fr:display-uri>0008</fr:display-uri>
                                <fr:route>/notes/0008/</fr:route>
                                <fr:title text="Interpretation">Interpretation</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  We define an interpretation as a function which maps propositional variables in a formula to truth values, so formally
</html:p>
                                <fr:tex display="block"><![CDATA[
  I : \texttt {Var} \to  \{\top , \bot \}
]]></fr:tex>
                                <html:p>
  We can <html:em>evaluate</html:em> a formula <html:em>under</html:em> an interpretation <fr:tex display="inline"><![CDATA[I]]></fr:tex> by substituting each propositional variable with its corresponding truth value given by <fr:tex display="inline"><![CDATA[I]]></fr:tex>. Naturally under different kinds of interpretations formulas can evaluate to different truth values. We can create a classifcation of formulas based on how many interpretations evaluate them to true or false.
</html:p>
                                <html:ol><html:li><html:strong>satisfiable</html:strong>: A formula is satisfiable if there exists at least one interpretation under which it evaluates to true.
  </html:li>
  <html:li><html:strong>unsatisfying</html:strong>: A formula is unsatisfying if there exists at least one interpretation under which it evaluates to false.
  </html:li>
  <html:li><html:strong>tautology</html:strong>: A formula is a tautology if it evaluates to true under every possible interpretation.
  </html:li>
  <html:li><html:strong>contradiction</html:strong>: A formula is a contradiction if it evaluates to false under every possible interpretation.
  </html:li>
  <html:li><html:strong>contingent</html:strong>: A formula is contingent if it is satisfiable and unsatisfying, i.e., there exists at least one interpretation under which it evaluates to true and at least one interpretation under which it evaluates to false.
  </html:li></html:ol>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0009/</fr:uri>
                                <fr:display-uri>0009</fr:display-uri>
                                <fr:route>/notes/0009/</fr:route>
                                <fr:title text="Evaluating PL Formulae">Evaluating PL Formulae</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:strong>
  Consider the formula 
  <fr:tex display="inline"><![CDATA[
    F \triangleq  (\neg  p \land  q)
  ]]></fr:tex>
  and interpretation 
  <fr:tex display="inline"><![CDATA[
    I \triangleq  \{p \to  \top , q \to  \bot \}
  ]]></fr:tex>
  Which of the following is true
</html:strong><html:ol><html:li><fr:tex display="inline"><![CDATA[I \models  F]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[I \nvDash  F]]></fr:tex></html:li></html:ol><html:strong>
  What about the formula
  <fr:tex display="block"><![CDATA[
    (p \land  q) \to  (\neg  p \lor  q)
  ]]></fr:tex>
  under the same interpretation?
</html:strong>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>22</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  Theres two main ways you can usually approach questions like this, the more drawn out operational way and then just going by observation more or less. Starting out with the more pedantic approach we can try to construct a proof tree for the formula under the given interpretation. So considering the first formula we have: 
  
  
    
    <fr:resource hash="4807516d6cf6f2fdc256701b3e189646"><fr:resource-content><html:img src="/notes/4807516d6cf6f2fdc256701b3e189646.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule {
      \inferrule {
        \inferrule {
          I(p) = \top 
        }{
          I \models  p
        }
      }{
        I \nvDash  \neg  p
      }
      \quad 
      \inferrule {
        \inferrule {
          I(q) = \bot 
        }{
          I \nvDash  q
        }
      }{
        I \nvDash  q
      }
    }{
      I \nvDash  (\neg  p \land  q)
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  


  <html:p>
    So we can see that the interpretation does not satisfy the formula. In other words for this assignment the formula does not hold true. Given that this is a somewhat simple formula we could also just see this by observation, i.e.
  </html:p>
  <fr:tex display="block"><![CDATA[
    \underbrace {\neg  p}_{\texttt {False}} \land  \underbrace {q}_{\texttt {False}} \equiv  \bot 
  ]]></fr:tex>
  <html:p>
    For the second formula lets just go with the simpler approach again, so we have
  </html:p>
  <fr:resource hash="f4ab80a835ec37191d2964edcfdc39a1"><fr:resource-content><html:img src="/notes/f4ab80a835ec37191d2964edcfdc39a1.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
    \usepackage {amsmath}
    \usepackage {eulervm}
    \usepackage [scaled=0.92]{inconsolata} 

  ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[
        {\small
      \begin{align*}
          (p \land q) \to (\neg p \lor q) &\equiv (\texttt{true} \land \texttt{false}) \to (\neg \texttt{true} \lor \texttt{false}) \tag{by $I$}\\
      &\equiv \texttt{false} \to (\texttt{false} \lor \texttt{false}) \\
      &\equiv \texttt{false} \to \texttt{false} \\
      &\equiv \texttt{true} \tag{vacuously true} 
      \end{align*}
    }
  ]]></fr:resource-source></fr:resource>

  <html:p>
    So in this case the formula is satisfied by the interpretation.
  </html:p>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000a/</fr:uri>
                                <fr:display-uri>000a</fr:display-uri>
                                <fr:route>/notes/000a/</fr:route>
                                <fr:title text="Evaluating sat/unsat/valid">Evaluating sat/unsat/valid</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:strong>Are the following formulas sat., unsat., or valid?</html:strong><html:ol><html:li><fr:tex display="inline"><![CDATA[(p\land  q) \to  \neg  p]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[(p \land  q) \to  (p \lor  \neg  q)]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[(p \to  (q \to  r)) \land  \neg ((p \land  q) \to  r)]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>22</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  As a reminder lets recap the definitions:
  <html:ul><html:li>
      A formula is <html:strong>satisfiable</html:strong> if there exists at least one combination of true/false assignments to its variables that makes the formula true.
    </html:li>
    <html:li>
      A formula is <html:strong>unsatisfiable</html:strong> if there is no combination of true/false assignments to its variables that makes the formula true (i.e., it is always false).
    </html:li>
    <html:li>
      A formula is <html:strong>valid</html:strong> (or a tautology) if it is true under all possible combinations of true/false assignments to its variables.
    </html:li></html:ul>
  <html:p>
    Now we can analyze each formula:
  </html:p>
  <html:ol><html:li>
      For the lhs to be true both p and q must be true. However, if p is true then <fr:tex display="inline"><![CDATA[\neg  p]]></fr:tex> is false, making the implication false. If p is false then the implication is vacuously true regardless of what we set q to. Thus, this formula is satisfiable (e.g., when p is false) but not valid (e.g., when p and q are true).
    </html:li>
    <html:li>
      If both p and q are true then the lhs is true and so is the rhs by virtue of p being true. If p is false then the implication is vacuously true regardless of q. If q is false then the rhs is true regardless of p. Thus, this formula is valid as it is true for all combinations of truth values for p and q.
    </html:li>
    <html:li>
      The first part <fr:tex display="inline"><![CDATA[(p \to  (q \to  r))]]></fr:tex> is true unless p is true and either q or r is false. The second part <fr:tex display="inline"><![CDATA[\neg ((p \land  q) \to  r)]]></fr:tex> is true when p and q are true but r is false. Thus we can satisfy the entire formula by setting p and q to true and r to false. However, if we set p to false then the first part is vacuously true, but the second part becomes false. Thus, this formula is falsifiable (e.g., when p and q are true and r is false) but not valid (e.g., when p is false).
    </html:li></html:ol>

  If you want to be absolutely sure about these kinds of questions constructing truth tables is always a good idea, albeit a bit tedious for formulas with many variables so just doing a bit of analysis like above is usually sufficient
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" expanded="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>11</fr:month>
                          <fr:day>22</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/000b/</fr:uri>
                        <fr:display-uri>000b</fr:display-uri>
                        <fr:route>/notes/000b/</fr:route>
                        <fr:title text="Lecture 2 - Normal Forms &amp; DPLL">Lecture 2 - Normal Forms &amp; DPLL</fr:title>
                        <fr:taxon>VU-VFS-2025</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>22</fr:day>
                            </fr:date>
                            <fr:title text="Formula Equivalence">Formula Equivalence</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000c/</fr:uri>
                                <fr:display-uri>000c</fr:display-uri>
                                <fr:route>/notes/000c/</fr:route>
                                <fr:title text="Equivalence of Formulae">Equivalence of Formulae</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  Two formulas <fr:tex display="inline"><![CDATA[F]]></fr:tex> and <fr:tex display="inline"><![CDATA[G]]></fr:tex> are said to be <html:strong>equivalent</html:strong>, written <fr:tex display="inline"><![CDATA[F \equiv  G]]></fr:tex>, if they have the same truth value under every interpretation. In other words, for every interpretation <fr:tex display="inline"><![CDATA[I]]></fr:tex>, <fr:tex display="inline"><![CDATA[I \models  F]]></fr:tex> if and only if <fr:tex display="inline"><![CDATA[I \models  G]]></fr:tex>.
</html:p>
                                <fr:tex display="block"><![CDATA[
  F \equiv  G \iff  \forall  I (I \models  F \iff  I \models  G)
]]></fr:tex>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000d/</fr:uri>
                                <fr:display-uri>000d</fr:display-uri>
                                <fr:route>/notes/000d/</fr:route>
                                <fr:title text="Normal Forms &amp; DPLL - Equivalence">Normal Forms &amp; DPLL - Equivalence</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:strong>Which of the following equivalences hold?</html:strong><html:ol><html:li><fr:tex display="inline"><![CDATA[\bot  \equiv  \bot ]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[\top  \equiv  \top ]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[\neg  \top  \equiv  \neg  \bot ]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[\neg  (p \land  q) \equiv  \neg  p \lor  \neg  q]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[p \equiv  p \lor  q]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[\neg  \neg  p \equiv  p]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>22</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      True. Both sides are always false.
    </html:li>
    <html:li>
      True. Both sides are always true.
    </html:li>
    <html:li>
      False. Left side is always false, right side is always true.
    </html:li>
    <html:li>
      True. This is <fr:link href="/notes/000g/" title="De Morgan's Laws" uri="https://kaierikniermann.github.io/notes/000g/" display-uri="000g" type="local">De Morgan's law</fr:link>. Good to remember 
      <fr:tex display="block"><![CDATA[
        \neg  (p \land  q) \equiv  \neg  p \lor  \neg  q
      ]]></fr:tex></html:li>
    <html:li>
      False. Left side is true when p is true, right side is true when either p or q is true.
    </html:li>
    <html:li>
      True. Double negation elimination.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>22</fr:day>
                            </fr:date>
                            <fr:title text="Negation Normal Forms">Negation Normal Forms</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000e/</fr:uri>
                                <fr:display-uri>000e</fr:display-uri>
                                <fr:route>/notes/000e/</fr:route>
                                <fr:title text="Negation Normal Form (NNF)">Negation Normal Form (NNF)</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  A formula <fr:tex display="inline"><![CDATA[F]]></fr:tex> is in Negation Normal Form (NNF) if the negation operator <fr:tex display="inline"><![CDATA[\neg ]]></fr:tex> is only applied to literals (i.e., propositional variables or their negations), and the only other allowed operators are conjunction <fr:tex display="inline"><![CDATA[\land ]]></fr:tex> and disjunction <fr:tex display="inline"><![CDATA[\lor ]]></fr:tex>. A nice way to think about it is that we can never have the case where we need to apply <fr:link href="/notes/000g/" title="De Morgan's Laws" uri="https://kaierikniermann.github.io/notes/000g/" display-uri="000g" type="local">De Morgan's laws</fr:link> to push negations further down the formula tree. So all negations come pre-distributed to the literals.
</html:p>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000f/</fr:uri>
                                <fr:display-uri>000f</fr:display-uri>
                                <fr:route>/notes/000f/</fr:route>
                                <fr:title text="Negation Normal Form (NNF)">Negation Normal Form (NNF)</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:strong>Which of the following formulas are in Negation Normal Form (NNF)?</html:strong><html:ol><html:li><fr:tex display="inline"><![CDATA[p \to  q]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[p \lor  (\neg  q  \land  (r \lor  \neg  s))]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[p \lor  (\neg  q \land  \neg  (\neg  r \land  s))]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[p \lor  (\neg  q \land  (\neg  \neg  r \lor  \neg  s)) ]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>22</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      No. The implication operator <fr:tex display="inline"><![CDATA[\to ]]></fr:tex> is not allowed in NNF.
    </html:li>
    <html:li>
      Yes. Negations are only applied to literals, and only <fr:tex display="inline"><![CDATA[\land ]]></fr:tex> and <fr:tex display="inline"><![CDATA[\lor ]]></fr:tex> are used.
    </html:li>
    <html:li>
      No. The negation operator <fr:tex display="inline"><![CDATA[\neg ]]></fr:tex> is applied to a non-literal formula <fr:tex display="inline"><![CDATA[(\neg  r \land  s)]]></fr:tex>.
    </html:li>
    <html:li>
      No. The double negation <fr:tex display="inline"><![CDATA[\neg  \neg  r]]></fr:tex> is not allowed in NNF. Important to remember since that can trip you up.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>22</fr:day>
                            </fr:date>
                            <fr:title text="Disjunctive Normal Form">Disjunctive Normal Form</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000k/</fr:uri>
                                <fr:display-uri>000k</fr:display-uri>
                                <fr:route>/notes/000k/</fr:route>
                                <fr:title text="Distributing Conjunction">Distributing Conjunction</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  The distributive law of conjunction over disjunction states that for any formulas <fr:tex display="inline"><![CDATA[F]]></fr:tex>, <fr:tex display="inline"><![CDATA[G]]></fr:tex>, and <fr:tex display="inline"><![CDATA[H]]></fr:tex>, the following equivalence holds:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \begin {align*}
  F \land  (G \lor  H) &\equiv  (F \land  G) \lor  (F \land  H) \\
  (F \lor  G) \land  H &\equiv  (F \land  H) \lor  (G \land  H)
  \end {align*}
]]></fr:tex>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000j/</fr:uri>
                                <fr:display-uri>000j</fr:display-uri>
                                <fr:route>/notes/000j/</fr:route>
                                <fr:title text="Eliminating Implications and Biconditionals">Eliminating Implications and Biconditionals</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  To eliminate implications (<fr:tex display="inline"><![CDATA[\to ]]></fr:tex>) and biconditionals (<fr:tex display="inline"><![CDATA[\leftrightarrow ]]></fr:tex>) from a formula <fr:tex display="inline"><![CDATA[F]]></fr:tex>, we can use the following equivalences:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \begin {align*}
  p \to  q &\equiv  \neg  p \lor  q \\
  p \leftrightarrow  q &\equiv  (p \land  q) \lor  (\neg  p \land  \neg  q)
  \end {align*}
]]></fr:tex>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000h/</fr:uri>
                                <fr:display-uri>000h</fr:display-uri>
                                <fr:route>/notes/000h/</fr:route>
                                <fr:title text="Disjunctive Normal Form (DNF)">Disjunctive Normal Form (DNF)</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  A formula <fr:tex display="inline"><![CDATA[F]]></fr:tex> is in Disjunctive Normal Form (DNF) if it is a disjunction of one or more conjunctions of one or more literals. In other words, <fr:tex display="inline"><![CDATA[F]]></fr:tex> can be expressed as a series of clauses connected by disjunctions (<fr:tex display="inline"><![CDATA[\lor ]]></fr:tex>), where each clause is a series of literals connected by conjunctions (<fr:tex display="inline"><![CDATA[\land ]]></fr:tex>). A literal is either a propositional variable or its negation.
</html:p>
                                <fr:tex display="block"><![CDATA[
  F = C_1 \lor  C_2 \lor  ... \lor  C_n
]]></fr:tex>
                                <html:p>
  Where each clause <fr:tex display="inline"><![CDATA[C_i]]></fr:tex> is of the form:
</html:p>
                                <fr:tex display="block"><![CDATA[
  C_i = L_{i1} \land  L_{i2} \land  ... \land  L_{im}
]]></fr:tex>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000l/</fr:uri>
                                <fr:display-uri>000l</fr:display-uri>
                                <fr:route>/notes/000l/</fr:route>
                                <fr:title text="Converting to DNF">Converting to DNF</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Convert the following formula into Disjunctive Normal Form (DNF):
</html:p><fr:tex display="block"><![CDATA[
  (q \lor  \neg  \neg  p) \land  (\neg  r \to  s)
]]></fr:tex>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>22</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <fr:resource hash="0ed774c5f98ccbf4fe2a8d866cb96b0e"><fr:resource-content><html:img src="/notes/0ed774c5f98ccbf4fe2a8d866cb96b0e.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
    \usepackage {amsmath}
    \usepackage {eulervm}
    \usepackage [scaled=0.92]{inconsolata} 
  ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[
        {\small
      \begin{align*}
        & (q \lor \neg \neg p) \land (\neg r \to s) \\
        & \equiv (q \lor p) \land (r \lor s) \tag{Eliminate Implication} \\
        & \equiv ((q \lor p) \land r) \lor ((q \lor p) \land s) \tag{Distribute Conjunction} \\
        & \equiv (q \land r) \lor (p \land r) \lor (q \land s) \lor (p \land s) \tag{Distribute Conjunction} \\
      \end{align*}
    }
  ]]></fr:resource-source></fr:resource>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>22</fr:day>
                            </fr:date>
                            <fr:title text="Equisatisfiability">Equisatisfiability</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000q/</fr:uri>
                                <fr:display-uri>000q</fr:display-uri>
                                <fr:route>/notes/000q/</fr:route>
                                <fr:title text="Equisatisfiability">Equisatisfiability</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  Two formulas are said to be <html:strong>equisatisfiable</html:strong> if either both formulas are satisfiable or both are unsatisfiable. In other words, there exists an assignment of truth values to the variables that makes one formula true if and only if there exists; not necessarily the same assignment; that makes the other formula true. Equisatisfiability is a weaker condition than logical equivalence, as equisatisfiable formulas may not have the same truth values under all assignments, but they share the same satisfiability status.
</html:p>
                                <fr:tex display="block"><![CDATA[
  \texttt {equisat}(F, G) \iff  (\exists  I.\ I \models  F) \iff  (\exists  J.\ J \models  G)
]]></fr:tex>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000r/</fr:uri>
                                <fr:display-uri>000r</fr:display-uri>
                                <fr:route>/notes/000r/</fr:route>
                                <fr:title text="Equisatisfiability">Equisatisfiability</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  If a formula <fr:tex display="inline"><![CDATA[F]]></fr:tex> and <fr:tex display="inline"><![CDATA[G]]></fr:tex> are equisatisfiable, then are they equivalent?
</html:p>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>22</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  No. We can answer this in a few different ways. In the most direct sense they are just definitionally not the same thing, in that equivalence requires that both formulas have the same truth value under all interpretations, whereas equisatisfiability only requires that both formulas have <html:em>a</html:em> satisfying interpretation or both be unsatisfiable.

  Another way to see it is that in an abstract sense equivalence describes an object-level relationship between formulas, whereas equisatisfiability describes a meta-level relationship about the existence of satisfying interpretations. Thus, they are fundamentally different kinds of relationships.
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>22</fr:day>
                            </fr:date>
                            <fr:title text="Tseitin Transformation">Tseitin Transformation</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000n/</fr:uri>
                                <fr:display-uri>000n</fr:display-uri>
                                <fr:route>/notes/000n/</fr:route>
                                <fr:title text="Conjunctive Normal Form (CNF)">Conjunctive Normal Form (CNF)</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  A formula is in <html:strong>Conjunctive Normal Form (CNF)</html:strong> if it is expressed as a conjunction of disjunctions of literals. In other words, a CNF formula is a series of clauses (disjunctions) connected by AND operators. Each clause contains literals (variables or their negations) connected by OR operators. For example, the formula <fr:tex display="inline"><![CDATA[(p \lor  \neg  q) \land  (r \lor  s \lor  \neg  t)]]></fr:tex> is in CNF.
</html:p>
                                <fr:tex display="block"><![CDATA[
  F = C_1 \land  C_2 \land  ... \land  C_n
]]></fr:tex>
                                <html:p>
  Where each clause <fr:tex display="inline"><![CDATA[C_i]]></fr:tex> is of the form:
</html:p>
                                <fr:tex display="block"><![CDATA[
  C_i = L_{i1} \lor  L_{i2} \lor  ... \lor  L_{im}
]]></fr:tex>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000m/</fr:uri>
                                <fr:display-uri>000m</fr:display-uri>
                                <fr:route>/notes/000m/</fr:route>
                                <fr:title text="Exponential Blow up problem">Exponential Blow up problem</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  When converting a formula to Disjunctive Normal Form (DNF) or Conjunctive Normal Form (CNF), the size of the resulting formula can grow exponentially in the worst case. This is known as the <html:strong>exponential blow up problem</html:strong>. For example, a formula with <fr:tex display="inline"><![CDATA[n]]></fr:tex> variables can result in a DNF or CNF with up to <fr:tex display="inline"><![CDATA[2^n]]></fr:tex> clauses.
</html:p>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000s/</fr:uri>
                                <fr:display-uri>000s</fr:display-uri>
                                <fr:route>/notes/000s/</fr:route>
                                <fr:title text="Tseytin's Transformation">Tseytin's Transformation</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  Tseytin's transformation is a method used in propositional logic to convert any given formula into an equisatisfiable formula in <fr:link href="/notes/000n/" title="Conjunctive Normal Form (CNF)" uri="https://kaierikniermann.github.io/notes/000n/" display-uri="000n" type="local">Conjunctive Normal Form (CNF)</fr:link>. The key idea behind Tseytin's transformation is to introduce new variables to represent subformulas of the original formula, thereby avoiding <fr:link href="/notes/000m/" title="Exponential Blow up problem" uri="https://kaierikniermann.github.io/notes/000m/" display-uri="000m" type="local">an exponential increase in size</fr:link> that can occur with naive CNF conversion methods. There are two key properties of Tseytin's for a formula <fr:tex display="inline"><![CDATA[F]]></fr:tex> and its Tseytin transformation <fr:tex display="inline"><![CDATA[F']]></fr:tex>:
</html:p>
                                <html:ol><html:li><html:strong>unsatisfiability:</html:strong> <fr:tex display="inline"><![CDATA[F]]></fr:tex> is unsatisfiable if and only if <fr:tex display="inline"><![CDATA[F']]></fr:tex> is unsatisfiable.
  </html:li>
  <html:li><html:strong>model correspondence:</html:strong> For every satisfying assignment (model) of <fr:tex display="inline"><![CDATA[F']]></fr:tex>, there exists a corresponding satisfying assignment of <fr:tex display="inline"><![CDATA[F]]></fr:tex>, and vice versa, when restricted to the original variables of <fr:tex display="inline"><![CDATA[F]]></fr:tex>.
  </html:li></html:ol>
                                <html:p>
  To demonstrate how it works lets consider the following formula
</html:p>
                                <fr:tex display="block"><![CDATA[
  \phi  = ((p \lor  q ) \land  r) \to  (\neg  s)
]]></fr:tex>
                                <html:ol><html:li><html:strong>Subformula identification:</html:strong> Identify the subformulas of <fr:tex display="inline"><![CDATA[\phi ]]></fr:tex> and assign a new variable to each subformula. For our example, we can identify the following subformulas and assign new variables:
    <fr:tex display="block"><![CDATA[
      \begin {align*}
      & \neg  s \\
      & p \lor  q \\
      & (p \lor  q) \land  r \\
      & ((p \lor  q) \land  r) \to  (\neg  s)
      \end {align*}
    ]]></fr:tex></html:li>
  <html:li><html:strong>Variable assignment:</html:strong> Assign new variables to each subformula:
    <fr:tex display="block"><![CDATA[
      \begin {align*}
      & x_1 \text { for } \neg  s \\
      & x_2 \text { for } p \lor  q \\
      & x_3 \text { for } (p \lor  q) \land  r \\
      & x_4 \text { for } ((p \lor  q) \land  r) \to  (\neg  s)
      \end {align*}
    ]]></fr:tex></html:li>
  <html:li><html:strong>Equivalence clauses:</html:strong> For each subformula, create clauses that enforce the equivalence between the new variable and the subformula it represents. For our example, we would create the following clauses:
    <fr:tex display="block"><![CDATA[
      \begin {align*}
      & (x_1 \leftrightarrow  \neg  s) \\
      & (x_2 \leftrightarrow  (p \lor  q)) \\
      & (x_3 \leftrightarrow  (x_2 \land  r)) \\
      & (x_4 \leftrightarrow  (x_3 \to  x_1))
      \end {align*}
    ]]></fr:tex></html:li>
  <html:li><html:strong>Conjunct of clauses:</html:strong> Combine all the equivalence clauses into a single formula in CNF. The final formula <fr:tex display="inline"><![CDATA[\phi ']]></fr:tex> will be the conjunction of all these clauses along with the clause that asserts the truth of the variable representing the entire formula (in this case, <fr:tex display="inline"><![CDATA[x_4]]></fr:tex>):
    <fr:tex display="block"><![CDATA[
      \phi ' = (x_1 \leftrightarrow  \neg  s) \land  (x_2 \leftrightarrow  (p \lor  q)) \land  (x_3 \leftrightarrow  (x_2 \land  r)) \land  (x_4 \leftrightarrow  (x_3 \to  x_1)) \land  x_4
    ]]></fr:tex></html:li>
  <html:li><html:strong>Conversion to CNF:</html:strong> Finally, convert the combined formula into CNF using standard techniques (like distributing disjunctions over conjunctions). The resulting formula will be in CNF and equisatisfiable to the original formula <fr:tex display="inline"><![CDATA[\phi ]]></fr:tex>. For example if we consider the clause 
    <fr:tex display="block"><![CDATA[
      x_2 \leftrightarrow  (p \lor  q)
    ]]></fr:tex> this can be converted to CNF as
    <fr:tex display="block"><![CDATA[
      (x_2 \lor  \neg  p) \land  (x_2 \lor  \neg  q) \land  (\neg  x_2 \lor  p \lor  q)
    ]]></fr:tex></html:li></html:ol>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000t/</fr:uri>
                                <fr:display-uri>000t</fr:display-uri>
                                <fr:route>/notes/000t/</fr:route>
                                <fr:title text="Tseytin's Transformation">Tseytin's Transformation</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Lets consider the following formula
</html:p><fr:tex display="block"><![CDATA[
  F \triangleq  (p \land  q) \lor  (p \land  \neg  r \land  s)
]]></fr:tex><html:p>
  Using Tseytin's transformation, convert the formula <fr:tex display="inline"><![CDATA[F]]></fr:tex> into an equisatisfiable formula in CNF.
</html:p>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>22</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  For the sake of brevity, let's skip assume the subformula extraction is already done, and we created the following equivalence clauses:
  <fr:tex display="block"><![CDATA[
    \begin {align*}
    F_1 &\triangleq  t_1 \leftrightarrow  (\neg  r \land  s) \\
    F_2 &\triangleq  t_2 \leftrightarrow  (p \land  t_1) \\
    F_3 &\triangleq  t_3 \leftrightarrow  (p \land  q) \\
    F_4 &\triangleq  t_4 \leftrightarrow  (t_2 \lor  t_3)
    \end {align*}
  ]]></fr:tex>
  This gives us the following conjunct for the transformed formula:
  <fr:tex display="block"><![CDATA[
    F' \triangleq  F_1 \land  F_2 \land  F_3 \land  F_4 \land  t_4
  ]]></fr:tex>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" expanded="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>11</fr:month>
                          <fr:day>22</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/000u/</fr:uri>
                        <fr:display-uri>000u</fr:display-uri>
                        <fr:route>/notes/000u/</fr:route>
                        <fr:title text="Lecture 3 - First Order Logic">Lecture 3 - First Order Logic</fr:title>
                        <fr:taxon>VU-VFS-2025</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>22</fr:day>
                            </fr:date>
                            <fr:title text="Syntax">Syntax</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000v/</fr:uri>
                                <fr:display-uri>000v</fr:display-uri>
                                <fr:route>/notes/000v/</fr:route>
                                <fr:title text="FOL - Syntax">FOL - Syntax</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  We can define a first order language as a tuple of 3 sets <fr:tex display="inline"><![CDATA[\langle  \mathcal  C, \mathcal  F, \mathcal  R\rangle ]]></fr:tex> where:
</html:p>
                                <html:ul><html:li><html:strong>Constants</html:strong> (<fr:tex display="inline"><![CDATA[\mathcal  C]]></fr:tex>): the set of constants in the language. E.g., <fr:tex display="inline"><![CDATA[\{a, b, c\}]]></fr:tex></html:li>
  <html:li><html:strong>Function Symbols</html:strong> (<fr:tex display="inline"><![CDATA[\mathcal  F]]></fr:tex>): the set of function symbols in the language. E.g., <fr:tex display="inline"><![CDATA[\{f, g, h\}]]></fr:tex></html:li>
  <html:li><html:strong>Relation Symbols</html:strong> (<fr:tex display="inline"><![CDATA[\mathcal  R]]></fr:tex>): the set of relation symbols in the language. E.g., <fr:tex display="inline"><![CDATA[\{R, S, T\}]]></fr:tex></html:li></html:ul>
                                <html:p>
  Using BNF we can define the syntax as follows
</html:p>
                                <fr:resource hash="18b8dd7c29a3cc72847fbb5fc08ba8f0">
                                  <fr:resource-content>
                                    <html:img src="/notes/18b8dd7c29a3cc72847fbb5fc08ba8f0.svg" />
                                  </fr:resource-content>
                                  <fr:resource-source type="latex" part="preamble"><![CDATA[
  \usepackage {amsmath}
  \usepackage {eulervm}
]]></fr:resource-source>
                                  <fr:resource-source type="latex" part="body"><![CDATA[
{\small  
  \begin {align*}
    \text {Atom} \quad  \alpha  &::= \top  \mid  \bot  \mid  p(t_1, \ldots , t_n) \\
    \text {Formula} \quad  F &::= \alpha  \mid  \neg  F  \mid  (F \land  F) \mid  (F \lor  F) \mid  (F \to  F) \mid  (F \leftrightarrow  F) \mid  \forall  x.\ F \mid  \exists  x.\ F \\
  \end {align*}
}
]]></fr:resource-source>
                                </fr:resource>
                                <html:p>
  Here the atom <fr:tex display="inline"><![CDATA[p]]></fr:tex> represents an <html:em>atomic predicate</html:em> applied to terms <fr:tex display="inline"><![CDATA[t_1, \ldots , t_n]]></fr:tex>, where <fr:tex display="inline"><![CDATA[p \in  \mathcal  R]]></fr:tex> with an arity of <fr:tex display="inline"><![CDATA[n]]></fr:tex></html:p>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000w/</fr:uri>
                                <fr:display-uri>000w</fr:display-uri>
                                <fr:route>/notes/000w/</fr:route>
                                <fr:title text="First Order Logic - Syntax">First Order Logic - Syntax</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:strong>Which of the following are syntactically valid formulas in first order logic?</html:strong><html:ol><html:li><fr:tex display="inline"><![CDATA[f(x)]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[p(x)]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[p(f(x))]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[p(p(x))]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[p(f(f(x)))]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>22</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li><fr:tex display="inline"><![CDATA[f(x)]]></fr:tex>: <html:em>Invalid</html:em>, as <fr:tex display="inline"><![CDATA[f]]></fr:tex> is a function symbol and cannot stand alone as a formula.
    </html:li>
    <html:li><fr:tex display="inline"><![CDATA[p(x)]]></fr:tex>: <html:em>Valid</html:em>, as <fr:tex display="inline"><![CDATA[p]]></fr:tex> is a relation symbol applied to the term <fr:tex display="inline"><![CDATA[x]]></fr:tex>.
    </html:li>
    <html:li><fr:tex display="inline"><![CDATA[p(f(x))]]></fr:tex>: <html:em>Valid</html:em>, as <fr:tex display="inline"><![CDATA[f(x)]]></fr:tex> is a term and <fr:tex display="inline"><![CDATA[p]]></fr:tex> is a relation symbol applied to that term.
    </html:li>
    <html:li><fr:tex display="inline"><![CDATA[p(p(x))]]></fr:tex>: <html:em>Invalid</html:em>, as <fr:tex display="inline"><![CDATA[p(x)]]></fr:tex> is a formula, not a term, and cannot be an argument to <fr:tex display="inline"><![CDATA[p]]></fr:tex>.
    </html:li>
    <html:li><fr:tex display="inline"><![CDATA[p(f(f(x)))]]></fr:tex>: <html:em>Valid</html:em>, as <fr:tex display="inline"><![CDATA[f(x)]]></fr:tex> is a term, and applying <fr:tex display="inline"><![CDATA[f]]></fr:tex> again yields another term, which can be an argument to <fr:tex display="inline"><![CDATA[p]]></fr:tex>.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>22</fr:day>
                            </fr:date>
                            <fr:title text="Quantifiers &amp; Scoping">Quantifiers &amp; Scoping</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000x/</fr:uri>
                                <fr:display-uri>000x</fr:display-uri>
                                <fr:route>/notes/000x/</fr:route>
                                <fr:title text="FOL - Quantifiers and Scoping">FOL - Quantifiers and Scoping</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  For quantifiers:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \forall  x.\ F \quad  \exists  x.\ F
]]></fr:tex>
                                <html:p>
  Each variable occurring within the formula <fr:tex display="inline"><![CDATA[F]]></fr:tex> known as the <html:em>scope</html:em> is either:
</html:p>
                                <html:ul><html:li><html:strong>bound</html:strong>: if it is within the scope of a quantifier that binds it. E.g., in <fr:tex display="inline"><![CDATA[\forall  x.\ P(x, y)]]></fr:tex>, the variable <fr:tex display="inline"><![CDATA[x]]></fr:tex> is bound.
  </html:li>
  <html:li><html:strong>free</html:strong>: if it is not bound by any quantifier within the formula. E.g., in <fr:tex display="inline"><![CDATA[\forall  x.\ P(x, y)]]></fr:tex>, the variable <fr:tex display="inline"><![CDATA[y]]></fr:tex> is free.
  </html:li></html:ul>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000y/</fr:uri>
                                <fr:display-uri>000y</fr:display-uri>
                                <fr:route>/notes/000y/</fr:route>
                                <fr:title text="Quantifiers and Scoping in FOL">Quantifiers and Scoping in FOL</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Consider the formula
</html:p><fr:tex display="block"><![CDATA[
  \forall  y.\ ((\forall  x.\ p(x))) \to  q(x, y)
]]></fr:tex><html:ol><html:li>
    Is the <fr:tex display="inline"><![CDATA[y]]></fr:tex> bound or free?
  </html:li>
  <html:li>
    Is the first occurrence of <fr:tex display="inline"><![CDATA[x]]></fr:tex> bound or free?
  </html:li>
  <html:li>
    Is the second occurrence of <fr:tex display="inline"><![CDATA[x]]></fr:tex> bound or free?
  </html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>22</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li><fr:tex display="inline"><![CDATA[y]]></fr:tex> is <html:em>bound</html:em>, as it is within the scope of the quantifier <fr:tex display="inline"><![CDATA[\forall  y]]></fr:tex>.
    </html:li>
    <html:li>
      The first occurrence of <fr:tex display="inline"><![CDATA[x]]></fr:tex> is <html:em>bound</html:em>, as it is within the scope of the quantifier <fr:tex display="inline"><![CDATA[\forall  x]]></fr:tex>.
    </html:li>
    <html:li>
      The second occurrence of <fr:tex display="inline"><![CDATA[x]]></fr:tex> is <html:em>free</html:em>, as it is not within the scope of any quantifier that binds it.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>22</fr:day>
                            </fr:date>
                            <fr:title text="Closed, Open &amp; Ground Formulas">Closed, Open &amp; Ground Formulas</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/000z/</fr:uri>
                                <fr:display-uri>000z</fr:display-uri>
                                <fr:route>/notes/000z/</fr:route>
                                <fr:title text="Closed, Open, and Ground Formulas (FOL)">Closed, Open, and Ground Formulas (FOL)</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  We have 3 important classifications of formulas in First Order Logic (FOL) based on the nature of their variables:
</html:p>
                                <html:ul><html:li><html:strong>Closed Formula</html:strong>: A formula with <html:em>no free variables</html:em>. All variables in the formula are bound by quantifiers. E.g., <fr:tex display="inline"><![CDATA[\forall  x.\ \exists  y.\ p(x, y)]]></fr:tex> is a closed formula.
  </html:li>
  <html:li><html:strong>Open Formula</html:strong>: A formula with <html:em>at least one free variable</html:em>. E.g., <fr:tex display="inline"><![CDATA[p(x, y)]]></fr:tex> is an open formula since both <fr:tex display="inline"><![CDATA[x]]></fr:tex> and <fr:tex display="inline"><![CDATA[y]]></fr:tex> are free.
  </html:li>
  <html:li><html:strong>Ground Formula</html:strong>: A formula with <html:em>no variables at all</html:em>. E.g., <fr:tex display="inline"><![CDATA[p(a, b)]]></fr:tex> is a ground formula if <fr:tex display="inline"><![CDATA[a]]></fr:tex> and <fr:tex display="inline"><![CDATA[b]]></fr:tex> are constants.
  </html:li></html:ul>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0010/</fr:uri>
                                <fr:display-uri>0010</fr:display-uri>
                                <fr:route>/notes/0010/</fr:route>
                                <fr:title text="FOL - Closed, Open, and Ground Formulas">FOL - Closed, Open, and Ground Formulas</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Consider the following formula
</html:p><fr:tex display="block"><![CDATA[
  \forall  y.\ ((\forall  x.\ p(x))) \to  (\exists  x.\ q(x, y))
]]></fr:tex><html:p>
  Is this formula closed, open, or ground?
</html:p>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>22</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  This formula is a <html:strong>closed formula</html:strong> because all variables within the formula are bound by quantifiers. The variable <fr:tex display="inline"><![CDATA[y]]></fr:tex> is bound by the quantifier <fr:tex display="inline"><![CDATA[\forall  y]]></fr:tex>, and both occurrences of <fr:tex display="inline"><![CDATA[x]]></fr:tex> are bound by their respective quantifiers <fr:tex display="inline"><![CDATA[\forall  x]]></fr:tex> and <fr:tex display="inline"><![CDATA[\exists  x]]></fr:tex>. There are no free variables in this formula. 

  A nice example of a ground formula is something like this 
  <fr:tex display="block"><![CDATA[
    p(a, f(b)) \to  q(c)
  ]]></fr:tex>
  We can see here that there are no variables at all; <fr:tex display="inline"><![CDATA[a]]></fr:tex>, <fr:tex display="inline"><![CDATA[b]]></fr:tex>, and <fr:tex display="inline"><![CDATA[c]]></fr:tex> are not bound by any quantifiers, hence the formula is ground since we aren't substituting/quantifying over any variables.
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>22</fr:day>
                            </fr:date>
                            <fr:title text="Term Evaluation">Term Evaluation</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0012/</fr:uri>
                                <fr:display-uri>0012</fr:display-uri>
                                <fr:route>/notes/0012/</fr:route>
                                <fr:title text="Interpretation (FOL)">Interpretation (FOL)</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  In first order logic a <html:em>Interpretation</html:em>; similar to the case of propositional logic; is a mapping which assigns meaning to the syntax of the language. In this instance it's a mapping from constants, function symbols and predicate symbols to specific objects, functions and relations in a given domain. We can define an interpretation as a sort of piece wise function as follows:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \begin {align*}
  I &: \mathcal  C \cup  \mathcal  F \cup  \mathcal  R \to  D \cup  (D^n \to  D) \cup  (D^n \to  \{\top , \bot \}) \\
  I(c) & = d \quad  \forall  c \in  \mathcal  C, d \in  D \\
  I(f) & = f_D: D^n \to  D \quad  \forall  f \in  \mathcal  F \\
  I(p) & = p_D: D^n \to  \{\top , \bot \} \quad  \forall  p \in  \mathcal  R \\
  \end {align*}
]]></fr:tex>
                                <html:p>
  Where <fr:tex display="inline"><![CDATA[D]]></fr:tex> (sometimes also denoted as <fr:tex display="inline"><![CDATA[U]]></fr:tex>) is the <html:em>domain of discourse</html:em> which is a non-empty set of objects over which the quantifiers range. Intuitively the domain of discourse represents what we wish to talk about in our interpretation. We can break this down into 3 parts:
</html:p>
                                <html:ul><html:li><html:strong>constants</html:strong> (<fr:tex display="inline"><![CDATA[c \in  \mathcal  C]]></fr:tex>): are mapped to specific elements in the domain <fr:tex display="inline"><![CDATA[d \in  D]]></fr:tex>. For example if <fr:tex display="inline"><![CDATA[c]]></fr:tex> is the constant <fr:tex display="inline"><![CDATA["a"]]></fr:tex> and <fr:tex display="inline"><![CDATA[D = \{1, 2, 3\}]]></fr:tex>, then <fr:tex display="inline"><![CDATA[I(a) = 1]]></fr:tex> could be a valid mapping.
  </html:li>
  <html:li><html:strong>function symbols</html:strong> (<fr:tex display="inline"><![CDATA[f \in  \mathcal  F]]></fr:tex>): are mapped to functions that take elements from the domain and return elements in the domain. For example if <fr:tex display="inline"><![CDATA[f]]></fr:tex> is a unary function symbol <fr:tex display="inline"><![CDATA["f"]]></fr:tex> and <fr:tex display="inline"><![CDATA[D = \{1, 2, 3\}]]></fr:tex>, then <fr:tex display="inline"><![CDATA[I(f) = f_D]]></fr:tex> where <fr:tex display="inline"><![CDATA[f_D(1) = 2]]></fr:tex>, <fr:tex display="inline"><![CDATA[f_D(2) = 3]]></fr:tex>, and <fr:tex display="inline"><![CDATA[f_D(3) = 1]]></fr:tex> could be a valid mapping.
  </html:li>
  <html:li><html:strong>relation symbols</html:strong> (<fr:tex display="inline"><![CDATA[p \in  \mathcal  R]]></fr:tex>): are mapped to relations (or predicates) that take elements from the domain and return truth values <fr:tex display="inline"><![CDATA[\{\top , \bot \}]]></fr:tex>. For example if <fr:tex display="inline"><![CDATA[p]]></fr:tex> is a binary relation symbol <fr:tex display="inline"><![CDATA["R"]]></fr:tex> and <fr:tex display="inline"><![CDATA[D = \{1, 2, 3\}]]></fr:tex>, then <fr:tex display="inline"><![CDATA[I(R) = R_D]]></fr:tex> where <fr:tex display="inline"><![CDATA[R_D(1, 2) = \top ]]></fr:tex>, <fr:tex display="inline"><![CDATA[R_D(2, 3) = \bot ]]></fr:tex>, and <fr:tex display="inline"><![CDATA[R_D(3, 1) = \top ]]></fr:tex> could be a valid mapping.
  </html:li></html:ul>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0013/</fr:uri>
                                <fr:display-uri>0013</fr:display-uri>
                                <fr:route>/notes/0013/</fr:route>
                                <fr:title text="Structures and Variable Assignments (FOL)">Structures and Variable Assignments (FOL)</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  A <html:strong>structure</html:strong> <fr:tex display="inline"><![CDATA[\mathcal {M}]]></fr:tex> for a first-order language <fr:tex display="inline"><![CDATA[\mathcal {L}]]></fr:tex> consists of:
</html:p>
                                <html:ul><html:li>
    A non-empty domain <fr:tex display="inline"><![CDATA[D]]></fr:tex>, which is the set of objects that the variables can refer to.
  </html:li>
  <html:li>
    An interpretation function <fr:tex display="inline"><![CDATA[I]]></fr:tex> that assigns meanings to the non-logical symbols in <fr:tex display="inline"><![CDATA[\mathcal {L}]]></fr:tex>:
  </html:li>
  <html:ul><html:li>
      For each constant symbol <fr:tex display="inline"><![CDATA[c]]></fr:tex> in <fr:tex display="inline"><![CDATA[\mathcal {L}]]></fr:tex>, <fr:tex display="inline"><![CDATA[I(c)]]></fr:tex> is an element of <fr:tex display="inline"><![CDATA[D]]></fr:tex>.
    </html:li>
    <html:li>
      For each n-ary function symbol <fr:tex display="inline"><![CDATA[f]]></fr:tex> in <fr:tex display="inline"><![CDATA[\mathcal {L}]]></fr:tex>, <fr:tex display="inline"><![CDATA[I(f)]]></fr:tex> is a function from <fr:tex display="inline"><![CDATA[D^n]]></fr:tex> to <fr:tex display="inline"><![CDATA[D]]></fr:tex>.
    </html:li>
    <html:li>
      For each n-ary predicate symbol <fr:tex display="inline"><![CDATA[P]]></fr:tex> in <fr:tex display="inline"><![CDATA[\mathcal {L}]]></fr:tex>, <fr:tex display="inline"><![CDATA[I(P)]]></fr:tex> is a subset of <fr:tex display="inline"><![CDATA[D^n]]></fr:tex>.
    </html:li></html:ul></html:ul>
                                <html:p>
  A <html:strong>variable assignment</html:strong> <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex> for a structure <fr:tex display="inline"><![CDATA[S]]></fr:tex> is a function that assigns each variable to an element of the domain <fr:tex display="inline"><![CDATA[D]]></fr:tex> of the structure. That is, for each variable <fr:tex display="inline"><![CDATA[x]]></fr:tex>, <fr:tex display="inline"><![CDATA[\sigma (x) \in  D]]></fr:tex>.
</html:p>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0011/</fr:uri>
                                <fr:display-uri>0011</fr:display-uri>
                                <fr:route>/notes/0011/</fr:route>
                                <fr:title text="Term evaluation (FOL)">Term evaluation (FOL)</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  In First Order Logic, terms are evaluated based on an <fr:link href="/notes/0012/" title="Interpretation (FOL)" uri="https://kaierikniermann.github.io/notes/0012/" display-uri="0012" type="local">interpretation</fr:link> <fr:tex display="inline"><![CDATA[I]]></fr:tex> and a <fr:link href="/notes/0013/" title="Structures and Variable Assignments (FOL)" uri="https://kaierikniermann.github.io/notes/0013/" display-uri="0013" type="local">variable assignment</fr:link> <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex> within a structure <fr:tex display="inline"><![CDATA[S]]></fr:tex> denoted as <fr:tex display="inline"><![CDATA[\langle  I, \sigma \rangle (t)]]></fr:tex>. The evaluation rules are as follows:
</html:p>
                                <html:ul><html:li>
    If <fr:tex display="inline"><![CDATA[t]]></fr:tex> is a constant symbol <fr:tex display="inline"><![CDATA[c]]></fr:tex>, then <fr:tex display="inline"><![CDATA[\langle  I, \sigma \rangle (c) = I(c)]]></fr:tex>.
  </html:li>
  <html:li>
    If <fr:tex display="inline"><![CDATA[t]]></fr:tex> is a variable <fr:tex display="inline"><![CDATA[x]]></fr:tex>, then <fr:tex display="inline"><![CDATA[\langle  I, \sigma \rangle (x) = \sigma (x)]]></fr:tex>.
  </html:li>
  <html:li>
    If <fr:tex display="inline"><![CDATA[t]]></fr:tex> is a function application <fr:tex display="inline"><![CDATA[f(t_1, t_2, \ldots , t_n)]]></fr:tex>, then 
    <fr:tex display="block"><![CDATA[
      \langle  I, \sigma \rangle (f(t_1, t_2, \ldots , t_n)) = I(f)(\langle  I, \sigma \rangle (t_1), \langle  I, \sigma \rangle (t_2), \ldots , \langle  I, \sigma \rangle (t_n))
    ]]></fr:tex></html:li></html:ul>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0014/</fr:uri>
                                <fr:display-uri>0014</fr:display-uri>
                                <fr:route>/notes/0014/</fr:route>
                                <fr:title text="Term evaluation (FOL)">Term evaluation (FOL)</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Consider the following domain/universe of discourse, variable assignment, and interpretation:
</html:p><html:ul><html:li>
    Universe 
    <fr:tex display="block"><![CDATA[
      U \triangleq  \{1, 2\}
    ]]></fr:tex></html:li>
  <html:li>
    Variable assignment
    <fr:tex display="block"><![CDATA[
      \sigma  \triangleq  \{x\mapsto  2, y\mapsto  1\}
    ]]></fr:tex></html:li>
  <html:li>
    Interpretation
    <fr:tex display="block"><![CDATA[
      \begin {align*}
      I & \triangleq  \{a \mapsto  1, b \mapsto  2\} \\
      I & \triangleq  \{f(1, 1) \mapsto  2, f(1, 2) \mapsto  2, f(2, 1) \mapsto  1, f(2, 2) \mapsto  1\}
      \end {align*}
    ]]></fr:tex></html:li></html:ul><html:p>
  What is the evaluation of the following terms under the given interpretation and variable assignment?
</html:p><html:ol><html:li><fr:tex display="inline"><![CDATA[f(a, y)]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[f(x, b)]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[f(f(x, b), f(a, y))]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>22</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li><fr:tex display="inline"><![CDATA[\langle  I, \sigma  \rangle  (f(a, y)) = I(f)(\langle  I, \sigma  \rangle  (a), \langle  I, \sigma  \rangle  (y)) = I(f)(I(a), \sigma (y)) = I(f)(1, 1) = 2]]></fr:tex></html:li>
    <html:li><fr:tex display="inline"><![CDATA[\langle  I, \sigma  \rangle  (f(x, b)) = I(f)(\langle  I, \sigma  \rangle  (x), \langle  I, \sigma  \rangle  (b)) = I(f)(\sigma (x), I(b)) = I(f)(2, 2) = 1]]></fr:tex></html:li>
    <html:li><fr:tex display="inline"><![CDATA[\langle  I, \sigma  \rangle  (f(f(x, b), f(a, y))) = I(f)(\langle  I, \sigma  \rangle  (f(x, b)), \langle  I, \sigma  \rangle  (f(a, y))) = I(f)(1, 2) = 2]]></fr:tex></html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>22</fr:day>
                            </fr:date>
                            <fr:title text="Semantic Entailment">Semantic Entailment</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0015/</fr:uri>
                                <fr:display-uri>0015</fr:display-uri>
                                <fr:route>/notes/0015/</fr:route>
                                <fr:title text="Semantic Entailment \models  (FOL)">Semantic Entailment <fr:tex display="inline"><![CDATA[\models ]]></fr:tex> (FOL)</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  We evaluate formulas in first order logic <html:em>under</html:em> a structure which consists of a domain and an interpretation function. In addition, we need a variable assignment to evaluate formulas with free variables. To denote truth under a structure <fr:tex display="inline"><![CDATA[S]]></fr:tex> and variable assignment <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex> we write:
</html:p><html:ul><html:li><html:strong>True</html:strong>: If a formula <fr:tex display="inline"><![CDATA[F]]></fr:tex> evaluates to true under <fr:tex display="inline"><![CDATA[U, I, \sigma ]]></fr:tex> we write <fr:tex display="block"><![CDATA[U, I, \sigma  \models  F]]></fr:tex></html:li>
  <html:li><html:strong>False</html:strong>: If a formula <fr:tex display="inline"><![CDATA[F]]></fr:tex> evaluates to false under <fr:tex display="inline"><![CDATA[U, I, \sigma ]]></fr:tex> we write <fr:tex display="block"><![CDATA[U, I, \sigma  \nvDash  F]]></fr:tex></html:li></html:ul><html:p>
  We can define semantic entailment inductively as follows:
</html:p>
  
    
    <fr:resource hash="d7624c2c82ab393fab290297f3fd0420"><fr:resource-content><html:img src="/notes/d7624c2c82ab393fab290297f3fd0420.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule *[right=True]{}{
    U, I, \sigma  \models  \top 
  }
  \and 
  \inferrule *[right=False]{}{
    U, I, \sigma  \not \models  \bot 
  }
  \and 
  \inferrule *[right=Eval]{
    p(t_1, \ldots , t_n) \\ I = \{p \mapsto  \langle  I, \sigma \rangle (t_1), \ldots , \langle  I, \sigma  \rangle (t_n)\}
  }{
    U, I, \sigma  \models  p(t_1, \ldots , t_n)
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0016/</fr:uri>
                                <fr:display-uri>0016</fr:display-uri>
                                <fr:route>/notes/0016/</fr:route>
                                <fr:title text="Semantic Entailment (FOL)">Semantic Entailment (FOL)</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Consider constants (free variables) <fr:tex display="inline"><![CDATA[a, b]]></fr:tex> and a unary function <fr:tex display="inline"><![CDATA[f]]></fr:tex>, and a binary predicate <fr:tex display="inline"><![CDATA[p]]></fr:tex>. Let <fr:tex display="inline"><![CDATA[U = \{\alpha , \beta \}]]></fr:tex> and interpretation function <fr:tex display="inline"><![CDATA[I]]></fr:tex> be defined as follows:
</html:p><fr:tex display="block"><![CDATA[
  \begin {align*}
  I &= \{a \mapsto  \alpha , b \mapsto  \beta \} \\
  I &= \{f(\alpha ) \mapsto  \beta , f(\beta ) \mapsto  \alpha \} \\
  I &= \{p(\beta , \alpha ) \mapsto  \top , p(\beta , \beta ) \mapsto  \top \}
  \end {align*}
]]></fr:tex><html:p>
  Under the structure <fr:tex display="inline"><![CDATA[S = (U, I)]]></fr:tex> and variable assignment <fr:tex display="inline"><![CDATA[\sigma  = \{x \mapsto  \alpha \}]]></fr:tex> what do the following formulas evaluate to?
</html:p><html:ol><html:li><fr:tex display="inline"><![CDATA[p(f(b), f(x))]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[p(f(x), f(b))]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[p(a, f(x))]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>22</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li><fr:tex display="inline"><![CDATA[p(f(b), f(x))]]></fr:tex> evaluates to <fr:tex display="inline"><![CDATA[\top ]]></fr:tex> because <fr:tex display="inline"><![CDATA[f(b) = f(\beta ) = \alpha ]]></fr:tex> and <fr:tex display="inline"><![CDATA[f(x) = f(\alpha ) = \beta ]]></fr:tex>, and <fr:tex display="inline"><![CDATA[p(\alpha , \beta ) = \top ]]></fr:tex>.
    </html:li>
    <html:li><fr:tex display="inline"><![CDATA[p(f(x), f(b))]]></fr:tex> evaluates to <fr:tex display="inline"><![CDATA[\top ]]></fr:tex> because <fr:tex display="inline"><![CDATA[f(x) = f(\alpha ) = \beta ]]></fr:tex> and <fr:tex display="inline"><![CDATA[f(b) = f(\beta ) = \alpha ]]></fr:tex>, and <fr:tex display="inline"><![CDATA[p(\beta , \alpha ) = \top ]]></fr:tex>.
    </html:li>
    <html:li><fr:tex display="inline"><![CDATA[p(a, f(x))]]></fr:tex> evaluates to <fr:tex display="inline"><![CDATA[\bot ]]></fr:tex> because <fr:tex display="inline"><![CDATA[a = \alpha ]]></fr:tex> and <fr:tex display="inline"><![CDATA[f(x) = f(\alpha ) = \beta ]]></fr:tex>, and <fr:tex display="inline"><![CDATA[p(\alpha , \beta ) = \bot ]]></fr:tex>.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>22</fr:day>
                            </fr:date>
                            <fr:title text="Semantic argument method">Semantic argument method</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0017/</fr:uri>
                                <fr:display-uri>0017</fr:display-uri>
                                <fr:route>/notes/0017/</fr:route>
                                <fr:title text="Connectives and Quantifiers (FOL)">Connectives and Quantifiers (FOL)</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  In addition to evaluating atomic formulas, we can define the evaluation of complex formulas using logical connectives and quantifiers as follows:
</html:p>
  
    
    <fr:resource hash="2ed6f8116f00585c9a6a6031eb24b377"><fr:resource-content><html:img src="/notes/2ed6f8116f00585c9a6a6031eb24b377.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule *[right=Not-True]{
    S, \sigma  \not \models  F
  }{
    S, \sigma  \models  \neg  F
  }
  \and 
  \inferrule *[right=Not-False]{
    S, \sigma  \models  F
  }{
    S, \sigma  \not \models  \neg  F
  }
  \and 
  \inferrule *[right=And-True]{
    S, \sigma  \models  F_1 \\ S, \sigma  \models  F_2
  }{
    S, \sigma  \models  F_1 \land  F_2
  }
  \and 
  \inferrule *[right=And-False]{
    S, \sigma  \not \models  F_1 \lor  S, \sigma  \not \models  F_2
  }{
    S, \sigma  \not \models  F_1 \land  F_2
  }
  \and 
  \inferrule *[right=Or-True]{
    S, \sigma  \models  F_1 \lor  S, \sigma  \models  F_2
  }{
    S, \sigma  \models  F_1 \lor  F_2 
  }
  \and 
  \inferrule *[right=Or-False]{
    S, \sigma  \not \models  F_1 \\ S, \sigma  \not \models  F_2
  }{
    S, \sigma  \not \models  F_1 \lor  F_2
  }
  \and 
  \inferrule *[right=Imp-True]{
    S, \sigma  \not \models  F_1 \lor  S, \sigma  \models  F_2
  }{
    S, \sigma  \models  F_1 \to  F_2
  }
  \and 
  \inferrule *[right=Imp-False]{
    S, \sigma  \models  F_1 \\ S, \sigma  \not \models  F_2
  }{
    S, \sigma  \not \models  F_1 \to  F_2
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
  For the proof rules of quantifiers we have two variants depending on whether we are dealing with free or bound variables:
</html:p>
  
    
    <fr:resource hash="e31d38f49dbceb637264aba1c17cc280"><fr:resource-content><html:img src="/notes/e31d38f49dbceb637264aba1c17cc280.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule *[right=$\forall $-$\top $]{
    S, \sigma  \models  x.\ F \\ \forall  d \in  D
  }{
    S, \sigma [x \mapsto  d] \models  \forall  F
  }
  \and 
  \inferrule *[right=$\forall $-$\bot $]{
    S, \sigma  \not \models  \exists  x.\ F \\ \exists  d \in  D
  }{
    S, \sigma [x \mapsto  d] \not \models  F
  }
  \and 
  \inferrule *[right=$\exists $-$\top $]{
    S, \sigma  \models  \exists  x.\ F \\ \exists  d \in  D
  }{
    S, \sigma [x \mapsto  d] \models  F
  }
  \and 
  \inferrule *[right=$\exists $-$\bot $]{
    S, \sigma  \not \models  \exists  x.\ F \\ \forall  d \in  D
  }{
    S, \sigma [x \mapsto  d] \not \models  F
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0018/</fr:uri>
                                <fr:display-uri>0018</fr:display-uri>
                                <fr:route>/notes/0018/</fr:route>
                                <fr:title text="Semantic Argument method (FOL)">Semantic Argument method (FOL)</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  In first order logic, the <html:em>semantic argument method</html:em> represents a proof by contradiction. The basic idea is as follows:
</html:p><html:ol><html:li>
    We assume that our formula <fr:tex display="inline"><![CDATA[F]]></fr:tex> is not valid, i.e., <fr:tex display="inline"><![CDATA[\exists  S, \sigma  \nvDash  F]]></fr:tex></html:li>
  <html:li>
    Use the proof rules to derive a contradiction from this assumption.
  </html:li>
  <html:li>
    If we can indeed derive a contradiction, we conclude that our initial assumption was false, and therefore <fr:tex display="inline"><![CDATA[F]]></fr:tex> must be valid.
  </html:li></html:ol><html:p>
  We can express the semantic argument method via the following inference rule:
</html:p>
  
    
    <fr:resource hash="2454f17b7350a6508743934c93b962c3"><fr:resource-content><html:img src="/notes/2454f17b7350a6508743934c93b962c3.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule *[right=Contradiction]{
    S, \sigma  \models  p(s_1, \ldots , s_n) \\
    S, \sigma  \models  \neg  p(t_1, \ldots , t_n) \\
    \langle  I, \sigma \rangle  (t_1) = \langle  I, \sigma \rangle  (s_1), \ldots , \langle  I, \sigma \rangle  (t_n) = \langle  I, \sigma \rangle  (s_n)
  }{
    S, \sigma  \models  \bot 
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
  So the idea here being that if we have a predicate and its negation both holding under the same interpretation and variable assignment, we can derive a contradiction. This allows us to conclude that our initial assumption (that the formula is not valid) must be false, thereby proving the validity of the formula.
</html:p></fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>11</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0019/</fr:uri>
                                <fr:display-uri>0019</fr:display-uri>
                                <fr:route>/notes/0019/</fr:route>
                                <fr:title text="Semantic Argument method (FOL)">Semantic Argument method (FOL)</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Consider the following formula:
</html:p><fr:tex display="block"><![CDATA[
  F \triangleq  (\forall  x.\ p(x)) \to  (\forall  y.\ p(y))
]]></fr:tex><html:p>
  Using the semantic argument method, determine whether the formula <fr:tex display="inline"><![CDATA[F]]></fr:tex> is valid.
</html:p>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>22</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  We begin by assuming that <fr:tex display="inline"><![CDATA[\exists  S, \sigma  \nvDash  F]]></fr:tex>
  <fr:tex display="block"><![CDATA[
    \begin {align*}
    & S, \sigma  \nvDash  (\forall  x.\ p(x)) \to  (\forall  y.\ p(y)) \\
    & \therefore  S, \sigma  \models  \forall  x.\ p(x) \land  S, \sigma  \nvDash  \forall  y.\ p(y) \\
    & \therefore  S, \sigma  \models  \forall  x.\ p(x) \land  S, \sigma  \models  \neg  \forall  y.\ p(y) \\
    \end {align*}
  ]]></fr:tex>
  Since we have <fr:tex display="inline"><![CDATA[p]]></fr:tex> and its negation both holding under the same interpretation and variable assignment, we can derive a contradiction using the Contradiction rule from the semantic argument method. Therefore, our initial assumption that <fr:tex display="inline"><![CDATA[F]]></fr:tex> is not valid must be false. Hence, we conclude that the formula <fr:tex display="inline"><![CDATA[F]]></fr:tex> is valid.
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" expanded="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>12</fr:month>
                          <fr:day>2</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/0032/</fr:uri>
                        <fr:display-uri>0032</fr:display-uri>
                        <fr:route>/notes/0032/</fr:route>
                        <fr:title text="Lecture 4 - First Order Theories">Lecture 4 - First Order Theories</fr:title>
                        <fr:taxon>VU-VFS-2025</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>2</fr:day>
                            </fr:date>
                            <fr:title text="Signatures and Axioms">Signatures and Axioms</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0033/</fr:uri>
                                <fr:display-uri>0033</fr:display-uri>
                                <fr:route>/notes/0033/</fr:route>
                                <fr:title text="First Order Theory T">First Order Theory <fr:tex display="inline"><![CDATA[T]]></fr:tex></fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  A <html:em>first order theory</html:em> (FOT) <fr:tex display="inline"><![CDATA[T]]></fr:tex> is defined by two main components:
</html:p>
                                <html:ul><html:li>
    A <html:em>signature</html:em> <fr:tex display="inline"><![CDATA[\Sigma ]]></fr:tex> of a set of constant, function, and predicate symbols
  </html:li>
  <html:li>
    A set of <html:em>axioms</html:em> <fr:tex display="inline"><![CDATA[\mathcal  A]]></fr:tex> consisting of closed (i.e. no free variables) formulas over the signature <fr:tex display="inline"><![CDATA[\Sigma ]]></fr:tex></html:li></html:ul>
                                <html:p>
  We say that a formula constructed from only from the contents of the signature <fr:tex display="inline"><![CDATA[\Sigma ]]></fr:tex> is a <fr:tex display="inline"><![CDATA[\Sigma ]]></fr:tex>-formula.
</html:p>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0034/</fr:uri>
                                <fr:display-uri>0034</fr:display-uri>
                                <fr:route>/notes/0034/</fr:route>
                                <fr:title text="Signatures and Axioms (FOL)">Signatures and Axioms (FOL)</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Consider a theory withthe following signature:
</html:p><fr:tex display="block"><![CDATA[
  \Sigma _H  : \{R = \{\texttt {taller}\}, C = F = \emptyset  \}
]]></fr:tex><html:p>
  And the axiom:
</html:p><fr:tex display="block"><![CDATA[
  \forall  x.\ \forall  y.\ (\texttt {taller}(x, y) \to  \neg  \texttt {taller}(y, x))
]]></fr:tex><html:p>
  Are the following legal <fr:tex display="inline"><![CDATA[\Sigma _H]]></fr:tex>-formulas?
</html:p><html:ol><html:li><fr:tex display="inline"><![CDATA[
      \exists  x.\ \forall  y.\ (\texttt {taller}(x, z) \land  \texttt {taller}(y, w))
    ]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[
    \exists  x.\ \forall  z.\ \texttt {taller}(x, z) \land  \texttt {taller}(\text {joe}, \text {tom})
  ]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>2</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      Yes
    </html:li>
    <html:li>
      No, there are no constants in the signature, so \text {joe} and \text {tom} are not valid terms.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>2</fr:day>
                            </fr:date>
                            <fr:title text="Models of Theories">Models of Theories</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0035/</fr:uri>
                                <fr:display-uri>0035</fr:display-uri>
                                <fr:route>/notes/0035/</fr:route>
                                <fr:title text="Structure &amp; Model of T (FOT)">Structure &amp; Model of <fr:tex display="inline"><![CDATA[T]]></fr:tex> (FOT)</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  A structure which we denote as:
</html:p>
                                <fr:tex display="block"><![CDATA[
  M \triangleq  \langle  U, I \rangle 
]]></fr:tex>
                                <html:p>
  Is a <html:strong>model of a theory</html:strong> <fr:tex display="inline"><![CDATA[T]]></fr:tex> (or <fr:tex display="inline"><![CDATA[T]]></fr:tex>-<html:strong>model</html:strong>) iff:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \forall  A \in  \mathcal  A_T.\ M \vDash  A
]]></fr:tex>
                                <html:p>
  where:
</html:p>
                                <html:ul><html:li><fr:tex display="inline"><![CDATA[U]]></fr:tex> is the universe or more commonly the <html:em>domain</html:em></html:li>
  <html:li><fr:tex display="inline"><![CDATA[I]]></fr:tex> is the <html:em>interpretation</html:em> which assigns some meaning to our formula</html:li></html:ul>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0036/</fr:uri>
                                <fr:display-uri>0036</fr:display-uri>
                                <fr:route>/notes/0036/</fr:route>
                                <fr:title text="Models of T_H">Models of <fr:tex display="inline"><![CDATA[T_H]]></fr:tex></fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  consider a structure consisting of a universe <fr:tex display="inline"><![CDATA[U]]></fr:tex> and interpretation <fr:tex display="inline"><![CDATA[I]]></fr:tex> as follows:
</html:p><fr:tex display="block"><![CDATA[
  U = \{A, B\} \quad  I = \{\texttt {taller} \mapsto  \{\langle  A, A\rangle , \langle  B, B\rangle \}\}
]]></fr:tex><html:p>
  Are the following models of the theory <fr:tex display="inline"><![CDATA[T]]></fr:tex> or not:
</html:p><html:ol><html:li>
    Is <fr:tex display="inline"><![CDATA[\langle  U, I\rangle ]]></fr:tex> a model of <fr:tex display="inline"><![CDATA[T]]></fr:tex></html:li>
  <html:li>
    If we change the interpretation to
    <fr:tex display="block"><![CDATA[
      I = \{\texttt {taller} \mapsto  \{\langle  A, B\rangle \}\}
    ]]></fr:tex>
    is the structure now a model of <fr:tex display="inline"><![CDATA[T]]></fr:tex>?
  </html:li>
  <html:li>
    If we add the following axiom
    <fr:tex display="block"><![CDATA[
      \forall  x, y, z.\ (\texttt {taller}(x, y) \land  \texttt {taller}(y, z) \to  \texttt {taller}(x, z))
    ]]></fr:tex>
    and we change the interpretation to
    <fr:tex display="block"><![CDATA[
      I = \{\texttt {taller} \mapsto  \{\langle  A, B \rangle , \langle  B, C \rangle \}\}
    ]]></fr:tex>
    then is the structure a model of <fr:tex display="inline"><![CDATA[T]]></fr:tex>?
  </html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>2</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:p>
    As a reminder we are working with the axiom:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \forall  x, y.\ (\texttt {taller}(x, y) \to  \neg  \texttt {taller}(y, x))
  ]]></fr:tex>
  <html:ol><html:li>
      Clearly no, as if we take <fr:tex display="inline"><![CDATA[x = A]]></fr:tex> and <fr:tex display="inline"><![CDATA[y = A]]></fr:tex> we have that both <fr:tex display="inline"><![CDATA[\texttt {taller}(A, A)]]></fr:tex> and <fr:tex display="inline"><![CDATA[\texttt {taller}(A, A)]]></fr:tex> hold, violating the axiom.
    </html:li>
    <html:li>
      Here we are chaning or interpretation to just the relation <fr:tex display="inline"><![CDATA[\texttt {taller}(A, B)]]></fr:tex> holding. In this case the axiom is satisfied as there are no values of <fr:tex display="inline"><![CDATA[x]]></fr:tex> and <fr:tex display="inline"><![CDATA[y]]></fr:tex> such that both <fr:tex display="inline"><![CDATA[\texttt {taller}(x, y)]]></fr:tex> and <fr:tex display="inline"><![CDATA[\texttt {taller}(y, x)]]></fr:tex> hold. So yes this is a model of <fr:tex display="inline"><![CDATA[T]]></fr:tex>.
    </html:li>
    <html:li>
      No, as if we take <fr:tex display="inline"><![CDATA[x = A]]></fr:tex>, <fr:tex display="inline"><![CDATA[y = B]]></fr:tex> and <fr:tex display="inline"><![CDATA[z = C]]></fr:tex> we have that both <fr:tex display="inline"><![CDATA[\texttt {taller}(A, B)]]></fr:tex> and <fr:tex display="inline"><![CDATA[\texttt {taller}(B, C)]]></fr:tex> hold, but <fr:tex display="inline"><![CDATA[\texttt {taller}(A, C)]]></fr:tex> does not hold (so not in our interpretation for the <fr:tex display="inline"><![CDATA[\texttt {taller}]]></fr:tex> relationship), violating the axiom.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>2</fr:day>
                            </fr:date>
                            <fr:title text="Satisfiability Modulo T">Satisfiability Modulo <fr:tex display="inline"><![CDATA[T]]></fr:tex></fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0037/</fr:uri>
                                <fr:display-uri>0037</fr:display-uri>
                                <fr:route>/notes/0037/</fr:route>
                                <fr:title text="Satisfiable &amp; Valid modulo T">Satisfiable &amp; Valid modulo <fr:tex display="inline"><![CDATA[T]]></fr:tex></fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  We say that a formula <fr:tex display="inline"><![CDATA[F]]></fr:tex> is <html:strong>satisfiable modulo</html:strong> <fr:tex display="inline"><![CDATA[T]]></fr:tex> iff <html:em>there exists</html:em> a <fr:tex display="inline"><![CDATA[T]]></fr:tex>-model <fr:tex display="inline"><![CDATA[M]]></fr:tex> and a variable assignment <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex> such that:
</html:p>
                                <fr:tex display="block"><![CDATA[
  M, \sigma  \vDash  F
]]></fr:tex>
                                <html:p>
  We say that a formula <fr:tex display="inline"><![CDATA[F]]></fr:tex> is <html:strong>valid modulo</html:strong> <fr:tex display="inline"><![CDATA[T]]></fr:tex> iff <html:em>forall</html:em> <fr:tex display="inline"><![CDATA[T]]></fr:tex>-models <fr:tex display="inline"><![CDATA[M]]></fr:tex> and all variable assignments <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex> we have:
</html:p>
                                <fr:tex display="block"><![CDATA[
  M, \sigma  \vDash  F
]]></fr:tex>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0039/</fr:uri>
                                <fr:display-uri>0039</fr:display-uri>
                                <fr:route>/notes/0039/</fr:route>
                                <fr:title text="FOL Validity vs Valid modulo T">FOL Validity vs Valid modulo <fr:tex display="inline"><![CDATA[T]]></fr:tex></fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  We can compare the two notions by understanding <html:em>validity in modulo</html:em> <fr:tex display="inline"><![CDATA[T]]></fr:tex> as a restriction of <html:em>validity in FOL</html:em> to only those models that are <fr:tex display="inline"><![CDATA[T]]></fr:tex>-models. So the implication of that is that if a formula is valid (true in all models), then its clearly also valid in the subset/restriction to only <fr:tex display="inline"><![CDATA[T]]></fr:tex>-models. However, the other way around does not hold, since a formula can be true in all <fr:tex display="inline"><![CDATA[T]]></fr:tex>-models, but false in some non-<fr:tex display="inline"><![CDATA[T]]></fr:tex>-model. Hence we have the following:
</html:p>
 
  
  <fr:resource hash="e17a21d7370f74a45bdb962c07a32b9d"><fr:resource-content><html:img src="/notes/e17a21d7370f74a45bdb962c07a32b9d.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
   
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

  ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\[
  \vDash  F \implies  T \vDash  F  
\]]]></fr:resource-source></fr:resource>
 
<html:p>
  But the other way around does not hold in general:
</html:p>
 
  
  <fr:resource hash="8bedd6a874fded6390949fd57cbf0d41"><fr:resource-content><html:img src="/notes/8bedd6a874fded6390949fd57cbf0d41.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
   
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

  ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\[
  T \vDash  F \centernot \implies  \vDash  F
\]]]></fr:resource-source></fr:resource>
 
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0038/</fr:uri>
                                <fr:display-uri>0038</fr:display-uri>
                                <fr:route>/notes/0038/</fr:route>
                                <fr:title text="Satisfiability in FOL vs FOT">Satisfiability in FOL vs FOT</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Consider some arbitrary first order theory <fr:tex display="inline"><![CDATA[T]]></fr:tex></html:p><html:ol><html:li>
    If a formula is valid in FOL, then is it also valid in modulo <fr:tex display="inline"><![CDATA[T]]></fr:tex>?
  </html:li>
  <html:li>
    If a formula is valid modulo <fr:tex display="inline"><![CDATA[T]]></fr:tex>, then is it also valid in FOL?
  </html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>2</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      Yes, if its valid in FOL that means its valid in <html:em>all models</html:em> which includes those models that are <fr:tex display="inline"><![CDATA[T]]></fr:tex>-models. Hence its also valid modulo <fr:tex display="inline"><![CDATA[T]]></fr:tex>.
    </html:li>
    <html:li>
      No, a formula can be valid in all <fr:tex display="inline"><![CDATA[T]]></fr:tex>-models, but false in some non-<fr:tex display="inline"><![CDATA[T]]></fr:tex>-model. Hence its not necessarily valid in FOL.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>2</fr:day>
                            </fr:date>
                            <fr:title text="Theory of Equality &amp; Congruence">Theory of Equality &amp; Congruence</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003a/</fr:uri>
                                <fr:display-uri>003a</fr:display-uri>
                                <fr:route>/notes/003a/</fr:route>
                                <fr:title text="Theory of Equality T">Theory of Equality <fr:tex display="inline"><![CDATA[T]]></fr:tex></fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  The <html:strong>theory of equality</html:strong> <fr:tex display="inline"><![CDATA[T_=]]></fr:tex> is a first order theory over the signature <fr:tex display="inline"><![CDATA[\Sigma _=]]></fr:tex> which contains:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \sigma _= : \{=, s\}
]]></fr:tex>
                                <html:p>
  Where <fr:tex display="inline"><![CDATA[=]]></fr:tex> is a binary relation symbol and <fr:tex display="inline"><![CDATA[s]]></fr:tex> is any constant function or predicate symbol. The axioms of the theory of equality are:
</html:p>
                                <fr:resource hash="91ec0848d003ec436b77f543939afd31">
                                  <fr:resource-content>
                                    <html:img src="/notes/91ec0848d003ec436b77f543939afd31.svg" />
                                  </fr:resource-content>
                                  <fr:resource-source type="latex" part="preamble"><![CDATA[
  \usepackage {eulervm}
  \usepackage {amsmath}
]]></fr:resource-source>
                                  <fr:resource-source type="latex" part="body"><![CDATA[
    \begin{align*}
    &\forall x.\ x = x \tag{reflexivity} \\
    &\forall x, y.\ x = y \to y = x \tag{symmetry} \\
    &\forall x, y, z.\ (x = y \land y = z) \to x = z \tag{transitivity} \\
  \end{align*}
]]></fr:resource-source>
                                </fr:resource>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003b/</fr:uri>
                                <fr:display-uri>003b</fr:display-uri>
                                <fr:route>/notes/003b/</fr:route>
                                <fr:title text="Theory of Equality">Theory of Equality</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Consider the universe:
</html:p><fr:tex display="block"><![CDATA[
  U = \{\alpha , \beta \}
]]></fr:tex><html:p>
  which of the following interpetations of <fr:tex display="inline"><![CDATA[=]]></fr:tex> are allowd by the axioms of <fr:tex display="inline"><![CDATA[T_=]]></fr:tex>:
</html:p><html:ol><html:li><fr:tex display="inline"><![CDATA[I(=) \triangleq  \{\langle  \alpha , \beta  \rangle , \langle  \beta  \alpha  \rangle \}]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[I(=) \triangleq  \{\langle  \alpha , \alpha  \rangle , \langle  \beta , \beta  \rangle \}]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[I(=) \triangleq  \{\langle  \alpha , \alpha  \rangle , \langle  \alpha , \beta  \rangle , \langle  \beta , \alpha  \rangle , \langle  \beta , \beta  \rangle \}]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>2</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      No, violates reflexivity axiom since neither <fr:tex display="inline"><![CDATA[\alpha  = \alpha ]]></fr:tex> nor <fr:tex display="inline"><![CDATA[\beta  = \beta ]]></fr:tex> are in the interpretation
    </html:li>
    <html:li>
      Yes, satisfies all axioms of equality
    </html:li>
    <html:li>
      Yes, satisfies all axioms of equality
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003c/</fr:uri>
                                <fr:display-uri>003c</fr:display-uri>
                                <fr:route>/notes/003c/</fr:route>
                                <fr:title text="(Left &amp; Right) Congruence Relations (FOT)">(Left &amp; Right) Congruence Relations (FOT)</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  In the most general sense we say that a relation <fr:tex display="inline"><![CDATA[R]]></fr:tex> over a set <fr:tex display="inline"><![CDATA[A]]></fr:tex> is a <html:strong>congruence</html:strong> with respect to a function <fr:tex display="inline"><![CDATA[f : A^n \to  A]]></fr:tex> if for all <fr:tex display="inline"><![CDATA[a_1, \ldots , a_n, b_1, \ldots , b_n \in  A]]></fr:tex> such that <fr:tex display="inline"><![CDATA[a_i\ R\ b_i]]></fr:tex> for all <fr:tex display="inline"><![CDATA[1 \leq  i \leq  n]]></fr:tex> we have:
</html:p>
                                <fr:tex display="block"><![CDATA[
  f(a_1, \ldots , a_n)\ R\ f(b_1, \ldots , b_n)
]]></fr:tex>
                                <html:p>
  if we denote <fr:tex display="inline"><![CDATA[\overline  x]]></fr:tex> as a vector of elements <fr:tex display="inline"><![CDATA[x_1, \ldots , x_n]]></fr:tex> we can rewrite this more succinctly as:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \forall  \overline  a, \overline  b \in  A^n.\ (\forall  i.\ a_i\ R\ b_i) \to  f(\overline  a)\ R\ f(\overline  b)
]]></fr:tex>
                                <html:p>
  In the case of first order theories we can then instantiate <fr:tex display="inline"><![CDATA[R]]></fr:tex> with things like equality or other relations defined in the theory. Additionally we can <fr:tex display="inline"><![CDATA[f]]></fr:tex> represent a function or predicate symbol from the signature of the theory. In the case of binary functions or predicates we can also define <html:strong>left</html:strong> and <html:strong>right congruence</html:strong> as follows:
</html:p>
                                <html:ol><html:li>
    A relation <fr:tex display="inline"><![CDATA[R]]></fr:tex> is a <html:strong>left congruence</html:strong> with respect to a binary function or predicate <fr:tex display="inline"><![CDATA[f : A \times  A \to  A]]></fr:tex> if for all <fr:tex display="inline"><![CDATA[a, b, c \in  A]]></fr:tex> such that <fr:tex display="inline"><![CDATA[a\ R\ b]]></fr:tex> we have:
  </html:li>
  <fr:tex display="block"><![CDATA[
    f(a, c)\ R\ f(b, c)
  ]]></fr:tex>
  <html:li>
    A relation <fr:tex display="inline"><![CDATA[R]]></fr:tex> is a <html:strong>right congruence</html:strong> with respect to a binary function or predicate <fr:tex display="inline"><![CDATA[f : A \times  A \to  A]]></fr:tex> if for all <fr:tex display="inline"><![CDATA[a, b, c \in  A]]></fr:tex> such that <fr:tex display="inline"><![CDATA[a\ R\ b]]></fr:tex> we have:
  </html:li>
  <fr:tex display="block"><![CDATA[
    f(c, a)\ R\ f(c, b)
  ]]></fr:tex></html:ol>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003d/</fr:uri>
                                <fr:display-uri>003d</fr:display-uri>
                                <fr:route>/notes/003d/</fr:route>
                                <fr:title text="Function &amp; Predicate congruence">Function &amp; Predicate congruence</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Consider the universe:
</html:p><fr:tex display="block"><![CDATA[
  U = \{a, b, c\}
]]></fr:tex><html:p>
  and the interpretation:
</html:p><fr:tex display="block"><![CDATA[
  I(=) \triangleq  \{\langle  a, a \rangle , \langle  a, b \rangle , \langle  b, a \rangle , \langle  b, b \rangle , \langle  c, c \rangle \}
]]></fr:tex><html:ol><html:li>
    Does the interpetation <fr:tex display="inline"><![CDATA[I(=)]]></fr:tex> satisfy the axioms of equality?
  </html:li>
  <html:li>
    Which interpretations for a function <fr:tex display="inline"><![CDATA[f]]></fr:tex> satisfy the axioms of congruence?
    <html:ol><html:li><fr:tex display="inline"><![CDATA[I(f) \triangleq  \{b \to  a, a \to  c, c \to  c\}]]></fr:tex></html:li>
      <html:li><fr:tex display="inline"><![CDATA[I(f) \triangleq  \{b \to  b, a \to  b, c \to  b\}]]></fr:tex></html:li>
      <html:li><fr:tex display="inline"><![CDATA[I(f) \triangleq  \{b \to  a, a \to  b, c \to  c\}]]></fr:tex></html:li></html:ol></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>2</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      Yes, the interpretation satisfies the axioms of equality
    </html:li>
    <html:li>
      Going through them one by one:
      <html:ol><html:li>
          No, because <fr:tex display="inline"><![CDATA[f(a) = c]]></fr:tex> and <fr:tex display="inline"><![CDATA[f(b) = a]]></fr:tex> but <fr:tex display="inline"><![CDATA[a\ I(=)\ b]]></fr:tex> yet <fr:tex display="inline"><![CDATA[c\ not\ I(=)\ a]]></fr:tex></html:li>
        <html:li>
          Yes, because <fr:tex display="inline"><![CDATA[f(a) = b]]></fr:tex> and <fr:tex display="inline"><![CDATA[f(b) = b]]></fr:tex> and <fr:tex display="inline"><![CDATA[a\ I(=)\ b]]></fr:tex> thus <fr:tex display="inline"><![CDATA[b\ I(=)\ b]]></fr:tex>, similarly for <fr:tex display="inline"><![CDATA[c]]></fr:tex></html:li>
        <html:li>
          Yes, because <fr:tex display="inline"><![CDATA[f(a) = b]]></fr:tex> and <fr:tex display="inline"><![CDATA[f(b) = a]]></fr:tex> and <fr:tex display="inline"><![CDATA[a\ I(=)\ b]]></fr:tex> thus <fr:tex display="inline"><![CDATA[b\ I(=)\ a]]></fr:tex>, similarly for <fr:tex display="inline"><![CDATA[c]]></fr:tex></html:li></html:ol></html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>2</fr:day>
                            </fr:date>
                            <fr:title text="Theory of Peano Arithmetic">Theory of Peano Arithmetic</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003e/</fr:uri>
                                <fr:display-uri>003e</fr:display-uri>
                                <fr:route>/notes/003e/</fr:route>
                                <fr:title text="Theory of Peano Arithmetic">Theory of Peano Arithmetic</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  Peano Arithmetic (PA) is a first order theory over the signature <fr:tex display="inline"><![CDATA[\Sigma _{PA}]]></fr:tex> which contains:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \Sigma _{PA} : \{0, S, +, \times , =\}
]]></fr:tex>
                                <html:p>
  Where <fr:tex display="inline"><![CDATA[0]]></fr:tex> is a constant symbol representing zero, <fr:tex display="inline"><![CDATA[S]]></fr:tex> is a unary function symbol representing the successor function, <fr:tex display="inline"><![CDATA[+]]></fr:tex> and <fr:tex display="inline"><![CDATA[\times ]]></fr:tex> are binary function symbols representing addition and multiplication respectively, and <fr:tex display="inline"><![CDATA[=]]></fr:tex> is a binary relation symbol representing equality. The axioms of Peano Arithmetic are:
</html:p>
                                <fr:resource hash="38b17d08c8a044cd82fc858e037bbf9f">
                                  <fr:resource-content>
                                    <html:img src="/notes/38b17d08c8a044cd82fc858e037bbf9f.svg" />
                                  </fr:resource-content>
                                  <fr:resource-source type="latex" part="preamble"><![CDATA[
  \usepackage {eulervm}
  \usepackage {amsmath}
]]></fr:resource-source>
                                  <fr:resource-source type="latex" part="body"><![CDATA[
    \begin{align*}
    &\forall x.\ S(x) \neq 0 \tag{zero} \\
    &\forall x, y.\ S(x) = S(y) \to x = y \tag{plus zero} \\
    &\forall x.\ x + 0 = x \tag{succ} \\
    &\forall x, y.\ x + S(y) = S(x + y) \tag{plus succ} \\
    &\forall x.\ x \times 0 = 0 \tag{times zero} \\
    &\forall x, y.\ x \times S(y) = (x \times y) + x \tag{times succ} \\
    &\forall P.\ (P(0) \land \forall x.\ (P(x) \to P(S(x)))) \to \forall x.\ P(x) \tag{induction}
  \end{align*}
]]></fr:resource-source>
                                </fr:resource>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003f/</fr:uri>
                                <fr:display-uri>003f</fr:display-uri>
                                <fr:route>/notes/003f/</fr:route>
                                <fr:title text="Theory of Peano Arithmetic">Theory of Peano Arithmetic</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Are the following well-formed <fr:tex display="inline"><![CDATA[T_{\text {PA}} formulae?]]></fr:tex></html:p><html:ol><html:li><fr:tex display="inline"><![CDATA[x + y = 1 \land  f(x) = 1 + 1]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[\forall  x.\ \exists  y.\ \exists  z.\ x + y = 1\land  z \times  x = 1 + 1]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[2x = y]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>2</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      No, the theory of Peano Arithmetic does not include function symbols like <fr:tex display="inline"><![CDATA[f]]></fr:tex>, nor does it include numerals like <fr:tex display="inline"><![CDATA[1]]></fr:tex> or <fr:tex display="inline"><![CDATA[2]]></fr:tex>. All terms must be constructed using the constant symbol <fr:tex display="inline"><![CDATA[0]]></fr:tex>, the successor function <fr:tex display="inline"><![CDATA[S]]></fr:tex>, and the function symbols <fr:tex display="inline"><![CDATA[+]]></fr:tex> and <fr:tex display="inline"><![CDATA[\times ]]></fr:tex>.
    </html:li>
    <html:li>
      Yes, this is a well-formed formula. It uses only the symbols and constructs allowed in the theory of Peano Arithmetic.
    </html:li>
    <html:li>
      No, this is not a well-formed formula. The expression <fr:tex display="inline"><![CDATA[2x]]></fr:tex> is not a valid term in Peano Arithmetic, as numerals like <fr:tex display="inline"><![CDATA[2]]></fr:tex> are not part of the language. Terms must be built using <fr:tex display="inline"><![CDATA[0]]></fr:tex>, <fr:tex display="inline"><![CDATA[S]]></fr:tex>, <fr:tex display="inline"><![CDATA[+]]></fr:tex>, and <fr:tex display="inline"><![CDATA[\times ]]></fr:tex>. A valid way to express the same idea would be <fr:tex display="inline"><![CDATA[S(S(0)) \times  x = y]]></fr:tex>. Or if we replace <fr:tex display="inline"><![CDATA[S]]></fr:tex> with <fr:tex display="inline"><![CDATA[1]]></fr:tex> then we could do <fr:tex display="inline"><![CDATA[(1 + 1) \times  x = y]]></fr:tex></html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>2</fr:day>
                            </fr:date>
                            <fr:title text="Theory of Rationals &amp; Integers">Theory of Rationals &amp; Integers</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003i/</fr:uri>
                                <fr:display-uri>003i</fr:display-uri>
                                <fr:route>/notes/003i/</fr:route>
                                <fr:title text="Theory of Rationals T_{\mathbb {Q}}">Theory of Rationals <fr:tex display="inline"><![CDATA[T_{\mathbb {Q}}]]></fr:tex></fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  The theory of rationals <fr:tex display="inline"><![CDATA[T_{\mathbb {Q}}]]></fr:tex> is a first-order theory over the signature <fr:tex display="inline"><![CDATA[\Sigma _{\mathbb {Q}}]]></fr:tex> which contains:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \Sigma _{\mathbb {Q}} : \{0, 1, +, -, =, \geq \}
]]></fr:tex>
                                <html:p>
  (Axioms ommitted for brevity.)
</html:p>
                                <html:p>
  Some important properties of <fr:tex display="inline"><![CDATA[T_{\mathbb {Q}}]]></fr:tex> are:
</html:p>
                                <html:ul><html:li>
    Full theory is <html:em>decidable</html:em> but doubly exponential.
  </html:li>
  <html:li>
    Conjunctive quantifier-free fragment is efficiently decidable (polynomial time).
  </html:li>
  <html:li><fr:tex display="inline"><![CDATA[T_{\mathbb {Q}}]]></fr:tex> is the basis for arithemtic reasoning in SMT solvers such as Z3.
  </html:li>
  <html:li>
    In practice the <html:em>simplex</html:em> algorithm is used.
  </html:li></html:ul>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003h/</fr:uri>
                                <fr:display-uri>003h</fr:display-uri>
                                <fr:route>/notes/003h/</fr:route>
                                <fr:title text="Theory of Presburger Arithmetic">Theory of Presburger Arithmetic</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  Presburger Arithmetic (PA) is a first order theory over the signature <fr:tex display="inline"><![CDATA[\Sigma _{\mathbb {N}}]]></fr:tex> which contains:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \Sigma _{\mathbb {N}} : \{0, 1, +, =\}
]]></fr:tex>
                                <html:p>
  Where <fr:tex display="inline"><![CDATA[0]]></fr:tex> and <fr:tex display="inline"><![CDATA[1]]></fr:tex> are constant symbols representing zero and one respectively, <fr:tex display="inline"><![CDATA[+]]></fr:tex> is a binary function symbol representing addition, and <fr:tex display="inline"><![CDATA[=]]></fr:tex> is a binary relation symbol representing equality. The axioms of Presburger Arithmetic are:
</html:p>
                                <fr:resource hash="b2cd095d79c0e49ba09ee38205cc6cdc">
                                  <fr:resource-content>
                                    <html:img src="/notes/b2cd095d79c0e49ba09ee38205cc6cdc.svg" />
                                  </fr:resource-content>
                                  <fr:resource-source type="latex" part="preamble"><![CDATA[
  \usepackage {eulervm}
  \usepackage {amsmath}
]]></fr:resource-source>
                                  <fr:resource-source type="latex" part="body"><![CDATA[
    \begin{align*}
    &\forall x.\ \neg(x + 1 = 0) \tag{zero} \\
    &\forall x.\ x + 0 = x \tag{plus zero} \\
    &\forall x, y.\ x + 1 = y + 1 \to x = y \tag{plus one} \\
    &\forall x.\ P(0) \land \forall x.\ (P(x) \to P(x + 1)) \to \forall x.\ P(x) \tag{induction}
  \end{align*}
]]></fr:resource-source>
                                </fr:resource>
                                <html:p>
  Some important properties of <fr:tex display="inline"><![CDATA[T_{\mathbb {N}} are]]></fr:tex>:
</html:p>
                                <html:ul><html:li>
    Validity in <html:em>quantifer-free</html:em> Presburger Arithmetic is decidable.
  </html:li>
  <html:li>
    Validity in <html:em>full</html:em> Presburger Arithmetic is decidable.
  </html:li>
  <html:li>
    Validity in Presburger Arithmetic has a super exponential complexity <fr:tex display="inline"><![CDATA[O(2^{2^n})]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[T_{\mathbb {N}}]]></fr:tex> is <html:em>complete</html:em>, i.e.
    <fr:tex display="block"><![CDATA[
      \forall  F.\ T_{\mathbb {N}} \models  F \lor  T_{\mathbb {N}} \models  \neg  F
    ]]></fr:tex></html:li></html:ul>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003k/</fr:uri>
                                <fr:display-uri>003k</fr:display-uri>
                                <fr:route>/notes/003k/</fr:route>
                                <fr:title text="Theory of rationals T_{\mathbb {Q}}">Theory of rationals <fr:tex display="inline"><![CDATA[T_{\mathbb {Q}}]]></fr:tex></fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Consider the following formula:
</html:p><fr:tex display="block"><![CDATA[
  \exists  x.\ (1 + 1) x = 1 + 1 + 1
]]></fr:tex><html:ol><html:li>
    Is this formula valid in <fr:tex display="inline"><![CDATA[T_{\mathbb {Q}}]]></fr:tex></html:li>
  <html:li>
    Is this formula valid in <fr:tex display="inline"><![CDATA[T_{\mathbb {Z}}]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>2</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      Yes, this formula is valid in <fr:tex display="inline"><![CDATA[T_{\mathbb {Q}}]]></fr:tex>. In the theory of rationals, we can find a rational number <fr:tex display="inline"><![CDATA[x = \frac {3}{2}]]></fr:tex> that satisfies the equation <fr:tex display="inline"><![CDATA[(1 + 1) x = 1 + 1 + 1]]></fr:tex>. Therefore, there exists an <fr:tex display="inline"><![CDATA[x]]></fr:tex> in the rationals that makes the equation true.
    </html:li>
    <html:li>
      No, this formula is not valid in <fr:tex display="inline"><![CDATA[T_{\mathbb {Z}}]]></fr:tex>. In the theory of integers, there is no integer <fr:tex display="inline"><![CDATA[x]]></fr:tex> that satisfies the equation <fr:tex display="inline"><![CDATA[(1 + 1) x = 1 + 1 + 1]]></fr:tex>, since <fr:tex display="inline"><![CDATA[\frac {3}{2}]]></fr:tex> is not an integer. Thus, there does not exist an integer <fr:tex display="inline"><![CDATA[x]]></fr:tex> that makes the equation true.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>2</fr:day>
                            </fr:date>
                            <fr:title text="Theory of Data structures">Theory of Data structures</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003l/</fr:uri>
                                <fr:display-uri>003l</fr:display-uri>
                                <fr:route>/notes/003l/</fr:route>
                                <fr:title text="Theory of Arrays">Theory of Arrays</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  The theory of arrays is a first-order theory that models arrays as functions from indices to values. Its signature includes:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \Sigma _A \triangleq  \{- [ - ], \langle  - \triangleleft  - \rangle , =\}
]]></fr:tex>
                                <html:p>
  where:
</html:p>
                                <html:ul><html:li><fr:tex display="inline"><![CDATA[-[ - ]]]></fr:tex>: read operation, which takes an array and an index and returns the value at that index.
  </html:li>
  <html:li><fr:tex display="inline"><![CDATA[\langle  - \triangleleft  - \rangle ]]></fr:tex>: write operation, which takes an array, an index, and a
    value, and returns a new array with the value at the specified index updated.
  </html:li>
  <html:li><fr:tex display="inline"><![CDATA[=]]></fr:tex>: equality relation, which checks if two arrays are identical.
  </html:li></html:ul>
                                <html:p>
  The axioms of the theory of arrays are:
</html:p>
                                <fr:resource hash="8ff9653ef4ba489edcda34b8856e7a7b">
                                  <fr:resource-content>
                                    <html:img src="/notes/8ff9653ef4ba489edcda34b8856e7a7b.svg" />
                                  </fr:resource-content>
                                  <fr:resource-source type="latex" part="preamble"><![CDATA[
  \usepackage {eulervm}
  \usepackage {amsmath}
]]></fr:resource-source>
                                  <fr:resource-source type="latex" part="body"><![CDATA[
    \begin{align*}
    \forall a, i, v.\; [a \langle i \triangleleft v \rangle][i] &= v \quad \tag{Read-Over-Write 1} \\
    \forall a, i, j, v.\; i \neq j \implies [a \langle i \triangleleft v \rangle][j] &= a[j] \quad \tag{Read-Over-Write 2} \\
    \forall a, b.\; (\forall i.\; a[i] = b[i]) &\implies a = b \quad \tag{Extensionality}
  \end{align*}
]]></fr:resource-source>
                                </fr:resource>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003m/</fr:uri>
                                <fr:display-uri>003m</fr:display-uri>
                                <fr:route>/notes/003m/</fr:route>
                                <fr:title text="Theory of arrays T_A">Theory of arrays <fr:tex display="inline"><![CDATA[T_A]]></fr:tex></fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Which of the following formula is valid/satisfiable/unsatisfiable ?
</html:p><html:ol><html:li><fr:tex display="inline"><![CDATA[a[3] = 2]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[a \langle  3 \triangleleft  5 \rangle [3] = 5]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[a \langle  3 \triangleleft  5 \rangle [3] = 3]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[a[3] = 2\land  a \langle  3 \triangleleft  5 \rangle [3] = 5]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>2</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      This formula is <html:strong>satisfiable</html:strong>. For example, if we have an array <fr:tex display="inline"><![CDATA[a]]></fr:tex> such that <fr:tex display="inline"><![CDATA[a[3] = 2]]></fr:tex>, then the formula holds true.
    </html:li>
    <html:li>
      This formula is <html:strong>valid</html:strong>. According to the Read-Over-Write axiom, when we write a value to an index in an array and then read from that same index, we get the value we just wrote. So regardless of the initial contents of array <fr:tex display="inline"><![CDATA[a]]></fr:tex>, after performing the write operation <fr:tex display="inline"><![CDATA[a \langle  3 \triangleleft  5 \rangle ]]></fr:tex>, reading from index <fr:tex display="inline"><![CDATA[3]]></fr:tex> will always yield <fr:tex display="inline"><![CDATA[5]]></fr:tex> hence making it always true (valid).
    </html:li>
    <html:li>
      This formula is <html:strong>unsatisfiable</html:strong>. According to the Read-Over-Write axiom, when we write a value to an index in an array and then read from that same index, we get the value we just wrote. Therefore, after performing the write operation <fr:tex display="inline"><![CDATA[a \langle  3 \triangleleft  5 \rangle ]]></fr:tex>, reading from index <fr:tex display="inline"><![CDATA[3]]></fr:tex> will always yield <fr:tex display="inline"><![CDATA[5]]></fr:tex>, making it impossible for it to equal <fr:tex display="inline"><![CDATA[3]]></fr:tex>.
    </html:li>
    <html:li>
      This formula is <html:strong>satisfiable</html:strong>. For example, if we have an array <fr:tex display="inline"><![CDATA[a]]></fr:tex> such that <fr:tex display="inline"><![CDATA[a[3] = 2]]></fr:tex>, then after performing the write operation <fr:tex display="inline"><![CDATA[a \langle  3 \triangleleft  5 \rangle ]]></fr:tex>, reading from index <fr:tex display="inline"><![CDATA[3]]></fr:tex> will yield <fr:tex display="inline"><![CDATA[5]]></fr:tex>. Thus, both parts of the conjunction can be true simultaneously though are not valid in all interpretations.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" expanded="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>12</fr:month>
                          <fr:day>2</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/003n/</fr:uri>
                        <fr:display-uri>003n</fr:display-uri>
                        <fr:route>/notes/003n/</fr:route>
                        <fr:title text="Lecture 5 - Nano and Hoare Logic">Lecture 5 - Nano and Hoare Logic</fr:title>
                        <fr:taxon>VU-VFS-2025</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>2</fr:day>
                            </fr:date>
                            <fr:title text="Semantics and Evaluation">Semantics and Evaluation</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>4</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003t/</fr:uri>
                                <fr:display-uri>003t</fr:display-uri>
                                <fr:route>/notes/003t/</fr:route>
                                <fr:title text="Simple Imperative Language - Syntax">Simple Imperative Language - Syntax</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  We define the syntax of a simple imperative programming language, using the followng bnf grammar:
</html:p>
  
    
    <fr:resource hash="d9358af54b1514c3e8ea6264dd0ad402"><fr:resource-content><html:img src="/notes/d9358af54b1514c3e8ea6264dd0ad402.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
      
    \usepackage{xcolor}               % color support
  \definecolor{dkgreen}{rgb}{0,0.6,0}
  \definecolor{gray}{rgb}{0.5,0.5,0.5}
  \definecolor{mauve}{rgb}{0.58,0,0.82}
  \definecolor{brown}{rgb}{0.921, 0.325, 0.078}
  \definecolor{lightline}{rgb}{0.8,0.8,0.8}

  \usepackage{libertine}
  \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  % \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig
  \usepackage{simplebnf}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[
      \begin {center}
        \begin {bnf}(
          prod-delim = {--},
          or-sym = {},
          prod-sep = 5pt,
        )[
          colspec = {llcll},
          column{1} = {font=\sffamily },
          column{2} = {mode=dmath},
          column{4} = {font=\ttfamily },
          column{5} = {font=\itshape \color {gray}},
        ]
          
      e : Exp ::=
    | n : number
    | x : variable
    | $e_1 + e_2$ : addition
    | $e_1 - e_2$ : subtraction
    | $e_1 * e_2$ : multiplication
    --
    b : BExp ::=
    | $\top$ : true
    | $\bot$ : false
    | $\neg b$ : negation
    | $b_1 \land b_2$ : conjunction
    | $b_1 \lor b_2$ : disjunction
    | $e_1 = e_2$ : equality
    | $e_1 \leq e_2$ : less than or equal
    --
    s : Stmt ::=
    | skip : skip
    | $x \coloneqq e$ : assignment
    | $s_1 ; s_2$ : sequencing
    | if $b$ then $s_1$ else $s_2$ : conditional
    | while $b$ do $s$ : while loop

        \end {bnf}
      \end {center}
    ]]></fr:resource-source></fr:resource>
  
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>4</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003u/</fr:uri>
                                <fr:display-uri>003u</fr:display-uri>
                                <fr:route>/notes/003u/</fr:route>
                                <fr:title text="Simple Imperative Language - Semantics">Simple Imperative Language - Semantics</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  We can divide the environmental big-step semantics of our simple language into three parts:
</html:p>
                                <html:ul><html:li><html:strong>Expression evaluation</html:strong>: Describes how arithmetic expressions are evaluated to numbers.
  </html:li>
  <html:li><html:strong>Boolean expression evaluation</html:strong>: Describes how boolean expressions are evaluated to boolean values (true/false).
  </html:li>
  <html:li><html:strong>Statement execution</html:strong>: Describes how statements are executed, transforming an initial state (environment) into a final state.
  </html:li></html:ul>
                                <html:p>
  The general big-step environmental evalutation rule is denoted as:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \langle  t, \sigma  \rangle  \Downarrow  v
]]></fr:tex>
                                <html:p>
  Here:
</html:p>
                                <html:ol><html:li>
    We have some starting term <fr:tex display="inline"><![CDATA[\texttt {t}]]></fr:tex> (which can be an expression, boolean expression, or statement), along with some state <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex>.
  </html:li>
  <html:li>
    The evaluation results in some value <fr:tex display="inline"><![CDATA[\texttt {v}]]></fr:tex> (which can be a number, boolean value, or new state).
  </html:li></html:ol>
                                <html:p>
  A quick aside here to deconstruct the term <html:strong>big-step environmental evaluation</html:strong>:
</html:p>
                                <html:ul><html:li>
    We say that this evaluation is <html:strong>big-step</html:strong> as it assumes some arbitrary state of intermediate steps, meaning that within big step semantics we do not care about intermediate computation only about some input expression and the final output value. A simple analogue to make here is that big-step semantics are akin to a teacher asking you to only show ur final answer to a math problem rather than all the steps you took to get there.
  </html:li>
  <html:li>
    We say that this evaluation is <html:strong>environmental</html:strong> (as opposed to being substitution based) as we explicitly keep track of a state <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex> which maps variables to their values. This is in contrast to substitution based semantics where variable occurrences are replaced directly with their values in expressions.
  </html:li></html:ul>
                                <html:p>
  The state <fr:tex display="inline"><![CDATA[\sigma  : \texttt {String} \to  \mathbb {Z}]]></fr:tex> represents a mapping from variables (commonly strings) to their corresponding values (numbers). We denote the updated state after assigning a value to a variable <fr:tex display="inline"><![CDATA[\texttt {x}]]></fr:tex> as:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \sigma [x \mapsto  n]
]]></fr:tex>
                                <html:p>
  This means that in the new state, the variable <fr:tex display="inline"><![CDATA[\texttt {x}]]></fr:tex> now maps to the number <fr:tex display="inline"><![CDATA[\texttt {n}]]></fr:tex>, while all other variable mappings remain unchanged from the original state <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex>.
</html:p>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2025</fr:year>
                                      <fr:month>12</fr:month>
                                      <fr:day>4</fr:day>
                                    </fr:date>
                                    <fr:title text="Expression evaluation">Expression evaluation</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  
    
    <fr:resource hash="6a4d239ebe747cfb08700219cfa18949"><fr:resource-content><html:img src="/notes/6a4d239ebe747cfb08700219cfa18949.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=E-Num]{
    }{
      \langle  n, \sigma  \rangle  \Downarrow  n
    }
    \and 
    \inferrule *[right=E-Var]{
    }{
      \langle  x, \sigma  \rangle  \Downarrow  \sigma (x)
    }
    \and 
    \inferrule *[right=E-Add]{
      \langle  e_1, \sigma  \rangle  \Downarrow  n_1 \\
      \langle  e_2, \sigma  \rangle  \Downarrow  n_2
    }{
      \langle  e_1 + e_2, \sigma  \rangle  \Downarrow  n_1 + n_2
    }
    \and 
    \inferrule *[right=E-Sub]{
      \langle  e_1, \sigma  \rangle  \Downarrow  n_1 \\
      \langle  e_2, \sigma  \rangle  \Downarrow  n_2
    }{
      \langle  e_1 - e_2, \sigma  \rangle  \Downarrow  n_1 - n_2
    }
    \and 
    \inferrule *[right=E-Mul]{
      \langle  e_1, \sigma  \rangle  \Downarrow  n_1 \\
      \langle  e_2, \sigma  \rangle  \Downarrow  n_2
    }{
      \langle  e_1 * e_2, \sigma  \rangle  \Downarrow  n_1 * n_2
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2025</fr:year>
                                      <fr:month>12</fr:month>
                                      <fr:day>4</fr:day>
                                    </fr:date>
                                    <fr:title text="Boolean expression evaluation">Boolean expression evaluation</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  
    
    <fr:resource hash="a16aa0da1d83a5e40e560fb3943d67ea"><fr:resource-content><html:img src="/notes/a16aa0da1d83a5e40e560fb3943d67ea.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=B-True]{
    }{
      \langle  \top , \sigma  \rangle  \Downarrow  \texttt {true}
    }
    \and 
    \inferrule *[right=B-False]{
    }{
      \langle  \bot , \sigma  \rangle  \Downarrow  \texttt {false}
    }
    \and 
    \inferrule *[right=B-Not]{
      \langle  b, \sigma  \rangle  \Downarrow  v
    }{
      \langle  \neg  b, \sigma  \rangle  \Downarrow  \neg  v
    }
    \and 
    \inferrule *[right=B-And]{
      \langle  b_1, \sigma  \rangle  \Downarrow  v_1 \\
      \langle  b_2, \sigma  \rangle  \Downarrow  v_2
    }{
      \langle  b_1 \land  b_2, \sigma  \rangle  \Downarrow  v_1 \land  v_2
    }
    \and 
    \inferrule *[right=B-Or]{
      \langle  b_1, \sigma  \rangle  \Downarrow  v_1 \\
      \langle  b_2, \sigma  \rangle  \Downarrow  v_2
    }{
      \langle  b_1 \lor  b_2, \sigma  \rangle  \Downarrow  v_1 \lor  v_2
    }
    \and 
    \inferrule *[right=B-Eq]{
      \langle  e_1, \sigma  \rangle  \Downarrow  n_1 \\
      \langle  e_2, \sigma  \rangle  \Downarrow  n_2
    }{
      \langle  e_1 = e_2, \sigma  \rangle  \Downarrow  (n_1 = n_2)
    }
    \and 
    \inferrule *[right=B-Leq]{
      \langle  e_1, \sigma  \rangle  \Downarrow  n_1 \\
      \langle  e_2, \sigma  \rangle  \Downarrow  n_2
    }{
      \langle  e_1 \leq  e_2, \sigma  \rangle  \Downarrow  (n_1 \leq  n_2)
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2025</fr:year>
                                      <fr:month>12</fr:month>
                                      <fr:day>4</fr:day>
                                    </fr:date>
                                    <fr:title text="Statement evaluation">Statement evaluation</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
  
    
    <fr:resource hash="c80b26dde9779d9a29c9fa2cc9590978"><fr:resource-content><html:img src="/notes/c80b26dde9779d9a29c9fa2cc9590978.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=S-Skip]{
    }{
      \langle  \texttt {skip}, \sigma  \rangle  \Downarrow  \sigma 
    }
    \and 
    \inferrule *[right=S-Assign]{
      \langle  e, \sigma  \rangle  \Downarrow  n
    }{
      \langle  x \coloneqq  e, \sigma  \rangle  \Downarrow  \sigma [x \mapsto  n]
    }
    \and 
    \inferrule *[right=S-Seq]{
      \langle  s_1, \sigma  \rangle  \Downarrow  \sigma ' \\
      \langle  s_2, \sigma ' \rangle  \Downarrow  \sigma ''
    }{
      \langle  s_1 ; s_2, \sigma  \rangle  \Downarrow  \sigma ''
    }
    \and 
    \inferrule *[right=S-IfTrue]{
      \langle  b, \sigma  \rangle  \Downarrow  \texttt {true} \\
      \langle  s_1, \sigma  \rangle  \Downarrow  \sigma '
    }{
      \langle  \texttt {if } b \texttt { then } s_1 \texttt { else } s_2, \sigma  \rangle  \Downarrow  \sigma '
    }
    \and 
    \inferrule *[right=S-IfFalse]{
      \langle  b, \sigma  \rangle  \Downarrow  \texttt {false} \\
      \langle  s_2, \sigma  \rangle  \Downarrow  \sigma '
    }{
      \langle  \texttt {if } b \texttt { then } s_1 \texttt { else } s_2, \sigma  \rangle  \Downarrow  \sigma '
    }
    \and 
    \inferrule *[right=S-WhileFalse]{
      \langle  b, \sigma  \rangle  \Downarrow  \texttt {false}
    }{
      \langle  \texttt {while } b \texttt { do } s, \sigma  \rangle  \Downarrow  \sigma 
    }
    \and 
    \inferrule *[right=S-WhileTrue]{
      \langle  b, \sigma  \rangle  \Downarrow  \texttt {true} \\
      \langle  s, \sigma  \rangle  \Downarrow  \sigma ' \\
      \langle  \texttt {while } b \texttt { do } s, \sigma ' \rangle  \Downarrow  \sigma ''
    }{
      \langle  \texttt {while } b \texttt { do } s, \sigma  \rangle  \Downarrow  \sigma ''
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
</fr:mainmatter>
                                </fr:tree>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>4</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003v/</fr:uri>
                                <fr:display-uri>003v</fr:display-uri>
                                <fr:route>/notes/003v/</fr:route>
                                <fr:title text="Simple Imperative Language - Evaluation">Simple Imperative Language - Evaluation</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:ol><html:li>
    What does the following evaluate to?
    <fr:tex display="block"><![CDATA[
      \langle  (x := x - 1), \sigma [x \mapsto  2] \rangle 
    ]]></fr:tex></html:li>
  <html:li>
    What does the following evaluate to?
    <fr:tex display="block"><![CDATA[
      \langle  \texttt {if } x + 1 \leq  3 \texttt { then } x := x - 1, \sigma [x \mapsto  1] \rangle 
    ]]></fr:tex></html:li>
  <html:li>
    What does the following evaluate to?
    <fr:tex display="block"><![CDATA[
      \langle  \texttt {while } (x + 1 \leq  3) \texttt { then } x := x - 1, \sigma [x \mapsto  1] \rangle 
    ]]></fr:tex></html:li>
  <html:li>
    Is the following a <fr:link href="/notes/003w/" title="Total &amp; Partial function" uri="https://kaierikniermann.github.io/notes/003w/" display-uri="003w" type="local">total function</fr:link>?
    <fr:tex display="block"><![CDATA[
      \langle  e, \sigma  \rangle  \Downarrow  n
    ]]></fr:tex></html:li>
  <html:li>
    Is the following a <fr:link href="/notes/003w/" title="Total &amp; Partial function" uri="https://kaierikniermann.github.io/notes/003w/" display-uri="003w" type="local">total function</fr:link>?
    <fr:tex display="block"><![CDATA[
      \langle  s, \sigma  \rangle  \Downarrow  \sigma '
    ]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>4</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      Starting in the state <fr:tex display="inline"><![CDATA[x \mapsto  2]]></fr:tex> we evaluate <fr:tex display="inline"><![CDATA[x := x - 1]]></fr:tex> to the state <fr:tex display="inline"><![CDATA[x \mapsto  1]]></fr:tex></html:li>
    <html:li>
      Starting in the state <fr:tex display="inline"><![CDATA[x \mapsto  1]]></fr:tex>, we first evaluate the condition <fr:tex display="inline"><![CDATA[x + 1 \leq  3]]></fr:tex>:
      <fr:tex display="block"><![CDATA[
        \begin {align*}
        \langle  x + 1, \sigma [x \mapsto  1] \rangle  &\Downarrow  2 \\
        \langle  3, \sigma [x \mapsto  1] \rangle  &\Downarrow  3 \\
        \langle  2 \leq  3, \sigma [x \mapsto  1] \rangle  &\Downarrow  \texttt {true}
        \end {align*}
      ]]></fr:tex>
      Since the condition evaluates to true, we then evaluate the then-branch <fr:tex display="inline"><![CDATA[x := x - 1]]></fr:tex>:
      <fr:tex display="block"><![CDATA[
        \begin {align*}
        \langle  x - 1, \sigma [x \mapsto  1] \rangle  &\Downarrow  0 \\
        \langle  x := 0, \sigma [x \mapsto  1] \rangle  &\Downarrow  \sigma [x \mapsto  0]
        \end {align*}
      ]]></fr:tex></html:li>
    <html:li>
      We again start by evaluating the condition
      <fr:tex display="block"><![CDATA[
        \begin {align*}
        \langle  x + 1, \sigma [x \mapsto  1] \rangle  &\Downarrow  2 \\
        \langle  3, \sigma [x \mapsto  1] \rangle  &\Downarrow  3 \\
        \langle  2 \leq  3, \sigma [x \mapsto  1] \rangle  &\Downarrow  \texttt {true}
        \end {align*}
      ]]></fr:tex>
      Since we can see that the body of the loop only decreases <fr:tex display="inline"><![CDATA[x]]></fr:tex>, we are stuck in an infinite loop:
      <fr:tex display="block"><![CDATA[
        \begin {align*}
        \langle  x := x - 1, \sigma [x \mapsto  1] \rangle  &\Downarrow  \sigma [x \mapsto  0] \\
        \langle  \texttt {while } (x + 1 \leq  3) \texttt { do } x := x - 1, \sigma [x \mapsto  0] \rangle  &\Downarrow  \sigma [x \mapsto  -1] \\
        \langle  \texttt {while } (x + 1 \leq  3) \texttt { do } x := x - 1, \sigma [x \mapsto  -1] \rangle  &\Downarrow  \sigma [x \mapsto  -2] \\
        &\vdots 
        \end {align*}
      ]]></fr:tex></html:li>
    <html:li>
      Yes, for every expression <fr:tex display="inline"><![CDATA[e]]></fr:tex> and state <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex>, there exists a number <fr:tex display="inline"><![CDATA[n]]></fr:tex> such that
      <fr:tex display="block"><![CDATA[
        \langle  e, \sigma  \rangle  \Downarrow  n
      ]]></fr:tex>
      This follows from the fact that expressions are finite syntax trees built from a finite set of rules, and each rule can be evaluated in a finite number of steps.
    </html:li>
    <html:li>
      No, there exist statements <fr:tex display="inline"><![CDATA[s]]></fr:tex> and states <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex> for which there is no resulting state <fr:tex display="inline"><![CDATA[\sigma ']]></fr:tex> such that
      <fr:tex display="block"><![CDATA[
        \langle  s, \sigma  \rangle  \Downarrow  \sigma '
      ]]></fr:tex>
      For example, consider the while-loop
      <fr:tex display="block"><![CDATA[
        \texttt {while } (x + 1 \leq  3) \texttt { do } x := x - 1
      ]]></fr:tex>
      starting from the state <fr:tex display="inline"><![CDATA[\sigma [x \mapsto  1]]]></fr:tex>. As shown in the previous question, this loop does not terminate, and thus there is no resulting state <fr:tex display="inline"><![CDATA[\sigma ']]></fr:tex>.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>2</fr:day>
                            </fr:date>
                            <fr:title text="Hoare Logic">Hoare Logic</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>5</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003x/</fr:uri>
                                <fr:display-uri>003x</fr:display-uri>
                                <fr:route>/notes/003x/</fr:route>
                                <fr:title text="Hoare triple - partial correctness">Hoare triple - partial correctness</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  The basic unit of reasoning or <html:em>judgement</html:em> of the <html:strong>partial correctness</html:strong> of a program is the <html:strong>Hoare triple</html:strong> denoted as:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \{P\}\ s\ \{Q\}
]]></fr:tex>
                                <html:p>
  where:
</html:p>
                                <html:ul><html:li><fr:tex display="inline"><![CDATA[P]]></fr:tex> represents the <html:strong>precondition</html:strong> which must hold true <html:em>before</html:em> the execution of the statement <fr:tex display="inline"><![CDATA[s]]></fr:tex>.
  </html:li>
  <html:li><fr:tex display="inline"><![CDATA[Q]]></fr:tex> represents the <html:strong>postcondition</html:strong> which must hold true <html:em>after</html:em> the execution of the statement <fr:tex display="inline"><![CDATA[s]]></fr:tex>, provided that <fr:tex display="inline"><![CDATA[P]]></fr:tex> was true before execution.
  </html:li></html:ul>
                                <html:p>
  If we consider a variable state <fr:tex display="inline"><![CDATA[\sigma  : \texttt {String} \to  \mathbb {Z}]]></fr:tex> mapping variable names to integer values, then we can define the partial correctness condition of a Hoare triple as follows:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \sigma  \vDash  P \to  \exists  \sigma '.\ \langle  s, \sigma  \rangle  \Downarrow  \sigma ' \to  \sigma ' \vDash  Q
]]></fr:tex>
                                <html:p>
  What this says is that: if the precondition <fr:tex display="inline"><![CDATA[P]]></fr:tex> holds in the initial state <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex>, and if executing the statement <fr:tex display="inline"><![CDATA[s]]></fr:tex> from that state leads to a new state <fr:tex display="inline"><![CDATA[\sigma ']]></fr:tex>, then the postcondition <fr:tex display="inline"><![CDATA[Q]]></fr:tex> must hold in the new state <fr:tex display="inline"><![CDATA[\sigma ']]></fr:tex>.
</html:p>
                                <html:p>
  In a more programmatic sense we can understand the pre and postconditions as assertions on the memory state <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex>, in other words they represent a function <fr:tex display="inline"><![CDATA[A : (\texttt {String} \to  \mathbb {Z}) \to  \texttt {Prop}]]></fr:tex> that evaluates to true or false based on the values of the variables in the state. Thus, we can rewrite the Hoare triple condition as:
</html:p>
                                <fr:tex display="block"><![CDATA[
  P(\sigma ) \to  \exists  \sigma '.\ \langle  s, \sigma  \rangle  \Downarrow  \sigma ' \to  Q(\sigma ')
]]></fr:tex>
                                <html:p>
  Or in lean equivalently as:
</html:p>
                                <html:pre class="code-block language-lean">
                                  <html:code class="language-lean">
  abbrev Condition := Memory -&gt; Prop

  def HoareTriple {P Q : Condition} (c : Stmt) : Prop :=
    ∀ σ σ', P σ → (c, σ) ⇓ₛ σ' → Q σ'
</html:code>
                                </html:pre>
                                <html:p>
  A note here is that we are using some custom notation for the big-step semantics relation. The notation <fr:tex display="inline"><![CDATA[\Downarrow _s]]></fr:tex> here simply means the big step evaluation relation for <html:em>statements</html:em>.
</html:p>
                                <html:p>
  In general for a Hoare triple we denote its validity as:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \vDash  \{P\}\ s\ \{Q\}
]]></fr:tex>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>5</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003y/</fr:uri>
                                <fr:display-uri>003y</fr:display-uri>
                                <fr:route>/notes/003y/</fr:route>
                                <fr:title text="Hoare triple evaluation">Hoare triple evaluation</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Asses the validity of each of the following Hoare triples.
</html:p><html:ol><html:li><fr:tex display="inline"><![CDATA[\{x = 0 \}\ x := x + 1\ \{x = 1\}]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[\{x = 0 \land  y = 1\}\ x := x + 1\ \{x = 1 \land  y = 2\}]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[\{x = 0 \land  y = 1\}\ x := x + 1 \{x = 1 \lor  y = 2\}]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[\{x = 0\}\ \texttt {while}\ \top \ \texttt {do}\ x := x + 1\ \{x = 1\}]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>5</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      Valid. If <fr:tex display="inline"><![CDATA[x = 0]]></fr:tex> before execution, then after executing <fr:tex display="inline"><![CDATA[x := x + 1]]></fr:tex>, <fr:tex display="inline"><![CDATA[x]]></fr:tex> will be <fr:tex display="inline"><![CDATA[1]]></fr:tex>.
    </html:li>
    <html:li>
      Invalid. While <fr:tex display="inline"><![CDATA[x]]></fr:tex> will be <fr:tex display="inline"><![CDATA[1]]></fr:tex> after execution, <fr:tex display="inline"><![CDATA[y]]></fr:tex> remains <fr:tex display="inline"><![CDATA[1]]></fr:tex>, so the post-condition <fr:tex display="inline"><![CDATA[y = 2]]></fr:tex> does not hold.
    </html:li>
    <html:li>
      Valid. After execution, <fr:tex display="inline"><![CDATA[x]]></fr:tex> will be <fr:tex display="inline"><![CDATA[1]]></fr:tex>, satisfying the post-condition <fr:tex display="inline"><![CDATA[x = 1 \lor  y = 2]]></fr:tex>.
    </html:li>
    <html:li>
      Valid. The loop runs indefinitely, so the post-condition is vacuously true as the program never terminates.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>2</fr:day>
                            </fr:date>
                            <fr:title text="Partial vs Total correctness">Partial vs Total correctness</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>5</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003z/</fr:uri>
                                <fr:display-uri>003z</fr:display-uri>
                                <fr:route>/notes/003z/</fr:route>
                                <fr:title text="Hoare triple - total correctness">Hoare triple - total correctness</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  The classical <fr:link href="/notes/003x/" title="Hoare triple - partial correctness" uri="https://kaierikniermann.github.io/notes/003x/" display-uri="003x" type="local">hoare triple</fr:link> <fr:tex display="inline"><![CDATA[\{P\}\ s\ \{Q\}]]></fr:tex> only captures the notion of <html:strong>partial correctness</html:strong>, meaning that if the program terminates, then the postcondition <fr:tex display="inline"><![CDATA[Q]]></fr:tex> holds given that the precondition <fr:tex display="inline"><![CDATA[P]]></fr:tex> held before execution. However, it does not guarantee that the program will terminate. To capture both correctness and termination, we define the <html:strong>total correctness</html:strong> Hoare triple denoted as:
</html:p>
                                <fr:tex display="block"><![CDATA[
  [P]\ s\ [Q]
]]></fr:tex>
                                <html:p>
  The total correctness Hoare triple asserts that:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \sigma  \vDash  P \to  \exists  \sigma '.\ \langle  s, \sigma  \rangle  \Downarrow  \sigma ' \land  \sigma ' \vDash  Q
]]></fr:tex>
                                <html:p>
  Or equivalently viewing the conditions as assertions on memory states:
</html:p>
                                <fr:tex display="block"><![CDATA[
  P(\sigma ) \to  \exists  \sigma '.\ \langle  s, \sigma  \rangle  \Downarrow  \sigma ' \land  Q(\sigma ')
]]></fr:tex>
                                <html:p>
  The central difference we can observe here is with the usage of a conjunction with the postcondition as opposed to an implication. This means that for total correctness, if the precondition <fr:tex display="inline"><![CDATA[P]]></fr:tex> holds in the initial state <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex>, then there must exist a final state <fr:tex display="inline"><![CDATA[\sigma ']]></fr:tex> such that executing the statement <fr:tex display="inline"><![CDATA[s]]></fr:tex> from <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex> leads to <fr:tex display="inline"><![CDATA[\sigma ']]></fr:tex> <html:em>and</html:em> the postcondition <fr:tex display="inline"><![CDATA[Q]]></fr:tex> holds in that final state. Whereas in the case of partial correctness, if we had non-termination, the postcondition could be vacuously true.
</html:p>
                                <html:p>
  For the sake of completeness let's also show how we might implement this in lean:
</html:p>
                                <html:pre class="code-block language-lean">
                                  <html:code class="language-lean">
  def TotalHoareTriple {P Q : Condition} (c : Stmt) : Prop :=
    ∀ σ, P σ → ∃ σ', (c, σ) ⇓ₛ σ' ∧ Q σ'
</html:code>
                                </html:pre>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>5</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0040/</fr:uri>
                                <fr:display-uri>0040</fr:display-uri>
                                <fr:route>/notes/0040/</fr:route>
                                <fr:title text="Understanding hoare triples">Understanding hoare triples</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:ol><html:li>
    What does <fr:tex display="inline"><![CDATA[\{\top \}\ s\ \{Q\}]]></fr:tex> express?
  </html:li>
  <html:li>
    What about <fr:tex display="inline"><![CDATA[\{P\}\ s\ \{\top \}]]></fr:tex>?
  </html:li>
  <html:li>
    What about <fr:tex display="inline"><![CDATA[[P]\ s\ [\top ]]]></fr:tex>?
  </html:li>
  <html:li>
    When does <fr:tex display="inline"><![CDATA[\{\top \}\ s\ \{\bot \}]]></fr:tex> hold?
  </html:li>
  <html:li>
    When does <fr:tex display="inline"><![CDATA[\{\bot \}\ s\ \{Q\}]]></fr:tex> hold?
  </html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>5</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      It states that no matter the initial state, if the program <fr:tex display="inline"><![CDATA[s]]></fr:tex> terminates, then the postcondition <fr:tex display="inline"><![CDATA[Q]]></fr:tex> will hold. In other words, all <html:em>terminating states</html:em> end up in or satisfy <fr:tex display="inline"><![CDATA[Q]]></fr:tex>.
    </html:li>
    <html:li>
      It states that if the precondition <fr:tex display="inline"><![CDATA[P]]></fr:tex> holds before execution of <fr:tex display="inline"><![CDATA[s]]></fr:tex>, then after execution (if it terminates), the postcondition will always be true. Since <fr:tex display="inline"><![CDATA[\top ]]></fr:tex> is always true, this Hoare triple is valid for any program <fr:tex display="inline"><![CDATA[s]]></fr:tex> and precondition <fr:tex display="inline"><![CDATA[P]]></fr:tex>.
    </html:li>
    <html:li>
      Since this is a total correctness Hoare triple, it states that if the precondition <fr:tex display="inline"><![CDATA[P]]></fr:tex> holds before execution of <fr:tex display="inline"><![CDATA[s]]></fr:tex>, then the program <fr:tex display="inline"><![CDATA[s]]></fr:tex> will always terminate, regardless of the final state. The postcondition <fr:tex display="inline"><![CDATA[\top ]]></fr:tex> is trivially satisfied since it is always true. In other words we terminate on all states satisfying <fr:tex display="inline"><![CDATA[P]]></fr:tex>.
    </html:li>
    <html:li>
      This Hoare triple holds if and only if the program <fr:tex display="inline"><![CDATA[s]]></fr:tex> <html:em>never terminates</html:em> for any initial state. Since the postcondition is <fr:tex display="inline"><![CDATA[\bot ]]></fr:tex>, which is always false, the only way for the Hoare triple to be valid is if there are no terminating executions of <fr:tex display="inline"><![CDATA[s]]></fr:tex>.
    </html:li>
    <html:li>
      This Hoare triple holds for any program <fr:tex display="inline"><![CDATA[s]]></fr:tex> and postcondition <fr:tex display="inline"><![CDATA[Q]]></fr:tex>, because the precondition <fr:tex display="inline"><![CDATA[\bot ]]></fr:tex> is always false. Since there are no initial states that satisfy <fr:tex display="inline"><![CDATA[\bot ]]></fr:tex>, the implication in the definition of the Hoare triple is vacuously true.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>2</fr:day>
                            </fr:date>
                            <fr:title text="Inference rules">Inference rules</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>5</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0043/</fr:uri>
                                <fr:display-uri>0043</fr:display-uri>
                                <fr:route>/notes/0043/</fr:route>
                                <fr:title text="Inference Rule Schema - Hoare logic">Inference Rule Schema - Hoare logic</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  To denote the idea of syntactic consequence / inference within Hoare logic we use the notation:
</html:p>
  
    
    <fr:resource hash="2e12a2e5ca0ca3ffda6781ef9f314039"><fr:resource-content><html:img src="/notes/2e12a2e5ca0ca3ffda6781ef9f314039.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule *[right=Rule-Schema]{
    \vdash  \{P\}\ s_1\ \{Q\} \\ 
    \ldots  \\
    \vdash  \{Q\}\ s_n\ \{R\}
  }{
    \vdash  \{P\}\ s\ \{R\}
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
  Which says that if we can derive the hoare triple <fr:tex display="inline"><![CDATA[\{P\}\ s_1\ \{Q\}]]></fr:tex> and so on up to <fr:tex display="inline"><![CDATA[\{Q\}\ s_n\ \{R\}]]></fr:tex> using the inference rules of Hoare logic, then we can derive the hoare triple <fr:tex display="inline"><![CDATA[\{P\}\ s\ \{R\}]]></fr:tex>.
</html:p><html:p>
  Inference rules without any hypotheses are considered <html:strong>base cases</html:strong>.
</html:p></fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>5</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0045/</fr:uri>
                                <fr:display-uri>0045</fr:display-uri>
                                <fr:route>/notes/0045/</fr:route>
                                <fr:title text="Hoare logic - assignment proof rule">Hoare logic - assignment proof rule</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:ol><html:li>
    Consider the assignment <fr:tex display="inline"><![CDATA[x := y]]></fr:tex> and the postcondition <fr:tex display="inline"><![CDATA[x > 2]]></fr:tex>. What needs to hold before the assignment such that <fr:tex display="inline"><![CDATA[x > 2]]></fr:tex> holds afterwards?
  </html:li>
  <html:li>
    Consider <fr:tex display="inline"><![CDATA[i := i + 1]]></fr:tex> and post-condition <fr:tex display="inline"><![CDATA[i > 10]]></fr:tex>. What do we need to know before the assignment such that i &gt; 10 holds afterwards?
  </html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>5</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      Let's write this out first as a hoare triple: <fr:tex display="inline"><![CDATA[\{?\}\ x := y\ \{x > 2\}]]></fr:tex>. Without even looking at the assignment rule it should be obvious that if we want <fr:tex display="inline"><![CDATA[x > 2]]></fr:tex> to hold after the assignment, then before the assignment we need <fr:tex display="inline"><![CDATA[y > 2]]></fr:tex>, since after the assignment <fr:tex display="inline"><![CDATA[x]]></fr:tex> will take the value of <fr:tex display="inline"><![CDATA[y]]></fr:tex>. So the hoare triple is valid when we have: <fr:tex display="inline"><![CDATA[\{y > 2\}\ x := y\ \{x > 2\}]]></fr:tex>.
    </html:li>
    <html:li>
      Similarly we write the hoare triple: <fr:tex display="inline"><![CDATA[\{?\}\ i := i + 1\ \{i > 10\}]]></fr:tex>. To ensure that <fr:tex display="inline"><![CDATA[i > 10]]></fr:tex> holds after the assignment, we need to consider what value of <fr:tex display="inline"><![CDATA[i]]></fr:tex> before the assignment will lead to <fr:tex display="inline"><![CDATA[i > 10]]></fr:tex> afterwards. Since we are incrementing <fr:tex display="inline"><![CDATA[i]]></fr:tex> by 1, we need <fr:tex display="inline"><![CDATA[i + 1 > 10]]></fr:tex> before the assignment, so our hoare triple becomes <fr:tex display="inline"><![CDATA[\{i + 1 > 10\}\ i := i + 1 \{i > 10\}]]></fr:tex>.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>5</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0044/</fr:uri>
                                <fr:display-uri>0044</fr:display-uri>
                                <fr:route>/notes/0044/</fr:route>
                                <fr:title text="Hoare triple inference rules - Nano language">Hoare triple inference rules - Nano language</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  The basic inference rules for the Hoare logic applied to the Nano language are as follows:
</html:p>
  
    
    <fr:resource hash="ae8a764266248441ae574ce29f32b3a7"><fr:resource-content><html:img src="/notes/ae8a764266248441ae574ce29f32b3a7.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule *[right=Assignment]{
  }{
    \vdash  \{P[x \mapsto  e]\}\ x := e\ \{P\}
  }
  \and 
  \inferrule *[right=Sequence]{
    \vdash  \{P\}\ s_1\ \{Q\} \\
    \vdash  \{Q\}\ s_2\ \{R\}
  }{
    \vdash  \{P\}\ s_1; s_2\ \{R\}
  }
  \and 
  \inferrule *[right=If]{
    \vdash  \{P \land  b\}\ s_1\ \{Q\} \\
    \vdash  \{P \land  \neg  b\}\ s_2\ \{Q\}
  }{
    \vdash  \{P\}\ \texttt {if}\ b\ \texttt {then}\ s_1\ \texttt {else}\ s_2\ \{Q\}
  }
  \and 
  \inferrule *[right=While]{
    \vdash  \{P \land  b\}\ s\ \{P\}
  }{
    \vdash  \{P\}\ \texttt {while}\ b\ \texttt {do}\ s\ \{P \land  \neg  b\}
  }
  \and  
  \inferrule *[right=Consequence]{
    \vDash  P' \to  P \\
    \vdash  \{P\}\ s\ \{Q\} \\
    \vDash  Q \to  Q'
  }{
    \vdash  \{P'\}\ s\ \{Q'\}
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>6</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0046/</fr:uri>
                                <fr:display-uri>0046</fr:display-uri>
                                <fr:route>/notes/0046/</fr:route>
                                <fr:title text="A hypothetical proof rule">A hypothetical proof rule</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  A friend suggests the following proof rule for assignments:
</html:p><fr:tex display="block"><![CDATA[
  \vdash  \{(x = e) \to  Q\}\ x := e\ \{Q\}
]]></fr:tex><html:p>
  Is the proof rule correct?
</html:p>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>6</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:p>
    Now let's test out the rule on a particular hoare triple:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \{?\}\ x := 4\ \{y = x\}
  ]]></fr:tex>
  <html:p>
    To make the hoare triple valid we would have to use the following precondition:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \vdash  \{(x = 4) \to  y = x\}\ x := 4\ \{y = x\}
  ]]></fr:tex>
  <html:p>
    but let's now assume the following initial state:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \sigma _1 = \{x \mapsto  3, y \mapsto  1\}
  ]]></fr:tex>
  <html:p>
    this does correctly entail our precondition, i.e. we have <fr:tex display="inline"><![CDATA[\sigma _1 \vDash  P]]></fr:tex> as necessary by virtue of vacous truth, then executing the statement we have:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \langle  x := 4, \sigma _1 \rangle  \Downarrow  \sigma _2
  ]]></fr:tex>
  <html:p>
    In the new context clearly <fr:tex display="inline"><![CDATA[x]]></fr:tex> is reassigned to 4, thus:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \sigma _2 = \{x \mapsto  4, y \mapsto  1\}
  ]]></fr:tex>
  <html:p>
    But we can see that clearly <fr:tex display="inline"><![CDATA[\sigma _2]]></fr:tex> violates our postcondition <fr:tex display="inline"><![CDATA[Q]]></fr:tex>, which is to say, <fr:tex display="inline"><![CDATA[\sigma _2 \nvDash  (y = x)]]></fr:tex>. The implication of this is that while the hoare triple is derivable it is <html:em>not</html:em> then necessarily also valid, in words this proof rule is unsound.
  </html:p>
  <html:p>
    For completeness let's also provide a proof of soundness. As a reminder soundness states that:
  </html:p>
  <html:blockquote>
    If a hoare triple is derivable using the inference rules of our system, then it is valid (i.e. true in all interpretations.)
  </html:blockquote>
  <html:p>
    Formally we express this as:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \vdash  \{P\}\ s\ \{Q\} \to  \vDash  \{P\}\ s\ \{Q\}
  ]]></fr:tex>
  <html:p>
    If we instantiate this rule for our hypothetical assignment rule we must demonstrate the following:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \forall  \sigma .\ \sigma  \vDash  (x = e) \to  Q \land  \exists  \sigma '.\ \langle  (x := e), \sigma  \rangle  \Downarrow  \sigma ' \to  \sigma ' \vDash  Q
  ]]></fr:tex>
  <fr:tree show-metadata="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>6</fr:day></fr:date><fr:taxon>Proof</fr:taxon></fr:frontmatter><fr:mainmatter><html:p>
      Let <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex> be the initial state before the assignment <fr:tex display="inline"><![CDATA[x := e]]></fr:tex>. We must show that if <fr:tex display="inline"><![CDATA[\sigma  \vDash  (x = e) \to  Q]]></fr:tex>, then, after executing <fr:tex display="inline"><![CDATA[x := e]]></fr:tex>, the resulting state <fr:tex display="inline"><![CDATA[\sigma ']]></fr:tex> satisfies <fr:tex display="inline"><![CDATA[\sigma ' \vDash  Q]]></fr:tex> (i.e. is valid for the assertions in the postcondition).
    </html:p><html:ul><html:li>
        Before the assignment we have <fr:tex display="inline"><![CDATA[\sigma  \vDash  (x = e) \to  Q]]></fr:tex>, in other words this means that:
        <fr:tex display="block"><![CDATA[
          \sigma (x) = \sigma (e) \to  \sigma  \vDash   Q
        ]]></fr:tex>
        so if the variable <fr:tex display="inline"><![CDATA[x]]></fr:tex> in the initial state evaluates to the same thing as some expression <fr:tex display="inline"><![CDATA[e]]></fr:tex> then our post postcondition is valid for this state.
      </html:li>
      <html:li>
        After the assignment we have a new state <fr:tex display="inline"><![CDATA[\sigma ']]></fr:tex> defined as:
        <fr:tex display="block"><![CDATA[
          \sigma '(x) = \sigma (e)
        ]]></fr:tex>
        with everything else being unchanged, which is to say that
        <fr:tex display="block"><![CDATA[
          \forall  y.\ y\ \mathrlap {\,/}{=}\ x \land  \sigma '(y) = \sigma (y)
        ]]></fr:tex></html:li>
      <html:li>
        Now we want to check if <fr:tex display="inline"><![CDATA[\sigma ' \vDash  Q]]></fr:tex> as desired, we proceed by a case analysis on the equality <fr:tex display="inline"><![CDATA[\sigma '(x) = \sigma (e)]]></fr:tex>
        <html:ul><html:li><html:em>Case:</html:em> <fr:tex display="inline"><![CDATA[\sigma (e) = \sigma (x)]]></fr:tex>, then by the precondition we have <fr:tex display="inline"><![CDATA[\sigma  \vDash  Q]]></fr:tex>. Since <fr:tex display="inline"><![CDATA[\sigma ']]></fr:tex> only changes the value of <fr:tex display="inline"><![CDATA[x]]></fr:tex> to <fr:tex display="inline"><![CDATA[\sigma (e)]]></fr:tex>, and <fr:tex display="inline"><![CDATA[Q]]></fr:tex> is satisfied by the initial state <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex> it follows that <fr:tex display="inline"><![CDATA[\sigma ' \vDash  Q]]></fr:tex>.
          </html:li>
          <html:li><html:em>Case:</html:em> <fr:tex display="inline"><![CDATA[\sigma (e) \ \mathrlap {\,/}{=}\ \sigma (x)]]></fr:tex>, then our precondition becomes vacuously true as the antecedent is false. However, as the assignment does terminate we do need to ensure that <fr:tex display="inline"><![CDATA[Q]]></fr:tex> holds in the new state <fr:tex display="inline"><![CDATA[\sigma ']]></fr:tex>. However, since <fr:tex display="inline"><![CDATA[Q]]></fr:tex> can be arbitrary we cannot guarantee that <fr:tex display="inline"><![CDATA[\sigma ' \vDash  Q]]></fr:tex>.
          </html:li></html:ul></html:li></html:ul></fr:mainmatter></fr:tree>
  <html:p>
    Let's link the proof of soundness back to the example, so in our inital state <fr:tex display="inline"><![CDATA[\sigma _1]]></fr:tex> we have that:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \sigma (x) \ \mathrlap {\,/}{=}\ \sigma (y) \equiv  3 \ \mathrlap {\,/}{=}\ 4
  ]]></fr:tex>
  <html:p>
    Since this means that the equality <fr:tex display="inline"><![CDATA[x = 4]]></fr:tex> is false we have that implication so the precondition <fr:tex display="inline"><![CDATA[P]]></fr:tex> is true. This corresponds precisely to the second case where <fr:tex display="inline"><![CDATA[\sigma (e) \ \mathrlap {\,/}{=}\ \sigma (x)]]></fr:tex>. The issue we can then see which naturally follows is that in the new state clearly its the case that:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \sigma _2 = \{x \mapsto  4, y \mapsto  1\} \nvDash  (x = y)
  ]]></fr:tex>
  <html:p>
    In other words we had the case where our precondition was vacuously true thus erroneously implying upon termination the arbitrary <fr:tex display="inline"><![CDATA[y = x]]></fr:tex> must also hold. Clearly then this proof rule is incorrect as in the case of a vacuous truth we are able to generate unsound hoare triples.
  </html:p>
  <html:p>
    To compare this with the <html:em>correct</html:em> assignment rule we have:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \vdash  \{P[x \mapsto  e]\}\ x := e\ \{P\}
  ]]></fr:tex>
  <html:p>
    we can notice here that by removing the consequent of the logical implication we ensure that if the assertion of x being substituted / being equal to the expression e <html:em>before</html:em> the execution of the statement doesn't hold, then it correctly means that we indeed cannot suggest that after an assignment our assertion <fr:tex display="inline"><![CDATA[P]]></fr:tex> is somehow correct.
  </html:p>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>6</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0047/</fr:uri>
                                <fr:display-uri>0047</fr:display-uri>
                                <fr:route>/notes/0047/</fr:route>
                                <fr:title text="Assessing provability">Assessing provability</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Using the correct proof rule for assignments, asses which of the hoare triples are provable i.e. valid.
</html:p>
  
    
    <fr:resource hash="ad663f7befbaeae2486b4d0e959338be"><fr:resource-content><html:img src="/notes/ad663f7befbaeae2486b4d0e959338be.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule *[right=Assign]{
  }{
    \vdash  \{P[x \mapsto  e]\}\ x := e\ \{P\}
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:ol><html:li><fr:tex display="inline"><![CDATA[\{y = 4\}\ x:= 4\ \{y = x\}]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[\{x + 1 = n\}\ x := x + 1\ \{x = n\}]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[\{y = x\}\ y := 2\ \{y = x\}]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[\{z = 3\}\ y := x\ \{z = 3\}]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>6</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      Yes, since we have that for any state <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex> the substitution
      <fr:tex display="block"><![CDATA[
        (y = x)[x \mapsto  4]
      ]]></fr:tex>
      holds, thus our precondition holds and upon termination of the assignment clearly our postcondition then holds as well.
    </html:li>
    <html:li>
      Yes, again we that our post condition says <fr:tex display="inline"><![CDATA[x = n]]></fr:tex> so <fr:tex display="inline"><![CDATA[(x = n)[ n \mapsto  (x + 1)]]]></fr:tex> holds as our precondition is then
      <fr:tex display="block"><![CDATA[
        (x + 1 = n)[n \mapsto  (x + 1)] = (x + 1 = x + 1)
      ]]></fr:tex></html:li>
    <html:li>
      No, again using our reasoning we have 
      <fr:tex display="block"><![CDATA[
        (y = x)[y \mapsto  2] = 2 = x
      ]]></fr:tex>
      but then if we have <fr:tex display="inline"><![CDATA[\sigma  = \{ x \mapsto  3\}]]></fr:tex> we can generate 
      <fr:tex display="block"><![CDATA[
        \sigma  \nvDash  (2 = x) \equiv  (2 = 3)
      ]]></fr:tex></html:li>
    <html:li>
      Yes, this is just correct by definition of a substitution leaving irrelevant variables unaffected.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>2</fr:day>
                            </fr:date>
                            <fr:title text="Consequence">Consequence</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>6</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0048/</fr:uri>
                                <fr:display-uri>0048</fr:display-uri>
                                <fr:route>/notes/0048/</fr:route>
                                <fr:title text="Precond. Strengthening &amp; Postcond. Weakening">Precond. Strengthening &amp; Postcond. Weakening</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  As a reminder in hoare logic we denote the consequence rule as follows:
</html:p>
  
    
    <fr:resource hash="c67b32a98e204fcbe7f95e1ed6f10a3d"><fr:resource-content><html:img src="/notes/c67b32a98e204fcbe7f95e1ed6f10a3d.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule *[right=Consequence]{
    \vDash  P' \to  P \\ \vdash  \{P\}\ s\ \{Q\} \\ \vDash  Q \to  Q'
  }{
    \vdash  \{P'\}\ s\ \{Q'\}
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
  On a high level this is quite evidently just transitivity, which is to say that if some assertion <fr:tex display="inline"><![CDATA[P']]></fr:tex> holds and by implication <fr:tex display="inline"><![CDATA[P]]></fr:tex> holds, and upon successful termination of <fr:tex display="inline"><![CDATA[s]]></fr:tex> we have that <fr:tex display="inline"><![CDATA[Q]]></fr:tex> holds and by implication <fr:tex display="inline"><![CDATA[Q']]></fr:tex> holds, then we can transitively reason that <fr:tex display="inline"><![CDATA[\{P'\}\ s\ \{Q'\}]]></fr:tex> would also hold for our program <fr:tex display="inline"><![CDATA[s]]></fr:tex>.
</html:p><html:p>
  What we can do here is decompose this rule into two separate rules:
</html:p><fr:tree show-metadata="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>6</fr:day></fr:date><fr:title text="Precondition strengthening">Precondition strengthening</fr:title></fr:frontmatter><fr:mainmatter>
  
    
    <fr:resource hash="d5f3ee2521e2c4f40c707279150c3182"><fr:resource-content><html:img src="/notes/d5f3ee2521e2c4f40c707279150c3182.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=Pre-Strength]{
      \vDash  P \to  P' \\ \vdash  \{P'\}\ s\ \{Q\}
    }{
      \vdash  \{P\}\ s\ \{Q\}
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
    The idea of strengthening here comes from the fact that the rhs of an implication always <html:em>at least</html:em> denotes a more restrictive or <html:em>strengthened</html:em> condition on the memory state <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex>. So a basic example being clearly:
  </html:p><fr:tex display="block"><![CDATA[
    x > 3 \to  x > 2
  ]]></fr:tex><html:p>
    So if we have that:
  </html:p><fr:tex display="block"><![CDATA[
    \sigma  \vDash  (x > 3) \to  (x > 2) \\ \vdash  \{x > 2\}\ s\ \{Q\}
  ]]></fr:tex><html:p>
    Which is to say that our hoare triple is derivable under the weaker precondition <fr:tex display="inline"><![CDATA[x > 2]]></fr:tex>, then clearly the same hoare triple is also derivable under the stronger pre-condition <fr:tex display="inline"><![CDATA[x > 3]]></fr:tex> as it implies our weaker condition, hence we can derive:
  </html:p><fr:tex display="block"><![CDATA[
    \vdash  \{x > 3\}\ s\ \{Q\}
  ]]></fr:tex><html:p>
    An example program we could take here would be something like:
  </html:p><fr:tex display="block"><![CDATA[
    \{x > 2\}\ \texttt {if}\ (x > 2)\ \texttt {then}\ y := 2 \texttt {else}\ y := 3\ \{y := 2\}
  ]]></fr:tex><html:p>
    Clearly here the condition just requires that <fr:tex display="inline"><![CDATA[x]]></fr:tex> is larger than 2, if our precondition asserts that its larger than 3, the <fr:tex display="inline"><![CDATA[\texttt {then}]]></fr:tex> branch executes just the same and our postcondition holds.
  </html:p></fr:mainmatter></fr:tree><fr:tree show-metadata="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>6</fr:day></fr:date><fr:title text="Postcondition weakening">Postcondition weakening</fr:title></fr:frontmatter><fr:mainmatter>
  
    
    <fr:resource hash="e06442d80aba57a8112249b972a0b377"><fr:resource-content><html:img src="/notes/e06442d80aba57a8112249b972a0b377.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=Post-Weaken.]{
      \vdash  \{P\}\ s\ \{Q'\} \\ \vDash  Q' \to  Q
    }{
      \vdash  \{P\}\ s\ \{Q\}
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
    On a high level this says that if we can prove some postcondition <fr:tex display="inline"><![CDATA[Q']]></fr:tex>, we can always relax this condition to something weaker. So in simpler terms if we have the fact that the postcondition <fr:tex display="inline"><![CDATA[Q']]></fr:tex> holds for some more restrictive state, then we can naturally lessen the restrictions and have it still hold.
  </html:p></fr:mainmatter></fr:tree></fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>6</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0049/</fr:uri>
                                <fr:display-uri>0049</fr:display-uri>
                                <fr:route>/notes/0049/</fr:route>
                                <fr:title text="Postcondition Weakening examples">Postcondition Weakening examples</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Suppose we can prove:
</html:p><fr:tex display="block"><![CDATA[
  \{\top \}\ s\ \{x = y \land  z = 2\}
]]></fr:tex><html:p>
  using the rule of post-condition weakening, which of the following can we prove?
</html:p><html:ol><html:li><fr:tex display="inline"><![CDATA[\{\top \}\ s\ \{x = y\}]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[\{\top \}\ s \ \{z = 2\}]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[\{\top \}\ s\ \{z > 2\}]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[\{\top \}\ s\ \{\forall  y.\ x = y\}]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[\{\top \}\ s\ \{\exists  y.\ x = y\}]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>6</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      Yes, this is provable, removing a conjunct is a common way of weakening an expresison as we are removing one condition.
    </html:li>
    <html:li>
      Yes, this is provable, same reasoning as in (1)
    </html:li>
    <html:li>
      This is also provable, more or less same reasoning as before, here we are using the fact that 
      <fr:tex display="block"><![CDATA[
        z = 2 \to  z > 0
      ]]></fr:tex>
      since obviously <fr:tex display="inline"><![CDATA[2 > 0]]></fr:tex></html:li>
    <html:li>
      No, this is not provable, while removing a conjunct does weaken our postcondition, if we then <html:em>also</html:em> quantify over all <fr:tex display="inline"><![CDATA[y]]></fr:tex> we make an assertion which is <html:strong>stronger</html:strong> then what the conjunct says, i.e. that <fr:tex display="inline"><![CDATA[x = y]]></fr:tex> <html:em>for a specific <fr:tex display="inline"><![CDATA[y]]></fr:tex></html:em>, hence this is not provable.
    </html:li>
    <html:li>
      Yes, this is provable. We have the fact that 
      <fr:tex display="block"><![CDATA[
        a = b \equiv  \exists  a = b
      ]]></fr:tex>
      so clearly this is the same as what we did for (1) just with no desugaring of existential syntax
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" expanded="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>12</fr:month>
                          <fr:day>6</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/004a/</fr:uri>
                        <fr:display-uri>004a</fr:display-uri>
                        <fr:route>/notes/004a/</fr:route>
                        <fr:title text="Lecture 6 - Hoare logic &amp; Weakest preconditions">Lecture 6 - Hoare logic &amp; Weakest preconditions</fr:title>
                        <fr:taxon>VU-VFS-2025</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>6</fr:day>
                            </fr:date>
                            <fr:title text="Loops &amp; Invariants">Loops &amp; Invariants</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>6</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004c/</fr:uri>
                                <fr:display-uri>004c</fr:display-uri>
                                <fr:route>/notes/004c/</fr:route>
                                <fr:title text="Checking valid invariants">Checking valid invariants</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Consider the following code:
</html:p><html:pre class="code-block language-python"><html:code class="language-python">
  i = 0;
  j = 0;
  n = 10;
  while i &lt; n do 
    i = i + 1;
    j = i + j
</html:code></html:pre><html:p>
  Which of the following is a loop invariant?
</html:p><html:ol><html:li><fr:tex display="inline"><![CDATA[i \leq  n]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[i < n]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[j \geq  n]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>6</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      Before the loop <fr:tex display="inline"><![CDATA[i = 0]]></fr:tex> and <fr:tex display="inline"><![CDATA[n = 10]]></fr:tex>, since that means <fr:tex display="inline"><![CDATA[i \leq  n]]></fr:tex> is true we move on to checking it holds true <html:em>after</html:em> each loop iteration. What we can observe is that the loop condition is <fr:tex display="inline"><![CDATA[i < n]]></fr:tex> and during the loop we have <fr:tex display="inline"><![CDATA[i = i + 1]]></fr:tex>, what this suggests is that clearly during the iteratons the invariant holds, additionally when <fr:tex display="inline"><![CDATA[i = 10]]></fr:tex> we have that <fr:tex display="inline"><![CDATA[10 < 0 \to  \bot ]]></fr:tex> hence the invariant also holds upon the termination of the loop, i.e. after the final iteration, thus it's indeed a valid loop invariant.
    </html:li>
    <html:li>
      No, this is not a valid invariant, we can see that its very close to being right, but it doesnt account for the case after the final iteration and before we check the loop condition, i.e. where <fr:tex display="inline"><![CDATA[i = 10]]></fr:tex>, hence its not a valid loop invariant because it does not hold true after each iteration.
    </html:li>
    <html:li>
      No, this is quite easy to see as it immediately fails even before we get into the loop as <fr:tex display="inline"><![CDATA[0 \geq  10 \to  \bot ]]></fr:tex>.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>6</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004d/</fr:uri>
                                <fr:display-uri>004d</fr:display-uri>
                                <fr:route>/notes/004d/</fr:route>
                                <fr:title text="Proving validity with invariants">Proving validity with invariants</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Let's consider the statement <fr:tex display="inline"><![CDATA[W]]></fr:tex>:
</html:p><html:pre class="code-block language-python"><html:code class="language-python">
  while x &lt; n do 
    x = x + 1
</html:code></html:pre><html:p>
  Answer the following questions:
</html:p><html:ol><html:li>
    Prove the validity of 
    <fr:tex display="block"><![CDATA[
      \vdash  \{x \leq  n\}\ W\ \{x \geq  n\}
    ]]></fr:tex>
    using the loop invariant <fr:tex display="inline"><![CDATA[I = x \leq  n]]></fr:tex></html:li> 
  <html:li>
    Would <fr:tex display="inline"><![CDATA[\top ]]></fr:tex> also have worked as a loop invariant?
  </html:li>
  <html:li>
    If we changed the post condition to <fr:tex display="inline"><![CDATA[x = n]]></fr:tex>, what would that have changed?
  </html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>6</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:p>
    As the usual piece of little assistance let's take a look at the while rule
  </html:p>
  
  
    
    <fr:resource hash="510feb572ccb159e80172c821612b9ea"><fr:resource-content><html:img src="/notes/510feb572ccb159e80172c821612b9ea.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=While]{
      \vdash  \{I \land  b\}\ s\ \{I\}
    }{
      \vdash  \{I\}\ \texttt {while}\ b\ \texttt {do}\ s\ \{I \land  \neg  b\}
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  

  <html:ol><html:li>
      Here we can try to construct the proof tree first of all, instantiating our rule with the given invariant we have: 
      
  
    
    <fr:resource hash="ff7656998e9e92f8893c373912cba5d0"><fr:resource-content><html:img src="/notes/ff7656998e9e92f8893c373912cba5d0.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
        \inferrule {
          \{x \leq  n \land  x < n\}\ x := x + 1\ \{x \leq  n\}
        }{
          \{x \leq  n\}\ W\ \{x \leq  n \land  \underbrace {x \geq  n}_{\neg  b}\}   
        }
      \end {mathpar}]]></fr:resource-source></fr:resource>
  

      Using the assignment rule we then want to prove the antecident here, so 
      
  
    
    <fr:resource hash="20c749146276ffdfaf2c600a94744eee"><fr:resource-content><html:img src="/notes/20c749146276ffdfaf2c600a94744eee.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
        \inferrule {}{
          \{Q[x := x + 1]\}\ x := x + 1\ \{Q\}
        }
      \end {mathpar}]]></fr:resource-source></fr:resource>
  

      instantiating this with or postcondition <fr:tex display="inline"><![CDATA[Q]]></fr:tex> we have
      
  
    
    <fr:resource hash="cd3e0abe522f0573ab42337bb4c40675"><fr:resource-content><html:img src="/notes/cd3e0abe522f0573ab42337bb4c40675.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
        \inferrule {}{
          \{(x \leq  n)[x \mapsto  x + 1]\}\ s\ \{x \leq  n\}
        }
      \end {mathpar}]]></fr:resource-source></fr:resource>
  

      in other words our precondition becomes
      <fr:tex display="block"><![CDATA[
        (x + 1) \leq  n
      ]]></fr:tex>
      Therefore the use the assignment rule we want we have to demonstrate
      <fr:tex display="block"><![CDATA[
        (x \leq  n \land  x < n \to  (x + 1) \leq  n)
      ]]></fr:tex>
      since we have that 
      <fr:tex display="block"><![CDATA[
        x \leq  n \land  x < n \equiv  x < n \to  (x + 1) \leq  n
      ]]></fr:tex>
      we clearly have that 
      
  
    
    <fr:resource hash="dae60e421b8d868a6a576b45d0b301fb"><fr:resource-content><html:img src="/notes/dae60e421b8d868a6a576b45d0b301fb.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
        \inferrule *[right=Pre-Strength]{
          \vdash  \{x + 1 \leq  n\}\ s\ \{x \leq  n\} \\ \vDash  (x \leq  n \land  x < n) \to  (x + 1) \leq  n 
        }{
          \vdash  \{x \leq  n \land  x < n\}\ x := x + 1\ \{x \leq  n\}
        }
      \end {mathpar}]]></fr:resource-source></fr:resource></html:li> 
    <html:li>
      Yes, let's again instantiate our rule
      
  
    
    <fr:resource hash="fe8fe062c22fd123b9f0913392bb48d3"><fr:resource-content><html:img src="/notes/fe8fe062c22fd123b9f0913392bb48d3.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
        \inferrule {
          \{\top  \land  x < n\}\ x := x + 1\ \{\top \}
        }{
          \{\top \}\ W\ \{\top  \land  x \geq  n \}
        }
      \end {mathpar}]]></fr:resource-source></fr:resource>
  

      since our postcondition for the assignmnet is a tautology, i.e. always valid, it will hold under substitution thus making the assignment trivially valid hence working as a correct loop invariant.
    </html:li>
    <html:li>
      Something we could observe in question (1) is that 
      
  
    
    <fr:resource hash="2dddb0d9a84bb5a9fac365035a048797"><fr:resource-content><html:img src="/notes/2dddb0d9a84bb5a9fac365035a048797.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
        \inferrule {
          \{x \leq  n\}\ W\ \{\overbrace {x \leq  n \land  x \geq  n}^{x = n}\} \\ \vDash  (x = n) \to  x \geq  n 
        }{
          \{x \leq  n\}\ W\ \{x \geq  n\}
        }
      \end {mathpar}]]></fr:resource-source></fr:resource>
  

      so this is a bit of a trick question in that with question 1 we are actually just using a postcondition weaking <html:em>on this postcondition</html:em>, hence this is naturally a valid postcondition.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>7</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004f/</fr:uri>
                                <fr:display-uri>004f</fr:display-uri>
                                <fr:route>/notes/004f/</fr:route>
                                <fr:title text="Invariant">Invariant</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  In the most straightforward sense we say that an invariant is simply:
</html:p>
                                <html:blockquote>
  A property that holds at all reachable states of the program
</html:blockquote>
                                <html:p>
  Formally we can say if <fr:tex display="inline"><![CDATA[P]]></fr:tex> denotes our property and <fr:tex display="inline"><![CDATA[\mathcal  R]]></fr:tex> denotes our set of reachable states then we can say that <fr:tex display="inline"><![CDATA[P]]></fr:tex> is an invariant if:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \forall  \sigma , \sigma  \in  \mathcal  R \to  P(\sigma )
]]></fr:tex>
                                <html:p>
  An important thing to note here is that an invariant by itself does not need to be checkable or syntactic in any sense, there are <html:strong>no requirements</html:strong> that <fr:tex display="inline"><![CDATA[P]]></fr:tex> must imply after each step. The distinction here is important because we can have something be an invariant though be insufficient as a proof rule.
</html:p>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>6</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004e/</fr:uri>
                                <fr:display-uri>004e</fr:display-uri>
                                <fr:route>/notes/004e/</fr:route>
                                <fr:title text="Inductive Invariant">Inductive Invariant</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  An inductive invariant is a regular invariant, which is to say that it:
</html:p><html:blockquote>
  is a property which holds at all reachable states of the program
</html:blockquote><html:p>
  But it has the additional constraint that it must be <fr:link href="/notes/002e/" title="Closed set" uri="https://kaierikniermann.github.io/notes/002e/" display-uri="002e" type="local">closed</fr:link> under the transition relation. In other words if it holds before a step, it must also hold after the step. Formally we say that a property <fr:tex display="inline"><![CDATA[P]]></fr:tex> represents an <html:strong>inductive invariant</html:strong> if:
</html:p><html:ul><html:li>
    As a <html:em>base case</html:em> it holds at program initialization
    <fr:tex display="block"><![CDATA[
      \texttt {init} \to  P
    ]]></fr:tex></html:li>
  <html:li>
    In the <html:em>inductive step</html:em> we have
    <fr:tex display="block"><![CDATA[
      P(\sigma ) \land  (S, \sigma ) \to  \sigma ' \to  P(\sigma ')
    ]]></fr:tex>
    in plain English: If the property holds on the state <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex> and after the <html:em>small step evaluation</html:em> <fr:tex display="inline"><![CDATA[S]]></fr:tex> we land in a new state <fr:tex display="inline"><![CDATA[\sigma ']]></fr:tex> then the property also holds in the new state <fr:tex display="inline"><![CDATA[\sigma ']]></fr:tex>. 
  </html:li></html:ul><html:p>
  If both of the conditions hold then we we automatically have that:
</html:p><fr:tex display="block"><![CDATA[
  \sigma  \in  \mathcal  R.\ P(\sigma )
]]></fr:tex><html:p>
  Which is to say that these conditions imply an inductive invariant is also an invariant. The prime example where we can see this is in the case of the while loop for hoare logic:
</html:p>
  
    
    <fr:resource hash="ce0d0a8b1cdc6f924015d66fdf7cfd17"><fr:resource-content><html:img src="/notes/ce0d0a8b1cdc6f924015d66fdf7cfd17.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule *[right=While]{
    \vdash  \{I \land  b\}\ s\ \{I\}
  }{
    \vdash  \{I\}\ \texttt {while}\ b\ \texttt {do}\ s\ \{I \land  \neg  b\}
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
  Here the invariant is represented by the assertion <fr:tex display="inline"><![CDATA[I]]></fr:tex> on the memory state. What this rule says is that:
</html:p><html:ul><html:li>
    If the assertion <fr:tex display="inline"><![CDATA[I]]></fr:tex> and the loop guard <fr:tex display="inline"><![CDATA[b]]></fr:tex> hold, and upon termination of <fr:tex display="inline"><![CDATA[s]]></fr:tex> we have that <fr:tex display="inline"><![CDATA[I]]></fr:tex> holds.
  </html:li>
  <html:li>
    Then we can lift the invariant out of the loop and say that it must hold for all loop iterations and upon termination of the loop we clearly have that our loop guard must be false and our invariant should still hold.
  </html:li></html:ul><html:p>
  This corresponds precisely to the notion of an <html:em>inductive</html:em> invariant as if we can demonstrate it holding for the execution and termination of a single statement - the base case - then we can derive the inductive case where it holds for all iterations.
</html:p></fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>7</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004g/</fr:uri>
                                <fr:display-uri>004g</fr:display-uri>
                                <fr:route>/notes/004g/</fr:route>
                                <fr:title text="Finding inductive invariants">Finding inductive invariants</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Consider the following statement <fr:tex display="inline"><![CDATA[W]]></fr:tex>:
</html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
  while x &lt; n do
    x := y;
    y := x + 1 
</html:code></html:pre><html:p>
  Say that we wanted to prove the following Hoare triple:
</html:p><fr:tex display="block"><![CDATA[
  \{x = 0 \land  y = 1\}\ W\ \{x \geq  0\}
]]></fr:tex><html:p>
  What is an inductive invariant <fr:tex display="inline"><![CDATA[I]]></fr:tex> which allows us to prove the triple?
</html:p>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>7</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:p>
    For reference lets pull up the while rule again:
  </html:p>
  
  
    
    <fr:resource hash="510feb572ccb159e80172c821612b9ea"><fr:resource-content><html:img src="/notes/510feb572ccb159e80172c821612b9ea.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=While]{
      \vdash  \{I \land  b\}\ s\ \{I\}
    }{
      \vdash  \{I\}\ \texttt {while}\ b\ \texttt {do}\ s\ \{I \land  \neg  b\}
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  

  <html:p>
    One not entirely unreasonable albiet simple choice is to try out the post condition <fr:tex display="inline"><![CDATA[x \geq  0]]></fr:tex>, its not too uncommon that a valid postcondition - or more often a variant of it - are in fact valid loop invariants. Testing this out it means we would have to prove the body:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \vdash  \{x \geq  0 \land  x < n\}\ x := y; y := x + 1\ \{x \geq  0\}
  ]]></fr:tex>
  <html:p>
    To see if this is inductive we can try and find a counterexample to demonstrate its not, and indeed we can see that <fr:tex display="inline"><![CDATA[\sigma  = \{y \mapsto  -1000, x \mapsto  1, n \mapsto  2 \}]]></fr:tex> would mean that <fr:tex display="inline"><![CDATA[P(\sigma )]]></fr:tex> would hold, and we could indeed step to a state <fr:tex display="inline"><![CDATA[\sigma ']]></fr:tex> though clearly we have that:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \sigma ' \ \mathrlap {\,/}{\vDash }\ (x \geq  0)[x \mapsto  -1000]
  ]]></fr:tex>
  <html:p>
    Since we can see here that the unconstrained <fr:tex display="inline"><![CDATA[y]]></fr:tex> is causing is issues lets go with:
  </html:p>
  <fr:tex display="block"><![CDATA[
    I \triangleq  x \geq  0 \land  y = x + 1
  ]]></fr:tex>
  <html:p>
    Since this ensures that <fr:tex display="inline"><![CDATA[y]]></fr:tex> is correctly related to <fr:tex display="inline"><![CDATA[x]]></fr:tex> it means that we indeed have that
    <fr:tex display="block"><![CDATA[
      \sigma  \vDash  I (x := y; y := x + 1, \sigma ) \to  \sigma ' \to  \sigma ' \vDash  I
    ]]></fr:tex>
    as desired
  </html:p>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>6</fr:day>
                            </fr:date>
                            <fr:title text="Arrays &amp; Invariants">Arrays &amp; Invariants</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003l/</fr:uri>
                                <fr:display-uri>003l</fr:display-uri>
                                <fr:route>/notes/003l/</fr:route>
                                <fr:title text="Theory of Arrays">Theory of Arrays</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  The theory of arrays is a first-order theory that models arrays as functions from indices to values. Its signature includes:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \Sigma _A \triangleq  \{- [ - ], \langle  - \triangleleft  - \rangle , =\}
]]></fr:tex>
                                <html:p>
  where:
</html:p>
                                <html:ul><html:li><fr:tex display="inline"><![CDATA[-[ - ]]]></fr:tex>: read operation, which takes an array and an index and returns the value at that index.
  </html:li>
  <html:li><fr:tex display="inline"><![CDATA[\langle  - \triangleleft  - \rangle ]]></fr:tex>: write operation, which takes an array, an index, and a
    value, and returns a new array with the value at the specified index updated.
  </html:li>
  <html:li><fr:tex display="inline"><![CDATA[=]]></fr:tex>: equality relation, which checks if two arrays are identical.
  </html:li></html:ul>
                                <html:p>
  The axioms of the theory of arrays are:
</html:p>
                                <fr:resource hash="8ff9653ef4ba489edcda34b8856e7a7b">
                                  <fr:resource-content>
                                    <html:img src="/notes/8ff9653ef4ba489edcda34b8856e7a7b.svg" />
                                  </fr:resource-content>
                                  <fr:resource-source type="latex" part="preamble"><![CDATA[
  \usepackage {eulervm}
  \usepackage {amsmath}
]]></fr:resource-source>
                                  <fr:resource-source type="latex" part="body"><![CDATA[
    \begin{align*}
    \forall a, i, v.\; [a \langle i \triangleleft v \rangle][i] &= v \quad \tag{Read-Over-Write 1} \\
    \forall a, i, j, v.\; i \neq j \implies [a \langle i \triangleleft v \rangle][j] &= a[j] \quad \tag{Read-Over-Write 2} \\
    \forall a, b.\; (\forall i.\; a[i] = b[i]) &\implies a = b \quad \tag{Extensionality}
  \end{align*}
]]></fr:resource-source>
                                </fr:resource>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>7</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004i/</fr:uri>
                                <fr:display-uri>004i</fr:display-uri>
                                <fr:route>/notes/004i/</fr:route>
                                <fr:title text="A hypothetical array inference rule">A hypothetical array inference rule</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Say we want to add arrays to our programming language, and we come up with the following inference rule to reason about assignments:
</html:p>
  
    
    <fr:resource hash="ac752829cdc3421250a0155d7991fa94"><fr:resource-content><html:img src="/notes/ac752829cdc3421250a0155d7991fa94.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule {}{
    \vdash  \{Q[a[e_1] \mapsto  e_2]\}\ a[e_1] := e_2\ \{Q\}
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
  Is this rule correct?
</html:p>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>7</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:p>
    There are a few ways we can answer this, starting in with the most pedantic let's construct the proof tree and then see if we can come up with a counter example, we consider the following hoare triple:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \{i = 1\}\ a[i] := 3; a[1] := 2\ \{a[i] = 3\}
  ]]></fr:tex>
  <html:p>
    By the sequence and precondition strengthening rule we have that
  </html:p>
  
  
    
    <fr:resource hash="40b0fd9b78430a73fece6d0c9349d8be"><fr:resource-content><html:img src="/notes/40b0fd9b78430a73fece6d0c9349d8be.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule {
      \vdash  \{i = 1 \to  3 = 3\}\ a[i] := 3\ \{a[i] = 3\} \\ 
      \vdash  \{a[i] = 3\}\ a[1] = 2\ \{a[i] = 3\}
    }{
      \vdash  \{i = 1\}\ a[i] := 3; a[1] := 2\ \{a[i] = 3\}
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  

  <html:p>
    Of note here we are deriving <fr:tex display="inline"><![CDATA[i = 1]]></fr:tex> through the following implications:
  </html:p>
  <fr:tex display="block"><![CDATA[
    Q[a[i] \mapsto  3] \equiv  (a[i] = 3)[a[i] \mapsto  3] \equiv  (3 = 3) \equiv  \top 
  ]]></fr:tex>
  <html:p>
    Where we know that <fr:tex display="inline"><![CDATA[i = 1 \to  \top ]]></fr:tex> so we can use precondition strengthening to use <fr:tex display="inline"><![CDATA[i = 1]]></fr:tex> as our precondition since it implies something we've already syntactically demonstrated to be provable.
  </html:p>
  <html:p>
    Clearly we have that the first assignment in the sequence holds by the naive assignment, same for the second assignment <fr:tex display="inline"><![CDATA[a[1] = 2]]></fr:tex> since it precondition reduces to the tautology <fr:tex display="inline"><![CDATA[\top ]]></fr:tex>, so the final rule is then derivable. But we can obviously see that it erroneously assumes that <fr:tex display="inline"><![CDATA[i]]></fr:tex> represents some kind of distinct index but, we can see that in the second assignment its aliased by the constant index <fr:tex display="inline"><![CDATA[1]]></fr:tex> which means that while we can derive the rule it is <html:em>not semantically valid</html:em> hence unsound.
  </html:p>
  <html:p>
    To compare this with the correct rule we have that:
  </html:p>
  
  
    
    <fr:resource hash="395f1fa21ead978e4709be636110ea8e"><fr:resource-content><html:img src="/notes/395f1fa21ead978e4709be636110ea8e.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule {
    }{
      \vdash  \{Q[a \mapsto  a \langle  e_1 \lhd  e_2 \rangle ]\}\ a[e_1] := e_2\ \{Q\}
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  

  <html:p>
    Now again let's try to derive the hoare triple we want to prove correct:
  </html:p>
  
  
    
    <fr:resource hash="389e6242b715dad6f6b3a142c523e5d5"><fr:resource-content><html:img src="/notes/389e6242b715dad6f6b3a142c523e5d5.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule {
      \vdash  \{i = 1\}\ a[i] := 3\ \{R\} \\
      \vdash  \{R\}\ a[1] := 3\ \{a[i] := 3\}
    }{
      \vdash  \{i = 1\}\ a[i] := 3; a[1] := 2\ \{a[i] = 3\}
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  

  <html:p>
    To derive we want to find some assertion <fr:tex display="inline"><![CDATA[R]]></fr:tex>, applying the correct assignment rule to the second assignment we define <fr:tex display="inline"><![CDATA[R]]></fr:tex> as.
  </html:p>
  <fr:tex display="block"><![CDATA[
    R \equiv  (a[i] := 3)[a \mapsto  a \langle  1 \lhd  2 \rangle ]
  ]]></fr:tex>
  <html:p>
    we can think of this as defining the function:
  </html:p>
  <fr:tex display="block"><![CDATA[
    a'(j) = \begin {cases}
      2 & \texttt {if}\ j = 1 \\
      a(j) & \text {otherwise}
    \end {cases}
  ]]></fr:tex>
  <html:p>
    we can then do a case split on the equality <fr:tex display="inline"><![CDATA[i = 1]]></fr:tex> using our defined function
  </html:p>
  <html:ol><html:li>
      If <fr:tex display="inline"><![CDATA[i = 1]]></fr:tex> then we have
      <fr:tex display="block"><![CDATA[
        a'[i] = a[1] = 2 \to  a'[i] = 3 \equiv  2 = 3 \equiv  \bot 
      ]]></fr:tex></html:li>
    <html:li>
      If <fr:tex display="inline"><![CDATA[i \ \mathrlap {\,/}{=}\ 1]]></fr:tex> we have
      <fr:tex display="block"><![CDATA[
        a'[i] = a[i] \to  a'[i] = 3 \equiv  a[i] = 3
      ]]></fr:tex></html:li></html:ol>
  <html:p>
    Since it clearly must be the case that <fr:tex display="inline"><![CDATA[i \ \mathrlap {\,/}{=}\ 1]]></fr:tex> it implies that our assertion <fr:tex display="inline"><![CDATA[R]]></fr:tex> is equivalent to:
  </html:p>
  <fr:tex display="block"><![CDATA[
    R \equiv  (i \ \mathrlap {\,/}{=}\ 1\land  a[i] = 3)
  ]]></fr:tex>
  <html:p>
    Now testing this rule on the first hoare triple:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \{i = 1\}\ a[i] := 3\ \{i \ \mathrlap {\,/}{=}\ 1\land  a[i] = 3\}
  ]]></fr:tex>
  <html:p>
    By the assignment rule we must somehow be able to derive <fr:tex display="inline"><![CDATA[i = 1]]></fr:tex> from the following:
  </html:p>
  <fr:tex display="block"><![CDATA[
    R[a \mapsto  a \langle  i \lhd  3 \rangle ]
  ]]></fr:tex>
  <html:p>
    substituting in our <fr:tex display="inline"><![CDATA[R]]></fr:tex> we get
  </html:p>
  <fr:tex display="block"><![CDATA[
    (i \ \mathrlap {\,/}{=}\ 1\land  a[i] = 3)[a \mapsto  a \langle  i \lhd  3 \rangle ]
  ]]></fr:tex>
  <html:p>
    after a reduction we have
  </html:p>
  <fr:tex display="block"><![CDATA[
    (i \ \mathrlap {\,/}{=}\ 1 \land  \underbrace {(a \langle  i \lhd  3 \rangle [i] = 3)}_{\top })
  ]]></fr:tex>
  <html:p>
    simplifying this we get
  </html:p>
  <fr:tex display="block"><![CDATA[
    (i \ \mathrlap {\,/}{=}\  1)
  ]]></fr:tex>
  <html:p>
    Which is where the crux of our issue lies, the precondition of our Hoare triple was <fr:tex display="inline"><![CDATA[i = 1]]></fr:tex>, but clearly here to derive our sequence of assignments we must have that i is not 1, hence this hoare triple is not derivable as its also clearly not valid.
  </html:p>
  <html:p>
    A simpler approach at establishing the same idea is by just directly working backwards
  </html:p>
  <fr:tex display="block"><![CDATA[
    \begin {align}
    a \langle  1 \lhd  2 \rangle [i] & = 3 \\
    a \langle  i \lhd  3 \rangle  \langle  1 \lhd  2 \rangle [i] & = 3
    \end {align}
  ]]></fr:tex>
  <html:p>
    so first we substitute <fr:tex display="inline"><![CDATA[a]]></fr:tex> for the assignment <fr:tex display="inline"><![CDATA[a[1] := 2]]></fr:tex>, then we update it for the assignment <fr:tex display="inline"><![CDATA[a[i] := 3]]></fr:tex>, then our precondition would imply that:
  </html:p>
  <fr:tex display="block"><![CDATA[
    i = 1 \to  a \langle  i \lhd  3 \rangle  \langle  1 \lhd  2 \rangle [i] = 3
  ]]></fr:tex>
  <html:p>
    We indeed cannot derive the triple with the precondition, as it should be trivially apparent that if <fr:tex display="inline"><![CDATA[i = 1]]></fr:tex> after overwriting with <fr:tex display="inline"><![CDATA[a[1] = 2]]></fr:tex> we clearly cannot have <fr:tex display="inline"><![CDATA[a[1] = 3]]></fr:tex>.
  </html:p>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>2</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/003m/</fr:uri>
                                <fr:display-uri>003m</fr:display-uri>
                                <fr:route>/notes/003m/</fr:route>
                                <fr:title text="Theory of arrays T_A">Theory of arrays <fr:tex display="inline"><![CDATA[T_A]]></fr:tex></fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Which of the following formula is valid/satisfiable/unsatisfiable ?
</html:p><html:ol><html:li><fr:tex display="inline"><![CDATA[a[3] = 2]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[a \langle  3 \triangleleft  5 \rangle [3] = 5]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[a \langle  3 \triangleleft  5 \rangle [3] = 3]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[a[3] = 2\land  a \langle  3 \triangleleft  5 \rangle [3] = 5]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>2</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      This formula is <html:strong>satisfiable</html:strong>. For example, if we have an array <fr:tex display="inline"><![CDATA[a]]></fr:tex> such that <fr:tex display="inline"><![CDATA[a[3] = 2]]></fr:tex>, then the formula holds true.
    </html:li>
    <html:li>
      This formula is <html:strong>valid</html:strong>. According to the Read-Over-Write axiom, when we write a value to an index in an array and then read from that same index, we get the value we just wrote. So regardless of the initial contents of array <fr:tex display="inline"><![CDATA[a]]></fr:tex>, after performing the write operation <fr:tex display="inline"><![CDATA[a \langle  3 \triangleleft  5 \rangle ]]></fr:tex>, reading from index <fr:tex display="inline"><![CDATA[3]]></fr:tex> will always yield <fr:tex display="inline"><![CDATA[5]]></fr:tex> hence making it always true (valid).
    </html:li>
    <html:li>
      This formula is <html:strong>unsatisfiable</html:strong>. According to the Read-Over-Write axiom, when we write a value to an index in an array and then read from that same index, we get the value we just wrote. Therefore, after performing the write operation <fr:tex display="inline"><![CDATA[a \langle  3 \triangleleft  5 \rangle ]]></fr:tex>, reading from index <fr:tex display="inline"><![CDATA[3]]></fr:tex> will always yield <fr:tex display="inline"><![CDATA[5]]></fr:tex>, making it impossible for it to equal <fr:tex display="inline"><![CDATA[3]]></fr:tex>.
    </html:li>
    <html:li>
      This formula is <html:strong>satisfiable</html:strong>. For example, if we have an array <fr:tex display="inline"><![CDATA[a]]></fr:tex> such that <fr:tex display="inline"><![CDATA[a[3] = 2]]></fr:tex>, then after performing the write operation <fr:tex display="inline"><![CDATA[a \langle  3 \triangleleft  5 \rangle ]]></fr:tex>, reading from index <fr:tex display="inline"><![CDATA[3]]></fr:tex> will yield <fr:tex display="inline"><![CDATA[5]]></fr:tex>. Thus, both parts of the conjunction can be true simultaneously though are not valid in all interpretations.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>10</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004j/</fr:uri>
                                <fr:display-uri>004j</fr:display-uri>
                                <fr:route>/notes/004j/</fr:route>
                                <fr:title text="Finding inductive invariants - arrays">Finding inductive invariants - arrays</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Consider the following while loop <fr:tex display="inline"><![CDATA[W]]></fr:tex>:
</html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
  while i &lt; n do
    a[i] := 0;
    i    := i + 1
</html:code></html:pre><html:p>
  Consider the following pre-and-post condition:
</html:p><fr:tex display="block"><![CDATA[
  \{i = 0 \land  n > 0\}\ W\ \{\forall  j.\ 0 \leq  j < n \to  a[j] = 0\}
]]></fr:tex><html:p>
  What is an inductive invariant that shows correctness?
</html:p>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>10</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:p>
    This is almost a sort of canonical example where the index replacement trick works really nicely. On a high level our postcondition asserts something about the array over the first <fr:tex display="inline"><![CDATA[n]]></fr:tex> indices, hence if we want to have an invariant which shows correctness, we can simply reframe our postcondition as an assertion up to the <fr:tex display="inline"><![CDATA[i]]></fr:tex>th position / iteration, in other words we simply replace <fr:tex display="inline"><![CDATA[n]]></fr:tex> with <fr:tex display="inline"><![CDATA[i]]></fr:tex>:
  </html:p>
  <fr:tex display="block"><![CDATA[
    \forall  j.\ 0 \leq  j < i \to  a[j] = 0
  ]]></fr:tex>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>6</fr:day>
                            </fr:date>
                            <fr:title text="Soundness &amp; Completeness">Soundness &amp; Completeness</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>5</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0041/</fr:uri>
                                <fr:display-uri>0041</fr:display-uri>
                                <fr:route>/notes/0041/</fr:route>
                                <fr:title text="Soundness &amp; Completeness - Hoare triples">Soundness &amp; Completeness - Hoare triples</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  In a very general sense if we have a logical or formal system a core idea is that we only want to prove things that are actually true, and conversely if we find something that is true we would want to be able to prove it. This leads to two important properties of formal systems:
</html:p>
                                <html:ul><html:li><html:strong>Soundness</html:strong> is the property that everything provable within the system is in fact true, within the context of hoare logic it means that all hoare triples which we can syntactically derive using our inference rules are by implication valid (i.e. true in all interpretations), formally:
    <fr:tex display="block"><![CDATA[
      \vdash  \{P\}\ s\ \{Q\} \to \ \vDash  \{P\}\ s\ \{Q\}
    ]]></fr:tex></html:li>
  <html:li><html:strong>Completeness</html:strong> is the property that everything that is true can be proven within the system, in the context of hoare logic it means that all valid hoare triples can be syntactically derived using our inference rules, formally:
    <fr:tex display="block"><![CDATA[
      \vDash  \{P\}\ s\ \{Q\} \to \ \vdash  \{P\}\ s\ \{Q\}
    ]]></fr:tex></html:li></html:ul>
                              </fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>6</fr:day>
                            </fr:date>
                            <fr:title text="Weakest precondition">Weakest precondition</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>10</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004k/</fr:uri>
                                <fr:display-uri>004k</fr:display-uri>
                                <fr:route>/notes/004k/</fr:route>
                                <fr:title text="Working backwards - weakest precondition">Working backwards - weakest precondition</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  I'll split this explanation into 3 parts, first the basic intuition, then the pen-and-paper reasoning, and finally a more granular explanation.
</html:p>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2025</fr:year>
                                      <fr:month>12</fr:month>
                                      <fr:day>10</fr:day>
                                    </fr:date>
                                    <fr:title text="The idea">The idea</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>
    Say we want to verify a hoare triple <fr:tex display="inline"><![CDATA[\{P\}\ s\ \{Q\}]]></fr:tex>, the <html:em>weakest precondition</html:em> approach is that we:
  </html:p>
                                    <html:ol><html:li>
      Start with our postcondition <fr:tex display="inline"><![CDATA[Q]]></fr:tex> and, going backwards, we compute a formula <fr:tex display="inline"><![CDATA[\texttt {wp}(s, Q)]]></fr:tex> called the <html:em>weakest precondition</html:em> of <fr:tex display="inline"><![CDATA[Q]]></fr:tex> w.r.t the statement <fr:tex display="inline"><![CDATA[s]]></fr:tex>.
    </html:li>
    <html:li><fr:tex display="inline"><![CDATA[\texttt {wp}(s, Q)]]></fr:tex> has the property that it's the weakest condition which <html:strong>guarantees that</html:strong> <fr:tex display="inline"><![CDATA[Q]]></fr:tex> will hold after the termination of <fr:tex display="inline"><![CDATA[s]]></fr:tex>.
    </html:li></html:ol>
                                    <html:p>
    Therefore we can say that the triple is valid:
  </html:p>
                                    <fr:tex display="block"><![CDATA[
    \vDash  \{P\}\ s\ \{Q\} \iff  P \to  \texttt {wp}(s, Q)
  ]]></fr:tex>
                                  </fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2025</fr:year>
                                      <fr:month>12</fr:month>
                                      <fr:day>10</fr:day>
                                    </fr:date>
                                    <fr:title text="The basic rules">The basic rules</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>
    The basic rules can be recursively defined as follows:
  </html:p>
                                    <html:ul><html:li>
      For <html:strong>assignments</html:strong>:
      <fr:tex display="block"><![CDATA[
        \texttt {wp}(x := e, Q) \triangleq  Q[x \mapsto  e]
      ]]></fr:tex></html:li>
    <html:li>
      For <html:strong>composition</html:strong>
      <fr:tex display="block"><![CDATA[
        \texttt {wp}(s_1; s_2, Q) \triangleq  \texttt {wp}(s_1, \texttt {wp}(s_2, Q))
      ]]></fr:tex></html:li>
    <html:li>
      For <html:strong>conditionals</html:strong>
      <fr:tex display="block"><![CDATA[
        \texttt {wp}(\texttt {if}\ b\ \texttt {then}\ s_1\ \texttt {else}\ s_2, Q) \triangleq  (b \to  \texttt {wp}(s_1, Q)) \land  (\neg  b \to  \texttt {wp}(s_2, Q))
      ]]></fr:tex></html:li></html:ul>
                                  </fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2025</fr:year>
                                      <fr:month>12</fr:month>
                                      <fr:day>10</fr:day>
                                    </fr:date>
                                    <fr:title text="The more detailed reasoning">The more detailed reasoning</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter><html:p>
    As a reminder, a Hoare triple:
  </html:p><fr:tex display="block"><![CDATA[
    \{P\}\ s\ \{Q\}
  ]]></fr:tex><html:p>
    Is simply a kind of syntax sugar for the logical formula:
  </html:p><fr:tex display="block"><![CDATA[
    \forall  \sigma , \sigma '.\ P(\sigma ) \to  (s, \sigma ) \Downarrow  \sigma ' \to  Q(\sigma )
  ]]></fr:tex><html:p>
    So for all source and target states, if we terminate on <fr:tex display="inline"><![CDATA[s]]></fr:tex> then <fr:tex display="inline"><![CDATA[Q]]></fr:tex> holds. Additionally, for different kinds of expressions we also have our constructions rules to ensure soundness, take for example assignment, our rule to only derive valid Hoare triples was:
  </html:p>
  
    
    <fr:resource hash="1f706d41965394f91a10df6073b856ca"><fr:resource-content><html:img src="/notes/1f706d41965394f91a10df6073b856ca.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule {}{
      \vdash  \{Q[x \mapsto  e]\}\ x := e\ \{Q\}
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
    If we assume <fr:tex display="inline"><![CDATA[e]]></fr:tex> to be some variable expression in a context <fr:tex display="inline"><![CDATA[\sigma  : \texttt {Vars} \to  \mathbb {Z}]]></fr:tex> which has to evaluate to a number before assignment then we can write the above rule more pedantically as:
  </html:p><fr:tex display="block"><![CDATA[
    \forall  \sigma , \sigma '.\ (\forall  n : \mathbb {Z}.\ (e, \sigma ) \Downarrow  n \to  Q[x \mapsto  n]) \to  (x := e, \sigma ) \Downarrow  \sigma ' \to  Q(\sigma ')
  ]]></fr:tex><html:p>
    The idea of backwards reasoning here is as follows:
  </html:p><html:ol><html:li>
      First we look at the big step evaluation <fr:tex display="inline"><![CDATA[(x := e, \sigma ) \Downarrow  \sigma ']]></fr:tex>, we know that if this assignment succeeded, it implies there must have been a successful evaluation of the <fr:tex display="inline"><![CDATA[e]]></fr:tex> term, we know this because the only way to have derived this step is by the following inference rule:
      
  
    
    <fr:resource hash="6c10f3f9ee55204e9496b67ae3f5df55"><fr:resource-content><html:img src="/notes/6c10f3f9ee55204e9496b67ae3f5df55.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
        \inferrule {
          \vdash  \forall  n.\ \langle  e, \sigma  \rangle  \Downarrow  n
        }{
          \vdash  \langle  x := e, \sigma  \rangle  \Downarrow  \sigma [x \mapsto  n]
        }
      \end {mathpar}]]></fr:resource-source></fr:resource></html:li>
    <html:li>
      Using what we've learned from (1) we apply the notion of inversion, i.e. if we know a conclusion to be true, we can assert the premises of that conclusion must have also been true, this in a sense gives us the premises to use as new judgements.
    </html:li>
    <html:li>
      Now looking at the expression
      <fr:tex display="block"><![CDATA[
        \forall  n : \mathbb {Z},.\ (e, \sigma ) \Downarrow  n \to  Q[x \mapsto  n]
      ]]></fr:tex>
      we can clearly derive the precondition <fr:tex display="inline"><![CDATA[Q[x \mapsto  n]]]></fr:tex> since we know the antecedent <fr:tex display="inline"><![CDATA[\forall  n.\ (e, \sigma ) \Downarrow  n]]></fr:tex> is true, as it must have been true to derive the big step evaluation.
    </html:li>
    <html:li>
      Since we have now demonstrated we can indeed provide sufficient reasoning to arrive at our conclusion <fr:tex display="inline"><![CDATA[Q(\sigma ')]]></fr:tex> this finishes the proof.
    </html:li></html:ol><html:p>
    The shorthand of the <html:em>weakest precondition</html:em> is nothing more than an expression of precisely this idea in a more concise fashion. Take for example <fr:tex display="inline"><![CDATA[\texttt {if conditions}]]></fr:tex>.
  </html:p><html:ol><html:li>
      We again start from our post-condition then proceed with a case split or more accurately an inversion on the evaluation rule.
    </html:li>
    <html:li>
      The inversion naturally gives us two branches, the true and false branch. This represents the conjunction here, then with each conjunct the antecedent of the implication is represented by the true or false guard condition <fr:tex display="inline"><![CDATA[b]]></fr:tex>, the consequent in this instance is simply a recursive call on the <fr:tex display="inline"><![CDATA[\texttt {then}]]></fr:tex> and <fr:tex display="inline"><![CDATA[\texttt {else}]]></fr:tex> branch bodies.
    </html:li></html:ol><html:p>
    The main thing I'm trying to drive home here is that the weakest precondition idea is fundamentally just based on the concept of:
  </html:p><html:ol><html:li>
      Seeing how a term must have been derived
    </html:li>
    <html:li>
      Recursively going up the chain of any other sub-terms
    </html:li></html:ol><html:p>
    So in a straightforward way, it's nothing more than chaining together all the individual proof rules for the various hoare triples. To show an example in lean using a some nice macros to create a simple syntax:
  </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
    example (n : Num) : 
    {{ ⟦ "x" ↦ n ⟧ }} 
      tm{ x := x + 1 } 
    {{ ⟦ "x" ↦ n + 1 ⟧ }} := by
    apply Hoare.assign'
    intro σ m hpre heval
    cases heval with
    | sum he1 he2 =&gt;
      cases he1; cases he2
      simp [hpre]
  </html:code></html:pre><html:p>The hoare triple we are proving here corresponds to this in the normal syntax:</html:p><fr:tex display="block"><![CDATA[
    \{x \mapsto  n \}\ x := x + 1\ \{x \mapsto  n + 1\}
  ]]></fr:tex><html:p>
    We can see here to "prove" this hoare triple was valid we started by doing our standard case split on the assign - that's the <fr:tex display="inline"><![CDATA[\texttt {apply Hoare.assign'}]]></fr:tex> - statement, then we were inside the addition, here we did a case split which gave us the lhs and rhs we were adding, after doing a case split on those two sides we could finally just simplify (and finalize) our proof using the fact that in <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex> <fr:tex display="inline"><![CDATA[x]]></fr:tex> evaluates to <fr:tex display="inline"><![CDATA[n]]></fr:tex>.
  </html:p></fr:mainmatter>
                                </fr:tree>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>10</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004m/</fr:uri>
                                <fr:display-uri>004m</fr:display-uri>
                                <fr:route>/notes/004m/</fr:route>
                                <fr:title text="Weakest precondition - while loop"><fr:link href="/notes/004k/" title="Working backwards - weakest precondition" uri="https://kaierikniermann.github.io/notes/004k/" display-uri="004k" type="local">Weakest precondition</fr:link> - while loop</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  In an abstract sense the weakest precondition for while loops is no different from that for most other syntactic constructs, to reason backward we apply inversion to the statement we are considering; in this case the while loop; and then simply recurse on the sub-terms. Though the while loop differentiates itself through the notion of invariants.
</html:p><html:p>
  Before we define how to compute the weakest precondition let's define the hoare rule again:
</html:p>
  
    
    <fr:resource hash="4f95541c155792a37a075207cfb1dad0"><fr:resource-content><html:img src="/notes/4f95541c155792a37a075207cfb1dad0.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule {
    \vdash  \{I \land  b\}\ s\ \{I\}
  }{
    \vdash  \{I\}\ \texttt {while}\ b\ \texttt {do}\ s\ \{I \land  \neg  b\}
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
  The central thing to observe here is the invariant hypothesis which acts as the premise for the while loop formation, if we write expand it out a bit we get:
</html:p><fr:tex display="block"><![CDATA[
  \{I(\sigma ) \land  b \Downarrow ^t \sigma \}\ s\ \{I\}
]]></fr:tex><html:p>
  So the idea, to reiterate again, is that if our invariant holds in the state <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex> and our loop condition evaluates to <fr:tex display="inline"><![CDATA[\texttt {true}]]></fr:tex>, then upon termination of <fr:tex display="inline"><![CDATA[s]]></fr:tex> i.e. the loop body we have that the invariant <fr:tex display="inline"><![CDATA[I]]></fr:tex> still holds.
</html:p><html:ol><html:li>
    In the false case our proof becomes trivial through inversion we know there is some terminating state <fr:tex display="inline"><![CDATA[\sigma _t]]></fr:tex> and we know the loop condition must have evaluated to false, hence we can immediately provide the conditions to fulfill the postcondition and thus create our valid hoare triple.
  </html:li>
  <html:li>
    The true case is a bit more complex, first let's look at the evaluation semantics for it
    
  
    
    <fr:resource hash="0b6c171b9d9141496d070da4344f4b9f"><fr:resource-content><html:img src="/notes/0b6c171b9d9141496d070da4344f4b9f.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
      \inferrule *[right=S-WhileTrue]{
        \langle  b, \sigma _1 \rangle  \Downarrow  \texttt {true} \\
        \langle  s, \sigma _1 \rangle  \Downarrow  \sigma _2\\
        \langle  \texttt {while } b \texttt { do } s, \sigma _2\rangle  \Downarrow  \sigma _3
      }{
        \langle  \texttt {while } b \texttt { do } s, \sigma _1 \rangle  \Downarrow  \sigma _3
      }
    \end {mathpar}]]></fr:resource-source></fr:resource>
  

    We can see the final state is <fr:tex display="inline"><![CDATA[\sigma _3]]></fr:tex> this means that the post-condition we want to prove for the true state is 
    <fr:tex display="block"><![CDATA[
      I(\sigma _3) \land  b \Downarrow  ^f \sigma _3
    ]]></fr:tex>
    The main thing we leverage here is the invariant hypothesis, rewriting it as a function we have 
    <fr:tex display="block"><![CDATA[
      \lambda  (\sigma , \sigma ').\ \lambda ( I(\sigma ) \land  b \Downarrow ^f \sigma ).\ \lambda  ((c, \sigma ) \Downarrow  \sigma ').\ I(\sigma ')
    ]]></fr:tex>
    in addition to 
    <fr:tex display="block"><![CDATA[
      \lambda \sigma .\ \lambda  I(\sigma ).\ \lambda  (\langle  W, \sigma  \rangle  = \langle  W, \sigma _2 \rangle ).\ I(\sigma _3) \land  b \Downarrow ^f \sigma _3
    ]]></fr:tex>
    The idea is then that we use inversion to give us the evaluated terms, we plug those terms into the invariant hypothesis to get <fr:tex display="inline"><![CDATA[I(\sigma _2)]]></fr:tex>, then using <fr:tex display="inline"><![CDATA[\sigma _2]]></fr:tex>, <fr:tex display="inline"><![CDATA[I(\sigma _2)]]></fr:tex>, and reflexivity (since <fr:tex display="inline"><![CDATA[\langle  W, \sigma _2\rangle  \equiv  \langle  W, \sigma _2 \rangle ]]></fr:tex>) we have created the proof that the invariant holds for the final memory state and the loop guard indeed evaluates to false.
  </html:li></html:ol></fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>10</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004l/</fr:uri>
                                <fr:display-uri>004l</fr:display-uri>
                                <fr:route>/notes/004l/</fr:route>
                                <fr:title text="Computing weakest preconditions">Computing weakest preconditions</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Consider the following statement:
</html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
  x := y + 1;
  if x &gt; 0 then
    z := 1
  else
    z := -1
</html:code></html:pre><html:p>
  Answer the following questions:
</html:p><html:ol><html:li>
    What is <fr:tex display="inline"><![CDATA[\texttt {wp}(s, z > 0)]]></fr:tex></html:li>
  <html:li>
    What is <fr:tex display="inline"><![CDATA[\texttt {wp}(s, z \leq  0)]]></fr:tex></html:li>
  <html:li>
    Can we prove <fr:tex display="inline"><![CDATA[\{-1 \leq  y\}\ s\ \{z > 0\}]]></fr:tex></html:li>
  <html:li>
    What about <fr:tex display="inline"><![CDATA[\{y > -1\}\ s\ \{z > 0\}]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>10</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      In an abstract sense the statement is a sequence of an assignment and an if statement, starting with the if statement we get:
      <fr:tex display="block"><![CDATA[
        (x > 0) \to  \texttt {wp}(z := 1, Q) \land  (x \leq  0) \to  \texttt {wp}(z := -1, Q)
      ]]></fr:tex>
      Both of the assignments resolve to substitutions of 1 and -1, so we get 
      <fr:tex display="block"><![CDATA[
        (x > 0) \to  (z > 0)[z \mapsto  1] \land  (x \leq  0) \to  (z > 0)[z \mapsto  -1]
      ]]></fr:tex>
      With sequences we know it's a nested pattern, i.e. <fr:tex display="inline"><![CDATA[\texttt {wp}(s_1, \texttt {wp}(s_2, Q))]]></fr:tex>, the second argument we already have, we know that <fr:tex display="inline"><![CDATA[s_1]]></fr:tex> here is just the assignment, so again we apply the subtitution 
      <fr:tex display="block"><![CDATA[
        ((x > 0) \to  Q[z \mapsto  1] \land  (x \leq  0) \to  Q[z \mapsto  -1])[x \mapsto  (y + 1)]
      ]]></fr:tex>
      which reduces to 
      <fr:tex display="block"><![CDATA[
        \begin {align}
          ((y + 1 > 0) \to  (1 > 0) &\land  (y + 1 \leq  0) \to  (-1 > 0)) \\
          ((y + 1 > 0) \to  \top  &\land  (y + 1 \leq  0) \to  \bot ) \\
          ((y + 1 > 0) \to  \top  &\land  \neg (y + 1 \leq  0)) \\
          ((y + 1 > 0) \to  \top  &\land  (y + 1 > 0)) \\
          ((y + 1 > 0) \to  \top )& \\
          (y + 1 > 0)& \\
        \end {align}
      ]]></fr:tex></html:li>
    <html:li>
      To skip ahead a slight bit, so we have 
      <fr:tex display="block"><![CDATA[
        (x > 0) \to  (z \leq  0)[z \mapsto  1] \land  (x \leq  0) \to  (z \leq  0)[z \mapsto  -1]
      ]]></fr:tex>
      then substituting for the intial assignment of <fr:tex display="inline"><![CDATA[x]]></fr:tex>
      <fr:tex display="block"><![CDATA[
        (y + 1 > 0) \to  (1 \leq  0) \land  (y + 1 \leq  0) \to  (-1 \leq  0)
      ]]></fr:tex>
      Here we just end up in the reverse case, i.e. 
      <fr:tex display="block"><![CDATA[
        (y + 1 > 0) \to  (\bot ) \land  (y + 1 \leq  0) \to  \top 
      ]]></fr:tex>
      reduces now to 
      <fr:tex display="block"><![CDATA[
        (y + 1 \leq  0)
      ]]></fr:tex></html:li>
    <html:li>
      The high level idea here is that we computed the weakest precondition for <fr:tex display="inline"><![CDATA[z > 0]]></fr:tex> already, it was 
      <fr:tex display="block"><![CDATA[
        (y + 1 > 0)
      ]]></fr:tex>
      since it's the weakest we can only admit other preconditions if they imply the weakest one, so if we then look at the implication 
      <fr:tex display="block"><![CDATA[
        -1 > y \to  (y + 1 > 0)
      ]]></fr:tex>
      we can trivially see that this implication does not hold, i.e. we cannot apply precondition strengthening here hence the rule does not allow us to prove the hoare triple.
    </html:li>
    <html:li>Same reasoning as above, but now it works since 
      <fr:tex display="block"><![CDATA[
        y > -1 \to  y + 1 > 0
      ]]></fr:tex>
      indeed makes sense
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>11</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004n/</fr:uri>
                                <fr:display-uri>004n</fr:display-uri>
                                <fr:route>/notes/004n/</fr:route>
                                <fr:title text="Verification conditions in while loops">Verification conditions in while loops</fr:title>
                                <fr:taxon>Example</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  Let's consider the following while loop:
</html:p>
                                <html:pre class="code-block language-lean">
                                  <html:code class="language-lean">
  @pre x &lt;= 0
  while [x &lt;= 6] (x &lt;= 5) do
    x := x + 1
  @post x = 6
</html:code>
                                </html:pre>
                                <html:p>
  if we denote the loop and its body as <fr:tex display="inline"><![CDATA[W]]></fr:tex>, then it corresponds to the following hoare triple:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \{x \leq  0\}\ W\ \{x = 6\}
]]></fr:tex>
                                <html:p>
  With the addition of the invariant <fr:tex display="inline"><![CDATA[I \triangleq  x \leq  6]]></fr:tex>, now the verification condition for the loop is expressed as:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \begin {align}
    \texttt {vc}(W [I], x = 6) &= \forall  \sigma .\ I(\sigma ) \land  (b \Downarrow ^t \sigma ) \to  \texttt {wp}(W [I], s, I(\sigma )) \\
    &\land  \forall  \sigma .\ I(\sigma ) \land  (b \Downarrow ^f \sigma ) \to  Q(\sigma ) \\
    &\land  \texttt {vc}(s, I)
  \end {align}
]]></fr:tex>
                                <html:p>
  starting with the first conjunct with have:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \forall  \sigma , x \leq  6 \to  (x \leq  5 \Downarrow ^t \sigma ) \to  \texttt {wp}(x := x + 1, (x \leq  6))
]]></fr:tex>
                                <html:p>
  After we unfold the <fr:tex display="inline"><![CDATA[\texttt {wp}]]></fr:tex> our goal reduces to:
</html:p>
                                <fr:tex display="block"><![CDATA[
  x \mapsto  x + 1 \leq  6 \equiv  x \leq  5
]]></fr:tex>
                                <html:p>
  And we clearly know this is true just by inversion of the evaluation of the loop guard. Moving on to the second conjunct:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \forall  \sigma .\ x \leq  6 \land  (x \leq  5 \Downarrow ^f \sigma ) \to  x = 6
]]></fr:tex>
                                <html:p>
  This represents our termination condition, here we know by inversion of the loop guard again that the premise of our implication becomes:
</html:p>
                                <fr:tex display="block"><![CDATA[
  x \leq  6 \land  x > 5 \to  x = 6
]]></fr:tex>
                                <html:p>
  Our final conjunct is the verification condition on the assignment, so:
</html:p>
                                <fr:tex display="block"><![CDATA[
  \texttt {vc}(x := x + 1, x \leq  6)
]]></fr:tex>
                                <html:p>
  Unfolding the call again we know this just resolves to <fr:tex display="inline"><![CDATA[\top ]]></fr:tex> as there are no verification conditions for assignment.
</html:p>
                                <html:p>
  Finally we also have to demonstrate that:
</html:p>
                                <fr:tex display="block"><![CDATA[
  (x \leq  0 \land  x = x_0) \to  \texttt {wp}(W [I], Q)
]]></fr:tex>
                                <html:p>
  unfolding the <fr:tex display="inline"><![CDATA[\texttt {wp}]]></fr:tex> again gives
</html:p>
                                <fr:tex display="block"><![CDATA[
  (x \leq  0 \land  x = x_0) \to  x \leq  6
]]></fr:tex>
                                <html:p>
  Clearly we can see this trivially holds, i.e. our precondition is stronger than the invariant, hence by precondition strengthening, it is valid.
</html:p>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2025</fr:year>
                                      <fr:month>12</fr:month>
                                      <fr:day>11</fr:day>
                                    </fr:date>
                                    <fr:title text="How do we get there though?">How do we get there though?</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter><html:p>
    I do think it's worth telling this as a bit of a story, we start with the fundamental theorem for while loops:
  </html:p>
  
    
    <fr:resource hash="f42c13c5bc0c06965aac3d8a53b4374b"><fr:resource-content><html:img src="/notes/f42c13c5bc0c06965aac3d8a53b4374b.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=HWhile]{
      \forall  \sigma , \sigma '.\ I(\sigma ) \land  (b \Downarrow ^t \sigma ) \to  (s, \sigma ) \Downarrow  \sigma ' \to  P(\sigma )
    }{
      \forall  \sigma , \sigma '.\ I(\sigma ) \to  (\texttt {while}\ b\ \texttt {do}\ s, \sigma ) \Downarrow  \sigma ' \to  I(\sigma ) \land  (b \Downarrow ^f \sigma ) 
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
    So this is just the expanded rule for constructing valid or sound while hoare triples, now this rule assumes that the invariant <fr:tex display="inline"><![CDATA[I]]></fr:tex> is the same as the precondition <fr:tex display="inline"><![CDATA[P]]></fr:tex> which is naturally not always the case, so it could be nice to have a rule which accounts for constructing valid while loops with invariants and custom preconditions. Same with custom post-conditions <fr:tex display="inline"><![CDATA[Q]]></fr:tex>.
  </html:p>
  
    
    <fr:resource hash="890b3d70f277eca374a0f7fd92162983"><fr:resource-content><html:img src="/notes/890b3d70f277eca374a0f7fd92162983.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \mprset {flushleft}
    \inferrule *[right=HWhile2]{
      (hS: \forall  \sigma , \sigma '.\ I(\sigma ) \land  (b \Downarrow ^t \sigma ) \to  (s, \sigma ) \Downarrow  \sigma ' \to  P(\sigma )) \\\\
      (hP: \forall  \sigma , P(\sigma ) \to  I(\sigma )) \\\\
      (hQ: \forall  I(\sigma ) \land  (b \Downarrow ^f \sigma ) \to  Q(\sigma ))
    }{
      \forall  \sigma , \sigma ' P(\sigma ) \to  (\texttt {while}\ b\ \texttt {do}\ s, \sigma ) \Downarrow  \sigma ' \to  Q(\sigma )
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
    If you want to be super pedantic you could show how this is just a combination of consequence + while rule. Anyway then, moving on we have the rule for <fr:tex display="inline"><![CDATA[\texttt {wp}]]></fr:tex> soundness.
  </html:p>
  
    
    <fr:resource hash="dd3f1daef4c0a411a628116908358df1"><fr:resource-content><html:img src="/notes/dd3f1daef4c0a411a628116908358df1.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=WPSound]{
      \texttt {vc}(s, Q)
    }{
      \forall  \sigma , \sigma '.\ \texttt {wp}(s, Q)(\sigma ) \to  (s, \sigma ) \Downarrow  \sigma ' \to  Q(\sigma ') 
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
    Now depending on how you actually design your <fr:tex display="inline"><![CDATA[\texttt {wp}]]></fr:tex> and <fr:tex display="inline"><![CDATA[\texttt {vc}]]></fr:tex> code this rule can look slightly different, though I like this distinction, in this instance for the case of while loops <fr:tex display="inline"><![CDATA[\texttt {wp}(W[I], Q)]]></fr:tex> simply returns the invariant <fr:tex display="inline"><![CDATA[I]]></fr:tex>, this means that again if we want to have a custom precondition for <fr:tex display="inline"><![CDATA[W]]></fr:tex> we'd want to verify we would extend the rule as:
  </html:p>
  
    
    <fr:resource hash="c2a2b2d56a7d61b460256853aa1900ae"><fr:resource-content><html:img src="/notes/c2a2b2d56a7d61b460256853aa1900ae.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=VCSound]{
      \texttt {vc}(s, Q) \\ \forall  \sigma , P(\sigma ) \to  \texttt {wp}(s, Q)(\sigma )
    }{
      \forall  \sigma , \sigma '.\ P(\sigma ) \to  (s, \sigma ) \Downarrow  \sigma ' \to  Q(\sigma ') 
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
    Thus for while loops it would become:
  </html:p>
  
    
    <fr:resource hash="1cd9102e2156e0e7a536397c134c1441"><fr:resource-content><html:img src="/notes/1cd9102e2156e0e7a536397c134c1441.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=VCSound-While]{
      \texttt {vc}(\texttt {while}\ b\ \texttt {do}\ s, Q) \\ \forall  P(\sigma ) \to  I(\sigma )
    }{
      \forall  \sigma , \sigma '.\ P(\sigma ) \to  (s, \sigma ) \Downarrow  \sigma ' \to  Q(\sigma ') 
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
    Where the verification conditions would unfold to what we discussed before.
  </html:p><html:p>
    A nice point to make here is that all of these rules are essentially derived from one another, which is to say that:
  </html:p>
 
  
  <html:figure><html:a href="
    " target="_blank" class="quiver-link">
    <fr:resource hash="be1b5988e0dbe18e4c588f358e8ce017"><fr:resource-content><html:img src="/notes/be1b5988e0dbe18e4c588f358e8ce017.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
   
   % String-diagram specific extensions live here. Add diagram tweaks without
 % re-running the full base preamble (to avoid duplicate definitions).

   
  
   \usepackage{eulervm}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{amsmath, amsthm, amsfonts}
  \usepackage{tikz, tikz-cd, mathtools, amssymb, stmaryrd}
  \usetikzlibrary{arrows.meta, shapes, positioning, calc, decorations.pathreplacing, backgrounds, fit, matrix, spath3}

  % A TikZ style for curved arrows of a fixed height, due to AndréC.
  \tikzset{curve/.style={settings={#1},to path={(\tikztostart)
        .. controls ($(\tikztostart)!\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
        and ($(\tikztostart)!1-\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
    .. (\tikztotarget)\tikztonodes}},
    settings/.code={\tikzset{quiver/.cd,#1}
    \def\pv##1{\pgfkeysvalueof{/tikz/quiver/##1}}},
  quiver/.cd,pos/.initial=0.35,height/.initial=0}

  % A TikZ style for shortening paths without the poor behaviour of `shorten <' and `shorten >'.
  \tikzset{between/.style n args={2}{/tikz/spath/at end path construction={
        \tikzset{spath/split at keep middle={current}{#1}{#2}}
  }}}

  % TikZ arrowhead/tail styles.
  \tikzset{tail reversed/.code={\pgfsetarrowsstart{tikzcd to}}}
  \tikzset{2tail/.code={\pgfsetarrowsstart{Implies[reversed]}}}
  \tikzset{2tail reversed/.code={\pgfsetarrowsstart{Implies}}}
  % TikZ arrow styles.
  \tikzset{no body/.style={/tikz/dash pattern=on 0 off 1mm}}


  ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[
    \[\begin {tikzcd}
      {\text {HWhile}} \\
      {\text {HWhile2}} \\
      {\text {WPSound-While}} \\
      {\text {VCSound-While}}
      \arrow ["{\text {uses}}", from=2-1, to=1-1]
      \arrow ["{\text {uses}}", from=3-1, to=2-1]
      \arrow ["{\text {uses}}", from=4-1, to=3-1]
    \end {tikzcd}\]
  ]]></fr:resource-source></fr:resource>
   </html:a></html:figure>
 
<html:p>
    In a conceptual sense verification conditions i.e. what we need to prove to demonstrate a hoare triple is valid, are simply a convenience mechanism derived from the fundamental logic of how we construct a hoare triple.
  </html:p></fr:mainmatter>
                                </fr:tree>
                              </fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" expanded="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>12</fr:month>
                          <fr:day>12</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/004p/</fr:uri>
                        <fr:display-uri>004p</fr:display-uri>
                        <fr:route>/notes/004p/</fr:route>
                        <fr:title text="Lecture 7 - VC's for functions and pointers">Lecture 7 - VC's for functions and pointers</fr:title>
                        <fr:taxon>VU-VFS-2025</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>12</fr:day>
                            </fr:date>
                            <fr:title text="Assertions">Assertions</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>12</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004q/</fr:uri>
                                <fr:display-uri>004q</fr:display-uri>
                                <fr:route>/notes/004q/</fr:route>
                                <fr:title text="Assertions &amp; Havoc">Assertions &amp; Havoc</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  We introduce 3 new syntactic constructs with their associated hoare rules, these constructs are:
</html:p>
                                <html:ul><html:li>
    The statement <fr:tex display="inline"><![CDATA[\texttt {assert(F)}]]></fr:tex> which <fr:tex display="inline"><![CDATA[\texttt {fails}]]></fr:tex> if <fr:tex display="inline"><![CDATA[F]]></fr:tex> evaluates to <fr:tex display="inline"><![CDATA[\bot ]]></fr:tex></html:li>
  <html:li>
    The statement <fr:tex display="inline"><![CDATA[\texttt {assume(F)}]]></fr:tex> which <html:em>tells us</html:em> that <fr:tex display="inline"><![CDATA[F]]></fr:tex> evaluates to <fr:tex display="inline"><![CDATA[\top ]]></fr:tex></html:li>
  <html:li>
    The statement <fr:tex display="inline"><![CDATA[\texttt {x := havoc()}]]></fr:tex> which assigns a non-deterministic value to a variable <fr:tex display="inline"><![CDATA[x]]></fr:tex></html:li></html:ul>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2025</fr:year>
                                      <fr:month>12</fr:month>
                                      <fr:day>12</fr:day>
                                    </fr:date>
                                    <fr:title text="Evaluation rules">Evaluation rules</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter><html:p>
    We introduce a new construct <fr:tex display="inline"><![CDATA[\texttt {fail}]]></fr:tex> which denotes the failure state, as an alternative to <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex>.
  </html:p>
  
    
    <fr:resource hash="ae7f136d04a0b18a085786e8e21f03eb"><fr:resource-content><html:img src="/notes/ae7f136d04a0b18a085786e8e21f03eb.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=AssertTrue]{
      \sigma  \vDash  F
    }{
      \langle  \texttt {assert}(F), \sigma  \rangle  \Downarrow  \sigma 
    }
    \and 
    \inferrule *[right=AssertFalse]{
      \sigma  \ \mathrlap {\,/}{\vDash }\ F 
    }{
      \langle  \texttt {assert}(F), \sigma  \rangle  \Downarrow  \texttt {fail}
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
    For the assumption we only have a <fr:tex display="inline"><![CDATA[\top ]]></fr:tex> rule, the idea being if the assumption holds then the statement is equivalent to a <fr:tex display="inline"><![CDATA[\texttt {skip}]]></fr:tex> otherwise the execution gets stuck <html:em>but doesn't fail</html:em>.
  </html:p>
  
    
    <fr:resource hash="13bef5c9407002338be261f562217a9d"><fr:resource-content><html:img src="/notes/13bef5c9407002338be261f562217a9d.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=AssumeTrue]{
      \sigma  \vDash  F
    }{
      \langle  \texttt {assume}(F), \sigma  \rangle  \Downarrow  \sigma 
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
    The idea with <html:em>getting stuck</html:em> being that since we aren't failing for the case of partial-correctness (failure or termination) it means we can simply ignore this case.
  </html:p><html:p>
    The final big-step evaluation rule is for the havoc statement:
  </html:p>
  
    
    <fr:resource hash="cd6249abdd51cb761839b63fd7375b7e"><fr:resource-content><html:img src="/notes/cd6249abdd51cb761839b63fd7375b7e.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=Havoc]{
      n \in  \mathbb {Z}
    }{
      \langle  x := \texttt {havoc}(), \sigma  \rangle  \Downarrow  \sigma [x \mapsto  n]
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2025</fr:year>
                                      <fr:month>12</fr:month>
                                      <fr:day>12</fr:day>
                                    </fr:date>
                                    <fr:title text="Hoare rules">Hoare rules</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter><html:p>
    In addition to our big-step evaluation rules we also have Hoare rules.
  </html:p>
  
    
    <fr:resource hash="df22b510951c12ccf7a001491e21bf58"><fr:resource-content><html:img src="/notes/df22b510951c12ccf7a001491e21bf58.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=Assert]{
      P \to  F
    }{
      \vdash  \{P\}\ \texttt {assert}(F)\ \{P \land  F\}
    }
    \and 
    \inferrule *[right=Assume]{
      \\
    }{
      \vdash  \{P\}\ \texttt {assume}(F)\ \{P \land  F\}
    }
    \and  
    \inferrule *[right=Havoc]{
      \\
    }{
      \vdash  \{\forall  y.\ Q[x\mapsto  y]\}\ x := \texttt {havoc}()\ \{Q\}
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
</fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2025</fr:year>
                                      <fr:month>12</fr:month>
                                      <fr:day>12</fr:day>
                                    </fr:date>
                                    <fr:title text="A more detailed explanation">A more detailed explanation</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>
    A central thing to understand with assertions especially is that they integrate a result's monad into the big-step evaluation semantics, in addition to the Hoare logic. So the idea is now instead of the relationship being denoted by:
  </html:p>
                                    <fr:tex display="block"><![CDATA[
    (\texttt {Stmt} \times  \texttt {Memory}) \to  \texttt {Memory} \to  \texttt {Prop}
  ]]></fr:tex>
                                    <html:p>
    It's now expressed as 
  </html:p>
                                    <fr:tex display="block"><![CDATA[
    (\texttt {Stmt} \times  \texttt {Memory}) \to  (\texttt {Result} \texttt {Memory}) \to  \texttt {Prop}
  ]]></fr:tex>
                                    <html:p>
    Where we can model <fr:tex display="inline"><![CDATA[\texttt {Result}]]></fr:tex> as the following monad 
  </html:p>
                                    <html:pre class="code-block language-lean">
                                      <html:code class="language-lean">
    inductive Result (α : Type)
    | ok : α → Result α      -- Normal termination with final state
    | fail : Result α        -- Assertion failure / error state
    deriving Repr, DecidableEq
  </html:code>
                                    </html:pre>
                                    <html:p>
    At this point if you want to be pedantic it's worth mentioning that the implication is that we are lifting all other inference rules into the context of this result monad, though for pedagogical purposes its enough to just assume that <fr:tex display="inline"><![CDATA[\Downarrow  \sigma ]]></fr:tex> just corresponds to <fr:tex display="inline"><![CDATA[\Downarrow  \texttt {.ok} \sigma ]]></fr:tex> i.e. evaluated into a non-fail state.
  </html:p>
                                    <html:p>
    The Hoare triple is where stuff becomes a bit more interesting. As a reminder, the classical hoare triple is basically just an alias for the logical formula:
  </html:p>
                                    <fr:tex display="block"><![CDATA[
    \forall  \sigma , \sigma '.\ P(\sigma ) \to  \langle  s, \sigma  \rangle  \Downarrow  \sigma ' \to  Q(\sigma ')
  ]]></fr:tex>
                                    <html:p>
    Naturally because we know are no longer evaluating into just <fr:tex display="inline"><![CDATA[\sigma ']]></fr:tex> but either an <fr:tex display="inline"><![CDATA[\texttt {ok}]]></fr:tex> or <fr:tex display="inline"><![CDATA[\texttt {fail}]]></fr:tex> state, it's worth asking how we actually represent that as a Hoare triple. We can start in much the same way as we do for the regular partial correctness hoare triple
  </html:p>
                                    <fr:tex display="block"><![CDATA[
    \forall  \sigma , \sigma _t.\ P(\sigma ) \to  \langle  s, \sigma  \rangle  \Downarrow  \sigma _t \to  (??)
  ]]></fr:tex>
                                    <html:p>
    Here we then run into I guess a design choice as to how we proceed, the two main possibilities are:
  </html:p>
                                    <html:ul><html:li>
      We <html:em>fail sometimes succeed other times</html:em> this would mean that:
      <fr:tex display="block"><![CDATA[
        (\exists  \sigma ', \sigma _t = \texttt {.ok}\ \sigma ' \land  Q(\sigma '))
      ]]></fr:tex>
      another way of seeing this is here we are <html:em>disallowig failure</html:em> meaning that for a hoare triple to be proven valid we must explicitly demonstrate as a side condition that we cannot fail otherwise our hoare triple is invalid.
    </html:li>
    <html:li>
      We <html:em>never fail</html:em> which would mean that:
      <fr:tex display="block"><![CDATA[
        (\forall  \sigma ', \sigma _t = \texttt {.ok}\ \sigma ' \land  Q(\sigma '))
      ]]></fr:tex>
      for this rule another way of seeing it is we are <html:em>ignoring failure</html:em> or <html:em>filter success states</html:em> since we are clearly only quantifying over those states that are successfull.
    </html:li></html:ul>
                                    <html:p>
    The latter option seems to be generally more common in theoretical settings because it doesn't require explicitly accounting for failure states, they are just implicitly filtered out in the logic.
  </html:p>
                                  </fr:mainmatter>
                                </fr:tree>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>12</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004r/</fr:uri>
                                <fr:display-uri>004r</fr:display-uri>
                                <fr:route>/notes/004r/</fr:route>
                                <fr:title text="Weakest precondition for assert and assume">Weakest precondition for assert and assume</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Answer the following:
</html:p><html:ol><html:li>
    What's <fr:tex display="inline"><![CDATA[\texttt {wp}(\texttt {assert}(P), Q)]]></fr:tex></html:li>
  <html:li>
    What's <fr:tex display="inline"><![CDATA[\texttt {wp}(\texttt {assume}(P), Q)]]></fr:tex></html:li>
  <html:li>
    Given a statement <fr:tex display="inline"><![CDATA[s]]></fr:tex>, can we transform it into a statement <fr:tex display="inline"><![CDATA[s']]></fr:tex> such that:
    <fr:tex display="block"><![CDATA[
      \vDash  \{P\}\ s\ \{Q\} \iff  \{\top \}\ s'\ \{\top \}
    ]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>12</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:p>
    We can remember that the weakest precondition is simply what we can derive reasoning backwards from the formulaic expression of a hoare triple.
  </html:p>
  <html:ol><html:li>
      Considering our wp formula we have 
      <fr:tex display="block"><![CDATA[
        \texttt {wp}(\texttt {assert}(b), Q)(\sigma ) \to  (\texttt {assert}(b), \sigma ) \Downarrow  \texttt {.ok}\ \sigma  \to  Q(\sigma )
      ]]></fr:tex>
      reasoning backwards we can start with a case split on the evaluation of the assertion, this leads to two cases
      <html:ul><html:li><fr:tex display="inline"><![CDATA[b]]></fr:tex> evaluates to <html:em>true</html:em>, as this case trivially implies that the assertion evaluates into <fr:tex display="inline"><![CDATA[\texttt {.ok}\ \sigma ]]></fr:tex> it means we must prove <fr:tex display="inline"><![CDATA[Q(\sigma )]]></fr:tex>. The only way we can prove this is by having our weakest precondition be a witness to this assertion.
        </html:li>
        <html:li><fr:tex display="inline"><![CDATA[b]]></fr:tex> evaluates to <html:em>false</html:em>, as this would imply a contradiction since the assertion evaluates to <fr:tex display="inline"><![CDATA[\texttt {.ok}\ \sigma ]]></fr:tex>, more specifically we know have to prove the contradiction that <fr:tex display="inline"><![CDATA[\texttt {.ok}\ \sigma  = \texttt {.fail} \sigma ]]></fr:tex>, we know (i.e. have a hypothesis) by inversion that <fr:tex display="inline"><![CDATA[b \Downarrow ^f \sigma ]]></fr:tex> since we know <fr:tex display="inline"><![CDATA[b]]></fr:tex> has to be true to prove the contradiction we also must ensure the weakest precondition states that <fr:tex display="inline"><![CDATA[b \Downarrow  ^t \sigma ]]></fr:tex></html:li></html:ul>
      from these two cases we can conclude that two demonstrate the soundness of the weakest precondition for assert statements, it must be the case that the <fr:tex display="inline"><![CDATA[\texttt {wp}]]></fr:tex> is the conjunction of the postcondition and the logical assertion that what is being asserted is indeed true, so we have that
      <fr:tex display="block"><![CDATA[
        \texttt {wp}(\texttt {assert}(b), Q)(\sigma ) \equiv  (b \Downarrow ^t \sigma ) \land  Q(\sigma )
      ]]></fr:tex>
      the more intuitive reasoning here is that <fr:tex display="inline"><![CDATA[Q]]></fr:tex> should hold before and after as an assert should, just by design, not do anything to the memory, it's only an assertion after all. Additionally, the condition should hold true as <fr:tex display="inline"><![CDATA[\texttt {wp}]]></fr:tex> <html:em>definitionally</html:em> describes a set of states where all terminating executions end in a state satisfying <fr:tex display="inline"><![CDATA[Q]]></fr:tex> thus if <fr:tex display="inline"><![CDATA[b]]></fr:tex> does not evaluate to true, there is no terminating execution from <fr:tex display="inline"><![CDATA[\sigma ]]></fr:tex>. 
    </html:li>
    <html:li>
      We can just use the more intuitive reasoning here, we know the weakest precondition characterizes a set of states where terminating executions end in a state satisfying <fr:tex display="inline"><![CDATA[Q]]></fr:tex>. The only way for something being assumed to be true leading to some other else is it if implies something else, thus our <fr:tex display="inline"><![CDATA[\texttt {wp}]]></fr:tex> becomes
      <fr:tex display="block"><![CDATA[
        \texttt {wp}(\texttt {assume}(b), Q)(\sigma ) \equiv  (b \Downarrow ^t \sigma ) \to  Q(\sigma )
      ]]></fr:tex>
      in terms of backward reasoning the idea is that <fr:tex display="inline"><![CDATA[\texttt {assume}(p)]]></fr:tex> essentially just adds a raw hypothesis <fr:tex display="inline"><![CDATA[(b \Downarrow ^t \sigma )]]></fr:tex> but clearly that by itself doesn't somehow allow me to just manifest <fr:tex display="inline"><![CDATA[Q(\sigma )]]></fr:tex>, the only way we could possibly get <fr:tex display="inline"><![CDATA[Q]]></fr:tex> from <fr:tex display="inline"><![CDATA[b]]></fr:tex> being true is if we have a function which states that <fr:tex display="inline"><![CDATA[b]]></fr:tex> being true implies <fr:tex display="inline"><![CDATA[Q]]></fr:tex>.
    </html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" expanded="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>12</fr:month>
                          <fr:day>15</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/004u/</fr:uri>
                        <fr:display-uri>004u</fr:display-uri>
                        <fr:route>/notes/004u/</fr:route>
                        <fr:title text="Lecture 8 - Horn Clauses">Lecture 8 - Horn Clauses</fr:title>
                        <fr:taxon>VU-VFS-2025</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>15</fr:day>
                            </fr:date>
                            <fr:title text="Introduction &amp; Syntax">Introduction &amp; Syntax</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>15</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004v/</fr:uri>
                                <fr:display-uri>004v</fr:display-uri>
                                <fr:route>/notes/004v/</fr:route>
                                <fr:title text="Horn clauses - Syntax">Horn clauses - Syntax</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  A Horn clause is a disjunctive clause (disjunction of literals) with at most one positive, i.e. unnegated literal. Often written in implication form as a conjunction of literals implying some literal called the head.
</html:p>
                                <fr:tex display="block"><![CDATA[
  \underbrace {\underbrace {p(x_1, x_2) \land  q(x_1, x_2, x_3) \land  \ldots }_\text {queries} \land  \underbrace {\phi }_\text {constraint}}_\text {body} \to  \underbrace {H}_\text {head}
]]></fr:tex>
                                <html:p>
  Here:
</html:p>
                                <html:ol><html:li><html:em>queries</html:em> are <html:strong>relations</html:strong> over some vector of variables
  </html:li>
  <html:li><fr:tex display="inline"><![CDATA[\phi ]]></fr:tex> represents a formula in a first-order theory which does not contain queries
  </html:li>
  <html:li><fr:tex display="inline"><![CDATA[H]]></fr:tex> is called the head and represents either a <html:em>query</html:em> in which case we also call the horn clause a <html:em>definite class</html:em> if it has the following shape
    <fr:tex display="block"><![CDATA[
      (p \land  q \land  \ldots  \land  \phi ) \to  H
    ]]></fr:tex>
    or a <html:em>fact</html:em> if it has the following shape
    <fr:tex display="block"><![CDATA[
      \top  \to  H
    ]]></fr:tex>
    <fr:tex display="inline"><![CDATA[H]]></fr:tex> can also be <fr:tex display="inline"><![CDATA[\bot ]]></fr:tex> in which case we refer to the horn clause as a <html:em>gloal clause</html:em> with the shape 
    <fr:tex display="block"><![CDATA[
      (p \land  q \land  \ldots  \land  \phi ) \to  \bot 
    ]]></fr:tex>
    with the idea being that as opposed to <html:em>assuming</html:em> the query holds we now <html:em>show</html:em> that it holds
  </html:li></html:ol>
                                <html:p>
  Free variables are implicitly universally quantified over, so a horn clause like
</html:p>
                                <fr:tex display="block"><![CDATA[
  \texttt {mortal}(X) \to  \texttt {human}(X)
]]></fr:tex>
                                <html:p>
  stands for
</html:p>
                                <fr:tex display="block"><![CDATA[
  \forall  X.\ \texttt {mortal}(X) \to  \texttt {human}(X)
]]></fr:tex>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>15</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004w/</fr:uri>
                                <fr:display-uri>004w</fr:display-uri>
                                <fr:route>/notes/004w/</fr:route>
                                <fr:title text="Horn clauses - Semantics">Horn clauses - Semantics</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter />
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>16</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0050/</fr:uri>
                                <fr:display-uri>0050</fr:display-uri>
                                <fr:route>/notes/0050/</fr:route>
                                <fr:title text="Horn clause - Solution">Horn clause - Solution</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  A <html:strong>solution</html:strong> is a function <fr:tex display="inline"><![CDATA[\Sigma ]]></fr:tex> that maps <html:em>queries</html:em> to <html:em>formulas</html:em> in the background theory over the same variables. Formally we write <fr:tex display="inline"><![CDATA[\Sigma  \vDash  C]]></fr:tex> and say that <fr:tex display="inline"><![CDATA[\Sigma ]]></fr:tex> satisfies <fr:tex display="inline"><![CDATA[C]]></fr:tex>, if <fr:tex display="inline"><![CDATA[C]]></fr:tex> is true if we replace all queries by their solutions, written as an inference rule:
</html:p>
  
    
    <fr:resource hash="d9ed32b08e0e488df79f18da6d8f0646"><fr:resource-content><html:img src="/notes/d9ed32b08e0e488df79f18da6d8f0646.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule {
    \Sigma (p) \land  \Sigma (q) \land  \ldots  \land  \phi  \to  \Sigma (r)
  }{
    \Sigma  \models  p(x_1, x_2) \land  q(x_1, x_2, x_3) \land  \ldots  \land  \phi  \to  r(x_1)
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
  We write <fr:tex display="inline"><![CDATA[\Sigma  \vDash  \mathcal {C}]]></fr:tex> and say that <fr:tex display="inline"><![CDATA[\Sigma ]]></fr:tex> <html:em>satisfies</html:em> the set of clauses <fr:tex display="inline"><![CDATA[\{C_1, C_2, \ldots , C_n\}]]></fr:tex>, if it satisfies all <html:em>individual clauses</html:em>, i.e:
</html:p><fr:tex display="block"><![CDATA[
  \Sigma  \vDash  C_1 \land  \Sigma  \vDash  C_2 \land  \ldots  \land  \Sigma  \vDash  C_n
]]></fr:tex><html:p>
  We say that <fr:tex display="inline"><![CDATA[\mathcal  C]]></fr:tex> is <html:strong>satisfiable</html:strong>, if <fr:tex display="inline"><![CDATA[\exists  \Sigma .\ \Sigma  \vDash  \mathcal  C]]></fr:tex></html:p></fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>16</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/004z/</fr:uri>
                                <fr:display-uri>004z</fr:display-uri>
                                <fr:route>/notes/004z/</fr:route>
                                <fr:title text="Finding recursive Horn clauses">Finding recursive Horn clauses</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  Is the following set of horn clauses recursive?
</html:p><html:ol><html:li><fr:tex display="block"><![CDATA[
      \begin {align}
        q(x) \land  r(x) &\to  p(x) \\
        p(x) \land  (x < n) &\to  \bot 
      \end {align}
    ]]></fr:tex></html:li>
  <html:li><fr:tex display="block"><![CDATA[
      \begin {align}
        q(x) \land  r(x) &\to  p(x) \\
        p(x) \land  (x > 0) &\to  r(x) \\
        p(x) \land  (x < n) &\to  \bot 
      \end {align}
    ]]></fr:tex></html:li></html:ol>
  
    
    
    <fr:tree show-metadata="false" expanded="false" toc="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>12</fr:month><fr:day>16</fr:day></fr:date><fr:taxon>Solution</fr:taxon></fr:frontmatter><fr:mainmatter>
  <html:ol><html:li>
      No, we can draw the dependency graph as follows
      
 
  
  <html:figure><html:a href="https://q.uiver.app/#q=WzAsMyxbMSwwLCJwIl0sWzAsMSwicSJdLFsyLDEsInIiXSxbMSwwXSxbMiwwXV0=" target="_blank" class="quiver-link">
    <fr:resource hash="182baed65cc7d3866c81269a209a1558"><fr:resource-content><html:img src="/notes/182baed65cc7d3866c81269a209a1558.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
   
   % String-diagram specific extensions live here. Add diagram tweaks without
 % re-running the full base preamble (to avoid duplicate definitions).

   
  
   \usepackage{eulervm}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{amsmath, amsthm, amsfonts}
  \usepackage{tikz, tikz-cd, mathtools, amssymb, stmaryrd}
  \usetikzlibrary{arrows.meta, shapes, positioning, calc, decorations.pathreplacing, backgrounds, fit, matrix, spath3}

  % A TikZ style for curved arrows of a fixed height, due to AndréC.
  \tikzset{curve/.style={settings={#1},to path={(\tikztostart)
        .. controls ($(\tikztostart)!\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
        and ($(\tikztostart)!1-\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
    .. (\tikztotarget)\tikztonodes}},
    settings/.code={\tikzset{quiver/.cd,#1}
    \def\pv##1{\pgfkeysvalueof{/tikz/quiver/##1}}},
  quiver/.cd,pos/.initial=0.35,height/.initial=0}

  % A TikZ style for shortening paths without the poor behaviour of `shorten <' and `shorten >'.
  \tikzset{between/.style n args={2}{/tikz/spath/at end path construction={
        \tikzset{spath/split at keep middle={current}{#1}{#2}}
  }}}

  % TikZ arrowhead/tail styles.
  \tikzset{tail reversed/.code={\pgfsetarrowsstart{tikzcd to}}}
  \tikzset{2tail/.code={\pgfsetarrowsstart{Implies[reversed]}}}
  \tikzset{2tail reversed/.code={\pgfsetarrowsstart{Implies}}}
  % TikZ arrow styles.
  \tikzset{no body/.style={/tikz/dash pattern=on 0 off 1mm}}


  ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[
        \[\begin {tikzcd}
          & p \\
          q && r
          \arrow [from=2-1, to=1-2]
          \arrow [from=2-3, to=1-2]
        \end {tikzcd}\]
      ]]></fr:resource-source></fr:resource>
   </html:a></html:figure></html:li>
    <html:li>
      Yes, because the head <fr:tex display="inline"><![CDATA[p]]></fr:tex> depends on the query <fr:tex display="inline"><![CDATA[r]]></fr:tex> and vv. again as a graph we can draw it as follows
      
 
  
  <html:figure><html:a href="https://q.uiver.app/#q=WzAsMyxbMSwwLCJwIl0sWzAsMSwicSJdLFsyLDEsInIiXSxbMSwwXSxbMiwwXSxbMCwyLCIiLDIseyJvZmZzZXQiOi0yLCJjdXJ2ZSI6LTJ9XV0=" target="_blank" class="quiver-link">
    <fr:resource hash="1d857ace1a4564b61ec6d573c46bf6ec"><fr:resource-content><html:img src="/notes/1d857ace1a4564b61ec6d573c46bf6ec.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
   
   % String-diagram specific extensions live here. Add diagram tweaks without
 % re-running the full base preamble (to avoid duplicate definitions).

   
  
   \usepackage{eulervm}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{amsmath, amsthm, amsfonts}
  \usepackage{tikz, tikz-cd, mathtools, amssymb, stmaryrd}
  \usetikzlibrary{arrows.meta, shapes, positioning, calc, decorations.pathreplacing, backgrounds, fit, matrix, spath3}

  % A TikZ style for curved arrows of a fixed height, due to AndréC.
  \tikzset{curve/.style={settings={#1},to path={(\tikztostart)
        .. controls ($(\tikztostart)!\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
        and ($(\tikztostart)!1-\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
    .. (\tikztotarget)\tikztonodes}},
    settings/.code={\tikzset{quiver/.cd,#1}
    \def\pv##1{\pgfkeysvalueof{/tikz/quiver/##1}}},
  quiver/.cd,pos/.initial=0.35,height/.initial=0}

  % A TikZ style for shortening paths without the poor behaviour of `shorten <' and `shorten >'.
  \tikzset{between/.style n args={2}{/tikz/spath/at end path construction={
        \tikzset{spath/split at keep middle={current}{#1}{#2}}
  }}}

  % TikZ arrowhead/tail styles.
  \tikzset{tail reversed/.code={\pgfsetarrowsstart{tikzcd to}}}
  \tikzset{2tail/.code={\pgfsetarrowsstart{Implies[reversed]}}}
  \tikzset{2tail reversed/.code={\pgfsetarrowsstart{Implies}}}
  % TikZ arrow styles.
  \tikzset{no body/.style={/tikz/dash pattern=on 0 off 1mm}}


  ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[
        \[\begin {tikzcd}
          & p \\
          q && r
          \arrow [shift left=2, curve={height=-12pt}, from=1-2, to=2-3]
          \arrow [from=2-1, to=1-2]
          \arrow [from=2-3, to=1-2]
        \end {tikzcd}\]
      ]]></fr:resource-source></fr:resource>
   </html:a></html:figure></html:li></html:ol>
</fr:mainmatter></fr:tree>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>15</fr:day>
                            </fr:date>
                            <fr:title text="Application of Horn clauses">Application of Horn clauses</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>19</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0059/</fr:uri>
                                <fr:display-uri>0059</fr:display-uri>
                                <fr:route>/notes/0059/</fr:route>
                                <fr:title text="Normalizing Horn clauses">Normalizing Horn clauses</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  Something of note when dealing with weakets preconditions <fr:link href="/notes/0056/" title="Weakest preconditions and Horn clauses" uri="https://kaierikniermann.github.io/notes/0056/" display-uri="0056" type="local">in terms of horn clauses</fr:link> is that we have to first normalize them to ensure they are in the correct horn format, which is to say we commonly have some horn clause in the form
</html:p>
                                <fr:tex display="block"><![CDATA[
  p(e_1, e_2) \land  \ldots  \land  \phi  \to  H(e_3) 
]]></fr:tex>
                                <html:p>
  where <fr:tex display="inline"><![CDATA[e_i]]></fr:tex> represents an expression, to normalize these clauses we lift the expressions out of the parameters for the predicates and into the list of conjuncts, i.e.:
</html:p>
                                <fr:tex display="block"><![CDATA[
  p(x_1, x_2) \land  x_1 = e_1 \land  x_2 = e_2 \land  x_3 = e_3 \land  \ldots  \land  \phi  \to  H(x_3)
]]></fr:tex>
                                <html:p>
  So we create fresh variables <fr:tex display="inline"><![CDATA[x_1, x_2, x_3]]></fr:tex> and assign these to the respective expressions then use them in place of the expressions themselves.
</html:p>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/005c/</fr:uri>
                                <fr:display-uri>005c</fr:display-uri>
                                <fr:route>/notes/005c/</fr:route>
                                <fr:title text="Strongest Postcondition">Strongest Postcondition</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  In the most straightforward sense the strongest postcondition, denoted <fr:tex display="inline"><![CDATA[\texttt {sp}]]></fr:tex> or <fr:tex display="inline"><![CDATA[\texttt {post}]]></fr:tex>, denotes the exact or <html:em>least</html:em> set of <html:strong>final states</html:strong> which we land in after a successful execution. Set theoretically we can denote it as.
</html:p>
                                <fr:tex display="block"><![CDATA[
  \texttt {sp}(s, P) = \{\sigma  \in  \Sigma  \mid  \exists  \sigma ' \in  \Sigma  : \sigma  ' \vDash  P \land  (s, \sigma ') \Downarrow  \sigma \}
]]></fr:tex>
                                <html:p>
  We can also use a more logic way of expressing it as follows
</html:p>
                                <fr:tex display="block"><![CDATA[
  \texttt {sp}(s, P) \triangleq  \exists  \sigma '.\ P(\sigma ') \land  (s, \sigma ') \Downarrow  \sigma 
]]></fr:tex>
                                <html:p>
  But the idea is in principle the same, it represents the set of states corresponding to some evaluated result based on some existing safe state.
</html:p>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>25</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/005k/</fr:uri>
                                <fr:display-uri>005k</fr:display-uri>
                                <fr:route>/notes/005k/</fr:route>
                                <fr:title text="Computing the strongest post-condition">Computing the strongest post-condition</fr:title>
                                <fr:taxon>Quiz</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  Consider the following set of Horn clauses
</html:p>
                                <fr:tex display="block"><![CDATA[
  \begin {align}
    x = 0 &\to  q(x) \\
    (q(y) \land  y < 6 \land  x = y + 1) \to  q(x)
  \end {align}
]]></fr:tex>
                              </fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>15</fr:day>
                            </fr:date>
                            <fr:title text="Abstraction">Abstraction</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/005d/</fr:uri>
                                <fr:display-uri>005d</fr:display-uri>
                                <fr:route>/notes/005d/</fr:route>
                                <fr:title text="Abstraction &amp; Concretization function">Abstraction &amp; Concretization function</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>
  In the most general sense we consider two domains, an abstract domain <fr:tex display="inline"><![CDATA[A]]></fr:tex> and a concrete domain <fr:tex display="inline"><![CDATA[C]]></fr:tex>. We have two functions the abstraction function
</html:p>
                                <fr:tex display="block"><![CDATA[
  \alpha  : C \to  A
]]></fr:tex>
                                <html:p>
  and the concretization function
</html:p>
                                <fr:tex display="block"><![CDATA[
  \gamma  : A \to  C
]]></fr:tex>
                                <html:p>
  Naturally we often instantiate these two domains for different scenarios.
</html:p>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2025</fr:year>
                                      <fr:month>12</fr:month>
                                      <fr:day>22</fr:day>
                                    </fr:date>
                                    <fr:title text="Example: Interval abstraction">Example: Interval abstraction</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>
    Let's consider a basic instance of abstraction where we think of the concrete domain as set's of numbers and the abstract domain as rangers or intervals of numbers which characterize these sets. So formally we say
  </html:p>
                                    <html:ul><html:li>
      Our concrete domain is the power set <fr:tex display="inline"><![CDATA[\mathcal  P(\mathbb {R})]]></fr:tex> of the natural real numbers <fr:tex display="inline"><![CDATA[\mathbb {R}]]></fr:tex> ordered by set-inclusion so <fr:tex display="inline"><![CDATA[\sqsubseteq  \equiv  \subseteq ]]></fr:tex></html:li>
    <html:li>
      Our abstract domain is represented by intervals in addition to the symbols for true and false, so
      <fr:tex display="block"><![CDATA[
        A = \textrm {Intervals} \cup  \{\top , \bot \}
      ]]></fr:tex></html:li>
    <html:li>
      Our concretization function maps from an interval to all those numbers contained within the interval, so as an example
      <fr:tex display="block"><![CDATA[
        \gamma ([l, u]) \equiv  \{x \mid  l \leq  x \leq  u\}
      ]]></fr:tex></html:li>
    <html:li>
      Our abstraction function which takes a concrete element <fr:tex display="inline"><![CDATA[c]]></fr:tex> then maps this to the meet or conjunct of all abstract element in which the ordering with the concretization function holds, i.e.
      <fr:tex display="block"><![CDATA[
        \alpha (c) = \bigwedge  \{a \in  A \mid  c \subseteq  \gamma (a)\}
      ]]></fr:tex>
      the idea is that it represents the most precise abstract representation which can capture the concrete element c. Operationally we can express this equivalently as 
      <fr:tex display="block"><![CDATA[
                \alpha(c \equiv \{x_1, x_2, \ldots, x_n\}) = \begin{cases}
          [\textrm{min}\ c, \textrm{max}\ c] & \textrm{if bounded} \\
          [\textrm{min}\ c, +\infty) & \textrm{if only lb} \\
          (-\infty, \textrm{max}\ c] & \textrm{if only ub} \\
          \top & \textrm{if unbounded} \\
          \bot & \textrm{if}\ = \emptyset
        \end{cases}
      ]]></fr:tex> 
      so more plainly we can understand the abstraction function of just being the most exact combination i.e. meet / conjunction of intervals to express our concrete element.
    </html:li></html:ul>
                                  </fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2025</fr:year>
                                      <fr:month>12</fr:month>
                                      <fr:day>22</fr:day>
                                    </fr:date>
                                    <fr:title text="Example: Predicate abstraction">Example: Predicate abstraction</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>
    A common application within the domain of logic and computer science is to consider the concrete domain as referring to formulas or equivalently set's of states, not too much unlike our power-set of numbers. With our abstract state then being a conjunct of predicates from some finite set <fr:tex display="inline"><![CDATA[P]]></fr:tex> which best characterize our concrete formulas.
  </html:p>
                                    <html:ul><html:li>
      Each element in the abstract domain is some permutation of our finite predicate set <fr:tex display="inline"><![CDATA[P]]></fr:tex>, so we have 
      <fr:tex display="block"><![CDATA[
        A = \mathcal  P(P) \quad  P_1 \sqsubseteq  P_2 \iff  P_2 \subseteq  P_1
      ]]></fr:tex>
      each abstract element <fr:tex display="inline"><![CDATA[a \in  P]]></fr:tex> is defined by the conjunction 
      <fr:tex display="block"><![CDATA[
        \bigwedge  _{p \in  a} p
      ]]></fr:tex> 
      hence our concretization function yields those set's of concrete states (or predicates representing these states) which satisfy <fr:tex display="inline"><![CDATA[a]]></fr:tex>. 
      <fr:tex display="block"><![CDATA[
        \gamma (a) = \{\sigma  \in  \Sigma  \mid  \forall  p \in  a.\ p(\sigma ) = \top \} \equiv  \llbracket  \bigwedge _{p \in  a} p \rrbracket  
      ]]></fr:tex></html:li>
    <html:li>
      The abstraction function is then defined more or less the usual way, we take in a concrete set of states <fr:tex display="inline"><![CDATA[c]]></fr:tex> then aggregate those predicates which describe our concrete set of states most precisely.
      <fr:tex display="block"><![CDATA[
        \alpha  (c) = \bigcap  \{a \in  A \mid  c \subseteq  \gamma (a)\}
      ]]></fr:tex>
      can equivalent formulation is 
      <fr:tex display="block"><![CDATA[
        \alpha  (c) = \bigwedge  \{p \in  P \mid  c \to  p\}
      ]]></fr:tex></html:li></html:ul>
                                    <html:p>
    Let's consider as an example 
  </html:p>
                                    <fr:tex display="block"><![CDATA[
    P = \{x \geq  0, x \geq  5, x \leq  10\} \quad  c = \{x = 7\}
  ]]></fr:tex>
                                    <html:p>
    Here we can define the abstraction function as follows
  </html:p>
                                    <fr:tex display="block"><![CDATA[
    \alpha  (x = 7) = \bigwedge  \{x \geq  0, x \geq  5, x \leq  10\}
  ]]></fr:tex>
                                  </fr:mainmatter>
                                </fr:tree>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/005e/</fr:uri>
                                <fr:display-uri>005e</fr:display-uri>
                                <fr:route>/notes/005e/</fr:route>
                                <fr:title text="Abstract strongest postcondition"><fr:link href="/notes/005d/" title="Abstraction &amp; Concretization function" uri="https://kaierikniermann.github.io/notes/005d/" display-uri="005d" type="local">Abstract</fr:link> strongest postcondition</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2025</fr:year>
                                      <fr:month>12</fr:month>
                                      <fr:day>22</fr:day>
                                    </fr:date>
                                    <fr:title text="The idea">The idea</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>
    Our usual strongest postcondition can be understood as a mapping from a concrete domain to a concrete domain, i.e.
  </html:p>
                                    <fr:tex display="block"><![CDATA[
    \begin {align}
      \texttt {sp} : \texttt {Stmt} \times  \texttt {C} \to  C
    \end {align}
  ]]></fr:tex>
                                    <html:p>
    Where <fr:tex display="inline"><![CDATA[C]]></fr:tex> represents our concrete domain, in the world of program logic this is typically assertions on the state of some memory environment. The idea behind the <html:em>abstract</html:em> <fr:tex display="inline"><![CDATA[\texttt {sp}]]></fr:tex>, is that we have a function
  </html:p>
                                    <fr:tex display="block"><![CDATA[
    \begin {align}
      \texttt {sp}^\# : \texttt {Stmt} \times  \texttt {A} \to  \texttt {A}
    \end {align}
  ]]></fr:tex>
                                    <html:p>
    In other words we are considering the strongest postcondition from within the abstract domain. Intuitively this just means that our predicates or assertions on the memory states (or equivalently the set of states we characterize) will be expressed in abstract terms.
  </html:p>
                                  </fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2025</fr:year>
                                      <fr:month>12</fr:month>
                                      <fr:day>22</fr:day>
                                    </fr:date>
                                    <fr:title text="In more detail">In more detail</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>
    The abstract strongest postcondition, denoted <fr:tex display="inline"><![CDATA[\texttt {sp}^\#]]></fr:tex> or <fr:tex display="inline"><![CDATA[\textrm {post\#}]]></fr:tex> is defined as
  </html:p>
                                    <fr:tex display="block"><![CDATA[
    \texttt {sp}^\# (s, a) = \alpha  (\texttt {sp}(s, \gamma (a)))
  ]]></fr:tex>
                                    <html:p>
    Let's explain a bit on how we can derive this, we begin with the idea that for each <fr:tex display="inline"><![CDATA[a \in  A]]></fr:tex> and each statement <fr:tex display="inline"><![CDATA[s]]></fr:tex> we want:
  </html:p>
                                    <fr:tex display="block"><![CDATA[
    \texttt {sp}(s, \gamma (a)) \subseteq  \gamma (\texttt {sp}^\#(s, a))
  ]]></fr:tex>
                                    <html:p>
    This expresses <html:strong>soundness</html:strong> in other words, the resulting set of states, generated by concretizing the abstraction <fr:tex display="inline"><![CDATA[a]]></fr:tex> must be contained within the prediction of the abstract transformer predicate <fr:tex display="inline"><![CDATA[\texttt {sp}^\#]]></fr:tex>. Then using the Galois connection we have between <fr:tex display="inline"><![CDATA[\alpha ]]></fr:tex> and <fr:tex display="inline"><![CDATA[\gamma ]]></fr:tex></html:p>
                                    <fr:tex display="block"><![CDATA[
    \forall  a \in  A, c \in  C.\ \alpha (c) \subseteq  a \iff  c \leq  \gamma  (a)
  ]]></fr:tex>
                                    <html:p>
    which expresses the notion that <fr:tex display="inline"><![CDATA[c]]></fr:tex> is <html:em>approximated</html:em> by <fr:tex display="inline"><![CDATA[a]]></fr:tex>. We can rewrite our earlier soundness condition as:
  </html:p>
                                    <fr:tex display="block"><![CDATA[
    \alpha (\texttt {sp}(s, \gamma (a))) \sqsubseteq  \texttt {sp}^\# (s, a)
  ]]></fr:tex>
                                    <html:p>
    two again denote the same conceptual thing that our abstract predicate transformer <fr:tex display="inline"><![CDATA[\texttt {sp}^\#]]></fr:tex> is an over-approximation of the analogous transformer for the concrete domain. As we would preferably like to have the most precise approximation we choose equality. Or stated differently by definition the most precise abstracted approximation of the strongest post-condition we can have for some abstracted state is literally just this state concretized, and the resulting set abstracted. 
  </html:p>
                                    <fr:tex display="block"><![CDATA[
    \texttt {sp}^\# (s, a) = \alpha (\texttt {sp}(s, \gamma (a)))
  ]]></fr:tex>
                                  </fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2025</fr:year>
                                      <fr:month>12</fr:month>
                                      <fr:day>22</fr:day>
                                    </fr:date>
                                    <fr:title text="Correctness">Correctness</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>
    The most important property to remember about the abstract strongest post-condition is that if we <html:em>do over-approximate an error state</html:em> it <html:strong>does not</html:strong> allow us to conclude that the program is wrong.
  </html:p>
                                  </fr:mainmatter>
                                </fr:tree>
                              </fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" expanded="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>12</fr:month>
                          <fr:day>23</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005g/</fr:uri>
                        <fr:display-uri>005g</fr:display-uri>
                        <fr:route>/notes/005g/</fr:route>
                        <fr:title text="Lecture 9 - Solving Horn Clauses">Lecture 9 - Solving Horn Clauses</fr:title>
                        <fr:taxon>VU-VFS-2025</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                    <fr:tree show-metadata="false" expanded="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>12</fr:month>
                          <fr:day>23</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005h/</fr:uri>
                        <fr:display-uri>005h</fr:display-uri>
                        <fr:route>/notes/005h/</fr:route>
                        <fr:title text="Lecture 10 - Information Flow Types">Lecture 10 - Information Flow Types</fr:title>
                        <fr:taxon>VU-VFS-2025</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>12</fr:month>
                              <fr:day>23</fr:day>
                            </fr:date>
                            <fr:title text="The type system">The type system</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2025</fr:year>
                                  <fr:month>12</fr:month>
                                  <fr:day>22</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/005f/</fr:uri>
                                <fr:display-uri>005f</fr:display-uri>
                                <fr:route>/notes/005f/</fr:route>
                                <fr:title text="Information Flow Types - Rules">Information Flow Types - Rules</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter><html:p>
  We define a typing judgement as 
</html:p><fr:tex display="block"><![CDATA[
  \Gamma  \vdash  e : \tau  
]]></fr:tex><html:p>
  Expressing that in the context <fr:tex display="inline"><![CDATA[\Gamma ]]></fr:tex> expression <fr:tex display="inline"><![CDATA[e]]></fr:tex> has a label <fr:tex display="inline"><![CDATA[\tau  \in  \mathcal  T]]></fr:tex></html:p>
  
    
    <fr:resource hash="e817215c8e8176b90fe550dfef532c91"><fr:resource-content><html:img src="/notes/e817215c8e8176b90fe550dfef532c91.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule *[right=T-Var]{
    \Gamma (x) = \tau  
  }{
    \Gamma  \vdash  x : \tau 
  }
  \and  
  \inferrule *[right=T-Num]{
    \\ 
  }{
    \Gamma  \vdash  n : \texttt {obs}
  }
  \and 
  \inferrule *[right=T-Plus]{
    \Gamma  \vdash  e_1 : \tau _1 \\
    \Gamma  \vdash  e_2 : \tau _2 
  }{
    \Gamma  e_1 + e_2 : \tau _1 \sqcup  \tau _2
  }
  \and 
  \inferrule *[right=True]{
    \\
  }{
    \Gamma  \vdash  \top  : \texttt {obs}
  }
  \and  
  \inferrule *[right=T-Or]{
    \Gamma  \vdash  b_1 : \tau _1 \\
    \Gamma  \vdash  b_2 : \tau _2 \\
  }{
    \Gamma  \vdash  b_1 \lor  b_2 : \tau _1 \sqcup  \tau _2
  }
  \and  
  \inferrule *[right=T-Eq]{
    \Gamma  \vdash  e_1 : \tau _1 \\
    \Gamma  \vdash  e_2 : \tau _2 
  }{
    \Gamma  e_1 = e_2 : \tau _1 \sqcup  \tau _2
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  

  
    
    <fr:resource hash="2998d80c704732e4ec1559ab8173463f"><fr:resource-content><html:img src="/notes/2998d80c704732e4ec1559ab8173463f.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
  \inferrule *[right=E-Assign]{
    \Gamma  \vdash  x : \tau _1 \\
    \Gamma  \vdash  e : \tau _2 \\
    \tau _2 \sqsubseteq  \tau _1 \\ 
    \texttt {pc} \sqsubseteq  \tau _1
  }{
    \Gamma , \texttt {pc} \vdash  x := e
  }
  \and  
  \inferrule *[right=E-Seq]{
    \Gamma , \texttt {pc} \vdash  s_1 \\
    \Gamma , \texttt {pc} \vdash  s_2
  }{
    \Gamma , \texttt {pc} \vdash  s_1 ; s_2
  }
  \and  
  \inferrule *[right=E-If]{
    \Gamma  \vdash  b : \texttt {obs} \\ 
    \Gamma  \vdash  s_1 \\
    \Gamma  \vdash  s_2
  }{
    \Gamma  \vdash  \texttt {if}\ b\ \texttt {then}\ s_1\ \texttt {else}\ s_2
  }
  \and 
  \inferrule *[right=E-While]{
    \Gamma  \vdash  b : \tau  \\
    \Gamma  \vdash  s 
  }{
    \Gamma  \vdash  \texttt {while}\ b\ \texttt {do}\ s
  }
  \and 
  \inferrule *[right=E-ArrRead]{
    \Gamma  \vdash  e : \texttt {obs} \\ 
    \Gamma  \vdash  a : \tau  
  }{
    \Gamma  \vdash  a[e] : \tau 
  }
\end {mathpar}]]></fr:resource-source></fr:resource>
  
</fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false" expanded="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>12</fr:month>
                          <fr:day>23</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005i/</fr:uri>
                        <fr:display-uri>005i</fr:display-uri>
                        <fr:route>/notes/005i/</fr:route>
                        <fr:title text="Lecture 11 - Information Flow &amp; Side Channels">Lecture 11 - Information Flow &amp; Side Channels</fr:title>
                        <fr:taxon>VU-VFS-2025</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                    <fr:tree show-metadata="false" expanded="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>12</fr:month>
                          <fr:day>23</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005j/</fr:uri>
                        <fr:display-uri>005j</fr:display-uri>
                        <fr:route>/notes/005j/</fr:route>
                        <fr:title text="Lecture 12 - Refinement Types">Lecture 12 - Refinement Types</fr:title>
                        <fr:taxon>VU-VFS-2025</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>2</fr:month>
                      <fr:day>11</fr:day>
                    </fr:date>
                    <fr:uri>https://kaierikniermann.github.io/notes/005l/</fr:uri>
                    <fr:display-uri>005l</fr:display-uri>
                    <fr:route>/notes/005l/</fr:route>
                    <fr:title text="Advanced Logic">Advanced Logic</fr:title>
                    <fr:taxon>VU-AL-2026</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>2</fr:month>
                          <fr:day>11</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005n/</fr:uri>
                        <fr:display-uri>005n</fr:display-uri>
                        <fr:route>/notes/005n/</fr:route>
                        <fr:title text="Week 1">Week 1</fr:title>
                        <fr:taxon>VU-AL-2026</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2026</fr:year>
                              <fr:month>2</fr:month>
                              <fr:day>11</fr:day>
                            </fr:date>
                            <fr:uri>https://kaierikniermann.github.io/notes/0062/</fr:uri>
                            <fr:display-uri>0062</fr:display-uri>
                            <fr:route>/notes/0062/</fr:route>
                            <fr:title text="Lecture 1">Lecture 1</fr:title>
                            <fr:taxon>VU-AL-2026</fr:taxon>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2026</fr:year>
                                  <fr:month>2</fr:month>
                                  <fr:day>11</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0064/</fr:uri>
                                <fr:display-uri>0064</fr:display-uri>
                                <fr:route>/notes/0064/</fr:route>
                                <fr:title text="Basic modal logic">Basic modal logic</fr:title>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2026</fr:year>
                                      <fr:month>2</fr:month>
                                      <fr:day>11</fr:day>
                                    </fr:date>
                                    <fr:uri>https://kaierikniermann.github.io/notes/006g/</fr:uri>
                                    <fr:display-uri>006g</fr:display-uri>
                                    <fr:route>/notes/006g/</fr:route>
                                    <fr:title text="Examples of modal patterns">Examples of modal patterns</fr:title>
                                    <fr:taxon>Example</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>Content</html:p>
                                  </fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2026</fr:year>
                                      <fr:month>2</fr:month>
                                      <fr:day>11</fr:day>
                                    </fr:date>
                                    <fr:uri>https://kaierikniermann.github.io/notes/006i/</fr:uri>
                                    <fr:display-uri>006i</fr:display-uri>
                                    <fr:route>/notes/006i/</fr:route>
                                    <fr:title text="Formulas of modal propositional logic">Formulas of modal propositional logic</fr:title>
                                    <fr:taxon>Definition</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>Definition text...</html:p>
                                  </fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2026</fr:year>
                                      <fr:month>2</fr:month>
                                      <fr:day>11</fr:day>
                                    </fr:date>
                                    <fr:uri>https://kaierikniermann.github.io/notes/006j/</fr:uri>
                                    <fr:display-uri>006j</fr:display-uri>
                                    <fr:route>/notes/006j/</fr:route>
                                    <fr:title text="Frame">Frame</fr:title>
                                    <fr:taxon>Definition</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>Definition text...</html:p>
                                    <fr:tree show-metadata="false">
                                      <fr:frontmatter>
                                        <fr:authors />
                                        <fr:date>
                                          <fr:year>2026</fr:year>
                                          <fr:month>2</fr:month>
                                          <fr:day>11</fr:day>
                                        </fr:date>
                                        <fr:uri>https://kaierikniermann.github.io/notes/006k/</fr:uri>
                                        <fr:display-uri>006k</fr:display-uri>
                                        <fr:route>/notes/006k/</fr:route>
                                        <fr:title text="Frame examples">Frame examples</fr:title>
                                        <fr:taxon>Example</fr:taxon>
                                      </fr:frontmatter>
                                      <fr:mainmatter>
                                        <html:p>Example content...</html:p>
                                      </fr:mainmatter>
                                    </fr:tree>
                                  </fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2026</fr:year>
                                      <fr:month>2</fr:month>
                                      <fr:day>11</fr:day>
                                    </fr:date>
                                    <fr:uri>https://kaierikniermann.github.io/notes/006l/</fr:uri>
                                    <fr:display-uri>006l</fr:display-uri>
                                    <fr:route>/notes/006l/</fr:route>
                                    <fr:title text="Model and pointed model">Model and pointed model</fr:title>
                                    <fr:taxon>Definition</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <fr:tree show-metadata="false">
                                      <fr:frontmatter>
                                        <fr:authors />
                                        <fr:date>
                                          <fr:year>2026</fr:year>
                                          <fr:month>2</fr:month>
                                          <fr:day>11</fr:day>
                                        </fr:date>
                                        <fr:uri>https://kaierikniermann.github.io/notes/006m/</fr:uri>
                                        <fr:display-uri>006m</fr:display-uri>
                                        <fr:route>/notes/006m/</fr:route>
                                        <fr:title text="Model example">Model example</fr:title>
                                        <fr:taxon>Example</fr:taxon>
                                      </fr:frontmatter>
                                      <fr:mainmatter>
                                        <html:p>Example content...</html:p>
                                      </fr:mainmatter>
                                    </fr:tree>
                                  </fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2026</fr:year>
                                      <fr:month>2</fr:month>
                                      <fr:day>11</fr:day>
                                    </fr:date>
                                    <fr:uri>https://kaierikniermann.github.io/notes/006n/</fr:uri>
                                    <fr:display-uri>006n</fr:display-uri>
                                    <fr:route>/notes/006n/</fr:route>
                                    <fr:title text="Local truth">Local truth</fr:title>
                                    <fr:taxon>Definition</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>Definition text...</html:p>
                                    <fr:tree show-metadata="false">
                                      <fr:frontmatter>
                                        <fr:authors />
                                        <fr:date>
                                          <fr:year>2026</fr:year>
                                          <fr:month>2</fr:month>
                                          <fr:day>11</fr:day>
                                        </fr:date>
                                        <fr:uri>https://kaierikniermann.github.io/notes/006o/</fr:uri>
                                        <fr:display-uri>006o</fr:display-uri>
                                        <fr:route>/notes/006o/</fr:route>
                                        <fr:title text="Local truth in a model">Local truth in a model</fr:title>
                                        <fr:taxon>Example</fr:taxon>
                                      </fr:frontmatter>
                                      <fr:mainmatter>
                                        <html:p>Example content...</html:p>
                                      </fr:mainmatter>
                                    </fr:tree>
                                  </fr:mainmatter>
                                </fr:tree>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2026</fr:year>
                                  <fr:month>2</fr:month>
                                  <fr:day>11</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0065/</fr:uri>
                                <fr:display-uri>0065</fr:display-uri>
                                <fr:route>/notes/0065/</fr:route>
                                <fr:title text="Dualities">Dualities</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <html:p>Content</html:p>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2026</fr:year>
                                  <fr:month>2</fr:month>
                                  <fr:day>11</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/0068/</fr:uri>
                                <fr:display-uri>0068</fr:display-uri>
                                <fr:route>/notes/0068/</fr:route>
                                <fr:title text="Syntax and semantics of prop1">Syntax and semantics of prop1</fr:title>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2026</fr:year>
                                      <fr:month>2</fr:month>
                                      <fr:day>11</fr:day>
                                    </fr:date>
                                    <fr:uri>https://kaierikniermann.github.io/notes/0066/</fr:uri>
                                    <fr:display-uri>0066</fr:display-uri>
                                    <fr:route>/notes/0066/</fr:route>
                                    <fr:title text="Syntax of prop1">Syntax of prop1</fr:title>
                                    <fr:taxon>Definition</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>Content</html:p>
                                  </fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2026</fr:year>
                                      <fr:month>2</fr:month>
                                      <fr:day>11</fr:day>
                                    </fr:date>
                                    <fr:uri>https://kaierikniermann.github.io/notes/0067/</fr:uri>
                                    <fr:display-uri>0067</fr:display-uri>
                                    <fr:route>/notes/0067/</fr:route>
                                    <fr:title text="Semantics of prop1">Semantics of prop1</fr:title>
                                    <fr:taxon>Definition</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>Content</html:p>
                                  </fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2026</fr:year>
                                      <fr:month>2</fr:month>
                                      <fr:day>11</fr:day>
                                    </fr:date>
                                    <fr:uri>https://kaierikniermann.github.io/notes/006c/</fr:uri>
                                    <fr:display-uri>006c</fr:display-uri>
                                    <fr:route>/notes/006c/</fr:route>
                                    <fr:title text="prop1 example">prop1 example</fr:title>
                                    <fr:taxon>Example</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>Example content...</html:p>
                                  </fr:mainmatter>
                                </fr:tree>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2026</fr:year>
                                      <fr:month>2</fr:month>
                                      <fr:day>11</fr:day>
                                    </fr:date>
                                    <fr:uri>https://kaierikniermann.github.io/notes/006e/</fr:uri>
                                    <fr:display-uri>006e</fr:display-uri>
                                    <fr:route>/notes/006e/</fr:route>
                                    <fr:title text="Soundness and completeness">Soundness and completeness</fr:title>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>Content</html:p>
                                  </fr:mainmatter>
                                </fr:tree>
                              </fr:mainmatter>
                            </fr:tree>
                            <fr:tree show-metadata="false">
                              <fr:frontmatter>
                                <fr:authors />
                                <fr:date>
                                  <fr:year>2026</fr:year>
                                  <fr:month>2</fr:month>
                                  <fr:day>11</fr:day>
                                </fr:date>
                                <fr:uri>https://kaierikniermann.github.io/notes/006a/</fr:uri>
                                <fr:display-uri>006a</fr:display-uri>
                                <fr:route>/notes/006a/</fr:route>
                                <fr:title text="Hilbert style proof system">Hilbert style proof system</fr:title>
                                <fr:taxon>Definition</fr:taxon>
                              </fr:frontmatter>
                              <fr:mainmatter>
                                <fr:tree show-metadata="false">
                                  <fr:frontmatter>
                                    <fr:authors />
                                    <fr:date>
                                      <fr:year>2026</fr:year>
                                      <fr:month>2</fr:month>
                                      <fr:day>11</fr:day>
                                    </fr:date>
                                    <fr:uri>https://kaierikniermann.github.io/notes/006d/</fr:uri>
                                    <fr:display-uri>006d</fr:display-uri>
                                    <fr:route>/notes/006d/</fr:route>
                                    <fr:title text="Hilbert proof example">Hilbert proof example</fr:title>
                                    <fr:taxon>Example</fr:taxon>
                                  </fr:frontmatter>
                                  <fr:mainmatter>
                                    <html:p>Example content...</html:p>
                                  </fr:mainmatter>
                                </fr:tree>
                              </fr:mainmatter>
                            </fr:tree>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2026</fr:year>
                              <fr:month>2</fr:month>
                              <fr:day>11</fr:day>
                            </fr:date>
                            <fr:uri>https://kaierikniermann.github.io/notes/0063/</fr:uri>
                            <fr:display-uri>0063</fr:display-uri>
                            <fr:route>/notes/0063/</fr:route>
                            <fr:title text="Lecture 2">Lecture 2</fr:title>
                            <fr:taxon>VU-AL-2026</fr:taxon>
                          </fr:frontmatter>
                          <fr:mainmatter />
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>2</fr:month>
                          <fr:day>11</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005o/</fr:uri>
                        <fr:display-uri>005o</fr:display-uri>
                        <fr:route>/notes/005o/</fr:route>
                        <fr:title text="Week 2">Week 2</fr:title>
                        <fr:taxon>VU-AL-2026</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>2</fr:month>
                          <fr:day>11</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005p/</fr:uri>
                        <fr:display-uri>005p</fr:display-uri>
                        <fr:route>/notes/005p/</fr:route>
                        <fr:title text="Week 3">Week 3</fr:title>
                        <fr:taxon>VU-AL-2026</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>2</fr:month>
                          <fr:day>11</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005q/</fr:uri>
                        <fr:display-uri>005q</fr:display-uri>
                        <fr:route>/notes/005q/</fr:route>
                        <fr:title text="Week 4">Week 4</fr:title>
                        <fr:taxon>VU-AL-2026</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>2</fr:month>
                          <fr:day>11</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005r/</fr:uri>
                        <fr:display-uri>005r</fr:display-uri>
                        <fr:route>/notes/005r/</fr:route>
                        <fr:title text="Week 5">Week 5</fr:title>
                        <fr:taxon>VU-AL-2026</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>2</fr:month>
                          <fr:day>11</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005s/</fr:uri>
                        <fr:display-uri>005s</fr:display-uri>
                        <fr:route>/notes/005s/</fr:route>
                        <fr:title text="Week 6">Week 6</fr:title>
                        <fr:taxon>VU-AL-2026</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>2</fr:month>
                          <fr:day>11</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005t/</fr:uri>
                        <fr:display-uri>005t</fr:display-uri>
                        <fr:route>/notes/005t/</fr:route>
                        <fr:title text="Week 7">Week 7</fr:title>
                        <fr:taxon>VU-AL-2026</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:date>
                      <fr:year>2026</fr:year>
                      <fr:month>2</fr:month>
                      <fr:day>11</fr:day>
                    </fr:date>
                    <fr:uri>https://kaierikniermann.github.io/notes/005m/</fr:uri>
                    <fr:display-uri>005m</fr:display-uri>
                    <fr:route>/notes/005m/</fr:route>
                    <fr:title text="Term Rewriting Systems">Term Rewriting Systems</fr:title>
                    <fr:taxon>VU-TRS-2026</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>2</fr:month>
                          <fr:day>11</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005u/</fr:uri>
                        <fr:display-uri>005u</fr:display-uri>
                        <fr:route>/notes/005u/</fr:route>
                        <fr:title text="Week 1">Week 1</fr:title>
                        <fr:taxon>VU-TRS-2026</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>2</fr:month>
                          <fr:day>11</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005v/</fr:uri>
                        <fr:display-uri>005v</fr:display-uri>
                        <fr:route>/notes/005v/</fr:route>
                        <fr:title text="Week 2">Week 2</fr:title>
                        <fr:taxon>VU-TRS-2026</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>2</fr:month>
                          <fr:day>11</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005w/</fr:uri>
                        <fr:display-uri>005w</fr:display-uri>
                        <fr:route>/notes/005w/</fr:route>
                        <fr:title text="Week 3">Week 3</fr:title>
                        <fr:taxon>VU-TRS-2026</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>2</fr:month>
                          <fr:day>11</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005x/</fr:uri>
                        <fr:display-uri>005x</fr:display-uri>
                        <fr:route>/notes/005x/</fr:route>
                        <fr:title text="Week 4">Week 4</fr:title>
                        <fr:taxon>VU-TRS-2026</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>2</fr:month>
                          <fr:day>11</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005y/</fr:uri>
                        <fr:display-uri>005y</fr:display-uri>
                        <fr:route>/notes/005y/</fr:route>
                        <fr:title text="Week 5">Week 5</fr:title>
                        <fr:taxon>VU-TRS-2026</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>2</fr:month>
                          <fr:day>11</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/005z/</fr:uri>
                        <fr:display-uri>005z</fr:display-uri>
                        <fr:route>/notes/005z/</fr:route>
                        <fr:title text="Week 6">Week 6</fr:title>
                        <fr:taxon>VU-TRS-2026</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2026</fr:year>
                          <fr:month>2</fr:month>
                          <fr:day>11</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/0060/</fr:uri>
                        <fr:display-uri>0060</fr:display-uri>
                        <fr:route>/notes/0060/</fr:route>
                        <fr:title text="Week 7">Week 7</fr:title>
                        <fr:taxon>VU-TRS-2026</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter />
                    </fr:tree>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
            <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
              <fr:frontmatter>
                <fr:authors />
                <fr:date>
                  <fr:year>2025</fr:year>
                  <fr:month>11</fr:month>
                  <fr:day>23</fr:day>
                </fr:date>
                <fr:uri>https://kaierikniermann.github.io/notes/001a/</fr:uri>
                <fr:display-uri>001a</fr:display-uri>
                <fr:route>/notes/001a/</fr:route>
                <fr:title text="Blog posts">Blog posts</fr:title>
              </fr:frontmatter>
              <fr:mainmatter>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:date>
                      <fr:year>2025</fr:year>
                      <fr:month>11</fr:month>
                      <fr:day>23</fr:day>
                    </fr:date>
                    <fr:uri>https://kaierikniermann.github.io/notes/001b/</fr:uri>
                    <fr:display-uri>001b</fr:display-uri>
                    <fr:route>/notes/001b/</fr:route>
                    <fr:title text="Understanding recursors with Lean4">Understanding recursors with Lean4</fr:title>
                    <fr:taxon>Blog</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>11</fr:month>
                          <fr:day>23</fr:day>
                        </fr:date>
                        <fr:title text="The recursor for natural numbers">The recursor for natural numbers</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>
    Before we define recursors, let's first introduce the idea of an inductive type. We'll do this by examining how lean defines natural numbers.
  </html:p>
                        <html:pre class="code-block language-lean">
                          <html:code class="language-lean">
    inductive Nat where
    | zero : Nat
    | succ (n : Nat) : Nat
  </html:code>
                        </html:pre>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>11</fr:month>
                          <fr:day>23</fr:day>
                        </fr:date>
                        <fr:title text="The recursor for natural numbers">The recursor for natural numbers</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter><html:p>
    Before we define recursors, let's first introduce the idea of an inductive type. We'll do this by examining how lean defines natural numbers.
  </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
    inductive Nat where
    | zero : Nat
    | succ (n : Nat) : Nat
  </html:code></html:pre><html:p>
    The idea here being that we can construct natural numbers by either using the constructor <html:code>zero</html:code> to get <html:code>0</html:code>, or by applying the constructor <html:code>succ</html:code> to an existing natural number to get its successor. For example, we can construct <html:code>3</html:code> as follows:
  </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
    def three : Nat := Nat.succ (Nat.succ (Nat.succ Nat.zero))
  </html:code></html:pre><html:p>
    We can equivalently express this definition using the type formation and term introduction rules:
  </html:p>
  
    
    <fr:resource hash="c76ba9ca452e4efa0a2374728195a21a"><fr:resource-content><html:img src="/notes/c76ba9ca452e4efa0a2374728195a21a.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
    \inferrule *[right=Form-Nat]{}{
      \mathbb {N} : \texttt {type}
    }
    \and  
    \inferrule *[right=Intro-Zero]{}{
      0 : \mathbb {N}
    }
    \and 
    \inferrule *[right=Intro-Succ]{
      n : \mathbb {N}
    }{
      \texttt {succ}\ n : \mathbb {N}
    }
  \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
    While this explanation for inductive types usually gives most people I think enough intuition to understand the basic notions of how to use them to construct something like natural numbers, I think it kind of misses the deeper idea of what an inductive type and by extension a recursor really is. To attempt to explain this we'll take a look into some categorical semantics behind inductive types.
  </html:p><fr:tree show-metadata="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>23</fr:day></fr:date><fr:uri>https://kaierikniermann.github.io/notes/001c/</fr:uri><fr:display-uri>001c</fr:display-uri><fr:route>/notes/001c/</fr:route><fr:title text="Natural Number Object (NNO)">Natural Number Object (NNO)</fr:title><fr:taxon>Definition</fr:taxon></fr:frontmatter><fr:mainmatter><html:p>
  We assume that <fr:tex display="inline"><![CDATA[\mathcal  L]]></fr:tex> is a category with a <fr:link href="/notes/001d/" title="Terminal Object (Category Theory)" uri="https://kaierikniermann.github.io/notes/001d/" display-uri="001d" type="local">terminal object</fr:link> <fr:tex display="inline"><![CDATA[1]]></fr:tex>. This category has a <html:em>natural number object</html:em> (NNO) if there exists an object <fr:tex display="inline"><![CDATA[\mathbb {N}]]></fr:tex> together with two morphisms:
</html:p><html:ul><html:li><fr:tex display="inline"><![CDATA[0 : 1 \to  \mathbb {N}]]></fr:tex></html:li>
  <html:li><fr:tex display="inline"><![CDATA[s : \mathbb {N} \to  \mathbb {N}]]></fr:tex></html:li></html:ul><html:p>
  such that, given any global element <fr:tex display="inline"><![CDATA[z : 1 \to  X]]></fr:tex> and any morphism <fr:tex display="inline"><![CDATA[f : X \to  X]]></fr:tex>, there exists a unique morphism <fr:tex display="inline"><![CDATA[u : \mathbb {N} \to  X]]></fr:tex> such that the following diagram commutes:
</html:p>
 
  
  <html:figure><fr:resource hash="451ab9726be7ca6a5fa1653caf21d4c5"><fr:resource-content><html:img src="/notes/451ab9726be7ca6a5fa1653caf21d4c5.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
   
   % String-diagram specific extensions live here. Add diagram tweaks without
 % re-running the full base preamble (to avoid duplicate definitions).

   
  
   \usepackage{eulervm}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{amsmath, amsthm, amsfonts}
  \usepackage{tikz, tikz-cd, mathtools, amssymb, stmaryrd}
  \usetikzlibrary{arrows.meta, shapes, positioning, calc, decorations.pathreplacing, backgrounds, fit, matrix, spath3}

  % A TikZ style for curved arrows of a fixed height, due to AndréC.
  \tikzset{curve/.style={settings={#1},to path={(\tikztostart)
        .. controls ($(\tikztostart)!\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
        and ($(\tikztostart)!1-\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
    .. (\tikztotarget)\tikztonodes}},
    settings/.code={\tikzset{quiver/.cd,#1}
    \def\pv##1{\pgfkeysvalueof{/tikz/quiver/##1}}},
  quiver/.cd,pos/.initial=0.35,height/.initial=0}

  % A TikZ style for shortening paths without the poor behaviour of `shorten <' and `shorten >'.
  \tikzset{between/.style n args={2}{/tikz/spath/at end path construction={
        \tikzset{spath/split at keep middle={current}{#1}{#2}}
  }}}

  % TikZ arrowhead/tail styles.
  \tikzset{tail reversed/.code={\pgfsetarrowsstart{tikzcd to}}}
  \tikzset{2tail/.code={\pgfsetarrowsstart{Implies[reversed]}}}
  \tikzset{2tail reversed/.code={\pgfsetarrowsstart{Implies}}}
  % TikZ arrow styles.
  \tikzset{no body/.style={/tikz/dash pattern=on 0 off 1mm}}


  ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[
  \begin {tikzcd}
    1 \arrow [r, "0"] \arrow [dr, "z"'] & \mathbb {N} \arrow [d, "u"] \arrow [r, "s"] & \mathbb {N} \arrow [d, "u"] \\
    & X \arrow [r, "f"'] & X
  \end {tikzcd}
]]></fr:resource-source></fr:resource></html:figure>
 
</fr:mainmatter></fr:tree><html:p>
    While at first this definition seems a bit needlessly abstract, it actually captures what the inductive type of natural numbers really is. The basic thing to recognize is that the two morphisms (just think of them as functions for now) in reality don't have anything to do with natural numbers directly. Instead, they act as a kind of blueprint for how we can use the properties or constraints of natural numbers to make anything. Here on a high level we can describe the two functions / constructors as follows:
  </html:p><html:ul><html:li><fr:tex display="inline"><![CDATA[0 : 1 \to  \mathbb {N}]]></fr:tex> - The represents the abstract idea of having some starting point or base case. Within natural numbers this is represented by <html:code>0</html:code>, but in reality it denotes an abstract concept of having a starting point.
    </html:li>
    <html:li><fr:tex display="inline"><![CDATA[s : \mathbb {N} \to  \mathbb {N}]]></fr:tex> - This represents the abstract idea of being able to build upon existing things to create new things. Within natural numbers this is represented by the successor function.
    </html:li></html:ul><html:p>
    Now this might quite fairly still seem a bit confusing and abstract. How can we <html:em>use properties</html:em> to <html:em>make anything?</html:em>. To describe this more formally lets constrain ourselves to the category of sets, <fr:tex display="inline"><![CDATA[\mathbf {Set}]]></fr:tex>. If you are unfamiliar with category theory it's sufficient to think of this as just a collection of all kinds of sets and functions between them.
  </html:p><fr:tree show-metadata="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>23</fr:day></fr:date><fr:uri>https://kaierikniermann.github.io/notes/001e/</fr:uri><fr:display-uri>001e</fr:display-uri><fr:route>/notes/001e/</fr:route><fr:title text="Natural Number Object (NNO) in Set">Natural Number Object (NNO) in Set</fr:title><fr:taxon>Example</fr:taxon></fr:frontmatter><fr:mainmatter><html:p>
  In the category <html:strong>Set</html:strong>, the natural number object (NNO) can be represented by the set of natural numbers <fr:tex display="inline"><![CDATA[\mathbb {N} = \{0, 1, 2, 3, \ldots \}]]></fr:tex>. If we take some arbitrary other set <fr:tex display="inline"><![CDATA[X]]></fr:tex> with some point <fr:tex display="inline"><![CDATA[x : 1 \to  X]]></fr:tex> (which can be identified with an element of <fr:tex display="inline"><![CDATA[X]]></fr:tex>) and some function <fr:tex display="inline"><![CDATA[f : X \to  X]]></fr:tex>, we can define a unique function <fr:tex display="inline"><![CDATA[u : \mathbb {N} \to  X]]></fr:tex> as follows:
</html:p><fr:tex display="block"><![CDATA[
  u(n) = \begin {cases}
  x & \text {if } n = 0 \\
  f^n(x) & \text {if } n \geq  0
  \end {cases}
]]></fr:tex></fr:mainmatter></fr:tree><html:p>
    So in plain English what this is saying is that given any set <fr:tex display="inline"><![CDATA[X]]></fr:tex> where we have some starting point <fr:tex display="inline"><![CDATA[x \in  X]]></fr:tex> and some way of building upon existing elements of <fr:tex display="inline"><![CDATA[X]]></fr:tex> (the function <fr:tex display="inline"><![CDATA[f : X \to  X]]></fr:tex>), we can use the properties of natural numbers to create a unique function <fr:tex display="inline"><![CDATA[u : \mathbb {N} \to  X]]></fr:tex> that maps natural numbers to elements of <fr:tex display="inline"><![CDATA[X]]></fr:tex> in a way that respects our starting point and building function. A natural next question to have might be
  </html:p><html:blockquote>
    But what does it mean to <html:em>respect</html:em> the starting point and building function?
  </html:blockquote><html:p>
    Here I'd fast say intuitively you can just imagine construct which has some notion of a start and some way of building upon existing things. For example let's imagine the following graph:
  </html:p><fr:tex display="block"><![CDATA[
    a \to  b \to  c \to  d \to  e \to  \ldots 
  ]]></fr:tex><html:p>
    Clearly here with have:
  </html:p><html:ul><html:li><html:strong>Starting point</html:strong>: Our start here is the node <fr:tex display="inline"><![CDATA[a]]></fr:tex>.
    </html:li>
    <html:li><html:strong>Building function</html:strong>: Our building function i.e. successor mechanism here is just following the arrows to the next node.
    </html:li></html:ul><html:p>
    So our two morphisms then are:
  </html:p><html:ul><html:li><fr:tex display="inline"><![CDATA[x : 1 \to  X]]></fr:tex> where <fr:tex display="inline"><![CDATA[x]]></fr:tex> maps to <fr:tex display="inline"><![CDATA[a]]></fr:tex>.
    </html:li>
    <html:li><fr:tex display="inline"><![CDATA[f : X \to  X]]></fr:tex> where <fr:tex display="inline"><![CDATA[f]]></fr:tex> maps each node to the next node along the arrow. That is
      <html:pre class="code-block language-lean"><html:code class="language-lean">
        f(a) = b
        f(b) = c
        f(c) = d
        f(d) = e
        ...
      </html:code></html:pre></html:li></html:ul><html:p>
    Creating a minimal replica of this in Lean we could do something like:
  </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
    inductive Node where
    | start : Node           -- this will play the role of “a”
    | next  : Node → Node

    def succNode (v : Node) : Node :=
      Node. next v

    def natToNode : ℕ → Node
      | 0       =&gt; Node.start
      | n + 1   =&gt; succNode (natToNode n)
  </html:code></html:pre><html:p>
    So we can see our function <fr:tex display="inline"><![CDATA[u : \mathbb {N} \to  X]]></fr:tex> here is represented by <html:code>natToNode</html:code>. Where the function maps <html:code>0</html:code> to <html:code>a</html:code> and each successor natural number to the next node along the arrow.
  </html:p><html:p>
    Something you might notice here is that if our <html:code>natToNode</html:code> function is replaced by just an identity, i.e.:
  </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
    def natToNat : ℕ → ℕ
      | 0       =&gt; 0
      | n + 1   =&gt; n + 1
  </html:code></html:pre><html:p>
    Then we get just the natural numbers themselves as defined by their properties. This is precisely what's expressed by the earlier commutative diagram we say. The two arrows:
  </html:p><fr:tex display="block"><![CDATA[
    1 \xrightarrow {0} \mathbb {N}
    \quad  \text { and } \quad  \mathbb {N} \xrightarrow {s} \mathbb {N}
  ]]></fr:tex><html:p>
    Are just the natural numbers defined by their properties. So in a sense the natural numbers are the most basic instantiation of their own properties. So now a fair thing to wonder is:
  </html:p><html:blockquote>
    So what does this have to do with recursers?
  </html:blockquote><html:p>
    Well the key insight here is that our functions <html:code>natToNat</html:code> and <html:code>natToNode</html:code> both <html:em>are our recursers</html:em> for the natural numbers. A recursor is just a function that allows us to define functions <html:em>out of</html:em> an inductive type by specifying how to handle each constructor of the inductive type. So equivalently we can express our recursor for natural numbers as:
  </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
    def recNat {C : Type} (z : C) (s : C → C) : ℕ → C
      | 0       =&gt; z
      | n + 1   =&gt; s (recNat z s n)
  </html:code></html:pre><html:p>
    If we examine the actual type signature generated by <html:code>#check Nat.rec</html:code> we have:
    </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
      «Nat».rec.{u}
      {motive : ℕ → Sort u}
      (zero : motive «Nat».zero)
      (succ : (n : ℕ)
        → motive n
        → motive n.succ)
      (t : ℕ) : motive t
    </html:code></html:pre><html:p>
      In our examples above we can see that the <html:code>motive</html:code> is just the type we are mapping to (either <fr:tex display="inline"><![CDATA[\mathbb {N}]]></fr:tex> or <fr:tex display="inline"><![CDATA[X]]></fr:tex>), the <html:code>zero</html:code> is our starting point (either <html:code>0</html:code> or <html:code>a</html:code>) and the <html:code>succ</html:code> is our building function (either the successor function or following the arrows). So using the recursor we can rewrite our earlier <html:code>natToNat</html:code> and <html:code>natToNode</html:code> functions as:
    </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
      def natToNat : ℕ → ℕ :=
        Nat.rec
          0                 -- | 0     =&gt; 0
          (fun n =&gt; n + 1)  -- | n + 1 =&gt; n + 1

      def natToNode : ℕ → Node :=
        Nat.rec
          Node.start            -- | 0     =&gt; Node.start
          (fun n =&gt; succNode n) -- | n + 1 =&gt; succNode (natToNode n)
    </html:code></html:pre></fr:mainmatter>
                    </fr:tree>
                    <html:p>
    This for the most part covers the basic idea of recursors for the sake of brevity I won't go into more instances of recursors for other inductive types though conceptually they work the same way. You specify how to handle each constructor of the inductive type and the recursor gives you a function that maps from the inductive type to whatever type you specified.
  </html:p>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>11</fr:month>
                          <fr:day>23</fr:day>
                        </fr:date>
                        <fr:title text="The connection to induction">The connection to induction</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>
      A very important property of recursors emerges when we make the motive dependent. To elaborate on what that means let's first consider the situation of simple stepwise induction.
    </html:p>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>23</fr:day>
                            </fr:date>
                            <fr:uri>https://kaierikniermann.github.io/notes/001f/</fr:uri>
                            <fr:display-uri>001f</fr:display-uri>
                            <fr:route>/notes/001f/</fr:route>
                            <fr:title text="Stepwise (Mathematical) Induction">Stepwise (Mathematical) Induction</fr:title>
                            <fr:taxon>Definition</fr:taxon>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
  Stepwise (mathematical/natural/ordinary) induction is a proof technique used to establish the truth of a statement <fr:tex display="inline"><![CDATA[P(n)]]></fr:tex> for all natural numbers <fr:tex display="inline"><![CDATA[n \in  \mathbb {N}]]></fr:tex>. The process involves two main steps:
</html:p>
                            <html:ol><html:li><html:strong>Base Case:</html:strong> Prove that the statement <fr:tex display="inline"><![CDATA[P(0)]]></fr:tex> is true.
  </html:li>
  <html:li><html:strong>Inductive Step:</html:strong> Assume that the statement <fr:tex display="inline"><![CDATA[P(k)]]></fr:tex> is true for some arbitrary natural number <fr:tex display="inline"><![CDATA[k \in  \mathbb {N}]]></fr:tex> (this assumption is called the <html:em>inductive hypothesis</html:em>). Then, using this assumption, prove that the statement <fr:tex display="inline"><![CDATA[P(k + 1)]]></fr:tex> is also true.
  </html:li></html:ol>
                            <html:p>
  If both the base case and the inductive step are successfully proven, we can conclude that the statement <fr:tex display="inline"><![CDATA[P(n)]]></fr:tex> holds for all natural numbers <fr:tex display="inline"><![CDATA[n \in  \mathbb {N}]]></fr:tex>. The concise formulation of this can be given by the induction principle.
</html:p>
                            <fr:tex display="block"><![CDATA[
  (P(0) \land  \forall  k \in  \mathbb {N}.\ (P(k) \to  P(k + 1))) \to  \forall  n \in  \mathbb {N}.\ P(n)
]]></fr:tex>
                          </fr:mainmatter>
                        </fr:tree>
                        <html:p>
      Something we can notice here just by superficial observation alone is that this seems to look an awful lot like the recursor for natural numbers we defined earlier. In fact, it <html:em>is</html:em> an application of the recursor for natural numbers for the <html:em>dependent</html:em> motive <fr:tex display="inline"><![CDATA[P : \mathbb {N} \to  \texttt {Prop}.]]></fr:tex>. To make this a little more concrete let's define a simple property over natural numbers:
    </html:p>
                        <html:pre class="code-block language-lean">
                          <html:code class="language-lean">
      def P (n : ℕ) : Prop := n + 0 = n
    </html:code>
                        </html:pre>
                        <html:p>
      Now its important to note that in an abstract sense this is no different from any other function from natural numbers to some type. The dependency comes into play when we try to use the recursor i.e. the properties of naturals with this motive.
    </html:p>
                        <html:pre class="code-block language-lean">
                          <html:code class="language-lean">
      def natToProp (n : ℕ) : (P n) :=
        Nat.rec
          (motive := P)
          (by simp [P])                    -- base case: P 0
          (fun n ih =&gt; by simp [P])        -- inductive step: P n → P (n+1)
          n
    </html:code>
                        </html:pre>
                        <html:p>
      A few things we can observe here:
    </html:p>
                        <html:ul><html:li>
        The recursor here represents a <html:em>dependent</html:em> function, which is to say that the return type of the function depends on the input value. Contrasting this to the earlier case where the return type was always just <fr:tex display="inline"><![CDATA[\mathbb {N}]]></fr:tex> or <fr:tex display="inline"><![CDATA[X]]></fr:tex>.
      </html:li>
      <html:li><html:strong>Base case</html:strong> - Importantly here as opposed to providing a function that returns some value of type <fr:tex display="inline"><![CDATA[C]]></fr:tex> for the base case, we instead provide a proof that the property <fr:tex display="inline"><![CDATA[P(0)]]></fr:tex> holds.
      </html:li>
      <html:li><html:strong>Inductive step</html:strong> - Similarly for the inductive step we provide a function that takes an arbitrary natural number <fr:tex display="inline"><![CDATA[n]]></fr:tex> and a proof that <fr:tex display="inline"><![CDATA[P(n)]]></fr:tex> holds (the inductive hypothesis) and returns a proof that <fr:tex display="inline"><![CDATA[P(n + 1)]]></fr:tex> holds.
      </html:li></html:ul>
                        <html:p>
      If we view this through the lens of the Curry-Howard correspondence it quite nicely illustrates how our proof here is just a program which constructs witnesses (valid proofs) for each natural number that the property <fr:tex display="inline"><![CDATA[P(n)]]></fr:tex> holds. In the same way that our earlier recursor provided elements on the correct type, this dependent recursor provides proofs on the correct property. As this application of a recursor to a proposition represents said proposition being true for all natural numbers, we can equivalently use this within a theorem.
    </html:p>
                        <html:pre class="code-block language-lean">
                          <html:code class="language-lean">
      theorem add_zero (n : ℕ) : n + 0 = n := natToProp n
    </html:code>
                        </html:pre>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>11</fr:month>
                          <fr:day>23</fr:day>
                        </fr:date>
                        <fr:title text="Case Study: Evaluating arithmetic expressions">Case Study: Evaluating arithmetic expressions</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter><html:p>
      As a little kind of case study I want to give an example of an inductive type (and its recursor) that most people become familiar with; in a sense; as early as primary school: the operational semantics of binary operators. We'll start by defining some basic syntax for arithmetic expressions:
    </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
      inductive BinOp where
      | add : BinOp
      | sub : BinOp
      | mul : BinOp
      | div : BinOp

      inductive Expr where
      | const : ℕ → Expr
      | binop : BinOp → Expr → Expr → Expr
    </html:code></html:pre><html:p>
      So here we have defined a simple language of arithmetic expressions consisting of natural number constants and binary operations. This provides us with the means to construct expressions like:
    </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
      #check Expr.binop BinOp.add (Expr.const 10) (Expr.const 20)
    </html:code></html:pre><html:p>
      If we want to actually define the semantics of how to evaluate these expressions we'll need to define a set of rewrite rules that describe how we can take an expression and reduce it to a value i.e. evaluate it. To evaluate an expression we want to traverse the expression tree and whenever we encounter a binary operation with two constant operands we want to apply the operation and replace the entire sub-expression with the resulting constant. We express this as 3 rewrite rules:
    </html:p><html:ul><html:li><html:strong>Left Evaluation</html:strong>: If the left operand of a binary operation can be reduced, then we reduce it.
      </html:li>
      <html:li><html:strong>Right Evaluation</html:strong>: If the left operand is a constant and the right operand can be reduced, then we reduce the right operand.
      </html:li>
      <html:li><html:strong>Operation Evaluation</html:strong>: If both operands are constants, we apply the binary operation and replace the entire sub-expression with the resulting constant.
      </html:li></html:ul><html:pre class="code-block language-lean"><html:code class="language-lean">
      def eval_op : BinOp → (Nat → Nat → Nat)
      | .add =&gt; Nat.add
      | .sub =&gt; Nat.sub
      | .mul =&gt; Nat.mul
      | .div =&gt; Nat.div

      inductive Step : Expr -&gt; Expr -&gt; Prop
      | ST_BinOp1 (op : BinOp)
          (e₁ e₁' e₂ : Expr)
          (h : Step e₁ e₁') :
          Step (Expr.binop op e₁ e₂)
               (Expr.binop op e₁' e₂)
      | ST_BinOp2 (op : BinOp)
          (v₁ : Nat)
          (e₂ e₂' : Expr)
          (h : Step e₂ e₂') :
          Step (Expr.binop op (Expr.const v₁) e₂)
               (Expr.binop op (Expr.const v₁) e₂')
      | ST_BinOpConst (op : BinOp) (v₁ v₂ : Nat) :
          Step (Expr.binop op (Expr.const v₁) (Expr.const v₂))
               (Expr.const (eval_op op v₁ v₂))
    </html:code></html:pre><html:p>
      Since expressions can naturally require multiple evaluations steps it makes sense to define a multistep evaluation relation as the reflexive transitive closure of the single step evaluation relation defined above. This we can define as:
    </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
      abbrev MultiStep := Relation.ReflTransGen Step

      -- helper notation to express multi-step evaluation
      notation:50 e " -&gt;ⁿ " e' =&gt;  MultiStep e e'
    </html:code></html:pre><html:p>
      Let's also define a small helper syntax and macro to make it easier to write arithmetic expressions:
    </html:p>
      
      <fr:tree show-metadata="false" expanded="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>23</fr:day></fr:date><fr:title text="A small arithmetic expression grammar">A small arithmetic expression grammar</fr:title></fr:frontmatter><fr:mainmatter><html:pre class="code-block language-lean"><html:code class="language-lean">
          declare_syntax_cat arithTm

          -- atoms
          syntax num                      : arithTm
          syntax "(" arithTm ")"          : arithTm

          -- multiplicative level (higher precedence)
          syntax:70 arithTm:70 "*" arithTm:71 : arithTm
          syntax:70 arithTm:70 "/" arithTm:71 : arithTm

          -- additive level (lower precedence)
          syntax:60 arithTm:60 "+" arithTm:61 : arithTm
          syntax:60 arithTm:60 "-" arithTm:61 : arithTm

          syntax "ex{" arithTm "}" : term

          macro_rules
            -- numerals
            | `(ex{ $n:num }) =&gt;
                `(Expr.const $n)

            -- parentheses
            | `(ex{ ($t:arithTm) }) =&gt;
                `(ex{$t})

            -- addition
            | `(ex{ $e₁:arithTm + $e₂:arithTm }) =&gt;
                `(Expr.binop BinOp.add (ex{$e₁}) (ex{$e₂}))

            -- subtraction
            | `(ex{ $e₁:arithTm - $e₂:arithTm }) =&gt;
                `(Expr.binop BinOp.sub (ex{$e₁}) (ex{$e₂}))

            -- multiplication
            | `(ex{ $e₁:arithTm * $e₂:arithTm }) =&gt;
                `(Expr.binop BinOp.mul (ex{$e₁}) (ex{$e₂}))

            -- division
            | `(ex{ $e₁:arithTm / $e₂:arithTm }) =&gt;
                `(Expr.binop BinOp.div (ex{$e₁}) (ex{$e₂}))
        </html:code></html:pre></fr:mainmatter></fr:tree>
    <fr:tree show-metadata="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>23</fr:day></fr:date><fr:title text="Describing arithmetic evaluation">Describing arithmetic evaluation</fr:title></fr:frontmatter><fr:mainmatter><html:p>
        Now say that we wanted to evaluate the expression <fr:tex display="inline"><![CDATA[((2 * 3) + 4)]]></fr:tex> on a high level what we would do is rewrite the multiplication to <fr:tex display="inline"><![CDATA[6 + 4]]></fr:tex> and then rewrite that to <fr:tex display="inline"><![CDATA[10]]></fr:tex>. Expressing this in lean we have:
      </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
        example : -- ((2 * 3) + 4) -&gt;ⁿ 10
        ex{ ((2 * 3) + 4) } -&gt;ⁿ ex{ 10 } :=
          .trans (rw_lhs (rw_const .mul 2 3)) (rw_const .add 6 4)
      </html:code></html:pre><html:p>
        Here we say that the expression <fr:tex display="inline"><![CDATA[((2 * 3) + 4)]]></fr:tex> after multiple steps evaluates to <fr:tex display="inline"><![CDATA[10]]></fr:tex> by first rewriting the left-hand side multiplication to <fr:tex display="inline"><![CDATA[6 + 4]]></fr:tex> and then rewriting that to <fr:tex display="inline"><![CDATA[10]]></fr:tex>. And we chain these operations together using the <html:code>.trans</html:code> constructor of the multistep evaluation relation. Now the question becomes, how do we define these rewrite steps? Intuitively we can imagine evaluation as being described by the following sort of graph
      </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
        +(lhs [op] rhs)
        |
        +-+(rw_lhs) -&gt;ⁿ lhs' [op] rhs    (1) reduce lhs some number of steps
          |
          +-+(rw_rhs) -&gt;ⁿ lhs [op] rhs'  (2) reduce rhs some number of steps
            |
            +- (rw_const) -&gt; value       (3) reduce both to a constant value
      </html:code></html:pre><html:p>
        The idea of each rule being that:
      </html:p><html:ul><html:li><html:strong>rw_lhs</html:strong>: If the left-hand side can be reduced some number of steps we can reduce it while keeping the right-hand side the same. This corresponds to the <html:code>ST_BinOp1</html:code> rule defined earlier.
        </html:li>
        <html:li><html:strong>rw_rhs</html:strong>: If the left-hand side is a constant we can reduce the right-hand side some number of steps while keeping the left-hand side the same. This corresponds to the <html:code>ST_BinOp2</html:code> rule defined earlier.
        </html:li>
        <html:li><html:strong>rw_const</html:strong>: If both sides are constants we can apply the binary operation and reduce the entire expression to a single constant value. This corresponds to the <html:code>ST_BinOpConst</html:code> rule defined earlier.
        </html:li></html:ul><html:p>
        As these rules are defined over the structure of multistep evaluation our implementation of them will naturally be in terms of the inductive structure of a multistep relationship:
      </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
        lemma rw_lhs (lhs_rw : lhs -&gt;ⁿ lhs') :
          (lhs [op] rhs) -&gt;ⁿ (lhs' [op] rhs) :=
        match lhs_rw with
        | .refl       =&gt; .refl
        | .tail S₁ S₂ =&gt; (rw_lhs S₁).tail (.ST_BinOp1 S₂)

        lemma rw_rhs (rhs_rw : rhs -&gt;ⁿ rhs') :
          ((.const lhs) [op] rhs) -&gt;ⁿ ((.const lhs) [op] rhs') :=
        match rhs_rw with
        | .refl       =&gt; .refl
        | .tail S₁ S₂ =&gt; (rw_rhs S₁).tail (.ST_BinOp2 S₂)

        lemma rw_const (op : BinOp) (lhs rhs : Nat) :
          ((.const lhs) [op] (.const rhs)) -&gt;ⁿ .const (eval_op op lhs rhs) :=
        .single (.ST_BinOpConst op lhs rhs)
      </html:code></html:pre><html:p>
        Alternatively we can specify the left and right rewrite rules using the recursor or or head induction principle for multistep evaluation:
      </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
        lemma rw_rhs' (rhs_rw : rhs -&gt;ⁿ rhs') :
          ((.const lhs) [op] rhs) -&gt;ⁿ ((.const lhs) [op] rhs') :=
        .rec
          (refl := .refl)
          (tail := by
            intro _ _ _ hcb ih
            exact ih.tail (.ST_BinOp2 hcb)
          ) rhs_rw

        lemma rw_rhs'' (rhs_rw : rhs -&gt;ⁿ rhs') :
          ((.const lhs) [op] rhs) -&gt;ⁿ ((.const lhs) [op] rhs') :=
        .head_induction_on
          (refl := .refl)
          (head := by
            intro _ _ hac _ ih
            exact ih.head (.ST_BinOp2 hac)
          ) rhs_rw
      </html:code></html:pre><html:p>
        The motive function here is inferred by Lean via the Lemma, which allos us to avoid having to explicitly specify it. Other than this we can see that the recursors again simply correspond to providing methods to describe what to do for each of the constructors.
      </html:p></fr:mainmatter></fr:tree><fr:tree show-metadata="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>23</fr:day></fr:date><fr:title text="Recursors describe usage">Recursors describe usage</fr:title></fr:frontmatter><fr:mainmatter><html:p>
        So at this point you might, I think fairly ask yourself:
      </html:p><html:blockquote>
        Wait why are you spending so much time on this random example for recursors?
      </html:blockquote><html:p>
        The main reason is that to me it provides one of the most grounded direct examples of what it means for a recursor function to <html:em>eliminate</html:em> a term of an inductive type. In general in type theory we say that <html:em>term elimination</html:em> represents the natural deduction rules for <html:em>how to use</html:em> terms of a given type. Applied to our example we can see that these recursors precisely correspond to the rules of how we evaluate i.e. <html:em>use</html:em> arithmetic expressions.
      </html:p><html:p>
        Each rewrite rule describes how we can take an expression and reduce it step by step until we reach a final value. So in a sense the recursor here <html:em>eliminates</html:em> the expression by providing a systematic way to break it down into its constituent parts and evaluate it. This is precisely the essence of what recursors do in type theory; they provide a way to systematically deconstruct and utilize terms of inductive types according to their defined structure and properties.
      </html:p></fr:mainmatter></fr:tree><fr:tree show-metadata="false"><fr:frontmatter><fr:authors /><fr:date><fr:year>2025</fr:year><fr:month>11</fr:month><fr:day>23</fr:day></fr:date><fr:title text="Proving correct evaluation">Proving correct evaluation</fr:title></fr:frontmatter><fr:mainmatter><html:p>
        One of the wonderful things we then naturally get from these recursors is that we can use them to describe how a correct evaluation works. So given our evaluation function:
      </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
        @[simp]
        def eval : Expr -&gt; Nat
          | Expr.const n =&gt; n
          | Expr.binop op e₁ e₂ =&gt;
              let v₁ := eval e₁
              let v₂ := eval e₂
              eval_op op v₁ v₂
      </html:code></html:pre><html:p>
        We can use the recursors describing the rewrite rules to show that this evaluation function for our expressions both yields a constant and that we have some sequence of reduction steps (application of rewrite rules) to get to said constant. Or expressed formally:
      </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
        (e : Expr) : -- for any expression e
          (∃ v : Nat), -- there exists a value v
            (eval e = v) ∧ (e -&gt;ⁿ (.const v))
            -- such that eval e = v and e reduces to the constant v
      </html:code></html:pre><html:p>
        The proof of this statement works by induction on the structure of the expression <html:code>e</html:code> if our expression represents a constant then the proof is trivial as we can just take the value of the constant itself. If our expression represents a binary operation then same as we showed for the concrete example we just apply our recursors to first rewrite the lhs, then the rhs and finally apply the operation to get the final constant value. In full the proof looks like:
      </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
        theorem eval_correct (e : Expr) :
        ∃ v : Nat, (eval e = v) ∧ (e -&gt;ⁿ (.const v)) := by
        induction e with
        | const n =&gt; exists n
        | binop op lhs rhs eval_lhs eval_rhs =&gt;
          rcases eval_lhs with ⟨lhs_v, ⟨rhs_is_v, lhs_rw⟩⟩
          rcases eval_rhs with ⟨rhs_v, ⟨lhs_is_v, rhs_rw⟩⟩
          simp [rhs_is_v, lhs_is_v]

          exact
            (rw_lhs lhs_rw).trans (
              (rw_rhs rhs_rw).trans (
                rw_const op lhs_v rhs_v
              )
            )
      </html:code></html:pre><html:p>
        In other words our proof for describing that our evaluation function is correct amounts to essentially simulating or describing quite literally how the evaluation works step by step using the recursors we defined earlier. To see precisely how <html:code>rcases</html:code> works here I'd recommend to paste the code into a Lean environment and examine the types of each of the intermediate values.
      </html:p></fr:mainmatter></fr:tree></fr:mainmatter>
                    </fr:tree>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:date>
                      <fr:year>2025</fr:year>
                      <fr:month>11</fr:month>
                      <fr:day>28</fr:day>
                    </fr:date>
                    <fr:uri>https://kaierikniermann.github.io/notes/002r/</fr:uri>
                    <fr:display-uri>002r</fr:display-uri>
                    <fr:route>/notes/002r/</fr:route>
                    <fr:title text="Type universes in Lean4">Type universes in Lean4</fr:title>
                    <fr:taxon>Blog</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>11</fr:month>
                          <fr:day>28</fr:day>
                        </fr:date>
                        <fr:title text="A brief overview">A brief overview</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>28</fr:day>
                            </fr:date>
                            <fr:title text="Universe hierarchy">Universe hierarchy</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter><html:p>
      In Lean4, types are organized into a hierarchy of <html:em>universes</html:em> (also referred to as <html:em>sorts</html:em>). Each universe is associated with a <html:em>level</html:em>, which is a natural number. The <fr:tex display="inline"><![CDATA[\texttt {Sort}]]></fr:tex> operator constructs a universe from a given level. To avoid things like Girard's paradox, Lean4 employs a stratified type system where each universe can only contain types from lower universes, we have the following hierarchy <fr:link href="/notes/baanen-bentkamp-blanchette-holzl-limperg-hitchhikers-2024/" title="The Hitchhiker’s Guide to Logical Verification (2024 Desktop Edition)" uri="https://kaierikniermann.github.io/notes/baanen-bentkamp-blanchette-holzl-limperg-hitchhikers-2024/" display-uri="baanen-bentkamp-blanchette-holzl-limperg-hitchhikers-2024" type="local">(1)</fr:link>:
    </html:p><fr:tex display="block"><![CDATA[
      \begin {align*}
      \texttt {Prop} : \texttt {Type 0} : \texttt {Type 1} : \texttt {Type 2} : \cdots  \\
      \texttt {Sort 0} : \texttt {Sort 1} : \texttt {Sort 2} : \texttt {Sort 3} : \cdots 
      \end {align*}
    ]]></fr:tex><html:p><fr:tex display="inline"><![CDATA[\texttt {Sort}]]></fr:tex> has two main aliases used in Lean4: <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> and <fr:tex display="inline"><![CDATA[\texttt {Type u}]]></fr:tex>. Here, <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> (which is equivalent to <fr:tex display="inline"><![CDATA[\texttt {Sort 0}]]></fr:tex>) is the universe of logical propositions, while <fr:tex display="inline"><![CDATA[\texttt {Type u}]]></fr:tex> (which is equivalent to <fr:tex display="inline"><![CDATA[\texttt {Sort (u + 1)}]]></fr:tex>) represents a universe of types at level <fr:tex display="inline"><![CDATA[u]]></fr:tex>. So we can say:
    </html:p><fr:tex display="block"><![CDATA[
      \texttt {Type u} \equiv  \texttt {Sort (u + 1)}
    ]]></fr:tex><fr:tex display="block"><![CDATA[
      \texttt {Prop} \equiv  \texttt {Sort 0}
    ]]></fr:tex><html:p>
      In general we can express the hierarchy for any universe level <fr:tex display="inline"><![CDATA[u]]></fr:tex> as follows:
    </html:p>
  
    
    <fr:resource hash="a3c29f626bfeab7896c406c2972da4df"><fr:resource-content><html:img src="/notes/a3c29f626bfeab7896c406c2972da4df.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
      \inferrule *[right=Sort]{}{
        \Gamma  \vdash  \texttt {Sort u} : \texttt {Sort (u + 1)}
      }
    \end {mathpar}]]></fr:resource-source></fr:resource>
  
</fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>28</fr:day>
                            </fr:date>
                            <fr:title text="Predicative universes">Predicative universes</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter><html:p>
      Except propositions, a type in a universe at level <fr:tex display="inline"><![CDATA[u]]></fr:tex> cannot quantify over types from strictly larger universes unless the whole result is lifted to a larger universe. In the case of types we have:
    </html:p>
  
    
    <fr:resource hash="6421c48de3f29311e497b41a79a808fd"><fr:resource-content><html:img src="/notes/6421c48de3f29311e497b41a79a808fd.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
      \inferrule *[right=ArrowType]{
        \Gamma  \vdash  \sigma  : \texttt {Type u} \\
        \Gamma  , x : \sigma  \vdash  \tau [x] : \texttt {Type v}
      }{
        \Gamma  \vdash  (x : \sigma ) \to  \tau [x] : \texttt {Type (max u v)}
      }
    \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
      To demonstrate some valid instance of this inference rule lets consider the following lean examples:
    </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
      example (α : Type 1) (β : Type 2) : Type 2 := α → β
      example (α : Type 2) (β : Type 1) : Type 2 := α → β
    </html:code></html:pre><html:p>
      Both of the above examples are valid because the resulting type is lifted to the maximum universe level of the input types. In general, we say that the behavior of the <fr:tex display="inline"><![CDATA[\texttt {Type}]]></fr:tex> universes is called <html:strong>predicative</html:strong> meaning that objects <html:em>may not</html:em> be defined in terms of quantifiers ranging over that same object.
    </html:p></fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>28</fr:day>
                            </fr:date>
                            <fr:title text="Impredicative universes">Impredicative universes</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter><html:p>
      We can observe that a function type's universe is determined by the universes of its argument and return types. However, in the case of propositions we have a different behavior:
    </html:p>
  
    
    <fr:resource hash="01b9da1304665deaca41d0e69e7e2b67"><fr:resource-content><html:img src="/notes/01b9da1304665deaca41d0e69e7e2b67.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
      \inferrule *[right=ArrowProp]{
        \Gamma  \vdash  \sigma  : \texttt {Sort u} \\ 
        \Gamma  , x : \sigma  \vdash  \tau [x] : \texttt {Prop}
      }{
        \Gamma  \vdash  (\forall  x : \sigma , \tau [x]) : \texttt {Prop}
      }
    \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
      Predicates, which are functions that return propositions, may have argument types in any universe, but the function itself remains in the <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> universe. This behavior is called <html:strong>impredicative</html:strong> meaning that objects <html:em>may</html:em> be defined in terms of quantifiers ranging over that same object. The rule <fr:tex display="inline"><![CDATA[\textsc {ArrowProp}]]></fr:tex> means that expressions such <fr:tex display="inline"><![CDATA[\forall  a : \texttt {Prop}, a \to  a]]></fr:tex>, which quantify over all propositions (including themselves), yield a proposition, that is:
    </html:p><fr:tex display="block"><![CDATA[
      (\forall  a : \texttt {Prop},\ a \to  a) : \texttt {Prop}
    ]]></fr:tex><html:p>
      We can see some more examples of quantifying both over propositions and types as follows:
    </html:p><html:pre class="code-block language-lean"><html:code class="language-lean">
      /-- Quantifying over propositions yields a proposition -/
      example : Prop := ∀ (P : Prop) (p1 p2 : P), p1 = p2

      /-- Proposition quantifying over all type stays in Prop -/
      example : Prop := ∀ (α : Type), ∀ (x : α), x = x
      example : Prop := ∀ (α : Type 5), ∀ (x : α), x = x
    </html:code></html:pre></fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>28</fr:day>
                            </fr:date>
                            <fr:title text="The general rule">The general rule</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter><html:p>
      We can combine these two rules to get a more general rule for function types that return types in any universe:
    </html:p>
  
    
    <fr:resource hash="0701b5f9a243365e0125751bf06c9e91"><fr:resource-content><html:img src="/notes/0701b5f9a243365e0125751bf06c9e91.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
     
    \usepackage{eulervm}
  \usepackage{mathtools}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{mathpartir}
  \usepackage{centernot}
  \usepackage[cal=cm]{mathalpha} % force \mathcal to CM-style callig

  \newcommand{\cf}[1]{\texttt{#1}}

    ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[\begin {mathpar}
      \inferrule *[right=Arrow]{
        \Gamma  \vdash  \sigma  : \texttt {Sort u} \\ 
        \Gamma  , x : \sigma  \vdash  \tau [x] : \texttt {Sort v}
      }{
        \Gamma  \vdash  (x : \sigma ) \to  \tau [x] : \texttt {Sort (imax u v)}
      }
    \end {mathpar}]]></fr:resource-source></fr:resource>
  
<html:p>
      Here the function type's universe is determined by the (impredicative max) <html:strong>imax</html:strong> of the universes of its argument and return types, where <fr:tex display="inline"><![CDATA[\texttt {imax}]]></fr:tex> is defined as follows:
    </html:p><fr:tex display="block"><![CDATA[
      \texttt {imax}(u, v) = \begin {cases}
      0 & \text {if } v = 0 \\
      \texttt {max}(u, v) & \text {otherwise}
      \end {cases}
    ]]></fr:tex></fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>28</fr:day>
                            </fr:date>
                            <fr:title text="The level grammar">The level grammar</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
      We can describe the level grammar via the following inductive type:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      inductive Level
      | zero : Level
      | succ : Level → Level
      | max  : Level → Level → Level
      | imax : Level → Level → Level
    </html:code>
                            </html:pre>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>11</fr:month>
                          <fr:day>28</fr:day>
                        </fr:date>
                        <fr:title text="Universe Binding">Universe Binding</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>28</fr:day>
                            </fr:date>
                            <fr:title text="Explicit">Explicit</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
      We can define functions and types that are <html:strong>universe polymorphic</html:strong> by introducing universe levels either <html:em>explicitly</html:em> or <html:em>implicitly</html:em>. An explicit universe level is specified directly in the definition, while an implicit universe level is inferred by Lean4. For example:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
        /-- Explicit universe level -/
        def map.{u v} {α : Type u} {β : Type v} 
            (f : α → β) : List α → List β :=
          | []       ⇒ []
          | x :: xs  =&gt; f x :: map f xs
      </html:code>
                            </html:pre>
                            <html:p>
      Here the map is declared with explicit universe levels <fr:tex display="inline"><![CDATA[u]]></fr:tex> and <fr:tex display="inline"><![CDATA[v]]></fr:tex> and instantiates the polymorphic <fr:tex display="inline"><![CDATA[\texttt {List}]]></fr:tex>. We can also define the same function with implicit universe levels as follows:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
        universe u v
        def map {α : Type u} {β : Type v} 
            (f : α → β) : List α → List β := ...
      </html:code>
                            </html:pre>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>28</fr:day>
                            </fr:date>
                            <fr:title text="Implicit">Implicit</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
      By default in Lean4 the option <fr:tex display="inline"><![CDATA[\texttt {autoImplicit}]]></fr:tex> is set to true, meaning that our universe levels will be inferred automatically meaning that we can simply write:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
        def map {α : Type u} {β : Type v} 
            (f : α → β) : List α → List β := ...
      </html:code>
                            </html:pre>
                            <html:p>
      Importantly automatic implicit parameter inference <html:em>only works</html:em> if the universe is mentioned in the header preceding the assignment, i.e:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
        /-- Bad: unknown universe u -/
        def L := List (Type u)
        /-- Good: universe u mentioned in header -/
        def L.{u} := List (Type u)
      </html:code>
                            </html:pre>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>28</fr:day>
                            </fr:date>
                            <fr:title text="Implicit + fresh">Implicit + fresh</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
      We can also go even further with implicit universes by allowing Lean4 to generate fresh universe levels for us. This is done by omitting the universe annotation and replacing it with a * suffix:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      /-- Fresh implicit universe levels -/
      def map {α : Type*} {β : Type*} 
          (f : α → β) : List α → List β := ...
    </html:code>
                            </html:pre>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>11</fr:month>
                          <fr:day>28</fr:day>
                        </fr:date>
                        <fr:title text="Universe Lifting">Universe Lifting</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>
    Sometimes we may want to explicitly lift a type from one universe to a higher universe. Lean4 provides lifting operators which are wrappers around terms of a type that reside in a higher universe. There are two main lifting operators:
  </html:p>
                        <html:ul><html:li><fr:tex display="inline"><![CDATA[\texttt {PLift}]]></fr:tex>: Lifts a proposition from <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex> (i.e. <fr:tex display="inline"><![CDATA[\texttt {Sort 1}]]></fr:tex>).
    </html:li>
    <html:li><fr:tex display="inline"><![CDATA[\texttt {ULift}]]></fr:tex>: Lifts a type from <fr:tex display="inline"><![CDATA[\texttt {Type u}]]></fr:tex> to any number of levels.
    </html:li></html:ul>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>28</fr:day>
                            </fr:date>
                            <fr:title text="PLift">PLift</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
      The <fr:tex display="inline"><![CDATA[\texttt {PLift}]]></fr:tex> operator is used to lift propositions into the first type universe. It is defined as follows:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      structure PLift (α : Sort u) : Type u where
        /-- Wraps a proof/value to increase its type's universe lvl -/
        up ::
        /-- Extracts a wrapped proof/value from a lifted prop/type. -/
        down : α
    </html:code>
                            </html:pre>
                            <html:p>
      Some simple examples:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      #check False       -- False : Prop
      #check PLift False -- PLift False : Type
      #check Nat         -- Nat : Type
      #check PLift Nat   -- PLift Nat : Type 1

      example : PLift Prop        := PLift.up True
      example : Prop              := (PLift.down (PLift.up False))
      example : List (PLift True) := [.up (by trivial), .up (by decide)]
    </html:code>
                            </html:pre>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>28</fr:day>
                            </fr:date>
                            <fr:title text="ULift">ULift</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
      The <fr:tex display="inline"><![CDATA[\texttt {ULift}]]></fr:tex> operator is used to lift types to higher universes. It is defined as follows:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      structure ULift.{r, s} (α : Type s) : Type (max s r) where
        /-- Wraps a value to increase its type's universe level. -/
        up ::
        /-- Extracts a wrapped value from a universe-lifted type. -/
        down : α
    </html:code>
                            </html:pre>
                            <html:p>
      Some simple examples:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      #check Nat               -- Nat : Type
      #check ULift Nat         -- ULift Nat : Type 1
      #check ULift (ULift Nat) -- ULift (ULift Nat) : Type 2

      example : ULift Nat        := ULift.up 42
      example : List (ULift Nat) := [.up 1, .up 2, .up 3]
    </html:code>
                            </html:pre>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>11</fr:month>
                          <fr:day>28</fr:day>
                        </fr:date>
                        <fr:title text="Example: Preorder Category">Example: Preorder Category</fr:title>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>
    A <html:em>preorder relation</html:em> is a binary relation that is <html:strong>reflexive</html:strong> and <html:strong>transitive</html:strong>. In Lean this is expressed as follows:
  </html:p>
                        <html:pre class="code-block language-lean">
                          <html:code class="language-lean">
    class Preorder (α : Type*) extends LE α, LT α where
      le_refl   : ∀ a : α, a ≤ a
      le_trans  : ∀ a b c : α, a ≤ b → b ≤ c → a ≤ c
      lt := fun a b =&gt; a ≤ b ∧ ¬b ≤ a
      lt_iff_le_not_ge : ∀ a b : α, a &lt; b ↔ a ≤ b ∧ ¬b ≤ a := by intros; rfl
  </html:code>
                        </html:pre>
                        <html:p>
    We can already see here that the preorder relation uses implicit universe polymorphism via the <fr:tex display="inline"><![CDATA[\texttt {Type*}]]></fr:tex> annotation. We can now construct a small category from a preorder relation as follows:
  </html:p>
                        <html:pre class="code-block language-lean">
                          <html:code class="language-lean">
    open CategoryTheory

    instance {α : Type u} [Preorder α] : SmallCategory α where
      Hom a b          := ULift &lt;| PLift (a ≤ b)
      id a             := .up &lt;| .up &lt;| le_refl a
      comp {a b c} f g := .up &lt;| .up &lt;| (le_trans f.down.down g.down.down)
  </html:code>
                        </html:pre>
                        <html:p>
    Let's break this down part by part starting with the homomorphism:
  </html:p>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>28</fr:day>
                            </fr:date>
                            <fr:title text="Arrows">Arrows</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
      For the case of the category definition, Lean fundamentally uses quivers to represent the homs between objects. Now before showing how lean defines them lets I think try and do it ourselves. So in this instance in an abstract sense we want the relationship <fr:tex display="inline"><![CDATA[\leq ]]></fr:tex> to represent our morphism or arrow between two objects, so in a sense the following two are equivalent:
    </html:p>
                            <fr:tex display="block"><![CDATA[
      a \leq  b \equiv  a \xrightarrow {\leq } b
    ]]></fr:tex>
                            <html:p>
      So in the most straightforward sense what we can do is define any kind of "container" to represent our source and target objects under some label, we can define this naively as follows:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      class Graph (Obj : Type) where
        arrow (source : Obj) (target : Obj) : Type
    </html:code>
                            </html:pre>
                            <html:p>
      Now let's try to define an instance of such a graph on a preorder relation in which our objects simply live in <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex>:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      instance {α : Type} [Preorder α] : Graph α where
        arrow a b := a ≤ b -- arrow from a to b is the relation a ≤ b
    </html:code>
                            </html:pre>
                            <html:p>
      Here we are declaring an instance, this instance takes
      <html:ul><html:li>
          An <html:strong>implicit type parameter</html:strong> <fr:tex display="inline"><![CDATA[\alpha ]]></fr:tex> which is the type of our objects at the universe level 0.
        </html:li>
        <html:li>
          A <html:strong>type class constraint</html:strong> <fr:tex display="inline"><![CDATA[\texttt {[Preorder α]}]]></fr:tex> which ensures that the type <fr:tex display="inline"><![CDATA[\alpha ]]></fr:tex> has a preorder relation defined on it. In other words it guarantees that the relation <fr:tex display="inline"><![CDATA[\leq ]]></fr:tex> is reflexive and transitive for all elements of type <fr:tex display="inline"><![CDATA[\alpha ]]></fr:tex>.
        </html:li></html:ul>
      And we provide the necessary implementation for the <fr:tex display="inline"><![CDATA[\texttt {arrow}]]></fr:tex> function by setting it to be the preorder relation <fr:tex display="inline"><![CDATA[\leq ]]></fr:tex>. But what you will notice is that we have a problem here, namely that our preorder relation lives in the universe <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> as it's obviously a logical relation, but our graph arrows need to live in <fr:tex display="inline"><![CDATA[\texttt {Type}]]></fr:tex> (i.e. <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex>). 
    </html:p>
                            <html:p>
      A first thought might be to just set the arrow type to be <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> directly, in our definition of the class <fr:tex display="inline"><![CDATA[\texttt {Graph}]]></fr:tex> though this is rather restrictive as it means that any graph we wish to define can only ever have arrows representing propositions, what if we want to have arrows represent other types such as functions or numbers?
    </html:p>
                            <html:p>
      One way to approach this is to use the <fr:tex display="inline"><![CDATA[\texttt {PLift}]]></fr:tex> operator to lift our preorder relation from <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex> as follows:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      instance {α : Type} [Preorder α] : Graph α where
        arrow a b := PLift (a ≤ b) -- lift relation to Type 0
    </html:code>
                            </html:pre>
                            <html:p>
      While this does work, and often is probably a reasonable way to go about things, much of Lean's mathlib employs universe polymorphic types to define various kinds of structures. Thus parameterizing over some universe level <fr:tex display="inline"><![CDATA[u]]></fr:tex> we define our polymorphic instance as:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      instance {α : Type u} [Preorder α] : Graph α where
        arrow a b := PLift (a ≤ b) 
    </html:code>
                            </html:pre>
                            <html:p>
      But now we naturally run into another issue, namely that the class for our graph is now no longer universe polymorphic which leads to a universe level mismatch. The most straightforward fix here is to simply make the objects in the graph universe polymorphic as well:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      class Graph (Obj : Type u) where -- now polymorphic over u
        arrow (source : Obj) (target : Obj) : Type
    </html:code>
                            </html:pre>
                            <html:p>
      But this leads to another question, what level should the arrows live in? We've already seen that arrows can represent various different kinds of things different from the types of objects themselves, (e.g. <fr:tex display="inline"><![CDATA[2 \leq  3]]></fr:tex> is a proposition but clearly 2 and 3 are numbers). Now one approach is to simply leave the arrows in <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex> but this already is mildly annoying as it forces us to lift any arrows that don't naturally live in <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex>. Furthermore, we've already seen that having the type stuck at Prop is also not nice, so what we can do is make the arrows' universe polymorphic as well, though over a different universe level <fr:tex display="inline"><![CDATA[v]]></fr:tex> motivated by the aforementioned situation of different levels of arrows and objects:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      class Graph (Obj : Type u) where
        arrow (source : Obj) (target : Obj) : Sort v

      instance {α : Type u} [Preorder α] : Graph α where
        arrow a b := a ≤ b -- now lives in Sort 0 (i.e. Prop)
    </html:code>
                            </html:pre>
                            <html:p>
      But hold up, why are we lifting in the definition of the instance for the SmallCategory? Let's take a look at all the relevant type signatures:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      -- Quiver 
      -- (V : Type u) where

      -- CategoryStruct
      -- (obj : Type u) : Type max u (v + 1) extends Quiver.{v + 1} obj

      -- Category 
      -- (obj : Type u) : Type max u (v + 1) extends CategoryStruct.{v} obj 

      -- SmallCategory
      -- (obj : Type u) : Type (u + 1) extends Category.{u} obj 
    </html:code>
                            </html:pre>
                            <html:p>
      Let's break this down step by step starting first with the relationship between CategoryStruct and Quiver, for the sake of simplicity i'll abstract away some exact names and make all universes explicit:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      variable {α : Type m} [Preorder α] (a b c : α)

      class Box.{u, v} (obj : Type u) where
        pair : obj → obj → Sort v

      class A.{u, v} (obj : Type u) 
        : Type max u (v + 1) extends (Box.{u, v + 1} obj) where
    </html:code>
                            </html:pre>
                            <html:p>
      I think an interesting question I first had here is with the extension of <fr:tex display="inline"><![CDATA[\texttt {Box}]]></fr:tex> in <fr:tex display="inline"><![CDATA[\texttt {A}]]></fr:tex> why might you want to increase the universe level of the arrows by one? The main reason this is done in general is to essentially constrain the <fr:tex display="inline"><![CDATA[v]]></fr:tex> to never be zero. The implication of this being that our extended class <fr:tex display="inline"><![CDATA[\texttt {A}]]></fr:tex> can never have any pairs which live in <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex>.
    </html:p>
                            <html:p>
      A good follow up to this might be, why would you not want things to live in <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex>? In the most general sense some reasons are:
    </html:p>
                            <html:ul><html:li><fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> is <html:em>proof irrelevant</html:em>: In Lean, propositions are considered proof irrelevant, meaning that all proofs of a given proposition are treated as equal. This can lead to loss of information when you want to be able to distinguish between different morphisms or in our simplified example pairs.
      </html:li>
      <html:li><fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> is <html:em>not computational</html:em>: Propositions in Lean are not computationally relevant, meaning that they do not have computational content. If you want to perform computations or extract algorithms from your morphisms or pairs, having them in <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> would prevent that.
      </html:li>
      <html:li><fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> has <html:em>limited structure</html:em>: Propositions in Lean do not have the same rich structure as types in higher universes. If you need to work with morphisms or pairs that have additional structure (like being functions, sets, etc.), you would want them to live in a higher universe.
      </html:li></html:ul>
                            <html:p>
      As an example we can consider the following:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      -- @classname disables universe inference for that class
      variable (a₁ : @A.{m, v} α)
      #check (a₁.pair a b : Sort (v + 1)) -- Box.pair a b : Type v
    </html:code>
                            </html:pre>
                            <html:p>
      We can see here that the pair now lives in <fr:tex display="inline"><![CDATA[\texttt {Sort (v + 1)}]]></fr:tex>, meaning that if we had <fr:tex display="inline"><![CDATA[v = 0]]></fr:tex> then our pairs would now live in <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex>. A natural byproduct of this choice - having arrows live in <fr:tex display="inline"><![CDATA[\texttt {Sort (v + 1)}]]></fr:tex> - is that the type of the structure itself must now live in the largest universe such that it can contain both the objects and the arrows. This is why we have the type signature <fr:tex display="inline"><![CDATA[\texttt {Type max u (v + 1)}]]></fr:tex> for <fr:tex display="inline"><![CDATA[\texttt {A}]]></fr:tex>. Equivalently we can expand this as:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      -- since Type u = Sort (u + 1) and Type (v + 1) = Sort (v + 2)
      Sort (max (u + 1) (v + 2)) 
    </html:code>
                            </html:pre>
                            <html:p>
      If we then create similarly abstract versions for the Category class (B) and SmallCategory class (C) we have:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      class B.{u, v} (obj : Type u) 
        : Type max u (v + 1) extends A.{u, v} obj where

      class C.{u} (obj : Type u) 
        : Type (u + 1) extends B.{u, u} obj where 
      --                        ^ can also type B.{u} (inferres v = u)
    </html:code>
                            </html:pre>
                            <html:p>
      We can see here that our SmallCategory (C) now constrains the arrows to live in the same universe as the objects by setting <fr:tex display="inline"><![CDATA[v = u]]></fr:tex> in the extension of <fr:tex display="inline"><![CDATA[\texttt {B}]]></fr:tex>. Thus, if we construct our pair, we have:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      variable (c : @C.{m} α)
      #check (c.pair a b : Sort (m + 1)) -- Box.pair a b : Type m
    </html:code>
                            </html:pre>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>28</fr:day>
                            </fr:date>
                            <fr:title text="Identity morphism">Identity morphism</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
      Next up let's look at the identity morphism:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      id a := .up &lt;| .up &lt;| le_refl a
    </html:code>
                            </html:pre>
                            <html:p>
      The identity is defined as a function that quantifies over all objects <fr:tex display="inline"><![CDATA[a]]></fr:tex> in our category and returns an arrow from <fr:tex display="inline"><![CDATA[a]]></fr:tex> to <fr:tex display="inline"><![CDATA[a]]></fr:tex>. Naturally we then first want to construct our arrow, the identity arrow from <fr:tex display="inline"><![CDATA[a]]></fr:tex> to <fr:tex display="inline"><![CDATA[a]]></fr:tex> is simply the reflexivity property of the preorder relation <fr:tex display="inline"><![CDATA[\leq ]]></fr:tex>, that is <fr:tex display="inline"><![CDATA[a \leq  a]]></fr:tex> which we can get via <fr:tex display="inline"><![CDATA[\texttt {le\_refl a}]]></fr:tex>. However since our arrows live in <fr:tex display="inline"><![CDATA[\texttt {Type m}]]></fr:tex>, we need to lift our relation twice, first using <fr:tex display="inline"><![CDATA[\texttt {PLift.up}]]></fr:tex> to lift it from <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex>, and then again using <fr:tex display="inline"><![CDATA[\texttt {ULift.up}]]></fr:tex> to lift it from <fr:tex display="inline"><![CDATA[\texttt {Type 0}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {Type m}]]></fr:tex>. A note to make for people unfamiliar with the syntax here, the following pieces of code are equivalent:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      -- .up &lt;| .up &lt;| le_refl a == ULift.up (PLift.up (le_refl a))
    </html:code>
                            </html:pre>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>28</fr:day>
                            </fr:date>
                            <fr:title text="Composition">Composition</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
      Finally let's look at the composition of arrows:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      comp {a b c} f g := .up &lt;| .up &lt;| (le_trans f.down.down g.down.down)
    </html:code>
                            </html:pre>
                            <html:p>
      The lifting portion here follows the same reasoning as the identity morphism, we need to lift the resulting relation from <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {Type m}]]></fr:tex>. The actual composition is done via the transitivity property of the preorder relation <fr:tex display="inline"><![CDATA[\leq ]]></fr:tex>. The thing is here that our input arrows <fr:tex display="inline"><![CDATA[f]]></fr:tex> and <fr:tex display="inline"><![CDATA[g]]></fr:tex> are both lifted types corresponding to:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      f : ULift (PLift (a ≤ b))
      g : ULift (PLift (b ≤ c))
    </html:code>
                            </html:pre>
                            <html:p>
      Thus to extract the actual preorder relations we need to use the <fr:tex display="inline"><![CDATA[\texttt {down}]]></fr:tex> method twice, first to go from <fr:tex display="inline"><![CDATA[\texttt {ULift}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {PLift}]]></fr:tex>, and then again to go from <fr:tex display="inline"><![CDATA[\texttt {PLift}]]></fr:tex> to the actual relation in <fr:tex display="inline"><![CDATA[\texttt {Prop}]]></fr:tex>. Once we have the two relations extracted we can then apply the transitivity property <fr:tex display="inline"><![CDATA[\texttt {le\_trans}]]></fr:tex> to get the composed relation <fr:tex display="inline"><![CDATA[a \leq  c]]></fr:tex> (which we then lift back up).
    </html:p>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                  </fr:mainmatter>
                </fr:tree>
                <fr:tree show-metadata="true" expanded="false" toc="false" numbered="false">
                  <fr:frontmatter>
                    <fr:authors />
                    <fr:date>
                      <fr:year>2025</fr:year>
                      <fr:month>11</fr:month>
                      <fr:day>29</fr:day>
                    </fr:date>
                    <fr:uri>https://kaierikniermann.github.io/notes/002u/</fr:uri>
                    <fr:display-uri>002u</fr:display-uri>
                    <fr:route>/notes/002u/</fr:route>
                    <fr:title text="A simple Bool category in Lean4">A simple Bool category in Lean4</fr:title>
                    <fr:taxon>Blog</fr:taxon>
                  </fr:frontmatter>
                  <fr:mainmatter>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>11</fr:month>
                          <fr:day>27</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/002m/</fr:uri>
                        <fr:display-uri>002m</fr:display-uri>
                        <fr:route>/notes/002m/</fr:route>
                        <fr:title text="Category">Category</fr:title>
                        <fr:taxon>Definition</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>
  There are a few ways you can define a <html:em>category</html:em>. In the most basic intuitive sense a category consists of a collection of things called <html:em>objects</html:em> and binary relationships (or transitions) between those objects called <html:em>morphisms</html:em> (or <html:em>arrows</html:em>). We can combine these relationships by <html:em>composing</html:em> them, and for each object there is an <html:em>identity morphism</html:em> that acts as a neutral element for composition. <fr:link href="/notes/nlab-category/" title="category" uri="https://kaierikniermann.github.io/notes/nlab-category/" display-uri="nlab-category" type="local">(1)</fr:link></html:p>
                        <html:p>
  In the context of <fr:link href="/notes/002l/" title="Quiver" uri="https://kaierikniermann.github.io/notes/002l/" display-uri="002l" type="local"><html:em>quivers</html:em></fr:link> a category can be defined as a quiver with a rule saying for how we can compose two edges that fit together to get a new edge. Furthermore, each vertex (object) has an edge starting and ending at that vertex (the identity morphism). The classical definition is something like this:
</html:p>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>27</fr:day>
                            </fr:date>
                            <fr:title text="The data">The data</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
    A <html:em>category</html:em> <fr:tex display="inline"><![CDATA[C]]></fr:tex> consists of:
  </html:p>
                            <html:ul><html:li>
      A collection (or <html:em>class</html:em> <fr:link href="/notes/johnson-yau-2d-categories-2020/" title="2-Dimensional Categories" uri="https://kaierikniermann.github.io/notes/johnson-yau-2d-categories-2020/" display-uri="johnson-yau-2d-categories-2020" type="local">(2)</fr:link>) of <html:strong>objects</html:strong>, denoted as <fr:tex display="inline"><![CDATA[\text {Ob}(C)]]></fr:tex> or <fr:tex display="inline"><![CDATA[C_0]]></fr:tex>.
    </html:li>
    <html:li>
      A collection (or <html:em>set</html:em> <fr:link href="/notes/johnson-yau-2d-categories-2020/" title="2-Dimensional Categories" uri="https://kaierikniermann.github.io/notes/johnson-yau-2d-categories-2020/" display-uri="johnson-yau-2d-categories-2020" type="local">(2)</fr:link>) of <html:strong>morphisms</html:strong> (or <html:em>arrows</html:em>), denoted <fr:tex display="inline"><![CDATA[C_1]]></fr:tex> or <fr:tex display="inline"><![CDATA[C(x, y)]]></fr:tex> for <fr:tex display="inline"><![CDATA[x, y \in  \text {Ob}(C)]]></fr:tex>.
      <html:ul><html:li>
          For every morphism <fr:tex display="inline"><![CDATA[f \in  C(x, y)]]></fr:tex>, there are two associated objects: the <html:em>source</html:em> (or <html:em>domain</html:em>) <fr:tex display="inline"><![CDATA[x]]></fr:tex> and the <html:em>target</html:em> (or <html:em>co-domain</html:em>) <fr:tex display="inline"><![CDATA[y]]></fr:tex>. In standard function notation, we write <fr:tex display="inline"><![CDATA[f: x \to  y]]></fr:tex> where <fr:tex display="inline"><![CDATA[x = \text {dom}(f)]]></fr:tex> and <fr:tex display="inline"><![CDATA[y = \text {cod}(f)]]></fr:tex>. NLab has a nice convention where it denotes the source <fr:tex display="inline"><![CDATA[s]]></fr:tex> of a morphism as <fr:tex display="inline"><![CDATA[s(f)]]></fr:tex> and the target <fr:tex display="inline"><![CDATA[t]]></fr:tex> as <fr:tex display="inline"><![CDATA[t(f)]]></fr:tex>.
        </html:li>
        <html:li>
          For every pair of morphisms <fr:tex display="inline"><![CDATA[f \in  C(x, y)]]></fr:tex> and <fr:tex display="inline"><![CDATA[g \in  C(y, z)]]></fr:tex> (s.t. <fr:tex display="inline"><![CDATA[t(f) = s(g)]]></fr:tex> i.e. the morphisms type check), there is a <html:strong>composition</html:strong> morphism <fr:tex display="inline"><![CDATA[g \circ  f \in  C(x, z)]]></fr:tex>. Written out we can denote this as:
          <fr:tex display="block"><![CDATA[
            C(x, y) \times  C(y, z) \to  C(x, z)
          ]]></fr:tex>
          in diagrammatic order this is often written as <fr:tex display="inline"><![CDATA[f; g]]></fr:tex> we can equivalently use a more graphical notation:
          
 
  
  <html:figure><fr:resource hash="d8323ce59463aa832587ad5330c42c75"><fr:resource-content><html:img src="/notes/d8323ce59463aa832587ad5330c42c75.svg" /></fr:resource-content><fr:resource-source type="latex" part="preamble"><![CDATA[
   
   % String-diagram specific extensions live here. Add diagram tweaks without
 % re-running the full base preamble (to avoid duplicate definitions).

   
  
   \usepackage{eulervm}
  \usepackage[scaled=0.92]{inconsolata}
  \usepackage{amsmath, amsthm, amsfonts}
  \usepackage{tikz, tikz-cd, mathtools, amssymb, stmaryrd}
  \usetikzlibrary{arrows.meta, shapes, positioning, calc, decorations.pathreplacing, backgrounds, fit, matrix, spath3}

  % A TikZ style for curved arrows of a fixed height, due to AndréC.
  \tikzset{curve/.style={settings={#1},to path={(\tikztostart)
        .. controls ($(\tikztostart)!\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
        and ($(\tikztostart)!1-\pv{pos}!(\tikztotarget)!\pv{height}!270:(\tikztotarget)$)
    .. (\tikztotarget)\tikztonodes}},
    settings/.code={\tikzset{quiver/.cd,#1}
    \def\pv##1{\pgfkeysvalueof{/tikz/quiver/##1}}},
  quiver/.cd,pos/.initial=0.35,height/.initial=0}

  % A TikZ style for shortening paths without the poor behaviour of `shorten <' and `shorten >'.
  \tikzset{between/.style n args={2}{/tikz/spath/at end path construction={
        \tikzset{spath/split at keep middle={current}{#1}{#2}}
  }}}

  % TikZ arrowhead/tail styles.
  \tikzset{tail reversed/.code={\pgfsetarrowsstart{tikzcd to}}}
  \tikzset{2tail/.code={\pgfsetarrowsstart{Implies[reversed]}}}
  \tikzset{2tail reversed/.code={\pgfsetarrowsstart{Implies}}}
  % TikZ arrow styles.
  \tikzset{no body/.style={/tikz/dash pattern=on 0 off 1mm}}


  ]]></fr:resource-source><fr:resource-source type="latex" part="body"><![CDATA[
          \[\begin {tikzcd}[column sep=small]
            x && y && z
            \arrow ["f", from=1-1, to=1-3]
            \arrow ["{f;g}", curve={height=-18pt}, from=1-1, to=1-5]
            \arrow ["g", from=1-3, to=1-5]
          \end {tikzcd}\]
        ]]></fr:resource-source></fr:resource></html:figure></html:li>
        <html:li>
          For every object <fr:tex display="inline"><![CDATA[x \in  \text {Ob}]]></fr:tex> there is an <html:strong>identity morphism</html:strong>:
          <fr:tex display="block"><![CDATA[
            (\text {id}_x : x \to  x) \in  C(x, x)
          ]]></fr:tex></html:li></html:ul>
      Note: Some additional notations for morphisms include <fr:tex display="inline"><![CDATA[\text {hom}(x, y)]]></fr:tex>, <fr:tex display="inline"><![CDATA[\text {hom}_C(x, y)]]></fr:tex> or <fr:tex display="inline"><![CDATA[C_1(x, y)]]></fr:tex>. Additionally, people use the notation <fr:tex display="inline"><![CDATA[\text {Mor(C)}]]></fr:tex> to denote the following disjoint union
      <fr:tex display="block"><![CDATA[
        \text {Mor}(C) = \bigsqcup _{x, y \in  \text {Ob}(C)} C(x, y)
      ]]></fr:tex>
      Which just expresses the idea that the collection of all morphisms in a category is made up of the morphisms between each pair of objects.
    </html:li></html:ul>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>27</fr:day>
                            </fr:date>
                            <fr:title text="The axioms">The axioms</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
    The above are often called <html:strong>data</html:strong> of a category. In addition to this data, a category must satisfy the following <html:strong>axioms</html:strong> or (<html:em>conditions</html:em>):
  </html:p>
                            <html:ul><html:li>
      Morphisms need to be <html:strong>associative</html:strong> which means that for every triple of morphisms <fr:tex display="inline"><![CDATA[f \in  C(w, x)]]></fr:tex>, <fr:tex display="inline"><![CDATA[g \in  C(x, y)]]></fr:tex>, and <fr:tex display="inline"><![CDATA[h \in  C(y, z)]]></fr:tex> the following holds:
      <fr:tex display="block"><![CDATA[
        h \circ  (g \circ  f) = (h \circ  g) \circ  f
      ]]></fr:tex></html:li>
    <html:li>
      For each morphism <fr:tex display="inline"><![CDATA[f \in  C(x, y)]]></fr:tex> the identity morphisms act as <html:strong>neutral elements</html:strong> for composition:
      <fr:tex display="block"><![CDATA[
        \text {id}_y \circ  f = f = f \circ  \text {id}_x
      ]]></fr:tex>
      This is also known as the <html:em>left</html:em> and <html:em>right</html:em> <html:strong>unit laws</html:strong> or just <html:strong>unity</html:strong> in general.
    </html:li></html:ul>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>27</fr:day>
                            </fr:date>
                            <fr:title text="Remarks">Remarks</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:ul>
                              <html:li>
      A category such as the one described above is often also called a 1-category to distinguish it from higher categories such as 2-categories, n-categories.
    </html:li>
                            </html:ul>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>11</fr:month>
                          <fr:day>29</fr:day>
                        </fr:date>
                        <fr:uri>https://kaierikniermann.github.io/notes/002s/</fr:uri>
                        <fr:display-uri>002s</fr:display-uri>
                        <fr:route>/notes/002s/</fr:route>
                        <fr:title text="Isomorphism (morphisms)">Isomorphism (morphisms)</fr:title>
                        <fr:taxon>Definition</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <html:p>
  A morphism <fr:tex display="inline"><![CDATA[f : X \to  Y]]></fr:tex> is called an <html:strong>Isomorphism</html:strong> if there exists a morphism <fr:tex display="inline"><![CDATA[g : Y \to  X]]></fr:tex> such that the following hold <fr:link href="/notes/johnson-yau-2d-categories-2020/" title="2-Dimensional Categories" uri="https://kaierikniermann.github.io/notes/johnson-yau-2d-categories-2020/" display-uri="johnson-yau-2d-categories-2020" type="local">(1)</fr:link>:
</html:p>
                        <fr:tex display="block"><![CDATA[
  g \circ  f = 1_X
  \quad 
  f \circ  g = 1_Y
]]></fr:tex>
                        <html:p>
  Sometimes an isomorphism is also denoted
</html:p>
                        <fr:tex display="block"><![CDATA[
  X \xrightarrow {\cong } Y
]]></fr:tex>
                      </fr:mainmatter>
                    </fr:tree>
                    <fr:tree show-metadata="false">
                      <fr:frontmatter>
                        <fr:authors />
                        <fr:date>
                          <fr:year>2025</fr:year>
                          <fr:month>11</fr:month>
                          <fr:day>29</fr:day>
                        </fr:date>
                        <fr:title text="The category">The category</fr:title>
                        <fr:taxon>Example</fr:taxon>
                      </fr:frontmatter>
                      <fr:mainmatter>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>29</fr:day>
                            </fr:date>
                            <fr:title text="The data">The data</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
      We want to start off by defining the data of our category. On a high level we want to define a category with two objects, <fr:tex display="inline"><![CDATA[\texttt {true}]]></fr:tex> and <fr:tex display="inline"><![CDATA[\texttt {false}]]></fr:tex>. Starting with the object representation we have:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      /-- A wrapper type to make a custom category on Bool -/
      structure BoolCat : Type where
        val : Bool
      deriving DecidableEq, Repr

      /-- The two objects -/
      def BoolCat.tt : BoolCat := ⟨true⟩
      def BoolCat.ff : BoolCat := ⟨false⟩
    </html:code>
                            </html:pre>
                            <html:p>
      Next we want to define the morphisms between these objects. For each pair of objects we express 3 kinds of morphisms: the identity morphism, a morphism from <fr:tex display="inline"><![CDATA[\texttt {false}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {true}]]></fr:tex>, <fr:tex display="inline"><![CDATA[\texttt {false}]]></fr:tex>from <fr:tex display="inline"><![CDATA[\texttt {true}]]></fr:tex> to <fr:tex display="inline"><![CDATA[\texttt {false}]]></fr:tex>. We can express this in Lean as follows:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      /-- Morphisms: we allow identity on each, plus iso between them -/
      inductive BCHom : BoolCat → BoolCat → Type
        | id (b : BoolCat) : BCHom b b
        | swap : BCHom BoolCat.tt BoolCat.ff
        | swapInv : BCHom BoolCat.ff BoolCat.tt
    </html:code>
                            </html:pre>
                            <html:p>
      Formally what this describes is a kind of piecewise function:
    </html:p>
                            <fr:tex display="block"><![CDATA[
      \text {f}(x, y) =
      \begin {cases}
      1_x &: x \to  x & \texttt {if } x = y \\
      \texttt {swap} &: \text {tt} \to  \text {ff} & \texttt {if } x = \text {tt} \land  y = \text {ff} \\
      \texttt {swapInv} &: \text {ff} \to  \text {tt} & \texttt {if } x = \text {ff} \land  y = \text {tt}
      \end {cases}
    ]]></fr:tex>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>29</fr:day>
                            </fr:date>
                            <fr:title text="Composition and Category instance">Composition and Category instance</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
      Now we have some notion of objects and morphisms between them, we can move on to defining composition of morphisms.
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      def comp : {X Y Z : BoolCat} → BCHom Y Z → BCHom X Y → BCHom X Z
        | _, _, _, id _, f =&gt; f
        | _, _, _, f, id _ =&gt; f
        | _, _, _, swapInv, swap =&gt; id _
        | _, _, _, swap, swapInv =&gt; id _
    </html:code>
                            </html:pre>
                            <html:p>
      This defines composition by pattern matching on the possible morphism combinations. Note that we have to explicitly handle the cases where we compose <fr:tex display="inline"><![CDATA[\texttt {swap}]]></fr:tex> and <fr:tex display="inline"><![CDATA[\texttt {swapInv}]]></fr:tex> to get the identity morphism on the respective objects. To construct our category we have to provide proofs for the category axioms, namely associativity and identity.
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      @[simp] theorem id_comp' {X Y : BoolCat} (f : BCHom X Y) 
          : comp (id Y) f = f := by
        cases f &lt;;&gt; rfl

      @[simp] theorem comp_id' {X Y : BoolCat} (f : BCHom X Y) 
          : comp f (id X) = f := by
        cases f &lt;;&gt; rfl

      theorem assoc'  (f : BCHom W X) (g : BCHom X Y) (h : BCHom Y Z) :
          comp h (comp g f) = comp (comp h g) f := by
        cases f &lt;;&gt; cases g &lt;;&gt; cases h &lt;;&gt; rfl
    </html:code>
                            </html:pre>
                            <html:p>
      With all this in place we can finally define our category instance:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      instance : Category BoolCat where
        -- The data
        Hom     := BCHom
        id      := BCHom. id
        comp    := fun f g =&gt; BCHom. comp g f

        -- Category laws
        id_comp := fun f     =&gt; BCHom.comp_id' f
        comp_id := fun f     =&gt; BCHom.id_comp' f
        assoc   := fun f g h =&gt; BCHom.assoc' f g h
    </html:code>
                            </html:pre>
                          </fr:mainmatter>
                        </fr:tree>
                        <fr:tree show-metadata="false">
                          <fr:frontmatter>
                            <fr:authors />
                            <fr:date>
                              <fr:year>2025</fr:year>
                              <fr:month>11</fr:month>
                              <fr:day>29</fr:day>
                            </fr:date>
                            <fr:title text="Isomorphisms in the Bool category">Isomorphisms in the Bool category</fr:title>
                          </fr:frontmatter>
                          <fr:mainmatter>
                            <html:p>
      Since we clearly see that the morphisms <fr:tex display="inline"><![CDATA[\texttt {swap}]]></fr:tex> and <fr:tex display="inline"><![CDATA[\texttt {swapInv}]]></fr:tex> are inverses of each other, we can construct an isomorphism between the two objects <fr:tex display="inline"><![CDATA[\texttt {tt}]]></fr:tex> and <fr:tex display="inline"><![CDATA[\texttt {ff}]]></fr:tex> as follows:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      def ttFfIso : BoolCat.tt ≅ BoolCat.ff where
        hom := BCHom.swap
        inv := BCHom.swapInv
        hom_inv_id := rfl
        inv_hom_id := rfl
    </html:code>
                            </html:pre>
                            <html:p>
      We can see that lean uses a similar notation for isomorphism as we do in our notes, namely the <fr:tex display="inline"><![CDATA[\texttt {≅}]]></fr:tex> symbol between the two objects. We can see that an isomorphism consists of a <fr:tex display="inline"><![CDATA[\texttt {hom}]]></fr:tex> and an <fr:tex display="inline"><![CDATA[\texttt {inv}]]></fr:tex> morphism along with proofs that composing them in either order yields the respective identity morphism. In Lean4 its defined as follows:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      structure Iso {C : Type u} [Category.{v} C] (X Y : C) where
        /-- The forward direction of an isomorphism. -/
        hom : X ⟶ Y
        /-- The backwards direction of an isomorphism. -/
        inv : Y ⟶ X
        /-- Composition is the identity on the source. -/
        hom_inv_id : hom ≫ inv = 𝟙 X := by cat_disch
        /-- Composition, in reverse, is the identity on the target. -/
        inv_hom_id : inv ≫ hom = 𝟙 Y := by cat_disch

      ...

      /-- Notation for an isomorphism in a category. -/
      infixr:10 " ≅ " =&gt; Iso 
    </html:code>
                            </html:pre>
                            <html:p>
      We can check out some properties of our isomorphism like so:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      -- Verify it's an isomorphism
      #check ttFfIso           -- BoolCat.tt ≅ BoolCat.ff
      #check ttFfIso.hom       -- BoolCat.tt ⟶ BoolCat.ff
      #check ttFfIso.inv       -- BoolCat.ff ⟶ BoolCat.tt
    </html:code>
                            </html:pre>
                            <html:p>
      Furthermore we can also show the identity isomorphism <fr:tex display="inline"><![CDATA[tt \cong  tt]]></fr:tex>:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      -- Every object is isomorphic to itself (trivially)
      def ttSelfIso : BoolCat.tt ≅ BoolCat.tt := Iso.refl _

      #check ttSelfIso -- BoolCat.tt ≅ BoolCat.tt
    </html:code>
                            </html:pre>
                            <html:p>
      Finally for the sake of completeness we can also demonstrate the isomorphism laws in examples as so:
    </html:p>
                            <html:pre class="code-block language-lean">
                              <html:code class="language-lean">
      -- The isomorphism laws
      example : ttFfIso.hom ≫ ttFfIso.inv = 𝟙 BoolCat.tt 
        := ttFfIso.hom_inv_id

      example : ttFfIso.inv ≫ ttFfIso.hom = 𝟙 BoolCat.ff 
        := ttFfIso.inv_hom_id
    </html:code>
                            </html:pre>
                          </fr:mainmatter>
                        </fr:tree>
                      </fr:mainmatter>
                    </fr:tree>
                  </fr:mainmatter>
                </fr:tree>
              </fr:mainmatter>
            </fr:tree>
          </fr:mainmatter>
        </fr:tree>
      </fr:mainmatter>
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Backlinks">Backlinks</fr:title>
      </fr:frontmatter>
      <fr:mainmatter />
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Related">Related</fr:title>
      </fr:frontmatter>
      <fr:mainmatter />
    </fr:tree>
    <fr:tree show-metadata="false" hidden-when-empty="true">
      <fr:frontmatter>
        <fr:authors />
        <fr:title text="Contributions">Contributions</fr:title>
      </fr:frontmatter>
      <fr:mainmatter />
    </fr:tree>
  </fr:backmatter>
</fr:tree>
