Jekyll2019-10-17T06:32:18+00:00https://ct075.github.io/feed.xmlThe Uncommon TrajectoryI do some code things.Cameron Wongcam@camdar.ioWhirlwind Introduction to Subtyping2019-10-17T00:00:00+00:002019-10-17T00:00:00+00:00https://ct075.github.io/2019-10-17/subtyping<p>(These notes are adapted from a lecture I gave for a student-run class on type
theory. See also the <a href="/assets/dist/subtyping.pdf">pdf version</a>)</p>
<p>The purpose of this text is to provide a high-level overview of the motivations
behind and basic theory of a subsumptive subtyping semantics over a
simply-typed lambda calculus similar to ML. In the interest of brevity, we will
elide a formal discussion of syntax forms, dynamics, etc, and simply discuss
what properties this system should have if embedded into ML. As such, you
should have some basic knowledge of ML and the formalities of ML-like
typesystems.</p>
<p>Disclaimer: The few “proofs” given <em>are not</em> completely rigorous. The biggest
elephant in the room is that we have not formally defined the behavior of our
system, and instead nebulously pretend that we’ve grafted things onto OCaml (or
SML). The sections marked as “proof” are intended as sketches that may be
superimposed onto a formal system with similar rules. <em>Please</em> contact me if
you spot an error; a major reason I set out to write this was to confirm to
myself that <em>I</em> properly understand these concepts.</p>
<h1 id="motivation">Motivation</h1>
<h2 id="typesafe-lists">Typesafe Lists</h2>
<p>Consider the function <code class="highlighter-rouge">hd : 'a list -> 'a</code> that returns the first element of a
list. Typically, this function is only defined on non-empty lists, raising some
form of error when given an empty input. One way around this is to instead use
a type such as <code class="highlighter-rouge">hd_opt : 'a list -> 'a option</code>, which forces the programmer to
handle the empty case explicitly. However, this is no better than pattern
matching on the list originally, and indeed only serves to delay the
boilerplate in cases in which the list is provably non-empty. For example,
consider the following (contrived) example:</p>
<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="n">v</span> <span class="o">:</span> <span class="kt">int</span> <span class="kt">list</span> <span class="o">=</span> <span class="n">map</span> <span class="n">foo</span> <span class="p">[</span><span class="mi">1</span><span class="o">,</span><span class="mi">2</span><span class="o">,</span><span class="mi">3</span><span class="o">,</span><span class="mi">4</span><span class="p">]</span> <span class="k">in</span>
<span class="k">match</span> <span class="n">hd_option</span> <span class="n">v</span> <span class="k">with</span>
<span class="o">|</span> <span class="nc">Some</span> <span class="n">x</span> <span class="o">-></span> <span class="n">do_something</span> <span class="n">x</span>
<span class="o">|</span> <span class="nc">None</span> <span class="o">-></span> <span class="k">assert</span> <span class="bp">false</span>
</code></pre></div></div>
<p>It is a feature of ML-inspired languages that, in cases like this, we generally
have no choice <em>but</em> to pattern match and think about what to do when
<code class="highlighter-rouge">hd_option v</code> is <code class="highlighter-rouge">None</code>. In this case, however, we <em>know</em> that the value <code class="highlighter-rouge">v</code> is
non-empty – <code class="highlighter-rouge">map f</code> is
a function returning a list of the same length as its input, so using this
function on <code class="highlighter-rouge">[1,2,3,4]</code> gives a list of length exactly 4. However, this fact
isn’t actually recorded in the type of <code class="highlighter-rouge">map</code> anywhere – it is <em>opaque</em> to the
typesystem. Because of this, the typesystem cannot prove that <code class="highlighter-rouge">v</code> is non-empty,
and so the “safe” thing to do is pattern match and explicitly mark the
extraneous case as unreachable. As you might expect, this boilerplate becomes
annoying very quickly, and so nearly every standard library for these languages
will provide unsafe function wrappers for this pattern (<code class="highlighter-rouge">Option.valOf</code> in
OCaml, for example). But in using these functions, we remove the safety net
provided by the compiler and typesystem, and invite runtime exceptions that
such constructs are designed to avoid (see: option types vs pervasive use of
<code class="highlighter-rouge">null</code> in other languages).</p>
<p>Instead, it would be ideal to <em>restrict</em> the type of <code class="highlighter-rouge">hd</code> to only act on lists
that are inhabited, so the compiler will throw an error if we attempt to
blindly take the first element of a potentially empty list. By <em>lifting</em> the
information about whether a list is empty into the typesystem, we can then
allow the typechecker to construct proofs that a given invocation of <code class="highlighter-rouge">hd</code> is
definitely safe (if we adjust other functions to match, of course).</p>
<h2 id="attempt-1-generalized-algebraic-datatypes">Attempt 1: Generalized Algebraic Datatypes</h2>
<p>A somewhat commonly-seen ``solution’’ to this issue that you might see uses
<a href="https://en.wikibooks.org/wiki/Haskell/GADT">GADTs</a> to attach type information
to the particular constructor. For example:</p>
<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">type</span> <span class="n">empty</span>
<span class="k">type</span> <span class="n">nonempty</span>
<span class="k">type</span> <span class="p">(</span><span class="k">'</span><span class="n">a</span><span class="o">,</span> <span class="n">_</span><span class="p">)</span> <span class="kt">list</span> <span class="o">=</span>
<span class="o">|</span> <span class="nc">Nil</span> <span class="o">:</span> <span class="p">(</span><span class="k">'</span><span class="n">a</span><span class="o">,</span> <span class="n">empty</span><span class="p">)</span> <span class="kt">list</span>
<span class="o">|</span> <span class="p">(</span><span class="o">::</span><span class="p">)</span> <span class="o">:</span> <span class="k">'</span><span class="n">a</span> <span class="o">*</span> <span class="p">(</span><span class="k">'</span><span class="n">a</span><span class="o">,</span> <span class="k">'</span><span class="n">b</span><span class="p">)</span> <span class="kt">list</span> <span class="o">-></span> <span class="p">(</span><span class="k">'</span><span class="n">a</span><span class="o">,</span> <span class="n">nonempty</span><span class="p">)</span> <span class="kt">list</span>
</code></pre></div></div>
<p>Then, we can note that <code class="highlighter-rouge">map</code> does not change the emptiness of its argument by
type-annotating it like so:</p>
<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">val</span> <span class="n">map</span> <span class="o">:</span> <span class="p">(</span><span class="k">'</span><span class="n">a</span> <span class="o">-></span> <span class="k">'</span><span class="n">b</span><span class="p">)</span> <span class="o">-></span> <span class="p">(</span><span class="k">'</span><span class="n">a</span><span class="o">,</span> <span class="k">'</span><span class="n">e</span><span class="p">)</span> <span class="kt">list</span> <span class="o">-></span> <span class="p">(</span><span class="k">'</span><span class="n">b</span><span class="o">,</span> <span class="k">'</span><span class="n">e</span><span class="p">)</span> <span class="kt">list</span>
</code></pre></div></div>
<p>where, because the output type <code class="highlighter-rouge">'e</code> must be the same as the input type <code class="highlighter-rouge">'e</code>, we
know that if the input list is <code class="highlighter-rouge">nonempty</code>, the output must also be <code class="highlighter-rouge">nonempty</code>.</p>
<p>This works great if we know that the output emptiness is fixed, or is the same
as the input list. However, we begin to run into issues where the relationship
between the input and output emptiness is not constant or identity. For
example, how would we encode the type of <code class="highlighter-rouge">append</code>?</p>
<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">val</span> <span class="n">append</span><span class="o">:</span> <span class="p">(</span><span class="k">'</span><span class="n">a</span><span class="o">,</span> <span class="k">'</span><span class="n">e1</span><span class="p">)</span> <span class="kt">list</span> <span class="o">-></span> <span class="p">(</span><span class="k">'</span><span class="n">a</span><span class="o">,</span> <span class="k">'</span><span class="n">e2</span><span class="p">)</span> <span class="kt">list</span> <span class="o">-></span> <span class="p">(</span><span class="k">'</span><span class="n">a</span><span class="o">,</span> <span class="o">???</span><span class="p">)</span> <span class="kt">list</span>
</code></pre></div></div>
<p>In fact, we <em>do</em> know something about the output type in this case – the
output of <code class="highlighter-rouge">append</code> is <code class="highlighter-rouge">empty</code> iff both inputs are. However, ML-style
typesystems lack support for <em>type-level lambdas</em>, and so we have no way to
express this type without employing more trickery.</p>
<p>Even worse, what about functions where the output has <em>no</em> relation to the
input?</p>
<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">val</span> <span class="n">filter</span><span class="o">:</span> <span class="p">(</span><span class="k">'</span><span class="n">a</span> <span class="o">-></span> <span class="kt">bool</span><span class="p">)</span> <span class="o">-></span> <span class="p">(</span><span class="k">'</span><span class="n">a</span><span class="o">,</span> <span class="k">'</span><span class="n">e</span><span class="p">)</span> <span class="kt">list</span> <span class="o">-></span> <span class="p">(</span><span class="k">'</span><span class="n">a</span><span class="o">,</span> <span class="o">???</span><span class="p">)</span> <span class="kt">list</span>
</code></pre></div></div>
<p>Here, we’re <em>completely</em> up the creek – there’s <em>no</em> way for us to know
whether the filtered list is empty.</p>
<p>One way around this is to use
<a href="https://wiki.haskell.org/Rank-N_types">higher-ranked polymorphism</a> and
continuation passing style to ``capture’’ the output. By making the type of
<code class="highlighter-rouge">filter</code> look like</p>
<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">val</span> <span class="n">filter</span><span class="o">:</span> <span class="p">(</span><span class="k">'</span><span class="n">a</span> <span class="o">-></span> <span class="kt">bool</span><span class="p">)</span> <span class="o">-></span> <span class="p">(</span><span class="k">'</span><span class="n">a</span><span class="o">,</span> <span class="k">'</span><span class="n">e</span><span class="p">)</span> <span class="kt">list</span> <span class="o">-></span>
<span class="p">(</span><span class="n">forall</span> <span class="n">b</span> <span class="o">.</span> <span class="p">(</span><span class="k">'</span><span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="p">)</span> <span class="kt">list</span> <span class="o">-></span> <span class="k">'</span><span class="n">c</span><span class="p">)</span> <span class="o">-></span>
<span class="k">'</span><span class="n">c</span>
</code></pre></div></div>
<p>we can force consumers of this function to provide a handler that is able to
handle both cases. The extra function argument at the end is the “continuation”
that consumes the list output by filter.</p>
<p>This is stylistically jarring, however, and ML-style languages generally don’t
support or require jumping through some hoops to encode rank N types.</p>
<h2 id="attempt-2-sum-types">Attempt 2: Sum Types</h2>
<p>The fundamental problem with <code class="highlighter-rouge">append</code> and <code class="highlighter-rouge">filter</code> in the previous example is
that, in different cases, these functions must return <em>different types</em>. This
is generally forbidden<sup id="fnref:1"><a href="#fn:1" class="footnote">1</a></sup>, and so we’re stuck.</p>
<p>On the other hand, we <em>have</em> a mechanism by which we can join two disparate
types – sum types! A generic list is <em>either</em> an empty list, or an inhabited
list. So we come up with</p>
<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">type</span> <span class="k">'</span><span class="n">a</span> <span class="n">emptylist</span> <span class="o">=</span> <span class="n">nil</span>
<span class="ow">and</span> <span class="k">'</span><span class="n">a</span> <span class="n">inhablist</span> <span class="o">=</span> <span class="p">(</span><span class="o">::</span><span class="p">)</span> <span class="k">of</span> <span class="k">'</span><span class="n">a</span> <span class="o">*</span> <span class="k">'</span><span class="n">a</span> <span class="kt">list</span>
<span class="ow">and</span> <span class="k">'</span><span class="n">a</span> <span class="kt">list</span> <span class="o">=</span> <span class="nc">E</span> <span class="k">of</span> <span class="k">'</span><span class="n">a</span> <span class="n">emptylist</span>
<span class="o">|</span> <span class="nc">N</span> <span class="k">of</span> <span class="k">'</span><span class="n">a</span> <span class="n">inhablist</span>
</code></pre></div></div>
<p>and so we can express functions like <code class="highlighter-rouge">filter</code> by returning an <code class="highlighter-rouge">'a list</code>,
whereas functions like <code class="highlighter-rouge">hd</code> must take in <code class="highlighter-rouge">'a inhablist</code> as input.</p>
<p>This is a lot of code for a relatively simple idea, though! In addition to the
mutually recursive types, here’s an example of <em>using</em> this type:</p>
<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="k">rec</span> <span class="n">map</span> <span class="n">f</span> <span class="nc">L</span> <span class="o">=</span>
<span class="k">match</span> <span class="nc">L</span> <span class="k">with</span>
<span class="o">|</span> <span class="nc">E</span> <span class="n">nil</span> <span class="o">-></span> <span class="nc">E</span> <span class="n">nil</span>
<span class="o">|</span> <span class="nc">N</span> <span class="p">(</span><span class="n">x</span> <span class="o">::</span> <span class="n">xs</span><span class="p">)</span> <span class="o">-></span> <span class="nc">N</span> <span class="p">(</span><span class="n">f</span> <span class="n">x</span> <span class="o">::</span> <span class="n">map</span> <span class="n">f</span> <span class="n">xs</span><span class="p">)</span>
</code></pre></div></div>
<p>Notice the extra uses of <code class="highlighter-rouge">E</code> and <code class="highlighter-rouge">N</code>. This adds clutter without really adding
meaning, and gets increasingly cumbersome as we write more complex functions.
In addition, you may have noticed that this <em>doesn’t even solve the original
problem!</em> When we call <code class="highlighter-rouge">map f [1,2,3,4]</code>, we get back a value of type <code class="highlighter-rouge">list</code>,
which <em>doesn’t tell us that the list is non-empty!</em></p>
<p>Really, what we <em>want</em> is a way to express that a non-empty list is the same as
a regular list, but with some <em>extra information</em> (particularly, that the list
is non-empty).</p>
<h1 id="the-subtyping-relation">The Subtyping Relation</h1>
<p>Let us introduce a new judgment into our typesystem. Let <script type="math/tex">% <![CDATA[
\tau_1 <: \tau_2 %]]></script>
(pronounced “extends”, as in “<script type="math/tex">\tau_1</script> extends <script type="math/tex">\tau_2</script>”) be a judgment
claiming pretty much exactly what we said above, that a value of type
<script type="math/tex">\tau_1</script> is equivalent to a value of type <script type="math/tex">\tau_2</script>, with some more specific
information attached. This leads to the following typing rule:</p>
<script type="math/tex; mode=display">% <![CDATA[
\frac{\Gamma \vdash e : \tau_1\ \ \ \tau_1 <: \tau_2}{\Gamma \vdash e :
\tau_2} %]]></script>
<p>This is known as the <em>subsumption</em> rule, where we allow terms to automatically
“upcast” from a subtype to a supertype. Using our intuition about what <code class="highlighter-rouge"><:</code>
means, this should make sense – if a <script type="math/tex">\tau_1</script> is a <script type="math/tex">\tau_2</script> with some extra
information, then we should be able to recover the <script type="math/tex">\tau_2</script> by discarding that
extra specificity.</p>
<p>Another important property to maintain with this relation is its transitivity.
In fact, if we are only concerned with typing specific expressions, then this
property is irrelevant, as we can already show that <script type="math/tex">e:\tau_1</script>, <script type="math/tex">% <![CDATA[
\tau_1 <:
\tau_2 %]]></script> and <script type="math/tex">% <![CDATA[
\tau_2 <: \tau_3 %]]></script> implies <script type="math/tex">e:\tau_3</script>.</p>
<p><strong>Exercise:</strong> Give a derivation showing this.</p>
<p>When discussing the types <em>themselves</em>, however, it is often convenient to add
a rule stating this directly:</p>
<script type="math/tex; mode=display">% <![CDATA[
\frac{\tau_1 <: \tau_2\ \ \ \tau_2 <: \tau_3}{\tau_1 <: \tau_3} %]]></script>
<p>To solve our list problem, then, we want <code class="highlighter-rouge">'a nlist</code> to be a <em>subtype</em> of
<code class="highlighter-rouge">'a list</code>, and re-structure all our functions accordingly. Before we address
this directly, however, we need to explore how, exactly, this relation should
behave.</p>
<h1 id="structural-subtyping">Structural Subtyping</h1>
<p>In any particular subtyped calculus, we might consider baking in forms of
<em>semantic</em> subtyping, where the relationship between two given types is based
on the fundamental properties of our primitive types. For example, convention
claims that <script type="math/tex">\mathbb{N}</script>, the set of natural numbers, is a subset of
<script type="math/tex">\mathbb{R}</script>, the set of reals. Then, assuming we have analogous types <code class="highlighter-rouge">nat</code>
and <code class="highlighter-rouge">float</code> in our language (using floating point numbers to approximate the
reals), we might decide that <code class="highlighter-rouge">nat <: float</code><sup id="fnref:2"><a href="#fn:2" class="footnote">2</a></sup>.</p>
<p>However, in the absence of such specificity about our basic types, let us
instead examine what properties might be derived <em>structurally</em>, examining only
the form of the types themselves.</p>
<h2 id="products">Products</h2>
<p>Consider the following two types:</p>
<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">type</span> <span class="n">t1</span> <span class="o">=</span> <span class="p">{</span> <span class="n">l1</span> <span class="o">:</span> <span class="n">a</span> <span class="k">type</span> <span class="n">t2</span> <span class="o">=</span> <span class="p">{</span> <span class="n">l1</span> <span class="o">:</span> <span class="n">a</span>
<span class="p">;</span> <span class="n">l2</span> <span class="o">:</span> <span class="n">b</span> <span class="p">;</span> <span class="n">l2</span> <span class="o">:</span> <span class="n">b</span>
<span class="p">}</span> <span class="p">;</span> <span class="n">l3</span> <span class="o">:</span> <span class="n">c</span>
<span class="p">}</span>
</code></pre></div></div>
<p>(note that we’re using <em>labeled</em> products, otherwise known as “records” instead
of standard tuples, because it makes the semantics much clearer)</p>
<p>In keeping with our intuition that “the subtype is the same as the supertype
but with more information”, we notice that any value of type <code class="highlighter-rouge">t2</code> has all the
fields of <code class="highlighter-rouge">t1</code> with the same types, but also has some data <code class="highlighter-rouge">l3</code>. We thus add
a “width-subtyping” rule for records:</p>
<script type="math/tex; mode=display">% <![CDATA[
\frac{}{\{ \ell_1 : \tau_1, \dots, \ell_n : \tau_n, \dots \}
<: \{ \ell_1 : \tau_1, \dots, \ell_n : \tau_n\}} %]]></script>
<p>saying that a record <script type="math/tex">\rho_1</script> is a subtype of another record <script type="math/tex">\rho_2</script> when
<script type="math/tex">\rho_1</script> contains all the same fields+types as <script type="math/tex">\rho_2</script>.</p>
<h2 id="sums">Sums</h2>
<p>Similarly, suppose we have the following two labeled variants:</p>
<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">type</span> <span class="n">t1</span> <span class="o">=</span> <span class="nc">L1</span> <span class="k">of</span> <span class="n">a</span> <span class="k">type</span> <span class="n">t2</span> <span class="o">=</span> <span class="nc">L1</span> <span class="k">of</span> <span class="n">a</span>
<span class="o">|</span> <span class="nc">L2</span> <span class="k">of</span> <span class="n">b</span> <span class="o">|</span> <span class="nc">L2</span> <span class="k">of</span> <span class="n">b</span>
<span class="o">|</span> <span class="nc">L3</span> <span class="k">of</span> <span class="n">c</span>
</code></pre></div></div>
<p>Which direction should the subtyping go? We might claim that a value of type
<code class="highlighter-rouge">t2</code> contains “extra” information compared to <code class="highlighter-rouge">t1</code> by noting that <code class="highlighter-rouge">t2</code> has an
extra variant, so a <code class="highlighter-rouge">t2</code> is a <code class="highlighter-rouge">t1</code> but <em>may</em> be different. However, this is
wrong, as demonstrated by the following snippet:</p>
<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">match</span> <span class="n">v</span> <span class="k">with</span>
<span class="o">|</span> <span class="nc">L1</span> <span class="n">x</span> <span class="o">-></span> <span class="n">do_something</span> <span class="n">x</span>
<span class="o">|</span> <span class="nc">L2</span> <span class="n">y</span> <span class="o">-></span> <span class="n">do_something_else</span> <span class="n">y</span>
</code></pre></div></div>
<p>If <code class="highlighter-rouge">t2 <: t1</code> truly, then it would be valid for <code class="highlighter-rouge">v</code> to be of the form <code class="highlighter-rouge">L3 z</code>,
as this is certainly of type <code class="highlighter-rouge">t2</code> and therefore type <code class="highlighter-rouge">t1</code>. But this would be
disastrous, as the match statement does not specify what to do in the <code class="highlighter-rouge">L3</code>
case!</p>
<p>We conclude by noting that the <em>other</em> direction is fine –</p>
<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">match</span> <span class="n">v</span> <span class="k">with</span>
<span class="o">|</span> <span class="nc">L1</span> <span class="n">x</span> <span class="o">-></span> <span class="n">do_something_1</span> <span class="n">x</span>
<span class="o">|</span> <span class="nc">L2</span> <span class="n">y</span> <span class="o">-></span> <span class="n">do_something_2</span> <span class="n">y</span>
<span class="o">|</span> <span class="nc">L3</span> <span class="n">z</span> <span class="o">-></span> <span class="n">do_something_3</span> <span class="n">z</span>
</code></pre></div></div>
<p>If <code class="highlighter-rouge">v : t1</code>, then we know that it is restricted to be an <code class="highlighter-rouge">L1</code> or <code class="highlighter-rouge">L2</code> variant,
so this match statement can never get stuck. The “extra information” gained
from having a <code class="highlighter-rouge">t1</code> over a <code class="highlighter-rouge">t2</code>, then, can be viewed as the information that
a <code class="highlighter-rouge">t1</code> is <em>not</em> an <code class="highlighter-rouge">L3</code> variant! So <code class="highlighter-rouge">t1 <: t2</code>.</p>
<p>Another way to view this is that, in many ways, sum types are “flipped around”
compared to product types. Categorically speaking, we claim that sums and
products are <em>dual</em> to each other (in fact, you’ll often find sums referred to
as “coproducts”, to make this relationship explicit). It makes sense, then,
that a “bigger” sum is related to a “smaller” sum in the <em>opposite</em> of the way
that bigger and smaller <em>products</em> relate.</p>
<h1 id="variance">Variance</h1>
<p>The next topic to consider relates to our type constructors. The exact question
we will be addressing is</p>
<blockquote>
<p>When is <script type="math/tex">% <![CDATA[
\tau_1\ t <: \tau_2\ t %]]></script>, for a particular type constructor <script type="math/tex">t</script>?</p>
</blockquote>
<p>To answer this question, we typically must examine not only the internals of
the constructor <script type="math/tex">t</script>, but also the relationship between <script type="math/tex">\tau_1</script> and <script type="math/tex">\tau_2</script>.
The way that the relationship between <script type="math/tex">\tau_1</script> and <script type="math/tex">\tau_2</script> affects the
relationship between <script type="math/tex">\tau_1\ t</script> and <script type="math/tex">\tau_2\ t</script> is known as <em>variance</em>.</p>
<h2 id="lists">Lists</h2>
<p>As we began this discussion by talking about lists, it seems only right that we
consider first the variance properties of the (idealized) type <code class="highlighter-rouge">'a list</code>.</p>
<p>The naive answer might be that <script type="math/tex">% <![CDATA[
\tau_1\ list <: \tau_2\ list %]]></script> when <script type="math/tex">% <![CDATA[
\tau_1 <:
\tau_2 %]]></script>. This is actually the correct thing to do – if <script type="math/tex">% <![CDATA[
\tau_1 <: \tau_2 %]]></script>,
then we can view all elements of a <script type="math/tex">\tau_1\ list</script> as a <script type="math/tex">\tau_2</script>, thus giving us
a <script type="math/tex">\tau_2 \ list</script>, so we might gain the rule</p>
<script type="math/tex; mode=display">% <![CDATA[
\frac{\tau_1 <: \tau_2}{\tau_1\ list <: \tau_2\ list} %]]></script>
<p>In fact, we can generalize this to “containers” in general.</p>
<p><strong>Theorem (Covariance of sources)</strong> <em>If there exists
a function of most general type <script type="math/tex">\forall a.(a\ t \rightarrow a)</script> that returns a
value for at least one input, then <script type="math/tex">% <![CDATA[
\tau_1\ t <: \tau_2\ t %]]></script> implies <script type="math/tex">% <![CDATA[
\tau_1 <:
\tau_2 %]]></script></em>.</p>
<p><em>Proof</em>.</p>
<p>Let <script type="math/tex">f, v, t, \tau_1, \tau_2</script> be such that <script type="math/tex">f: \forall a.(a\ t \rightarrow a)</script>,
<script type="math/tex">v: \tau_1\ t</script> and <script type="math/tex">% <![CDATA[
\tau_1\ t <: \tau_2\ t %]]></script>.</p>
<p>By subsumption, <script type="math/tex">v: \tau_2\ t</script>, so <script type="math/tex">f\ v : \tau_2</script>.</p>
<p>Alternatively, <script type="math/tex">f\ v : \tau_1</script>.</p>
<p>Because <script type="math/tex">f</script> is universally quantified, it cannot rely on any properties of
<script type="math/tex">\tau_1</script> or <script type="math/tex">\tau_2</script>. But then, <script type="math/tex">f\ v</script> is arbitrary. In particular, any object
of type <script type="math/tex">\tau_1</script> can be written as <script type="math/tex">f\ v</script> for an appropriate <script type="math/tex">v</script>.</p>
<p>But <script type="math/tex">f\ v</script> is the same object regardless of whether <script type="math/tex">v</script> is viewed as a
<script type="math/tex">\tau_1\ t</script> or a <script type="math/tex">\tau_2\ t</script>, so we must be able to view arbitrary objects of
type <script type="math/tex">\tau_1</script> as objects of type <script type="math/tex">\tau_2</script>.</p>
<script type="math/tex; mode=display">\square</script>
<h2 id="functions">Functions</h2>
<p>Functions are a strange case, because a function arrow really has <em>two</em> type
variables, the input and the output. We’ll examine these one at a time.</p>
<p>Consider types <script type="math/tex">\tau \rightarrow \tau_1</script> and <script type="math/tex">\tau \rightarrow \tau_2</script>, where
<script type="math/tex">\tau</script> is fixed. If <script type="math/tex">\tau</script> is a type inhabited with an object <script type="math/tex">\sigma</script>, then
certainly <script type="math/tex">\lambda f : f \sigma</script> is a function of type <script type="math/tex">\forall a . ((\tau
\rightarrow a) \rightarrow a)</script>, so by the above we know that function arrows
should be covariant in their second argument. In fact, by a slightly modified
argument, we can show this even when <script type="math/tex">\tau</script> is the empty type <script type="math/tex">\bot</script> (hint:
suppose that there existed some function of type <script type="math/tex">(\bot \rightarrow \tau_1)
\rightarrow \rho</script> and consider what behavior this function could possibly
have).</p>
<p>The first argument, on the other hand, actually <em>flips</em> this behavior. If we
have a function of type <script type="math/tex">\tau_1 \rightarrow \tau</script>, we’re eventually going to
want to <em>call</em> it on a value of type <script type="math/tex">\tau_1</script> (formally we might say that we
are allowed to <em>eliminate</em> this function by passing it an input). For this to
be safe, we must know that any subtype of the type <script type="math/tex">\tau_1 \rightarrow \tau</script>
must be able to safely handle a <script type="math/tex">\tau_1</script>. But this means that subtypes of
<script type="math/tex">\tau_1 \rightarrow \tau</script> must have <em>supertypes</em> of <script type="math/tex">\tau_1</script> on the left (as
otherwise they might perform an operation that is only implemented by the
subtype). This gives us the rule</p>
<script type="math/tex; mode=display">% <![CDATA[
\frac{\tau_2 <: \tau_1}{\tau_1 \rightarrow \tau <: \tau_2 \rightarrow \tau} %]]></script>
<p>This phenomenon, in which we <em>reverse</em> the relationship between <script type="math/tex">\tau_1</script> and
<script type="math/tex">\tau_2</script> to <script type="math/tex">\tau_1\ t</script> and <script type="math/tex">\tau_2\ t</script> is known as <em>contravariance</em>.</p>
<p>By duality, we might expect to be able to produce a similar theorem to the
one given above, perhaps by the existence of a function of type <script type="math/tex">\forall a.
(a \rightarrow a\ t)</script>. Unfortunately, this doesn’t quite work – the function
<script type="math/tex">\lambda x.[x]</script> has type <script type="math/tex">\forall a.(a \rightarrow a\ list)</script>, but lists are
definitely not contravariant.</p>
<p><strong>Proposition (Contravariance of sinks)</strong> <em>If there exists a type <script type="math/tex">c</script> such that
there exists a function of type <script type="math/tex">f</script> such that <script type="math/tex">f : \forall a . (a \rightarrow
a\ t \rightarrow c)</script>, then <script type="math/tex">% <![CDATA[
\tau_1\ t <: \tau_2\ t %]]></script> implies <script type="math/tex">% <![CDATA[
\tau_2 <:
\tau_1 %]]></script></em>.</p>
<p>This is marked as a proposition, rather than a theorem, because it is false as
stated. For example, the function <script type="math/tex">\lambda \__1.\lambda \__2.()</script> has type
<script type="math/tex">\forall a . \forall b . (a \rightarrow b \rightarrow unit)</script>, which of course
specializes to <script type="math/tex">\forall a . (a \rightarrow a\ t \rightarrow c)</script> for <em>any</em>
<script type="math/tex">t</script>. It may be enough to assert that <script type="math/tex">f</script> “meaningfully uses” its arguments, but
this is difficult to formalize. That said, I’m not actually sure that <em>this</em> is
true either – if you can prove it (even semi-informally in our ML-like world),
<em>please</em> let me know!</p>
<h2 id="mutable-references">Mutable References</h2>
<p>It turns out that mutable state (important to imperative programming) interacts
in an interesting way with subtyping variance. Consider the types <script type="math/tex">\tau_1\ ref</script>
and <script type="math/tex">\tau_2\ ref</script>, referring to the types of <em>mutable reference cells</em>.</p>
<p>Notice that the dereference function <code class="highlighter-rouge">!</code> has type <script type="math/tex">\forall a . (a\ ref
\rightarrow a)</script>, so by covariance of sources (I promise I will explain the
terms “source” and “sink” shortly), we have that <script type="math/tex">% <![CDATA[
\tau_1\ ref <: \tau_2
\ ref %]]></script> implies <script type="math/tex">% <![CDATA[
\tau_1 <: \tau_2 %]]></script>.</p>
<p>However, <script type="math/tex">% <![CDATA[
\tau_1 <: \tau_2 %]]></script> is <em>not</em> sufficient to conclude that <script type="math/tex">% <![CDATA[
\tau_1\ ref
<: \tau_2\ ref %]]></script>. Let <code class="highlighter-rouge">A <: B</code> be types, and consider the following code:</p>
<div class="language-ocaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="n">magic</span> <span class="p">(</span><span class="n">r</span><span class="o">:</span> <span class="nc">A</span> <span class="n">ref</span><span class="p">)</span> <span class="p">(</span><span class="n">v</span><span class="o">:</span> <span class="nc">B</span><span class="p">)</span> <span class="o">:</span> <span class="nc">A</span> <span class="o">=</span>
<span class="p">(</span><span class="n">r</span> <span class="o">:</span> <span class="nc">B</span> <span class="n">ref</span><span class="p">)</span> <span class="o"><-</span> <span class="n">v</span><span class="p">;</span>
<span class="o">!</span><span class="n">r</span>
</code></pre></div></div>
<p>Remember that the rule of subsumption means that annotating <code class="highlighter-rouge">r</code> as type <code class="highlighter-rouge">B ref</code>
is a no-op (just a hint to the compiler). But <code class="highlighter-rouge">!r</code> (= <code class="highlighter-rouge">v</code>) is definitely of
type <code class="highlighter-rouge">A</code>, as <code class="highlighter-rouge">r : A ref</code>, even though <code class="highlighter-rouge">v</code> is already of type <code class="highlighter-rouge">B</code>! The only way
this is safe is if <code class="highlighter-rouge">B <: A</code>.</p>
<p>In fact, we need <em>both directions</em> to assert that <script type="math/tex">% <![CDATA[
\tau_1\ ref <: \tau_2\ ref %]]></script>.
This can only happen if <script type="math/tex">\tau_1</script> and <script type="math/tex">\tau_2</script> are the same type up to some
definition of “same” (reordering of labels, etc)<sup id="fnref:3"><a href="#fn:3" class="footnote">3</a></sup>. This property is known
as <em>invariance</em>.</p>
<p>One way to think of covariance and contravariance is to discuss what you can
<em>do</em> with an <code class="highlighter-rouge">'a t</code>. If having an <code class="highlighter-rouge">'a t</code> possibly <em>gives</em> you an <code class="highlighter-rouge">'a</code>, it
is called a <em>source</em>, and is therefore covariant by the proof above. Otherwise,
if an <code class="highlighter-rouge">'a t</code> <em>consumes</em> an <code class="highlighter-rouge">'a</code>, then it is called a <em>sink</em>, which is
contravariant using the same reasoning as with function arguments. However,
references are <em>both</em> a source (by dereferencing) <em>and</em> a sink (by writing a
value to the cell). We don’t run into this issue with <em>immutable</em> containers
because growing a container necessarily changes the type of the (resulting)
container, but writing a value to a ref cell <em>doesn’t</em> retroactively change its
type.</p>
<h2 id="bivariance">Bivariance</h2>
<p>Thus far, we’ve seen examples of both covariant and contravariant type
constructors, along with a type constructor that is both (invariant). You may
then ask whether there exists a type of variance that is <em>neither</em> – that is,
if there exists some <script type="math/tex">t</script> such that
<script type="math/tex">% <![CDATA[
\tau_1\ t <: \tau_2\ t %]]></script> regardless of the relation between <script type="math/tex">\tau_1</script> and
<script type="math/tex">\tau_2</script>.</p>
<p>In fact, there is! This is the case when an object of type <script type="math/tex">\tau\ t</script> is
entirely unrelated to objects of type <script type="math/tex">\tau</script>. This is most often seen with
phantom type variables intended to aid typechecking. Such types are known as
<em>bivariant</em> in the given input.</p>
<p>We can show that this is the <em>only</em> possibility for a type to be bivariant by
appealing to the source theorem and sink proposition above. Regarding the
latter case, if <script type="math/tex">% <![CDATA[
\tau_1\ t <: \tau_2\ t %]]></script> always, then we can sink <em>any value</em>
into a value of type <script type="math/tex">\tau\ t</script> (for any <script type="math/tex">\tau</script>!). This can only possibly be
safe if sinking a value is a no-op.</p>
<p><strong>Exercise:</strong> Provide a similar argument to the above without the source
theorem to show that a bivariant type constructor cannot be a source. (Hint:
let <script type="math/tex">\tau = \bot</script>)</p>
<h1 id="bounded-quantification">Bounded Quantification</h1>
<p>You may notice that, after all that, we <em>still</em> haven’t solved the problem we
initially set out to! Even if we construct a type <code class="highlighter-rouge">'a nlist</code> such that <code class="highlighter-rouge">'a
nlist <: 'a list</code>, we <em>still</em> can’t tell the typechecker that <code class="highlighter-rouge">map</code> only
returns an <code class="highlighter-rouge">nlist</code> if given an <code class="highlighter-rouge">nlist</code>!</p>
<p>The solution is to adjust how we approach polymorphism. Previously, ML-style
languages supported only <em>unbounded quantification</em> in their types.
Polymorphism was all-or-nothing; either you had a specific type or you must
be generic over <em>all</em> possible types. This is denoted via the implicit
<script type="math/tex">\forall</script> seen in polymorphic ML types. However, now we have interesting things
to say about types and how they relate to each other, which in turn enrichens
our type language.</p>
<p>In particular, we can now have types of the form <script type="math/tex">% <![CDATA[
\forall\{t : t <: s\}.\tau %]]></script>
and <script type="math/tex">% <![CDATA[
\forall\{t : s <: t\}.\tau %]]></script>, where we can <em>upper- or lower-bound</em> the
range of types we are quantifying over.</p>
<p>This allows us to solve our list problem relatively elegantly via a combination
of subtyping and GADTs by declaring types <script type="math/tex">unknown</script>, <script type="math/tex">% <![CDATA[
nonempty <: unknown %]]></script> and
<script type="math/tex">% <![CDATA[
empty <: unknown %]]></script>. Then <code class="highlighter-rouge">map</code> can have type <script type="math/tex">% <![CDATA[
\forall\{e : e <: unknown\} .
\forall a . ((a \rightarrow b) \rightarrow (a,e) list \rightarrow (b,e) list) %]]></script>.</p>
<p><strong>Exercise:</strong> Show that you can express the type of <code class="highlighter-rouge">append</code> under this scheme.
You may assume any reasonable extension of the syntax to, say, provide an upper
and lower bound at the same time, or to allow multiple bounds to apply at once.</p>
<p>Many modern-day subtyping schemes allow quantification in this way. For
example, in Java, there exists a type <code class="highlighter-rouge">List<? extends T></code> for <script type="math/tex">% <![CDATA[
\forall\{t:t <:
T\}.t\ list %]]></script> and <code class="highlighter-rouge">List<? super T></code> for <script type="math/tex">% <![CDATA[
\forall\{t:T <: t\}.t\ list %]]></script>. However,
adding expressiveness to a type-level language often leads to trouble. In fact,
typechecking a system with bounded quantification in both directions is
<em>undecidable</em>.</p>
<h1 id="references">References</h1>
<p>[1] Pierce, Benjamin C. Types and Programming Languages. The MIT Press, 2002.</p>
<p>[2] Reynolds, John C. “Design of the Programming Language Forsythe.” Algol-like Languages, 28 June 1996.</p>
<p>[3] Grigore, Radu. “Java Generics Are Turing Complete.” ACM SIGPLAN Notices, vol. 52, no. 1, 1 Jan. 2017, pp. 73–85.</p>
<div class="footnotes">
<ol>
<li id="fn:1">
<p>There are exceptions stemming from type shenanigans (oftentimes via
GADTs!), but this isn’t one of them. <a href="#fnref:1" class="reversefootnote">↩</a></p>
</li>
<li id="fn:2">
<p>This may seem alarming – <code class="highlighter-rouge">nat</code> is
certainly not a <em>subset</em> of <code class="highlighter-rouge">float</code> on any real computer architecture!
We will gloss over this issue with regards to subsumption for now, as it is
largely inconsequential without discussion of syntax forms and dynamic
semantics. Attempting to address this leads to “coercive” subtyping, where
casts must be made explicit. <a href="#fnref:2" class="reversefootnote">↩</a></p>
</li>
<li id="fn:3">
<p>We should be careful that we don’t claim that <script type="math/tex">% <![CDATA[
\tau_1 <: \tau_2 %]]></script> and
<script type="math/tex">% <![CDATA[
\tau_2 <: \tau_1 %]]></script> implies <script type="math/tex">\tau_1 \cong \tau_2</script> (isomorphism) unduly, as
isomorphism often works strangely with subsumptive subtyping. For example,
<script type="math/tex">(a,(b,c)) \cong ((a,b),c)</script>, but in these cases the term <script type="math/tex">v.0</script> is
ambiguous. The difference is technical and difficult to reason about
without formally defining semantics. <a href="#fnref:3" class="reversefootnote">↩</a></p>
</li>
</ol>
</div>Cameron Wongcam@camdar.io(These notes are adapted from a lecture I gave for a student-run class on type theory. See also the pdf version)The Great Theorem Prover Challenge II2018-07-04T00:00:00+00:002018-07-04T00:00:00+00:00https://ct075.github.io/2018-07-04/theorem-prover-2<p><em>This is the second of a series on Hillel Wayne’s <a href="https://www.hillelwayne.com/post/theorem-prover-showdown/">Great Theorem Prover
Showdown</a>. Make sure
to check out the <a href="https://blog.camdar.io/2018-06-21/theorem-prover-1/">first part</a>!
You can also follow my progress in
<a href="https://github.com/CT075/theorem-prover-showdown">this repository</a>.</em></p>
<p>In the last installation of “Cam learns to use a theorem prover”, we got
acquainted with Liquid Haskell, induction, and formal specifications while
writing a verified version of the legendary LeftPad function.</p>
<p>Today, I’ll be going over my solution to the next challenge, “Unique”. This one
actually gave me more trouble than LeftPad, contrary to Twitter’s opinion of
it.</p>
<p>Our task is to, given a list <code class="highlighter-rouge">L</code> construct a list containing every unique
element of <code class="highlighter-rouge">L</code> exactly once (in any order).</p>
<p>Let’s start with the code itself:</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">{-@ reflect elem @-}</span>
<span class="n">elem</span> <span class="o">::</span> <span class="kt">Eq</span> <span class="n">a</span> <span class="o">=></span> <span class="n">a</span> <span class="o">-></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="kt">Bool</span>
<span class="n">elem</span> <span class="n">x</span> <span class="kt">[]</span> <span class="o">=</span> <span class="kt">False</span>
<span class="n">elem</span> <span class="n">x</span> <span class="p">(</span><span class="n">y</span><span class="o">:</span><span class="n">ys</span><span class="p">)</span> <span class="o">=</span> <span class="n">x</span> <span class="o">==</span> <span class="n">y</span> <span class="o">||</span> <span class="n">elem</span> <span class="n">x</span> <span class="n">ys</span>
<span class="cm">{-@ reflect unique @-}</span>
<span class="n">unique</span> <span class="o">::</span> <span class="kt">Eq</span> <span class="n">a</span> <span class="o">=></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">unique</span> <span class="kt">[]</span> <span class="o">=</span> <span class="kt">[]</span>
<span class="n">unique</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span>
<span class="o">|</span> <span class="n">x</span> <span class="p">`</span><span class="n">elem</span><span class="p">`</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">unique</span> <span class="n">xs</span>
<span class="o">|</span> <span class="n">otherwise</span> <span class="o">=</span> <span class="n">x</span><span class="o">:</span><span class="n">unique</span> <span class="n">xs</span>
</code></pre></div></div>
<p>This is fairly straightforward – an element <code class="highlighter-rouge">x</code> is unique in <code class="highlighter-rouge">x:xs</code> if <code class="highlighter-rouge">x</code> is
not present in <code class="highlighter-rouge">xs</code>, so we keep it. Now for the specification:</p>
<blockquote>
<p>Takes a sequence of integers, returns the unique elements of that list. There
is no requirement on the ordering of the returned values.</p>
</blockquote>
<p>As usual, I think that our code is “obviously” correct. In fact, our code is
even more general – we can take any <code class="highlighter-rouge">Eq a</code>, but it specializes to integers
easily enough.</p>
<p>Let’s see if we can prove it.</p>
<h2 id="the-obvious-part">The “Obvious” Part</h2>
<p>The “main” property of <code class="highlighter-rouge">Unique</code> is that every element in <code class="highlighter-rouge">xs</code> appears exactly
once in <code class="highlighter-rouge">unique xs</code>. And this is important, because it means that a) we didn’t
drop any elements and b) we actually removed duplicate elements. We can do so
like this:</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">{-@ reflect count @-}</span>
<span class="n">count</span> <span class="o">::</span> <span class="kt">Eq</span> <span class="n">a</span> <span class="o">=></span> <span class="n">a</span> <span class="o">-></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="kt">Int</span>
<span class="n">count</span> <span class="kr">_</span> <span class="kt">[]</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">count</span> <span class="n">x</span> <span class="p">(</span><span class="n">y</span><span class="o">:</span><span class="n">ys</span><span class="p">)</span>
<span class="o">|</span> <span class="n">x</span> <span class="o">==</span> <span class="n">y</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">count</span> <span class="n">x</span> <span class="n">ys</span>
<span class="o">|</span> <span class="n">otherwise</span> <span class="o">=</span> <span class="n">count</span> <span class="n">x</span> <span class="n">ys</span>
<span class="cm">{-@ thmUniqueNoDup :: xs:[a] -> {x:a | elem x xs} ->
{count x (unique xs) == 1}
@-}</span>
<span class="n">thmUniqueNoDup</span> <span class="o">::</span> <span class="kt">Eq</span> <span class="n">a</span> <span class="o">=></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="n">a</span> <span class="o">-></span> <span class="nb">()</span>
</code></pre></div></div>
<p>Now, here is where I got stuck. No matter what I tried, I couldn’t quite come
up with a way to make LH infer this proof automagically, the way we did before.</p>
<p>It turns out that LH does come with some hand-guidance tools. We can, in fact,
step through code execution symbolically to show that it exhibits some property
(correctness or otherwise) for all relevant inputs. While automating the entire
process can be computationally intractable, we (as humans) have a fair bit more
intuition and can “know” where to begin – we can write the proof, and
the computer can check if our proof is correct<sup id="fnref:1"><a href="#fn:1" class="footnote">1</a></sup>.</p>
<p>Here’s the case where <code class="highlighter-rouge">y</code> is an element of <code class="highlighter-rouge">xs</code>.</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">thmUniqueNoDup</span> <span class="o">::</span> <span class="kt">Eq</span> <span class="n">a</span> <span class="o">=></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="n">a</span> <span class="o">-></span> <span class="kt">Proof</span>
<span class="n">thmUniqueNoDup</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="n">y</span>
<span class="o">|</span> <span class="n">y</span> <span class="p">`</span><span class="n">elem</span><span class="p">`</span> <span class="n">xs</span> <span class="o">=</span>
<span class="kr">if</span> <span class="n">x</span> <span class="o">==</span> <span class="n">y</span> <span class="kr">then</span>
<span class="n">count</span> <span class="n">y</span> <span class="p">(</span><span class="n">unique</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">))</span>
<span class="o">==.</span> <span class="n">count</span> <span class="n">y</span> <span class="p">(</span><span class="n">unique</span> <span class="n">xs</span><span class="p">)</span>
<span class="o">==.</span> <span class="mi">1</span> <span class="o">?</span> <span class="n">thmUniqueNoDup</span> <span class="n">xs</span> <span class="n">y</span>
<span class="o">***</span> <span class="kt">QED</span>
<span class="kr">else</span>
<span class="n">count</span> <span class="n">y</span> <span class="p">(</span><span class="n">unique</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">))</span>
<span class="o">==.</span> <span class="n">count</span> <span class="n">y</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">unique</span> <span class="n">xs</span><span class="p">)</span>
<span class="o">==.</span> <span class="n">count</span> <span class="n">y</span> <span class="p">(</span><span class="n">unique</span> <span class="n">xs</span><span class="p">)</span>
<span class="o">==.</span> <span class="mi">1</span> <span class="o">?</span> <span class="n">thmUniqueNoDup</span> <span class="n">xs</span> <span class="n">y</span>
<span class="o">***</span> <span class="kt">QED</span>
</code></pre></div></div>
<p>Let’s break this down a bit. <code class="highlighter-rouge">==.</code> is the Liquid Haskell combinator for
“extensionally equivalent to”, which means that the expressions on both sides
will evaluate to the same value (or lack of value). When we use this, we’re
asking LH to check whether using that equivalence as a step is justified<sup id="fnref:2"><a href="#fn:2" class="footnote">2</a></sup>.</p>
<p>As before, though, sometimes LH can’t figure out that a given step is justified
on its own. Instead, we can provide a justification for a step with the <code class="highlighter-rouge">?</code>
combinator. For example, in this step</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">count</span> <span class="n">y</span> <span class="p">(</span><span class="n">unique</span> <span class="n">xs</span><span class="p">)</span> <span class="o">==.</span> <span class="mi">1</span> <span class="o">?</span> <span class="n">thmUniqueNoDup</span> <span class="n">xs</span> <span class="n">y</span>
</code></pre></div></div>
<p>By our assumption on <code class="highlighter-rouge">y</code>, we know <code class="highlighter-rouge">y </code><code class="highlighter-rouge">elem</code><code class="highlighter-rouge"> xs</code>. Thus, by the types of
<code class="highlighter-rouge">thmUniqueNoDup</code> (that is, by our inductive hypothesis), we know that
<code class="highlighter-rouge">count y (unique xs)</code> evaluates to <code class="highlighter-rouge">1</code>.</p>
<p>The final thing here is <code class="highlighter-rouge">*** QED</code>, which finalizes the “proof” in Haskell
types. We need this to ensure that we can actually have a term of the Haskell
type <code class="highlighter-rouge">Proof</code> provided by Liquid Haskell.</p>
<p>Next case might start looking like this:</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">thmUniqueNoDup</span> <span class="o">::</span> <span class="kt">Eq</span> <span class="n">a</span> <span class="o">=></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="n">a</span> <span class="o">-></span> <span class="kt">Proof</span>
<span class="n">thmUniqueNoDup</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="n">y</span>
<span class="o">|</span> <span class="n">otherwise</span> <span class="o">=</span>
<span class="n">count</span> <span class="n">y</span> <span class="p">(</span><span class="n">unique</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">))</span>
<span class="o">==.</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">count</span> <span class="n">y</span> <span class="p">(</span><span class="n">unique</span> <span class="n">xs</span><span class="p">)</span>
<span class="o">==.</span> <span class="mi">1</span> <span class="o">?</span> <span class="n">someTheorem</span>
<span class="o">***</span> <span class="kt">QED</span>
</code></pre></div></div>
<p>So what can we use for <code class="highlighter-rouge">someTheorem</code>? We’d need to somehow show that
<code class="highlighter-rouge">count y (unique xs)</code> is <code class="highlighter-rouge">0</code>, but our inductive hypothesis can only tell us
that <code class="highlighter-rouge">count x (unique xs)</code> is equal to <code class="highlighter-rouge">1</code>!</p>
<p>It turns out that we don’t actually have enough to show that the other case is
sound. To do that, we’ll need two auxiliary theorems:</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">{-@ reflect thmElemCount @-}</span>
<span class="cm">{-@ thmElemCount :: Eq a =>
x:a -> xs:{[a] | not elem x xs} -> { count x xs == 0 }
@-}</span>
<span class="n">thmElemCount</span> <span class="o">::</span> <span class="kt">Eq</span> <span class="n">a</span> <span class="o">=></span> <span class="n">a</span> <span class="o">-></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="nb">()</span>
<span class="n">thmElemCount</span> <span class="n">x</span> <span class="kt">[]</span> <span class="o">=</span> <span class="nb">()</span>
<span class="n">thmElemCount</span> <span class="n">x</span> <span class="p">(</span><span class="n">y</span><span class="o">:</span><span class="n">ys</span><span class="p">)</span> <span class="o">=</span> <span class="n">thmElemCount</span> <span class="n">x</span> <span class="n">ys</span>
<span class="cm">{-@ thmUniqueExistInv ::
xs:[a] ->
{x:a | not elem x xs} ->
{ not elem x (unique xs) }
@-}</span>
<span class="n">thmUniqueExistInv</span> <span class="o">::</span> <span class="kt">Eq</span> <span class="n">a</span> <span class="o">=></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="n">a</span> <span class="o">-></span> <span class="kt">Proof</span>
<span class="n">thmUniqueExistInv</span> <span class="kt">[]</span> <span class="n">y</span> <span class="o">=</span> <span class="n">trivial</span> <span class="o">***</span> <span class="kt">QED</span>
<span class="n">thmUniqueExistInv</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="n">y</span>
<span class="o">=</span> <span class="n">elem</span> <span class="n">y</span> <span class="p">(</span><span class="n">unique</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">))</span>
<span class="o">==.</span> <span class="n">elem</span> <span class="n">y</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">unique</span> <span class="n">xs</span><span class="p">)</span>
<span class="o">==.</span> <span class="n">elem</span> <span class="n">y</span> <span class="p">(</span><span class="n">unique</span> <span class="n">xs</span><span class="p">)</span>
<span class="o">==.</span> <span class="kt">False</span> <span class="o">?</span> <span class="n">thmUniqueExistInv</span> <span class="n">xs</span> <span class="n">y</span>
<span class="o">***</span> <span class="kt">QED</span>
</code></pre></div></div>
<p>The first simply creates and proves the “obvious” relation between <code class="highlighter-rouge">elem</code> and
<code class="highlighter-rouge">count</code>. We’ll ultimately be invoking <em>this</em> theorem to get our <code class="highlighter-rouge">0</code>. The second
is slightly more interesting. Note that the precondition for <code class="highlighter-rouge">thmElemCount</code> is
that <code class="highlighter-rouge">x</code> is <em>not</em> an element of <code class="highlighter-rouge">xs</code>. However, we haven’t actually shown that
<code class="highlighter-rouge">unique xs</code> won’t contain any elements not in <code class="highlighter-rouge">xs</code>! So we need to prove it.</p>
<p>This gives us our final step:</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">...</span>
<span class="o">==.</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">count</span> <span class="n">y</span> <span class="p">(</span><span class="n">unique</span> <span class="n">xs</span><span class="p">)</span>
<span class="o">==.</span> <span class="mi">1</span> <span class="o">?</span> <span class="n">thmUniqueExistInv</span> <span class="n">xs</span> <span class="n">y</span> <span class="p">`</span><span class="n">seq</span><span class="p">`</span> <span class="n">thmElemCount</span> <span class="n">y</span> <span class="p">(</span><span class="n">unique</span> <span class="n">xs</span><span class="p">)</span>
<span class="o">***</span> <span class="kt">QED</span>
</code></pre></div></div>
<p>Notice the <code class="highlighter-rouge">seq</code> here. In order to cite <code class="highlighter-rouge">thmElemCount</code>, we need to show that
<code class="highlighter-rouge">y</code> is not an element of <code class="highlighter-rouge">unique xs</code>, so we must first use <code class="highlighter-rouge">thmUniqueExistInv</code>.</p>
<h2 id="the-less-obvious-part">The Less Obvious Part</h2>
<p>In most worlds, this would be enough. We’ve shown that, for every element in
<code class="highlighter-rouge">xs</code>, <code class="highlighter-rouge">unique xs</code> contains that element exactly once. Incidentally, we also
showed that <code class="highlighter-rouge">unique xs</code> didn’t “spawn” elements – if an element isn’t in
<code class="highlighter-rouge">xs</code>, it can’t be in <code class="highlighter-rouge">unique xs</code> either.</p>
<p>However, we’re not done yet. The world of type theory (of which Liquid
Haskell’s refinement types are a subworld) is one based on <em>constructive
logic</em> (otherwise known as <em>intuitionistic logic</em>), which removes the law
of the excluded middle. That is, <script type="math/tex">\neg \neg P \nRightarrow P</script>. In this
particular case, that means that we’re not done! We’ve only proven that
every element in <code class="highlighter-rouge">unique xs</code> is <em>not not in</em> <code class="highlighter-rouge">xs</code>, which is not the same as
saying that it’s <em>in</em> <code class="highlighter-rouge">xs</code><sup id="fnref:3"><a href="#fn:3" class="footnote">3</a></sup>.</p>
<p>For the sake of completeness, let’s show that <code class="highlighter-rouge">x</code> being in <code class="highlighter-rouge">unique xs</code> implies
that <code class="highlighter-rouge">x</code> is in <code class="highlighter-rouge">xs</code> as well!</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">{-@ thmUniqueExist ::
xs:[a] ->
{x:a | elem x (unique xs)} ->
{ elem x xs }
@-}</span>
<span class="n">thmUniqueExist</span> <span class="o">::</span> <span class="kt">Eq</span> <span class="n">a</span> <span class="o">=></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="n">a</span> <span class="o">-></span> <span class="kt">Proof</span>
<span class="n">thmUniqueExist</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="n">y</span>
<span class="o">|</span> <span class="n">y</span> <span class="o">==</span> <span class="n">x</span> <span class="o">=</span> <span class="n">trivial</span> <span class="o">***</span> <span class="kt">QED</span>
<span class="o">|</span> <span class="n">otherwise</span>
<span class="o">=</span> <span class="n">elem</span> <span class="n">y</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span>
<span class="o">==.</span> <span class="n">elem</span> <span class="n">y</span> <span class="n">xs</span>
<span class="o">==.</span> <span class="kt">True</span> <span class="o">?</span> <span class="n">thmUniqueExist'</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="n">y</span> <span class="p">`</span><span class="n">seq</span><span class="p">`</span> <span class="n">thmUniqueExist</span> <span class="n">xs</span> <span class="n">y</span>
<span class="o">***</span> <span class="kt">QED</span>
<span class="cm">{-@ thmUniqueExist' ::
xs:{[a] | len xs > 0} ->
{x:a | elem x (unique xs) && x != hd xs} ->
{ elem x (unique (tl xs)) }
@-}</span>
<span class="n">thmUniqueExist'</span> <span class="o">::</span> <span class="kt">Eq</span> <span class="n">a</span> <span class="o">=></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="n">a</span> <span class="o">-></span> <span class="kt">Proof</span>
<span class="n">thmUniqueExist'</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="n">y</span>
<span class="o">=</span> <span class="n">elem</span> <span class="n">y</span> <span class="p">(</span><span class="n">unique</span> <span class="p">(</span><span class="n">tl</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)))</span>
<span class="o">==.</span> <span class="n">elem</span> <span class="n">y</span> <span class="p">(</span><span class="n">unique</span> <span class="n">xs</span><span class="p">)</span>
<span class="o">==.</span> <span class="n">elem</span> <span class="n">y</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">unique</span> <span class="n">xs</span><span class="p">)</span>
<span class="o">==.</span> <span class="n">elem</span> <span class="n">y</span> <span class="p">(</span><span class="n">unique</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">))</span>
<span class="o">==.</span> <span class="kt">True</span>
<span class="o">***</span> <span class="kt">QED</span>
</code></pre></div></div>
<p>I won’t go over every step, but an important step is in the derivation of
<code class="highlighter-rouge">thmUniqueExist'</code>, in which we actually step “backwards” from
<code class="highlighter-rouge">elem y (x:unique xs)</code> to <code class="highlighter-rouge">elem y (unique (x:xs))</code> (by the definition of
<code class="highlighter-rouge">unique</code>). I’m actually not particularly satisfied with this proof; in
particular I find the forced use of <code class="highlighter-rouge">hd</code> and <code class="highlighter-rouge">tl</code> to be extremely inelegant.
If you know of a better way, please let me know!</p>
<p>Onwards to Fulcrum! This one may take a bit longer – I’ve been sitting on this
solution to Unique for about a week, but Fulcrum has been giving me <em>way</em> more
trouble.</p>
<div class="footnotes">
<ol>
<li id="fn:1">
<p>If you think this sounds similar to P vs NP, you’d be correct! Proof generation is actually coNP-complete, which means that it’s easy to check that a proof is <em>wrong</em>, but difficult to create a proof from scratch or verify that it’s correct! <a href="#fnref:1" class="reversefootnote">↩</a></p>
</li>
<li id="fn:2">
<p>Technically, LH doesn’t check <em>every</em> step. The official documentation states that LH will only check that the first and last steps are justified, but with some experimentation I’ve found that certain intermediate steps are mandatory. Who knows? <a href="#fnref:2" class="reversefootnote">↩</a></p>
</li>
<li id="fn:3">
<p>The difference may seem academic to you, and in this case it arguably is. For a better discussion of the difference between classical and logical systems, check out <a href="https://existentialtype.wordpress.com/2017/03/04/a-proof-by-contradiction-is-not-a-proof-that-derives-a-contradiction/">this</a> awesome blog post by Professor Harper of CMU. <a href="#fnref:3" class="reversefootnote">↩</a></p>
</li>
</ol>
</div>Cameron Wongcam@camdar.ioThis is the second of a series on Hillel Wayne’s Great Theorem Prover Showdown. Make sure to check out the first part! You can also follow my progress in this repository.The Great Theorem Prover Challenge I2018-06-21T00:00:00+00:002018-06-21T00:00:00+00:00https://ct075.github.io/2018-06-21/theorem-prover-1<p>I was having a discussion with a coworker over lunch the other day about code
reasoning and informal correctness (things like “it feels correct” and “it
passes a very extensive array of tests”). At some point, the conversation
strayed to the relative merits of imperative vs functional paradigms, and which
one “feels” easier, as it always does. As a fairly loud proponent of
functional-styled programming, I, of course, made the standard arguments about
the heap and global state, etc, and was rebuffed by “the overhead of juggling
abstractions”.</p>
<p>Now, I won’t get into why I think the response is bullshit (tl;dr if you have
to “juggle” an abstraction, it’s not really a very good abstraction), but it
did leave me somewhat at a loss as to how we were defining “feeling” easy. It’s
a very fuzzy, subjective term, and not really one I’m prepared to go into at
any depth.</p>
<p>This brings us to the subject of formal verification. One argument for powerful
and expressive static typesystems is to give strong compile-time guarantees,
which can aid in correctness. For example, in Python, if we create a function
that operates primarily on integers, it may not work correctly or even just
blow up if given, say, a string. This introduces a vector for bugs if we don’t
properly check the return type of some other function, and can cause crashes or
(worse) subtly wrong behavior. However, with a static typesystem, we can <em>know</em>
that the function is never called on anything but a number – because otherwise
the function wouldn’t typecheck, and the code wouldn’t compile at all!</p>
<p>Formal verification is taking this idea to its logical conclusion – what if we
encode <em>all</em> correctness properties inherent to the code in some way that can
be checked alongisde the code at compile time? Well, the first thing you’ll
find is that you start running into Rice’s Theorem (or more generally, the
halting problem), but you also find that there are a surprising number of
things that can be done and ways to do them.</p>
<p>A few months ago, I found Hillel Wayne’s <a href="https://www.hillelwayne.com/post/theorem-prover-showdown/">Great Theorem Prover Showdown</a> on reddit, and found
the included discussion quite interesting. After that argument with my friend,
I decided that I’d also bite the bullet and try it for myself.</p>
<p>“After all,” I thought, “it’s <em>functional programming</em>. We do proofs like that
for the entire semester in 15-150; how hard can it be to write an equivalent in
a theorem proving language?”</p>
<p>Now, before I go any further, let me outline my previous personal experience
with formal verification:</p>
<ul>
<li>A brief section of a static analysis course at university discussing loop
invariants and pre-/post-condition analysis (contracts)</li>
<li>An even briefer single lesson about refinement types, given by some friends
in the CMU PL community</li>
<li>Hillel Wayne’s blog post</li>
</ul>
<p>Note that none of the above even involved <em>touching</em> a theorem prover (the
closest I had gotten was brute-forcing some logic problems using the Z3
Haskell bindings). Not that I’m about to let that stop me. So let’s dive into
<code class="highlighter-rouge">Leftpad</code>, the first challenge. I chose to approach this with <a href="https://ucsd-progsys.github.io/liquidhaskell-blog/">Liquid Haskell</a> because it seemed to be the
simpler of the two (Idris being the other option) to just pick up and get
running.</p>
<h1 id="the-challenge">The Challenge</h1>
<p><em>You can follow my progress in <a href="https://github.com/CT075/theorem-prover-showdown">this</a> repository.</em></p>
<p>Our goal is to replicate the classic <code class="highlighter-rouge">leftPad</code> function that pads a string to a
desired length.</p>
<p>The first thing we need to do is write the code itself. Most people attempting
this challenge did some variant on a <code class="highlighter-rouge">replicate</code> solution, but I opted for a
more naturally-recursive version (this ended up being a good decision).</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">leftPad</span> <span class="o">::</span> <span class="kt">Int</span> <span class="o">-></span> <span class="n">a</span> <span class="o">-></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">leftPad</span> <span class="n">n</span> <span class="n">x</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">leftPad'</span> <span class="n">k</span> <span class="n">x</span> <span class="n">xs</span>
<span class="kr">where</span> <span class="n">k</span> <span class="o">=</span> <span class="n">max</span> <span class="mi">0</span> <span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="n">size</span> <span class="n">xs</span><span class="p">)</span>
<span class="n">leftPad'</span> <span class="mi">0</span> <span class="kr">_</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">xs</span>
<span class="n">leftPad'</span> <span class="n">n</span> <span class="n">x</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">x</span> <span class="o">:</span> <span class="n">leftPad'</span> <span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="n">x</span> <span class="n">xs</span>
</code></pre></div></div>
<p>Now, let’s get onto actually proving this “correct”. Everyone with a hat in
this game (including me!) will talk your ears off about how “correctness”
doesn’t really mean anything without a “specification” to guide it. In this
case, we’ve been helpfully provided an informal spec, but not really anything
by way of a formalized contract to follow. That’s fine, part of our job is to
turn informal specs into formal ones.</p>
<p>The specification for LeftPad, as given is:</p>
<blockquote>
<p>Takes a padding character, a string, and a total length, returns the string
padded to that length with that character. If length is less than the length of
the string, does nothing.</p>
</blockquote>
<p>Ooookay. That’s a little vague. Breaking it down, we start by looking at the
inputs – “given a padding character, a string, and a total length”. This gives
us our input types:</p>
<h2 id="a-first-try">A First Try</h2>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">{-@ leftPad :: Int -> a -> [a] -> [a]
@-}</span>
</code></pre></div></div>
<p>It’s a start, but it’s not particularly useful. To really leverage the power of
LH, we need to actually use our types to prove something! The point of leftPad
is to ensure that a string is the correct length, so let’s try to prove that:</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">{-@ reflect leftPad @-}</span>
<span class="cm">{-@ leftPad :: n:Int -> x:a -> xs:[a] ->
result:{ [a] |
size result = max n (size xs)
}
@-}</span>
</code></pre></div></div>
<p>What this means is that the result of leftPad will be of length <code class="highlighter-rouge">n</code> or the same
length of the original string, whichever is larger. We also <code class="highlighter-rouge">reflect</code> our
function, so it becomes a proper term in the logic.</p>
<p>According to some people, this is enough. The function is “obviously” correct.
Let’s test that assumption – does Liquid Haskell think that we’re done?</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Error: Liquid Type Mismatch
33 | leftPad n x xs = leftPad' k x xs
^^^^^^^^^^^^^^^
Inferred type
VV : {v : [a] | [SNIPPED: big mess] }
not a subtype of Required type
VV : {VV : [a] | Main.size VV == Main.max n (Main.size xs)}
In Context
xs : {v : [a] | Main.size v >= 0 && len v >= 0}
n : {n : Int | n >= 0}
x : a
Error: Liquid Type Mismatch
44 | leftPad' n x xs = x : leftPad' (n-1) x xs
^^^
Inferred type
VV : {v : Int | v == ?b - (1 : int)}
not a subtype of Required type
VV : {VV : Int | VV < ?b && VV >= 0}
In Context
?b : Int
</code></pre></div></div>
<p>(if you just tried this for yourself, you may need to also define <code class="highlighter-rouge">size</code> and
<code class="highlighter-rouge">max</code> and reflect them into the logic)</p>
<p>Okay, there are two errors here. The first is that big mess of types on the
function we actuallly annotated. I’ll get there in a bit. The <em>second</em> error,
however, seems to be saying that our types are wrong for <code class="highlighter-rouge">leftPad'</code> as well!
What gives?</p>
<p>It turns out that LH is actually smart enough to recognize that the function
won’t terminate if given an input <code class="highlighter-rouge">n < 0</code>. Because we like our programs to be
decidable, this lets LH decide that the type of the first argument to
<code class="highlighter-rouge">leftPad'</code> should be positive, as seen by the <code class="highlighter-rouge">VV >= 0</code>. In fact, a similar
argument can be used to show an <em>upper</em> bound as well! Notice that our only
base case is <code class="highlighter-rouge">n = 0</code>. This means that, in order to make progress, we should
have <code class="highlighter-rouge">n</code> decrease every time – thus <code class="highlighter-rouge">VV < ?b</code>. This seems like a less hard
rule than the previous, but I’m not really familiar enough to say what would
happen if we had multiple axes (or even just a nonstandard termination
condition). However, we have no conditions on the <em>original</em> input, and there’s
nothing stopping us from just passing in a negative <code class="highlighter-rouge">n</code>. Thus the type
mismatch.</p>
<p>The crux of the issue is that LH can’t (or won’t try to) understand what
<code class="highlighter-rouge">leftPad'</code> is doing, or what theorems it upholds. We can fix that by adding
some manual annotations of our own:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{-@ reflect leftPad' @-}
{-@ leftPad' :: n:Nat -> x:a -> xs:[a] ->
result:{[a] |
size result = n + size xs
}
@-}
</code></pre></div></div>
<p>The only new thing is <code class="highlighter-rouge">Nat</code>, which means <code class="highlighter-rouge">n:{Int | n >= 0}</code><sup id="fnref:1"><a href="#fn:1" class="footnote">1</a></sup>.</p>
<p>We run it through <code class="highlighter-rouge">liquid</code> and… it’s safe! Wait, what?</p>
<p>This blew my mind the first time I saw this. The only effort really expended by
me was to <em>tell Liquid Haskell what my functions should do</em>, and it was able to
tell me with no<sup id="fnref:2"><a href="#fn:2" class="footnote">2</a></sup> other information!</p>
<p>The key here is induction, the idea that properties hold over certain
operations. If that seems a little abstract, let’s walk it through.</p>
<p>First, let’s make sure that the function is even well-formed. We have</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">leftPad</span> <span class="n">n</span> <span class="n">x</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">leftPad'</span> <span class="n">k</span> <span class="n">x</span> <span class="n">xs</span>
<span class="kr">where</span> <span class="n">k</span> <span class="o">=</span> <span class="n">max</span> <span class="mi">0</span> <span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="n">size</span> <span class="n">xs</span><span class="p">)</span>
</code></pre></div></div>
<p><code class="highlighter-rouge">max</code> probably has a type like <code class="highlighter-rouge">x:Int -> y:Int -> r:{Int | r >= x && r >= y}</code>
<sup id="fnref:3"><a href="#fn:3" class="footnote">3</a></sup>. This means that <code class="highlighter-rouge">max 0 i</code> is a subtype of <code class="highlighter-rouge">r:{Int | r >= 0}</code>
automatically… which means that <code class="highlighter-rouge">k</code> must have type <code class="highlighter-rouge">Nat</code>, and is thus a valid
input to <code class="highlighter-rouge">leftPad'</code>! <code class="highlighter-rouge">x</code> and <code class="highlighter-rouge">xs</code> have no special conditions, so those just
pass through.</p>
<p>Onto <code class="highlighter-rouge">leftPad'</code>. We know that, given valid inputs, our result must satisfy
the type <code class="highlighter-rouge">r:{[a] | size r = n + size xs}</code>. For our base case, we find that</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>leftPad' 0 x xs = xs
</code></pre></div></div>
<p>so <code class="highlighter-rouge">r = xs</code> in this case. We also have <code class="highlighter-rouge">n = 0</code>, so we want to show that</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>size xs = 0 + size xs
</code></pre></div></div>
<p>which is a no-brainer.</p>
<p>Next, our inductive step.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>leftPad' n x xs = x : leftPad' (n-1) x xs
</code></pre></div></div>
<p>For this to be well-typed, we need to know a few things, namely that
<code class="highlighter-rouge">n-1</code> is a <code class="highlighter-rouge">Nat</code>, or that <code class="highlighter-rouge">n-1 >= 0</code>. Luckily, we already know that <code class="highlighter-rouge">n >= 0</code>
because we’re given <code class="highlighter-rouge">n:Nat</code> as a precondition. But wait, we also know that
<code class="highlighter-rouge">n != 0</code>, because we pattern matched on it earlier! Thus, <code class="highlighter-rouge">n > 0</code> for sure,
so <code class="highlighter-rouge">n - 1 >= 0</code> is fine.</p>
<p>Next, we can use our “inductive hypothesis” – we can assume that an recursive
uses of <code class="highlighter-rouge">leftPad'</code> are well-typed. That means, in this case, that we know that
<code class="highlighter-rouge">leftPad' (n-1) x xs</code> returns something of type <code class="highlighter-rouge">r:{[a] | size r = n-1 + size
xs}</code>. We want to exhibit a term of type <code class="highlighter-rouge">r:{[a] | size r = n + size xs}</code>. Well,
by the definition of <code class="highlighter-rouge">size</code>, <code class="highlighter-rouge">x:l</code> has type <code class="highlighter-rouge">r:{[a] | size r = 1 + size l}</code>,
so our returned expression <code class="highlighter-rouge">x : leftPad' (n-1) x xs</code> should have type
<code class="highlighter-rouge">r:{[a] | size r = 1 + size (leftPad' (n-1) x xs) }</code>… which is
<code class="highlighter-rouge">r:{[a] | size r = 1 + (n-1) + size xs}</code>, or <em>exactly what we wanted</em>.</p>
<p>All of this reasoning, by the way, was decided by LH with no prompting from me.
The only thing I did was provide the code and the types, the typechecking
happened automagically. The phrase “obviously correct” has a bit more weight
after that.</p>
<h2 id="not-so-obvious">Not so Obvious</h2>
<p>You may notice that we haven’t actually fulfilled the spec given by Hillel. For
example, a function that took a random <code class="highlighter-rouge">n</code> elements from the input would also
fulfill the spec we’ve given so far. We need to also encode that the original
string is <em>padded</em> with the pad character. The way this is formalized is as
follows:</p>
<blockquote>
<p>Given a list <code class="highlighter-rouge">xs</code>, fill element <code class="highlighter-rouge">x</code> and a length <code class="highlighter-rouge">n</code>, for any index <code class="highlighter-rouge">i</code>,</p>
<ul>
<li>If <code class="highlighter-rouge">i < n - size xs</code>, the list element should be <code class="highlighter-rouge">x</code>.</li>
<li>Otherwise, the list element should be the corresponding element of <code class="highlighter-rouge">xs</code></li>
</ul>
</blockquote>
<p>We can represent this in Haskell by introducing a separate predicate as
follows:</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">{-@ reflect leftPadElt @-}</span>
<span class="cm">{-@ leftPadElt :: n:Int -> x:a -> xs:[a] -> i:{Nat | i < n} -> a @-}</span>
<span class="n">leftPadElt</span> <span class="o">::</span> <span class="kt">Int</span> <span class="o">-></span> <span class="n">a</span> <span class="o">-></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="kt">Int</span> <span class="o">-></span> <span class="n">a</span>
<span class="n">leftPad</span> <span class="kt">Elt</span> <span class="n">n</span> <span class="n">x</span> <span class="n">xs</span> <span class="n">i</span>
<span class="o">|</span> <span class="n">i</span> <span class="o"><</span> <span class="n">k</span> <span class="o">=</span> <span class="n">x</span>
<span class="o">|</span> <span class="n">otherwise</span> <span class="o">=</span> <span class="n">x</span> <span class="o">!!</span> <span class="p">(</span><span class="n">i</span><span class="o">-</span><span class="n">k</span><span class="p">)</span>
<span class="kr">where</span> <span class="n">k</span> <span class="o">=</span> <span class="n">max</span> <span class="mi">0</span> <span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="n">size</span> <span class="n">xs</span><span class="p">)</span>
</code></pre></div></div>
<p>Because LH doesn’t have “forall” quantification (this leads to a nasty thing
called “the halting problem”), we can’t really encode something like</p>
<p>“For all <code class="highlighter-rouge">i</code> from <code class="highlighter-rouge">0 to n</code>, <code class="highlighter-rouge">leftPad n x xs !! i == leftPadElt n x xs i</code>”</p>
<p>into the type of <code class="highlighter-rouge">leftPad</code> itself. Instead, we need to show this by
demonstrating a term of type</p>
<p><code class="highlighter-rouge">n:Int -> x:a -> xs:[a] -> i:{Nat | i < n} ->
{leftPad n x xs !! i == leftPadElt n x xs i}</code></p>
<p>So, how do we do that? Well, any proof with no actually associated “data” (like
the list elements) can be seen as having a refinement on the type <code class="highlighter-rouge">()</code>, a term
that fulfills all the conditions we need. If that’s a little hard to follow,
don’t worry – it will (hopefully!) make more sense in a moment.</p>
<p>There are two parts to the elements definition, one for the first <code class="highlighter-rouge">k</code> elements
and one for the last <code class="highlighter-rouge">size xs</code> elements, so it makes sense to split our “proof”
into two parts. Let’s take a look at the first part.</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">{-@ thmLeftPadA :: n:Nat -> x:a -> xs:[a] -> i:{Nat | i < n} ->
{ leftPad' n x xs !! i == x }
@-}</span>
</code></pre></div></div>
<p>Notice that I’m using <code class="highlighter-rouge">leftPad'</code> here instead of <code class="highlighter-rouge">leftPad</code>. That’s because
we’ve already shown (defined) <code class="highlighter-rouge">leftPad</code> to be a special case of <code class="highlighter-rouge">leftPad'</code>, so
it makes sense to prove something about the easier function to reason about.</p>
<p>So what would a term like this look like? Well, we can start with something
simple: by definition, <code class="highlighter-rouge">leftPad' n x xs = x:[something]</code><sup id="fnref:4"><a href="#fn:4" class="footnote">4</a></sup>. But wait, that
means <code class="highlighter-rouge">leftPad' n x xs !! 0 == x</code> always… so the result of
<code class="highlighter-rouge">thmLeftPadA n xs 0</code> <em>already</em> has the right type.</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">thmLeftPadA</span> <span class="o">::</span> <span class="kt">Int</span> <span class="o">-></span> <span class="n">a</span> <span class="o">-></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="kt">Int</span> <span class="o">-></span> <span class="nb">()</span>
<span class="n">thmLeftPadA</span> <span class="n">n</span> <span class="n">x</span> <span class="n">xs</span> <span class="mi">0</span> <span class="o">=</span> <span class="nb">()</span>
</code></pre></div></div>
<p>What about the other case? Same as any other proof by induction!</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">thmLeftPadA</span> <span class="o">::</span> <span class="kt">Int</span> <span class="o">-></span> <span class="n">a</span> <span class="o">-></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="kt">Int</span> <span class="o">-></span> <span class="nb">()</span>
<span class="n">thmLeftPadA</span> <span class="n">n</span> <span class="n">x</span> <span class="n">xs</span> <span class="mi">0</span> <span class="o">=</span> <span class="nb">()</span>
<span class="n">thmLeftPadA</span> <span class="n">n</span> <span class="n">x</span> <span class="n">xs</span> <span class="n">i</span> <span class="o">=</span> <span class="n">thmLeftPadA</span> <span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="n">x</span> <span class="n">xs</span> <span class="p">(</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div></div>
<p>By the same reasoning as before, we know that <code class="highlighter-rouge">i > 0</code>. We actually know <code class="highlighter-rouge">n > 0</code>
as well, because the type <code class="highlighter-rouge">i:{Nat | i < 0}</code> is uninhabited. Thus the recursive
call to <code class="highlighter-rouge">thmLeftPadA</code> is well-founded. This gives us a term of type
<code class="highlighter-rouge">{leftPad' (n-1) x xs !! (i-1) == x}</code>. Again by definition, <code class="highlighter-rouge">leftPad' n x xs</code>
is equal to <code class="highlighter-rouge">x:leftPad' (n-1) x xs</code> and <code class="highlighter-rouge">(x:xs) !! i</code> is <code class="highlighter-rouge">xs !! i-1</code>, which
means that this is, in fact, equivalent to a term of the type we want!</p>
<p>The second part looks like this (the derivation is left to the reader):</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">{-@ thmLeftPadB ::
n:Nat -> x:a -> xs:[a] ->
i:{Nat | i >= n && i < n + size xs} ->
{ leftPad' n x xs !! i == xs !! (i-n) }
@-}</span>
<span class="n">thmLeftPadB</span> <span class="o">::</span> <span class="kt">Int</span> <span class="o">-></span> <span class="n">a</span> <span class="o">-></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="kt">Int</span> <span class="o">-></span> <span class="nb">()</span>
<span class="n">thmLeftPadB</span> <span class="mi">0</span> <span class="n">x</span> <span class="n">xs</span> <span class="n">i</span> <span class="o">=</span> <span class="nb">()</span>
<span class="n">thmLeftPadB</span> <span class="n">n</span> <span class="n">x</span> <span class="n">xs</span> <span class="n">i</span> <span class="o">=</span> <span class="n">thmLeftPadB</span> <span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="n">x</span> <span class="n">xs</span> <span class="p">(</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div></div>
<p>All that’s left is to string these two parts together into our final proof:</p>
<div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">{-@ thmLeftPad :: n:Int -> x:a -> xs:[a] -> i:{Nat | i < n} ->
{ leftPad n x xs !! i == leftPadElt n x xs i }
@-}</span>
<span class="n">thmLeftPad</span> <span class="o">::</span> <span class="kt">Int</span> <span class="o">-></span> <span class="n">a</span> <span class="o">-></span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-></span> <span class="kt">Int</span> <span class="o">-></span> <span class="nb">()</span>
<span class="n">thmLeftPad</span> <span class="n">n</span> <span class="n">x</span> <span class="n">xs</span> <span class="n">i</span>
<span class="o">|</span> <span class="n">i</span> <span class="o"><</span> <span class="n">k</span> <span class="o">=</span> <span class="n">thmLeftPadA</span> <span class="n">k</span> <span class="n">x</span> <span class="n">xs</span> <span class="n">i</span>
<span class="o">|</span> <span class="n">otherwise</span> <span class="o">=</span> <span class="n">thmLeftPadB</span> <span class="n">k</span> <span class="n">x</span> <span class="n">xs</span> <span class="n">i</span>
<span class="kr">where</span> <span class="n">k</span> <span class="o">=</span> <span class="n">max</span> <span class="mi">0</span> <span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="n">size</span> <span class="n">xs</span><span class="p">)</span>
</code></pre></div></div>
<p>And there you have it! We have a <em>formally verified</em> leftPad.</p>
<div class="footnotes">
<ol>
<li id="fn:1">
<p>I’m a computer scientist. Of course 0 is a natural number. <a href="#fnref:1" class="reversefootnote">↩</a></p>
</li>
<li id="fn:2">
<p>Okay, with a little extra. I did have to define <code class="highlighter-rouge">size</code> and <code class="highlighter-rouge">max</code>. <a href="#fnref:2" class="reversefootnote">↩</a></p>
</li>
<li id="fn:3">
<p>Because I just let LH infer it for me, I don’t actually know for sure. <a href="#fnref:3" class="reversefootnote">↩</a></p>
</li>
<li id="fn:4">
<p>Technically, <code class="highlighter-rouge">n = 0</code> is the exception, but that actually violates the precondition on <code class="highlighter-rouge">thmLeftPadA</code>. <a href="#fnref:4" class="reversefootnote">↩</a></p>
</li>
</ol>
</div>Cameron Wongcam@camdar.ioI was having a discussion with a coworker over lunch the other day about code reasoning and informal correctness (things like “it feels correct” and “it passes a very extensive array of tests”). At some point, the conversation strayed to the relative merits of imperative vs functional paradigms, and which one “feels” easier, as it always does. As a fairly loud proponent of functional-styled programming, I, of course, made the standard arguments about the heap and global state, etc, and was rebuffed by “the overhead of juggling abstractions”.Who needs an API, anyway?2016-06-30T00:00:00+00:002016-06-30T00:00:00+00:00https://ct075.github.io/2016-06-30/trolling<p>Alt Title: My (Failed) Quest to Achieve Automated Trolling</p>
<p>So today is my good friend’s birthday. As is typical of a birthday, I had several photos of said friend to post on his wall, but wait! Instead of being boring and doing a collage/album, I wanted to return the favor he paid to me on my birthday by posting one every hour. Given that I had seven of them, I would need to stick around (or at least pay attention) every hour. Ugh. Add that I’m impatient, and we get a recipe for “not a good idea”!</p>
<p>Enter scripting! My thought was to set a timer for every hour to post a photo to his wall (with the accompanying caption), but little did I know that this was quite a tall order (and probably one that FB doesn’t endorse anyway).</p>
<p>My first thought (of course) is to google “Facebook API post photo to wall”. This gets me to <a href="http://stackoverflow.com/questions/14504397/facebook-api-how-to-publish-photo-on-the-users-wall">this page</a> and <a href="https://developers.facebook.com/docs/php/howto/uploadphoto">this page</a>. Both look like PHP. Pass. (A bit more preliminary research showed that FB only officially supports JS and PHP. Yeesh. And they say they want to <em>promote</em> new programmers?)</p>
<p>Searching for the python SDK is a little more fruitful, although I’m faced with the same problem of “how do i post phot”. With enough digging and reflection (the <a href="https://docs.python.org/3/library/inspect.html">inspect module</a> is fantastic and should be used on mystery libraries frequently if you’re like me and need to know how <em>everything works</em>), I find <a href="the same page as before">https://developers.facebook.com/docs/graph-api/reference/user/photos</a>, but now with some clarity - particularly the “target_id” parameter.</p>
<p>All good, it seems - I can now programmatically upload photos to a friend’s wall. Last thing I need to do is authenticate.</p>
<p>Wait, what?</p>
<p>You see, Facebook authenticates its apps with some kind of “user token”. I have no idea how to obtain one of these, nor is it important enough for me to find out. I did do some fiddling around with Facebook Apps and ended up with something called an “App Secret”, but that doesn’t allow me to post to walls. I’m sure that, with enough patience, I could finagle a way (perhaps by adapting the php code found earlier), but at this point I’ve literally done an hour of research on, essentially, a prank.</p>
<p><img src="http://imgs.xkcd.com/comics/automation.png" alt="xkcd 1319" /></p>
<p><a href="https://xkcd.com/1319/">source</a></p>
<p>Sitting here a few hours later, though, I’ve started to appreciate FB’s obscurity. By making their SDK so obtuse (well, the actual documentation looks alright, but <em>PHP</em>?), they drive away a lot of amateur (read: non-profitable) programmers like myself who are just looking for a bit of fun with the system. Particularly, it prevents people (namely, me) from screwing around and <em>automating</em> an annoyance system. Maybe it’s a good thing that FB doesn’t let other people mess up a potentially curated, professional wall with a mere script.</p>
<p>At least, maybe not without some $$$ behind it.</p>Cameron Wongcam@camdar.ioAlt Title: My (Failed) Quest to Achieve Automated TrollingPACTF 2016 - Reflections2016-05-22T00:00:00+00:002016-05-22T00:00:00+00:00https://ct075.github.io/2016-05-22/pactf-reflections<p>By the time anybody is reading this, we should have finalized both DQs and
prizes for PACTF 2016. If I said I thought everything went 100% as I wanted it
to, I’d be lying, but I’m overall pretty happy with how things went.</p>
<p>The first thing I have to mention is how amazing it is to open the admin panel
and see 1600 registered users and 1000 registered teams. When we gave our speech
to the gathered members of the Abbot Academy Association (AAA), we mentioned
that similar competitions had numbers close to this, but only after a year or
two of running with a reputation built up. “We’d be thrilled to get half that
many,” we said, predicting about 500 teams and 1000 users. By our guess (after
filtering out the various dummy accounts we found and extrapolating a few more),
we still got about 50% more participation than I’d ever dreamed of.</p>
<h2 id="ctfery">CTFery</h2>
<p>Writing the problems for this competition was by far the most fun part of this
process, at least for me. Cryptography especially - you’d be surprised how much
people were overthinking some of the problems (the square problem especially).
The binary round was a little weirder; as a procrastinating high school student
I predictably had not finished writing the code for the majority of my problems
until the Saturday before Round 2 launched. That and I still had no idea how nc
worked on the server-side (I ultimately ended up writing a python script to
serve it on the port for me) so that was a fun last 3/4 hour rush to launch. I
was almost completely uninvolved with the web round (I wrote the SQL problems
but they were pretty much copy-pasted from other CTFs and the internet), but
Tony was a real workhorse and pulled it together.</p>
<p>I’m with several of the competitors in that having themed rounds really doesn’t
work that well. Regex fits with “binary” just as well as everyone thinks - it
doesn’t. When we first came up with the round format, the idea was that every
round would have a hodgepodge of problems, and that they would each be a
smaller version of what a larger CTF “sprint” would look like. At the same time,
though, themed rounds meant that I could push off all my work until immediately
before the round itself went live, so that’s that I suppose.</p>
<p>I’m honestly surprised the framework held together as well as it did. We had
some issues with the scoreboard being recalculated every time someone loaded it
(leading to the weird issue where we’d cache the entire page including the
navbar with the “your team” etc stuff in the top right corner), but that fixed
itself when we got the server to thread properly. Writing CTFlex was a super
educational experience that I haven’t really had before so I’m grateful for
that.</p>
<h2 id="communication">Communication</h2>
<p>If you ask me, our biggest mistake (specifically my downfall) was our lack of
communication, especially during the last round. This should come as a surprise
to almost nobody who was in IRC at any point during that last week when I
would show up solely to mention “yeah there are no hints this round” and then
again to mention “yeah well rip the flagdump”. The first round was, in my mind,
actually went pretty well (all things considered) beyond the whole Got Bits
fiasco, but things sort of snowballed on my end. Specifically, I had two tests
and an essay during Round 2 keeping me away from IRC, which led to the
short-lived reign of “Camdar_mobile” and my personal annoyance at having to deal
with things during my trip to PAX East that weekend.</p>
<p>In hindsight, volunteering myself to be the “public face” of PACTF wasn’t as
good an idea as I thought. As much as I enjoy hanging out on IRC and meeting
cool people (to all of you who stuck around to chat for more than the forty-five
seconds it took to ask me a question, this one goes out to you), it was kind of
shitty mentally to deal with the constant complaints and insults (particularly
about Got Bits round 1). As time went on, I had less and less motivation to sit
on the channel and deal with the (at times) thirty different people begging me
for hints (which, in turn, led to more people angrily emailing us for
clarifications). I like to think I have pretty thick skin, but I’m really not
suited for playing the part of the “front man” who has to wade through the
accusations of cheating and bullshit problems.</p>
<h2 id="well">Well…</h2>
<p>Overall, though, I don’t think our first try could have gone much better. There
were definitely some people who would disagree (the zodiac killer even took some
time out of their busy schedule to kill the last six hours of our competition!),
but I’m honestly okay with it. Thanks to everyone for their participation and
feedback and we hope to see you again next year!</p>Cameron Wongcam@camdar.ioBy the time anybody is reading this, we should have finalized both DQs and prizes for PACTF 2016. If I said I thought everything went 100% as I wanted it to, I’d be lying, but I’m overall pretty happy with how things went.