<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>Jesper Cockx's Blog</title>
        <link>https://jesper.sikanda.be</link>
        <description><![CDATA[My blog on everything Agda, dependent types, and life]]></description>
        <atom:link href="https://jesper.sikanda.be/rss.xml" rel="self"
                   type="application/rss+xml" />
        <lastBuildDate>Thu, 22 Jan 2026 00:00:00 UT</lastBuildDate>
        <item>
    <title>Introduction to Coinduction in Agda Part 1: Coinductive Programming</title>
    <link>https://jesper.sikanda.be/posts/coinduction-part-1.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Introduction to Coinduction in Agda Part 1: Coinductive Programming</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Introduction to Coinduction in Agda Part 1: Coinductive Programming</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on January 22, 2026
    </p>
    <!--
<pre class="Agda"><a id="133" class="Symbol">{-#</a> <a id="137" class="Keyword">OPTIONS</a> <a id="145" class="Pragma">--guardedness</a> <a id="159" class="Pragma">--sized-types</a> <a id="173" class="Symbol">#-}</a>
<a id="177" class="Symbol">{-#</a> <a id="181" class="Keyword">OPTIONS</a> <a id="189" class="Pragma">--cubical</a> <a id="199" class="Pragma">-WnoUnsupportedIndexedMatch</a> <a id="227" class="Symbol">#-}</a>
<a id="231" class="Symbol">{-#</a> <a id="235" class="Keyword">OPTIONS</a> <a id="243" class="Pragma">--allow-unsolved-metas</a> <a id="266" class="Symbol">#-}</a>

<a id="271" class="Keyword">open</a> <a id="276" class="Keyword">import</a> <a id="283" href="Data.Bool.Base.html" class="Module">Data.Bool.Base</a> <a id="298" class="Keyword">using</a> <a id="304" class="Symbol">(</a><a id="305" href="Agda.Builtin.Bool.html#173" class="Datatype">Bool</a><a id="309" class="Symbol">;</a> <a id="311" href="Agda.Builtin.Bool.html#198" class="InductiveConstructor">true</a><a id="315" class="Symbol">;</a> <a id="317" href="Agda.Builtin.Bool.html#192" class="InductiveConstructor">false</a><a id="322" class="Symbol">;</a> <a id="324" href="Data.Bool.Base.html#951" class="Function">not</a><a id="327" class="Symbol">;</a> <a id="329" href="Data.Bool.Base.html#1005" class="Function Operator">_∧_</a><a id="332" class="Symbol">;</a> <a id="334" href="Data.Bool.Base.html#1063" class="Function Operator">_∨_</a><a id="337" class="Symbol">;</a> <a id="339" href="Data.Bool.Base.html#1515" class="Function Operator">if_then_else_</a><a id="352" class="Symbol">)</a>
<a id="354" class="Keyword">open</a> <a id="359" class="Keyword">import</a> <a id="366" href="Data.Empty.html" class="Module">Data.Empty</a> <a id="377" class="Keyword">using</a> <a id="383" class="Symbol">(</a><a id="384" href="Data.Empty.html#914" class="Function">⊥</a><a id="385" class="Symbol">;</a> <a id="387" href="Data.Empty.html#1069" class="Function">⊥-elim</a><a id="393" class="Symbol">)</a>
<a id="395" class="Keyword">open</a> <a id="400" class="Keyword">import</a> <a id="407" href="Data.Fin.Base.html" class="Module">Data.Fin.Base</a> <a id="421" class="Keyword">using</a> <a id="427" class="Symbol">(</a><a id="428" href="Data.Fin.Base.html#1132" class="Datatype">Fin</a><a id="431" class="Symbol">;</a> <a id="433" href="Data.Fin.Base.html#1154" class="InductiveConstructor">zero</a><a id="437" class="Symbol">;</a> <a id="439" href="Data.Fin.Base.html#1175" class="InductiveConstructor">suc</a><a id="442" class="Symbol">)</a>
<a id="444" class="Keyword">open</a> <a id="449" class="Keyword">import</a> <a id="456" href="Data.List.Base.html" class="Module">Data.List.Base</a> <a id="471" class="Keyword">using</a> <a id="477" class="Symbol">(</a><a id="478" href="Agda.Builtin.List.html#147" class="Datatype">List</a><a id="482" class="Symbol">;</a> <a id="484" href="Data.List.Base.html#7301" class="InductiveConstructor">[]</a><a id="486" class="Symbol">;</a> <a id="488" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">_∷_</a><a id="491" class="Symbol">)</a>
<a id="493" class="Keyword">open</a> <a id="498" class="Keyword">import</a> <a id="505" href="Data.Maybe.Base.html" class="Module">Data.Maybe.Base</a> <a id="521" class="Keyword">using</a> <a id="527" class="Symbol">(</a><a id="528" href="Agda.Builtin.Maybe.html#135" class="Datatype">Maybe</a><a id="533" class="Symbol">;</a> <a id="535" href="Agda.Builtin.Maybe.html#194" class="InductiveConstructor">nothing</a><a id="542" class="Symbol">;</a> <a id="544" href="Agda.Builtin.Maybe.html#173" class="InductiveConstructor">just</a><a id="548" class="Symbol">)</a>
<a id="550" class="Keyword">open</a> <a id="555" class="Keyword">import</a> <a id="562" href="Data.Nat.Base.html" class="Module">Data.Nat.Base</a> <a id="576" class="Keyword">using</a> <a id="582" class="Symbol">(</a><a id="583" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a><a id="584" class="Symbol">;</a> <a id="586" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a><a id="590" class="Symbol">;</a> <a id="592" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a><a id="595" class="Symbol">;</a> <a id="597" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">_+_</a><a id="600" class="Symbol">;</a> <a id="602" href="Agda.Builtin.Nat.html#539" class="Primitive Operator">_*_</a><a id="605" class="Symbol">)</a>
<a id="607" class="Keyword">open</a> <a id="612" class="Keyword">import</a> <a id="619" href="Data.Product.Base.html" class="Module">Data.Product.Base</a> <a id="637" class="Keyword">using</a> <a id="643" class="Symbol">(</a><a id="644" href="Data.Product.Base.html#1618" class="Function Operator">_×_</a><a id="647" class="Symbol">;</a> <a id="649" href="Agda.Builtin.Sigma.html#235" class="InductiveConstructor Operator">_,_</a><a id="652" class="Symbol">;</a> <a id="654" href="Data.Product.Base.html#636" class="Field">proj₁</a><a id="659" class="Symbol">;</a> <a id="661" href="Data.Product.Base.html#650" class="Field">proj₂</a><a id="666" class="Symbol">)</a>
<a id="668" class="Keyword">open</a> <a id="673" class="Keyword">import</a> <a id="680" href="Data.Sum.Base.html" class="Module">Data.Sum.Base</a> <a id="694" class="Symbol">as</a> <a id="697" class="Module">Sum</a> <a id="701" class="Keyword">using</a> <a id="707" class="Symbol">(</a><a id="708" href="Data.Sum.Base.html#625" class="Datatype Operator">_⊎_</a><a id="711" class="Symbol">;</a> <a id="713" href="Data.Sum.Base.html#675" class="InductiveConstructor">inj₁</a><a id="717" class="Symbol">;</a> <a id="719" href="Data.Sum.Base.html#700" class="InductiveConstructor">inj₂</a><a id="723" class="Symbol">;</a> <a id="725" href="Data.Sum.Base.html#811" class="Function Operator">[_,_]</a><a id="730" class="Symbol">;</a> <a id="732" href="Data.Sum.Base.html#980" class="Function Operator">[_,_]′</a><a id="738" class="Symbol">)</a>
<a id="740" class="Keyword">open</a> <a id="745" class="Keyword">import</a> <a id="752" href="Data.Vec.Base.html" class="Module">Data.Vec.Base</a> <a id="766" class="Keyword">using</a> <a id="772" class="Symbol">(</a><a id="773" href="Data.Vec.Base.html#1119" class="Datatype">Vec</a><a id="776" class="Symbol">;</a> <a id="778" href="Data.Vec.Base.html#1155" class="InductiveConstructor">[]</a><a id="780" class="Symbol">;</a> <a id="782" href="Data.Vec.Base.html#1174" class="InductiveConstructor Operator">_∷_</a><a id="785" class="Symbol">)</a>
<a id="787" class="Keyword">open</a> <a id="792" class="Keyword">import</a> <a id="799" href="Function.Base.html" class="Module">Function.Base</a> <a id="813" class="Keyword">using</a> <a id="819" class="Symbol">(</a><a id="820" href="Function.Base.html#704" class="Function">id</a><a id="822" class="Symbol">;</a> <a id="824" href="Function.Base.html#725" class="Function">const</a><a id="829" class="Symbol">;</a> <a id="831" href="Function.Base.html#1134" class="Function Operator">_∘_</a><a id="834" class="Symbol">)</a>
<a id="836" class="Keyword">open</a> <a id="841" class="Keyword">import</a> <a id="848" href="Relation.Binary.PropositionalEquality.html" class="Module">Relation.Binary.PropositionalEquality</a> <a id="886" class="Keyword">using</a> <a id="892" class="Symbol">(</a><a id="893" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">_≡_</a><a id="896" class="Symbol">;</a> <a id="898" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a><a id="902" class="Symbol">;</a> <a id="904" href="Relation.Binary.PropositionalEquality.Core.html#2035" class="Function">sym</a><a id="907" class="Symbol">;</a> <a id="909" href="Relation.Binary.PropositionalEquality.Core.html#2080" class="Function">trans</a><a id="914" class="Symbol">;</a> <a id="916" href="Relation.Binary.PropositionalEquality.Core.html#1481" class="Function">cong</a><a id="920" class="Symbol">;</a> <a id="922" href="Relation.Binary.PropositionalEquality.Core.html#1718" class="Function">cong₂</a><a id="927" class="Symbol">;</a> <a id="929" href="Relation.Binary.PropositionalEquality.Core.html#2131" class="Function">subst</a><a id="934" class="Symbol">)</a>
<a id="936" class="Keyword">open</a> <a id="941" class="Keyword">import</a> <a id="948" href="Relation.Binary.PropositionalEquality.Properties.html" class="Module">Relation.Binary.PropositionalEquality.Properties</a> <a id="997" class="Keyword">using</a> <a id="1003" class="Symbol">(</a><a id="1004" class="Keyword">module</a> <a id="1011" href="Relation.Binary.PropositionalEquality.Properties.html#6850" class="Module">≡-Reasoning</a><a id="1022" class="Symbol">)</a>

<a id="1025" class="Keyword">variable</a>
  <a id="1036" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="1038" href="coinduction-part-1.html#1038" class="Generalizable">B</a> <a id="1040" href="coinduction-part-1.html#1040" class="Generalizable">C</a> <a id="1042" class="Symbol">:</a> <a id="1044" href="Agda.Primitive.html#388" class="Primitive">Set</a>
  <a id="1050" href="coinduction-part-1.html#1050" class="Generalizable">x</a> <a id="1052" href="coinduction-part-1.html#1052" class="Generalizable">y</a> <a id="1054" href="coinduction-part-1.html#1054" class="Generalizable">z</a> <a id="1056" class="Symbol">:</a> <a id="1058" href="coinduction-part-1.html#1036" class="Generalizable">A</a>
  <a id="1062" href="coinduction-part-1.html#1062" class="Generalizable">f</a> <a id="1064" href="coinduction-part-1.html#1064" class="Generalizable">g</a> <a id="1066" href="coinduction-part-1.html#1066" class="Generalizable">h</a> <a id="1068" class="Symbol">:</a> <a id="1070" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="1072" class="Symbol">→</a> <a id="1074" href="coinduction-part-1.html#1038" class="Generalizable">B</a>
  <a id="1078" href="coinduction-part-1.html#1078" class="Generalizable">s</a> <a id="1080" href="coinduction-part-1.html#1080" class="Generalizable">s1</a> <a id="1083" href="coinduction-part-1.html#1083" class="Generalizable">s2</a> <a id="1086" class="Symbol">:</a> <a id="1088" href="coinduction-part-1.html#1036" class="Generalizable">A</a>

<a id="half"></a><a id="1091" href="coinduction-part-1.html#1091" class="Function">half</a> <a id="1096" class="Symbol">:</a> <a id="1098" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="1100" class="Symbol">→</a> <a id="1102" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a>
<a id="1104" href="coinduction-part-1.html#1091" class="Function">half</a> <a id="1109" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a> <a id="1114" class="Symbol">=</a> <a id="1116" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>
<a id="1121" href="coinduction-part-1.html#1091" class="Function">half</a> <a id="1126" class="Symbol">(</a><a id="1127" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="1131" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a><a id="1135" class="Symbol">)</a> <a id="1137" class="Symbol">=</a> <a id="1139" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>
<a id="1144" href="coinduction-part-1.html#1091" class="Function">half</a> <a id="1149" class="Symbol">(</a><a id="1150" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="1154" class="Symbol">(</a><a id="1155" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="1159" href="coinduction-part-1.html#1159" class="Bound">n</a><a id="1160" class="Symbol">))</a> <a id="1163" class="Symbol">=</a> <a id="1165" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="1169" class="Symbol">(</a><a id="1170" href="coinduction-part-1.html#1091" class="Function">half</a> <a id="1175" href="coinduction-part-1.html#1159" class="Bound">n</a><a id="1176" class="Symbol">)</a>
</pre>-->
<p>This week I am staying at the welcoming University of Twente for the
<a href="https://cyclic-structures.gitlab.io/school2026/">Dutch Winter School on Logic and Verification</a>
to teach a course on Agda. Since the overall theme of the school is cyclic structures and
coinduction, I wanted to show off Agda’s capabilities in that area. However, it
turns out that there is not a lot of introductory material on coinduction in
Agda, and the Agda user manual on coinduction is also quite bare-bones (something that was already
pointed out to me by the group of TU Delft bachelor students who did a project
on coinduction in Agda last year). This is a big shame, since Agda’s approach to
coinduction is quite unique and in my opinion much better than what other
proof assistants have on offer (though I hear Isabelle’s support is quite good
as well). So I want to rectify this situation by sharing an introductory tutorial
series on coinduction in Agda here on my blog.</p>
<p>Perhaps some of you reading this are now thinking “coin-what?” Coinduction might
sound like a scary thing involving lots of symbols and proofs (and it often is),
but it is not my intention to go deep into the theoretical basis of coinduction,
Rather I want to show how to use it in Agda with some practical examples.
From this practical perspective, coinduction is just a principled way to
program with infinite or cyclic structures such as streams and graphs in a total
language like Agda. It’s not that Agda doesn’t allow you to define infinite
lists, you just have to be honest about their inclusion when defining the type.
And coinduction is precisely the way you can express that honesty.</p>
<p>I have three lectures at the winter school, so I’ll also divide this tutorial
into three blog posts:</p>
<ol type="1">
<li>Coinductive programming (this post)</li>
<li>Coinductive proving</li>
<li>Case studies and applications</li>
</ol>
<p>I assume you already know the basics of how to use
Agda, which you can learn for example from my lecture notes on <a href="https://github.com/jespercockx/agda-lecture-notes/blob/master/agda.pdf">Programming and
Proving in Agda</a>.
If you have any questions, corrections, or additions to this tutorial, please
let me know via <a href="https://agda.zulipchat.com/">Zulip</a>, the
<a href="https://agda.club/@jesper">Fediverse</a>, or good ol’ <a href="j.g.h.cockx@tudelft.nl">email</a>.</p>
<h1 id="record-types-and-copattern-matching">Record types and copattern matching</h1>
<p>Before I explain coinduction in Agda proper, we first need to understand the
foundations that it is built upon, which are record types and copattern matching.
First off, <a href="https://agda.readthedocs.io/en/v2.8.0/language/record-types.html">record types</a>
in Agda are just like we’d expect from other languages:
a type bundling a of a number of <em>fields</em> into a single type. Apart from its fields,
a record type can also optionally be given a constructor.</p>
<p>For example, we define a type of rectangles with fields for the height and
the width:</p>
<pre class="Agda"><a id="4063" class="Keyword">record</a> <a id="Rect"></a><a id="4070" href="coinduction-part-1.html#4070" class="Record">Rect</a> <a id="4075" class="Symbol">:</a> <a id="4077" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="4081" class="Keyword">where</a>
  <a id="4089" class="Keyword">constructor</a> <a id="rect"></a><a id="4101" href="coinduction-part-1.html#4101" class="InductiveConstructor">rect</a> <a id="4106" class="Comment">-- optional</a>
  <a id="4120" class="Keyword">field</a>
    <a id="Rect.height"></a><a id="4130" href="coinduction-part-1.html#4130" class="Field">height</a> <a id="4137" class="Symbol">:</a> <a id="4139" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a>
    <a id="Rect.width"></a><a id="4145" href="coinduction-part-1.html#4145" class="Field">width</a>  <a id="4152" class="Symbol">:</a> <a id="4154" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a>
</pre>
<p>To construct a value of a record type, we either use the <code>record { ... }</code> syntax
with named fields or use the constructor directly (if we declared one):</p>
<pre class="Agda"><a id="square"></a><a id="4319" href="coinduction-part-1.html#4319" class="Function">square</a> <a id="4326" class="Symbol">:</a> <a id="4328" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="4330" class="Symbol">→</a> <a id="4332" href="coinduction-part-1.html#4070" class="Record">Rect</a>
<a id="4337" href="coinduction-part-1.html#4319" class="Function">square</a> <a id="4344" href="coinduction-part-1.html#4344" class="Bound">x</a> <a id="4346" class="Symbol">=</a> <a id="4348" class="Keyword">record</a> <a id="4355" class="Symbol">{</a> <a id="4357" href="coinduction-part-1.html#4130" class="Field">height</a> <a id="4364" class="Symbol">=</a> <a id="4366" href="coinduction-part-1.html#4344" class="Bound">x</a> <a id="4368" class="Symbol">;</a> <a id="4370" href="coinduction-part-1.html#4145" class="Field">width</a> <a id="4376" class="Symbol">=</a> <a id="4378" href="coinduction-part-1.html#4344" class="Bound">x</a> <a id="4380" class="Symbol">}</a>

<a id="square'"></a><a id="4383" href="coinduction-part-1.html#4383" class="Function">square'</a> <a id="4391" class="Symbol">:</a> <a id="4393" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="4395" class="Symbol">→</a> <a id="4397" href="coinduction-part-1.html#4070" class="Record">Rect</a>
<a id="4402" href="coinduction-part-1.html#4383" class="Function">square'</a> <a id="4410" href="coinduction-part-1.html#4410" class="Bound">x</a> <a id="4412" class="Symbol">=</a> <a id="4414" href="coinduction-part-1.html#4101" class="InductiveConstructor">rect</a> <a id="4419" href="coinduction-part-1.html#4410" class="Bound">x</a> <a id="4421" href="coinduction-part-1.html#4410" class="Bound">x</a>
</pre>
<p>We can access the fields of a record value by using the <strong>projections</strong>
<code>Rect.height</code> and <code>Rect.width</code>:</p>
<pre class="Agda"><a id="area"></a><a id="4537" href="coinduction-part-1.html#4537" class="Function">area</a> <a id="4542" class="Symbol">:</a> <a id="4544" href="coinduction-part-1.html#4070" class="Record">Rect</a> <a id="4549" class="Symbol">→</a> <a id="4551" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a>
<a id="4553" href="coinduction-part-1.html#4537" class="Function">area</a> <a id="4558" href="coinduction-part-1.html#4558" class="Bound">r</a> <a id="4560" class="Symbol">=</a> <a id="4562" href="coinduction-part-1.html#4130" class="Field">Rect.height</a> <a id="4574" href="coinduction-part-1.html#4558" class="Bound">r</a> <a id="4576" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">+</a> <a id="4578" href="coinduction-part-1.html#4145" class="Field">Rect.width</a> <a id="4589" href="coinduction-part-1.html#4558" class="Bound">r</a>
</pre>
<p>To avoid having to write the name of the record type in front of each
projection, we <em>open</em> the record to bring projections into scope:</p>
<pre class="Agda"><a id="4741" class="Keyword">open</a> <a id="4746" href="coinduction-part-1.html#4070" class="Module">Rect</a>

<a id="perimeter"></a><a id="4752" href="coinduction-part-1.html#4752" class="Function">perimeter</a> <a id="4762" class="Symbol">:</a> <a id="4764" href="coinduction-part-1.html#4070" class="Record">Rect</a> <a id="4769" class="Symbol">→</a> <a id="4771" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a>
<a id="4773" href="coinduction-part-1.html#4752" class="Function">perimeter</a> <a id="4783" href="coinduction-part-1.html#4783" class="Bound">r</a> <a id="4785" class="Symbol">=</a> <a id="4787" class="Number">2</a> <a id="4789" href="Agda.Builtin.Nat.html#539" class="Primitive Operator">*</a> <a id="4791" href="coinduction-part-1.html#4130" class="Field">height</a> <a id="4798" href="coinduction-part-1.html#4783" class="Bound">r</a> <a id="4800" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">+</a> <a id="4802" class="Number">2</a> <a id="4804" href="Agda.Builtin.Nat.html#539" class="Primitive Operator">*</a> <a id="4806" href="coinduction-part-1.html#4145" class="Field">width</a> <a id="4812" href="coinduction-part-1.html#4783" class="Bound">r</a>
</pre>
<p>We can also use projections in <em>postfix</em> notation by starting their name with a <code>.</code>:</p>
<pre class="Agda"><a id="rotate"></a><a id="4914" href="coinduction-part-1.html#4914" class="Function">rotate</a> <a id="4921" class="Symbol">:</a> <a id="4923" href="coinduction-part-1.html#4070" class="Record">Rect</a> <a id="4928" class="Symbol">→</a> <a id="4930" href="coinduction-part-1.html#4070" class="Record">Rect</a>
<a id="4935" href="coinduction-part-1.html#4914" class="Function">rotate</a> <a id="4942" href="coinduction-part-1.html#4942" class="Bound">r</a> <a id="4944" class="Symbol">=</a> <a id="4946" href="coinduction-part-1.html#4101" class="InductiveConstructor">rect</a> <a id="4951" class="Symbol">(</a><a id="4952" href="coinduction-part-1.html#4942" class="Bound">r</a> <a id="4954" class="Symbol">.</a><a id="4955" href="coinduction-part-1.html#4145" class="Field">width</a><a id="4960" class="Symbol">)</a> <a id="4962" class="Symbol">(</a><a id="4963" href="coinduction-part-1.html#4942" class="Bound">r</a> <a id="4965" class="Symbol">.</a><a id="4966" href="coinduction-part-1.html#4130" class="Field">height</a><a id="4972" class="Symbol">)</a>
</pre>
<p>Postfix notation is especially useful when working with nested record types
since we can stack them without any parentheses. Postfix notation is also
required when using the projection as a copattern in a pattern lambda (see
below).</p>
<p>One way to think about record types is as a single-constructor data type
with some syntactic sugar for the projections. However, there is a deeper and
more fruitful way of looking at record types as being dual to data types. Where
data types are defined by all the different ways of <em>constructing</em> an element,
record types are defined by all the possible <em>observations</em> we can make of an
element. To define a function that has a <em>data type</em> as an <em>input</em>, we
should define it for each of the <em>constructors</em> of the data type (this is
<em>pattern matching</em>). Dually, to define a function that has a <em>record
type</em> as its <em>output</em>, we should define it for each of the <em>projections</em> of the
record type. This is called <a href="https://agda.readthedocs.io/en/v2.8.0/language/copatterns.html"><em>copattern matching</em></a>.</p>
<p>Concretely, to define a function by copattern matching we just define what
should be the value of each of the projections applied to it. For example, below
we define <code>squash r</code> by the values of its projections <code>height (squash r)</code> and
<code>width (squash r)</code>:</p>
<pre class="Agda"><a id="squash"></a><a id="6275" href="coinduction-part-1.html#6275" class="Function">squash</a> <a id="6282" class="Symbol">:</a> <a id="6284" href="coinduction-part-1.html#4070" class="Record">Rect</a> <a id="6289" class="Symbol">→</a> <a id="6291" href="coinduction-part-1.html#4070" class="Record">Rect</a>
<a id="6296" href="coinduction-part-1.html#4130" class="Field">height</a> <a id="6303" class="Symbol">(</a><a id="6304" href="coinduction-part-1.html#6275" class="Function">squash</a> <a id="6311" href="coinduction-part-1.html#6311" class="Bound">r</a><a id="6312" class="Symbol">)</a> <a id="6314" class="Symbol">=</a> <a id="6316" href="coinduction-part-1.html#1091" class="Function">half</a> <a id="6321" class="Symbol">(</a><a id="6322" href="coinduction-part-1.html#4130" class="Field">height</a> <a id="6329" href="coinduction-part-1.html#6311" class="Bound">r</a><a id="6330" class="Symbol">)</a>
<a id="6332" href="coinduction-part-1.html#4145" class="Field">width</a>  <a id="6339" class="Symbol">(</a><a id="6340" href="coinduction-part-1.html#6275" class="Function">squash</a> <a id="6347" href="coinduction-part-1.html#6347" class="Bound">r</a><a id="6348" class="Symbol">)</a> <a id="6350" class="Symbol">=</a> <a id="6352" class="Number">2</a> <a id="6354" href="Agda.Builtin.Nat.html#539" class="Primitive Operator">*</a> <a id="6356" href="coinduction-part-1.html#4145" class="Field">width</a> <a id="6362" href="coinduction-part-1.html#6347" class="Bound">r</a>
</pre>
<p>Copattern matching can also be used together with postfix projections:</p>
<pre class="Agda"><a id="squeeze"></a><a id="6449" href="coinduction-part-1.html#6449" class="Function">squeeze</a> <a id="6457" class="Symbol">:</a> <a id="6459" href="coinduction-part-1.html#4070" class="Record">Rect</a> <a id="6464" class="Symbol">→</a> <a id="6466" href="coinduction-part-1.html#4070" class="Record">Rect</a>
<a id="6471" href="coinduction-part-1.html#6449" class="Function">squeeze</a> <a id="6479" href="coinduction-part-1.html#6479" class="Bound">r</a>  <a id="6482" class="Symbol">.</a><a id="6483" href="coinduction-part-1.html#4130" class="Field">height</a>  <a id="6491" class="Symbol">=</a> <a id="6493" class="Number">2</a> <a id="6495" href="Agda.Builtin.Nat.html#539" class="Primitive Operator">*</a> <a id="6497" class="Symbol">(</a><a id="6498" href="coinduction-part-1.html#6479" class="Bound">r</a> <a id="6500" class="Symbol">.</a><a id="6501" href="coinduction-part-1.html#4130" class="Field">height</a><a id="6507" class="Symbol">)</a>
<a id="6509" href="coinduction-part-1.html#6449" class="Function">squeeze</a> <a id="6517" href="coinduction-part-1.html#6517" class="Bound">r</a>  <a id="6520" class="Symbol">.</a><a id="6521" href="coinduction-part-1.html#4145" class="Field">width</a>   <a id="6529" class="Symbol">=</a> <a id="6531" href="coinduction-part-1.html#1091" class="Function">half</a> <a id="6536" class="Symbol">(</a><a id="6537" href="coinduction-part-1.html#6517" class="Bound">r</a> <a id="6539" class="Symbol">.</a><a id="6540" href="coinduction-part-1.html#4145" class="Field">width</a><a id="6545" class="Symbol">)</a>
</pre>
<p>Finally, copattern matching can also be used in a <a href="https://agda.readthedocs.io/en/v2.8.0/language/lambda-abstraction.html#pattern-lambda">pattern-matching
lambda</a>:</p>
<pre class="Agda"><a id="expand"></a><a id="6725" href="coinduction-part-1.html#6725" class="Function">expand</a> <a id="6732" class="Symbol">:</a> <a id="6734" href="coinduction-part-1.html#4070" class="Record">Rect</a> <a id="6739" class="Symbol">→</a> <a id="6741" href="coinduction-part-1.html#4070" class="Record">Rect</a>
<a id="6746" href="coinduction-part-1.html#6725" class="Function">expand</a> <a id="6753" href="coinduction-part-1.html#6753" class="Bound">r</a> <a id="6755" class="Symbol">=</a> <a id="6757" class="Symbol">λ</a> <a id="6759" class="Keyword">where</a>
  <a id="6767" class="Symbol">.</a><a id="6768" href="coinduction-part-1.html#4130" class="Field">height</a> <a id="6775" class="Symbol">→</a> <a id="6777" class="Number">2</a> <a id="6779" href="Agda.Builtin.Nat.html#539" class="Primitive Operator">*</a> <a id="6781" href="coinduction-part-1.html#6753" class="Bound">r</a> <a id="6783" class="Symbol">.</a><a id="6784" href="coinduction-part-1.html#4130" class="Field">height</a>
  <a id="6793" class="Symbol">.</a><a id="6794" href="coinduction-part-1.html#4145" class="Field">width</a>  <a id="6801" class="Symbol">→</a> <a id="6803" class="Number">2</a> <a id="6805" href="Agda.Builtin.Nat.html#539" class="Primitive Operator">*</a> <a id="6807" href="coinduction-part-1.html#6753" class="Bound">r</a> <a id="6809" class="Symbol">.</a><a id="6810" href="coinduction-part-1.html#4145" class="Field">width</a>
</pre>
<p>Since the lambda function itself is anonymous, there is nothing that the
projection can be syntactically applied to, so the use of postfix notation in
pattern lambdas is mandatory.</p>
<p>If the copattern notation does not yet make sense 100%, don’t worry. There’ll
be many more examples once we define some coinductive record types.</p>
<h1 id="coinductive-record-types">Coinductive record types</h1>
<p>The simplest example of a
<a href="https://agda.readthedocs.io/en/v2.8.0/language/coinduction.html">coinductive type</a>
is the type of <em>streams</em>, i.e.
infinite lists of values of a given type. Concretely, in Agda we define streams
as a record type that consists of a <strong>head</strong> element of type <code>A</code> and a <strong>tail</strong>
which is another stream. Since the type <code>Stream</code> occurs recursively in its own
definition, we have to indicate to Agda whether we want the type to only include
finite values (<code>inductive</code>) or also infinite values (<code>coinductive</code>). In this
case, we want to include infinite streams, since otherwise we would end up with
an empty type.</p>
<pre class="Agda"><a id="7820" class="Keyword">module</a> <a id="GuardedCoinduction"></a><a id="7827" href="coinduction-part-1.html#7827" class="Module">GuardedCoinduction</a> <a id="7846" class="Keyword">where</a>

  <a id="7855" class="Keyword">record</a> <a id="GuardedCoinduction.Stream"></a><a id="7862" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="7869" class="Symbol">(</a><a id="7870" href="coinduction-part-1.html#7870" class="Bound">A</a> <a id="7872" class="Symbol">:</a> <a id="7874" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="7877" class="Symbol">)</a> <a id="7879" class="Symbol">:</a> <a id="7881" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="7885" class="Keyword">where</a>
    <a id="7895" class="Keyword">coinductive</a>
    <a id="7911" class="Keyword">field</a>
      <a id="GuardedCoinduction.Stream.head"></a><a id="7923" href="coinduction-part-1.html#7923" class="Field">head</a>  <a id="7929" class="Symbol">:</a> <a id="7931" href="coinduction-part-1.html#7870" class="Bound">A</a>
      <a id="GuardedCoinduction.Stream.tail"></a><a id="7939" href="coinduction-part-1.html#7939" class="Field">tail</a>  <a id="7945" class="Symbol">:</a> <a id="7947" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="7954" href="coinduction-part-1.html#7870" class="Bound">A</a>
  <a id="7958" class="Keyword">open</a> <a id="7963" href="coinduction-part-1.html#7862" class="Module">Stream</a>
</pre>
<p>We use the projections to define functions on streams:</p>
<pre class="Agda">  <a id="GuardedCoinduction.firstTwo"></a><a id="8041" href="coinduction-part-1.html#8041" class="Function">firstTwo</a> <a id="8050" class="Symbol">:</a> <a id="8052" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="8059" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="8061" class="Symbol">→</a> <a id="8063" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="8065" href="Data.Product.Base.html#1618" class="Function Operator">×</a> <a id="8067" href="coinduction-part-1.html#1036" class="Generalizable">A</a>
  <a id="8071" href="coinduction-part-1.html#8041" class="Function">firstTwo</a> <a id="8080" href="coinduction-part-1.html#8080" class="Bound">s</a> <a id="8082" class="Symbol">=</a> <a id="8084" href="coinduction-part-1.html#8080" class="Bound">s</a> <a id="8086" class="Symbol">.</a><a id="8087" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="8092" href="Agda.Builtin.Sigma.html#235" class="InductiveConstructor Operator">,</a> <a id="8094" href="coinduction-part-1.html#8080" class="Bound">s</a> <a id="8096" class="Symbol">.</a><a id="8097" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="8102" class="Symbol">.</a><a id="8103" href="coinduction-part-1.html#7923" class="Field">head</a>

  <a id="GuardedCoinduction.take"></a><a id="8111" href="coinduction-part-1.html#8111" class="Function">take</a> <a id="8116" class="Symbol">:</a> <a id="8118" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="8120" class="Symbol">→</a> <a id="8122" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="8129" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="8131" class="Symbol">→</a> <a id="8133" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="8138" href="coinduction-part-1.html#1036" class="Generalizable">A</a>
  <a id="8142" href="coinduction-part-1.html#8111" class="Function">take</a> <a id="8147" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>    <a id="8155" href="coinduction-part-1.html#8155" class="Bound">s</a> <a id="8157" class="Symbol">=</a> <a id="8159" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a>
  <a id="8164" href="coinduction-part-1.html#8111" class="Function">take</a> <a id="8169" class="Symbol">(</a><a id="8170" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="8174" href="coinduction-part-1.html#8174" class="Bound">n</a><a id="8175" class="Symbol">)</a> <a id="8177" href="coinduction-part-1.html#8177" class="Bound">s</a> <a id="8179" class="Symbol">=</a> <a id="8181" href="coinduction-part-1.html#8177" class="Bound">s</a> <a id="8183" class="Symbol">.</a><a id="8184" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="8189" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="8191" href="coinduction-part-1.html#8111" class="Function">take</a> <a id="8196" href="coinduction-part-1.html#8174" class="Bound">n</a> <a id="8198" class="Symbol">(</a><a id="8199" href="coinduction-part-1.html#8177" class="Bound">s</a> <a id="8201" class="Symbol">.</a><a id="8202" href="coinduction-part-1.html#7939" class="Field">tail</a><a id="8206" class="Symbol">)</a>

  <a id="GuardedCoinduction.drop"></a><a id="8211" href="coinduction-part-1.html#8211" class="Function">drop</a> <a id="8216" class="Symbol">:</a> <a id="8218" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="8220" class="Symbol">→</a> <a id="8222" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="8229" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="8231" class="Symbol">→</a> <a id="8233" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="8240" href="coinduction-part-1.html#1036" class="Generalizable">A</a>
  <a id="8244" href="coinduction-part-1.html#8211" class="Function">drop</a> <a id="8249" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>     <a id="8258" href="coinduction-part-1.html#8258" class="Bound">s</a>  <a id="8261" class="Symbol">=</a> <a id="8263" href="coinduction-part-1.html#8258" class="Bound">s</a>
  <a id="8267" href="coinduction-part-1.html#8211" class="Function">drop</a> <a id="8272" class="Symbol">(</a><a id="8273" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="8277" href="coinduction-part-1.html#8277" class="Bound">n</a><a id="8278" class="Symbol">)</a>  <a id="8281" href="coinduction-part-1.html#8281" class="Bound">s</a>  <a id="8284" class="Symbol">=</a> <a id="8286" href="coinduction-part-1.html#8211" class="Function">drop</a> <a id="8291" href="coinduction-part-1.html#8277" class="Bound">n</a> <a id="8293" class="Symbol">(</a><a id="8294" href="coinduction-part-1.html#8281" class="Bound">s</a> <a id="8296" class="Symbol">.</a><a id="8297" href="coinduction-part-1.html#7939" class="Field">tail</a><a id="8301" class="Symbol">)</a>
</pre>
<p>If we have an existing stream we can use it to build new streams using the
<code>record</code> syntax:</p>
<pre class="Agda">  <a id="GuardedCoinduction._∷S_"></a><a id="8411" href="coinduction-part-1.html#8411" class="Function Operator">_∷S_</a> <a id="8416" class="Symbol">:</a> <a id="8418" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="8420" class="Symbol">→</a> <a id="8422" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="8429" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="8431" class="Symbol">→</a> <a id="8433" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="8440" href="coinduction-part-1.html#1036" class="Generalizable">A</a>
  <a id="8444" href="coinduction-part-1.html#8444" class="Bound">x</a> <a id="8446" href="coinduction-part-1.html#8411" class="Function Operator">∷S</a> <a id="8449" href="coinduction-part-1.html#8449" class="Bound">xs</a> <a id="8452" class="Symbol">=</a> <a id="8454" class="Keyword">record</a> <a id="8461" class="Symbol">{</a> <a id="8463" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="8468" class="Symbol">=</a> <a id="8470" href="coinduction-part-1.html#8444" class="Bound">x</a> <a id="8472" class="Symbol">;</a> <a id="8474" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="8479" class="Symbol">=</a> <a id="8481" href="coinduction-part-1.html#8449" class="Bound">xs</a> <a id="8484" class="Symbol">}</a>

  <a id="GuardedCoinduction._++_"></a><a id="8489" href="coinduction-part-1.html#8489" class="Function Operator">_++_</a> <a id="8494" class="Symbol">:</a> <a id="8496" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="8501" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="8503" class="Symbol">→</a> <a id="8505" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="8512" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="8514" class="Symbol">→</a> <a id="8516" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="8523" href="coinduction-part-1.html#1036" class="Generalizable">A</a>
  <a id="8527" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a>       <a id="8536" href="coinduction-part-1.html#8489" class="Function Operator">++</a> <a id="8539" href="coinduction-part-1.html#8539" class="Bound">ys</a> <a id="8542" class="Symbol">=</a> <a id="8544" href="coinduction-part-1.html#8539" class="Bound">ys</a>
  <a id="8549" class="Symbol">(</a><a id="8550" href="coinduction-part-1.html#8550" class="Bound">x</a> <a id="8552" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="8554" href="coinduction-part-1.html#8554" class="Bound">xs</a><a id="8556" class="Symbol">)</a> <a id="8558" href="coinduction-part-1.html#8489" class="Function Operator">++</a> <a id="8561" href="coinduction-part-1.html#8561" class="Bound">ys</a> <a id="8564" class="Symbol">=</a> <a id="8566" href="coinduction-part-1.html#8550" class="Bound">x</a> <a id="8568" href="coinduction-part-1.html#8411" class="Function Operator">∷S</a> <a id="8571" class="Symbol">(</a><a id="8572" href="coinduction-part-1.html#8554" class="Bound">xs</a> <a id="8575" href="coinduction-part-1.html#8489" class="Function Operator">++</a> <a id="8578" href="coinduction-part-1.html#8561" class="Bound">ys</a><a id="8580" class="Symbol">)</a>
</pre>
<p>However, if we try to define a new stream with a record constructor,
Agda’s termination check fails:</p>
<pre class="Agda">  <a id="8699" class="Keyword">module</a> <a id="GuardedCoinduction.BadZeroes"></a><a id="8706" href="coinduction-part-1.html#8706" class="Module">BadZeroes</a> <a id="8716" class="Keyword">where</a>
    <a id="8726" class="Symbol">{-#</a> <a id="8730" class="Keyword">NON_TERMINATING</a> <a id="8746" class="Symbol">#-}</a>
    <a id="GuardedCoinduction.BadZeroes.zeroes"></a><a id="8754" href="coinduction-part-1.html#8754" class="Function">zeroes</a> <a id="8761" class="Symbol">:</a> <a id="8763" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="8770" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a>
    <a id="8776" href="coinduction-part-1.html#8754" class="Function">zeroes</a> <a id="8783" class="Symbol">=</a> <a id="8785" class="Keyword">record</a> <a id="8792" class="Symbol">{</a> <a id="8794" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="8799" class="Symbol">=</a> <a id="8801" class="Number">0</a> <a id="8803" class="Symbol">;</a> <a id="8805" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="8810" class="Symbol">=</a> <a id="8812" href="coinduction-part-1.html#8754" class="Function">zeroes</a> <a id="8819" class="Symbol">}</a>
</pre>
<p>There is actually a good reason why Agda rejects this definition: with it,
normalizing the expression <code>zeroes</code> will go into an infinite loop. Since Agda
needs to reduce terms during type checking, this would mean that Agda’s type
checker could loop forever as well, which we’d like to avoid.</p>
<p>To define a new stream, we have to use copatterns instead:</p>
<pre class="Agda">  <a id="GuardedCoinduction.zeroes"></a><a id="9189" href="coinduction-part-1.html#9189" class="Function">zeroes</a> <a id="9196" class="Symbol">:</a> <a id="9198" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="9205" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a>
  <a id="9209" href="coinduction-part-1.html#9189" class="Function">zeroes</a> <a id="9216" class="Symbol">.</a><a id="9217" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="9222" class="Symbol">=</a> <a id="9224" class="Number">0</a>
  <a id="9228" href="coinduction-part-1.html#9189" class="Function">zeroes</a> <a id="9235" class="Symbol">.</a><a id="9236" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="9241" class="Symbol">=</a> <a id="9243" href="coinduction-part-1.html#9189" class="Function">zeroes</a>
</pre>
<p>The expression <code>zeroes</code> only reduces when projections are applied to it, thus
there is no infinite loops created by this definition. The key point is that to
compute each consecutive value in the stream <code>zeroes</code>, we need an additional
application of <code>tail</code>. Hence Agda will only compute the stream for as far as we
have asked for.</p>
<p>We generalize the definition of <code>zeroes</code> to <code>repeat</code> a given value:</p>
<pre class="Agda">  <a id="GuardedCoinduction.repeat"></a><a id="9666" href="coinduction-part-1.html#9666" class="Function">repeat</a> <a id="9673" class="Symbol">:</a> <a id="9675" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="9677" class="Symbol">→</a> <a id="9679" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="9686" href="coinduction-part-1.html#1036" class="Generalizable">A</a>
  <a id="9690" href="coinduction-part-1.html#9666" class="Function">repeat</a> <a id="9697" href="coinduction-part-1.html#9697" class="Bound">x</a> <a id="9699" class="Symbol">.</a><a id="9700" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="9705" class="Symbol">=</a> <a id="9707" href="coinduction-part-1.html#9697" class="Bound">x</a>
  <a id="9711" href="coinduction-part-1.html#9666" class="Function">repeat</a> <a id="9718" href="coinduction-part-1.html#9718" class="Bound">x</a> <a id="9720" class="Symbol">.</a><a id="9721" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="9726" class="Symbol">=</a> <a id="9728" href="coinduction-part-1.html#9666" class="Function">repeat</a> <a id="9735" href="coinduction-part-1.html#9718" class="Bound">x</a>
</pre>
<p><strong>Exercise.</strong> Define the <code>lookup</code> function on streams and prove that looking up any value in <code>repeat x</code> returns <code>x</code>:</p>
<pre class="Agda">  <a id="GuardedCoinduction.lookup"></a><a id="9870" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="9877" class="Symbol">:</a> <a id="9879" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="9886" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="9888" class="Symbol">→</a> <a id="9890" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="9892" class="Symbol">→</a> <a id="9894" href="coinduction-part-1.html#1036" class="Generalizable">A</a>
  <a id="GuardedCoinduction.lookup-repeat"></a><a id="9898" href="coinduction-part-1.html#9898" class="Function">lookup-repeat</a> <a id="9912" class="Symbol">:</a> <a id="9914" class="Symbol">(</a><a id="9915" href="coinduction-part-1.html#9915" class="Bound">x</a> <a id="9917" class="Symbol">:</a> <a id="9919" href="coinduction-part-1.html#1036" class="Generalizable">A</a><a id="9920" class="Symbol">)</a> <a id="9922" class="Symbol">(</a><a id="9923" href="coinduction-part-1.html#9923" class="Bound">n</a> <a id="9925" class="Symbol">:</a> <a id="9927" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a><a id="9928" class="Symbol">)</a> <a id="9930" class="Symbol">→</a> <a id="9932" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="9939" class="Symbol">(</a><a id="9940" href="coinduction-part-1.html#9666" class="Function">repeat</a> <a id="9947" href="coinduction-part-1.html#9915" class="Bound">x</a><a id="9948" class="Symbol">)</a> <a id="9950" href="coinduction-part-1.html#9923" class="Bound">n</a> <a id="9952" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="9954" href="coinduction-part-1.html#9915" class="Bound">x</a>
</pre>
<details>
<summary>
<strong>Solution.</strong>
</summary>
<pre class="Agda">  <a id="10012" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="10019" href="coinduction-part-1.html#10019" class="Bound">xs</a> <a id="10022" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>    <a id="10030" class="Symbol">=</a> <a id="10032" href="coinduction-part-1.html#10019" class="Bound">xs</a> <a id="10035" class="Symbol">.</a><a id="10036" href="coinduction-part-1.html#7923" class="Field">head</a>
  <a id="10043" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="10050" href="coinduction-part-1.html#10050" class="Bound">xs</a> <a id="10053" class="Symbol">(</a><a id="10054" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="10058" href="coinduction-part-1.html#10058" class="Bound">n</a><a id="10059" class="Symbol">)</a> <a id="10061" class="Symbol">=</a> <a id="10063" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="10070" class="Symbol">(</a><a id="10071" href="coinduction-part-1.html#10050" class="Bound">xs</a> <a id="10074" class="Symbol">.</a><a id="10075" href="coinduction-part-1.html#7939" class="Field">tail</a><a id="10079" class="Symbol">)</a> <a id="10081" href="coinduction-part-1.html#10058" class="Bound">n</a>

  <a id="10086" href="coinduction-part-1.html#9898" class="Function">lookup-repeat</a> <a id="10100" href="coinduction-part-1.html#10100" class="Bound">x</a> <a id="10102" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>    <a id="10110" class="Symbol">=</a> <a id="10112" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
  <a id="10119" href="coinduction-part-1.html#9898" class="Function">lookup-repeat</a> <a id="10133" href="coinduction-part-1.html#10133" class="Bound">x</a> <a id="10135" class="Symbol">(</a><a id="10136" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="10140" href="coinduction-part-1.html#10140" class="Bound">n</a><a id="10141" class="Symbol">)</a> <a id="10143" class="Symbol">=</a> <a id="10145" href="coinduction-part-1.html#9898" class="Function">lookup-repeat</a> <a id="10159" href="coinduction-part-1.html#10133" class="Bound">x</a> <a id="10161" href="coinduction-part-1.html#10140" class="Bound">n</a>
</pre>
</details>
<p>Just using copatterns is not sufficient to define a sensible stream, however.
For example, computing the second element of the stream <code>ones</code> defined below
loops forever:</p>
<pre class="Agda">  <a id="10360" class="Keyword">module</a> <a id="GuardedCoinduction.BadOnes"></a><a id="10367" href="coinduction-part-1.html#10367" class="Module">BadOnes</a> <a id="10375" class="Keyword">where</a>
    <a id="10385" class="Symbol">{-#</a> <a id="10389" class="Keyword">NON_TERMINATING</a> <a id="10405" class="Symbol">#-}</a>
    <a id="GuardedCoinduction.BadOnes.ones"></a><a id="10413" href="coinduction-part-1.html#10413" class="Function">ones</a> <a id="10418" class="Symbol">:</a> <a id="10420" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="10427" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a>
    <a id="10433" href="coinduction-part-1.html#10413" class="Function">ones</a> <a id="10438" class="Symbol">.</a><a id="10439" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="10444" class="Symbol">=</a> <a id="10446" class="Number">1</a>
    <a id="10452" href="coinduction-part-1.html#10413" class="Function">ones</a> <a id="10457" class="Symbol">.</a><a id="10458" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="10463" class="Symbol">=</a> <a id="10465" href="coinduction-part-1.html#10413" class="Function">ones</a> <a id="10470" class="Symbol">.</a><a id="10471" href="coinduction-part-1.html#7939" class="Field">tail</a>
</pre>
<p>To avoid bad definitions such as this one, Agda requires that coinductive values
should be <strong>productive</strong>: applying any (finite) number of projections to them
should terminate. This is enforced by the <strong>guardedness criterion</strong>: every
(co)recursive call needs to appear</p>
<ul>
<li>in a clause with a copattern, <em>and</em></li>
<li>either at the top level or as the argument to one or more constructors.</li>
</ul>
<p>(Side note: the Agda user manual does not have a proper specification of the
guardedness criterion, so I am not sure if this description is 100% correct. Let
me know if you have a better description.)</p>
<p>To use the guardedness criterion for productivity, we need to enable it
explicitly by using the <code>--guardedness</code> flag (e.g. by putting <code>{-# OPTIONS --guardedness #-}</code> at the top of the file). The reason we have to enable it
explicitly is because Agda also provides an alternative way to check
productivity, namely <em>sized types</em>, that we’ll discuss below.</p>
<p>As another example, we define a <code>map</code> function on streams:</p>
<pre class="Agda">  <a id="GuardedCoinduction.map"></a><a id="11491" href="coinduction-part-1.html#11491" class="Function">map</a> <a id="11495" class="Symbol">:</a> <a id="11497" class="Symbol">(</a><a id="11498" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="11500" class="Symbol">→</a> <a id="11502" href="coinduction-part-1.html#1038" class="Generalizable">B</a><a id="11503" class="Symbol">)</a> <a id="11505" class="Symbol">→</a> <a id="11507" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="11514" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="11516" class="Symbol">→</a> <a id="11518" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="11525" href="coinduction-part-1.html#1038" class="Generalizable">B</a>
  <a id="11529" href="coinduction-part-1.html#11491" class="Function">map</a> <a id="11533" href="coinduction-part-1.html#11533" class="Bound">f</a> <a id="11535" href="coinduction-part-1.html#11535" class="Bound">xs</a> <a id="11538" class="Symbol">.</a><a id="11539" href="coinduction-part-1.html#7923" class="Field">head</a>  <a id="11545" class="Symbol">=</a> <a id="11547" href="coinduction-part-1.html#11533" class="Bound">f</a> <a id="11549" class="Symbol">(</a><a id="11550" href="coinduction-part-1.html#11535" class="Bound">xs</a> <a id="11553" class="Symbol">.</a><a id="11554" href="coinduction-part-1.html#7923" class="Field">head</a><a id="11558" class="Symbol">)</a>
  <a id="11562" href="coinduction-part-1.html#11491" class="Function">map</a> <a id="11566" href="coinduction-part-1.html#11566" class="Bound">f</a> <a id="11568" href="coinduction-part-1.html#11568" class="Bound">xs</a> <a id="11571" class="Symbol">.</a><a id="11572" href="coinduction-part-1.html#7939" class="Field">tail</a>  <a id="11578" class="Symbol">=</a> <a id="11580" href="coinduction-part-1.html#11491" class="Function">map</a> <a id="11584" href="coinduction-part-1.html#11566" class="Bound">f</a> <a id="11586" class="Symbol">(</a><a id="11587" href="coinduction-part-1.html#11568" class="Bound">xs</a> <a id="11590" class="Symbol">.</a><a id="11591" href="coinduction-part-1.html#7939" class="Field">tail</a><a id="11595" class="Symbol">)</a>
</pre>
<p>A counterexample to the guardedness criterion is the following definition of the
stream of natural numbers:</p>
<pre class="Agda">  <a id="11721" class="Keyword">module</a> <a id="GuardedCoinduction.FailingNats"></a><a id="11728" href="coinduction-part-1.html#11728" class="Module">FailingNats</a> <a id="11740" class="Keyword">where</a>
    <a id="11750" class="Symbol">{-#</a> <a id="11754" class="Keyword">TERMINATING</a> <a id="11766" class="Symbol">#-}</a>
    <a id="GuardedCoinduction.FailingNats.nats"></a><a id="11774" href="coinduction-part-1.html#11774" class="Function">nats</a> <a id="11779" class="Symbol">:</a> <a id="11781" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="11788" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a>
    <a id="11794" href="coinduction-part-1.html#11774" class="Function">nats</a> <a id="11799" class="Symbol">.</a><a id="11800" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="11805" class="Symbol">=</a> <a id="11807" class="Number">0</a>
    <a id="11813" href="coinduction-part-1.html#11774" class="Function">nats</a> <a id="11818" class="Symbol">.</a><a id="11819" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="11824" class="Symbol">=</a> <a id="11826" href="coinduction-part-1.html#11491" class="Function">map</a> <a id="11830" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="11834" href="coinduction-part-1.html#11774" class="Function">nats</a>
</pre>
<p>The recursive call to <code>nats</code> appears in an argument to the function <code>map</code> which
is not a constructor, so it fails the guardedness check. The problem with this
definition is that the guardedness checker does not look at the definition of
<code>map</code> so for all it knows it might not produce a value “in time” for the <code>nats</code>
definition to be productive. For example, if we used the following definition of
<code>map</code>, then <code>nats</code> would cease to be productive.</p>
<pre class="Agda">  <a id="GuardedCoinduction.map'"></a><a id="12302" href="coinduction-part-1.html#12302" class="Function">map'</a> <a id="12307" class="Symbol">:</a> <a id="12309" class="Symbol">(</a><a id="12310" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="12312" class="Symbol">→</a> <a id="12314" href="coinduction-part-1.html#1038" class="Generalizable">B</a><a id="12315" class="Symbol">)</a> <a id="12317" class="Symbol">→</a> <a id="12319" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="12326" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="12328" class="Symbol">→</a> <a id="12330" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="12337" href="coinduction-part-1.html#1038" class="Generalizable">B</a>
  <a id="12341" href="coinduction-part-1.html#12302" class="Function">map'</a> <a id="12346" href="coinduction-part-1.html#12346" class="Bound">f</a> <a id="12348" href="coinduction-part-1.html#12348" class="Bound">xs</a> <a id="12351" class="Symbol">.</a><a id="12352" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="12357" class="Symbol">=</a> <a id="12359" href="coinduction-part-1.html#12346" class="Bound">f</a> <a id="12361" class="Symbol">(</a><a id="12362" href="coinduction-part-1.html#12348" class="Bound">xs</a> <a id="12365" class="Symbol">.</a><a id="12366" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="12371" class="Symbol">.</a><a id="12372" href="coinduction-part-1.html#7923" class="Field">head</a><a id="12376" class="Symbol">)</a>
  <a id="12380" href="coinduction-part-1.html#12302" class="Function">map'</a> <a id="12385" href="coinduction-part-1.html#12385" class="Bound">f</a> <a id="12387" href="coinduction-part-1.html#12387" class="Bound">xs</a> <a id="12390" class="Symbol">.</a><a id="12391" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="12396" class="Symbol">=</a> <a id="12398" href="coinduction-part-1.html#11491" class="Function">map</a> <a id="12402" href="coinduction-part-1.html#12385" class="Bound">f</a> <a id="12404" class="Symbol">(</a><a id="12405" href="coinduction-part-1.html#12387" class="Bound">xs</a> <a id="12408" class="Symbol">.</a><a id="12409" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="12414" class="Symbol">.</a><a id="12415" href="coinduction-part-1.html#7939" class="Field">tail</a><a id="12419" class="Symbol">)</a>
</pre>
<p>We can assist the productivity checker by first defining the more general
<code>natsFrom</code> stream:</p>
<pre class="Agda">  <a id="GuardedCoinduction.natsFrom"></a><a id="12530" href="coinduction-part-1.html#12530" class="Function">natsFrom</a> <a id="12539" class="Symbol">:</a> <a id="12541" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="12543" class="Symbol">→</a> <a id="12545" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="12552" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a>
  <a id="12556" href="coinduction-part-1.html#12530" class="Function">natsFrom</a> <a id="12565" href="coinduction-part-1.html#12565" class="Bound">n</a> <a id="12567" class="Symbol">.</a><a id="12568" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="12573" class="Symbol">=</a> <a id="12575" href="coinduction-part-1.html#12565" class="Bound">n</a>
  <a id="12579" href="coinduction-part-1.html#12530" class="Function">natsFrom</a> <a id="12588" href="coinduction-part-1.html#12588" class="Bound">n</a> <a id="12590" class="Symbol">.</a><a id="12591" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="12596" class="Symbol">=</a> <a id="12598" href="coinduction-part-1.html#12530" class="Function">natsFrom</a> <a id="12607" class="Symbol">(</a><a id="12608" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="12612" href="coinduction-part-1.html#12588" class="Bound">n</a><a id="12613" class="Symbol">)</a>

  <a id="GuardedCoinduction.nats"></a><a id="12618" href="coinduction-part-1.html#12618" class="Function">nats</a> <a id="12623" class="Symbol">:</a> <a id="12625" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="12632" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a>
  <a id="12636" href="coinduction-part-1.html#12618" class="Function">nats</a> <a id="12641" class="Symbol">=</a> <a id="12643" href="coinduction-part-1.html#12530" class="Function">natsFrom</a> <a id="12652" class="Number">0</a>
</pre>
<p>Alternatively, we can use <em>sized types</em> to provide Agda with more information
about <code>map</code> (see later in this post).</p>
<p><strong>Exercise.</strong> Prove that the <code>lookup</code> function commutes with <code>map</code>:</p>
<pre class="Agda">  <a id="GuardedCoinduction.lookup-map"></a><a id="12855" href="coinduction-part-1.html#12855" class="Function">lookup-map</a> <a id="12866" class="Symbol">:</a> <a id="12868" class="Symbol">(</a><a id="12869" href="coinduction-part-1.html#12869" class="Bound">i</a> <a id="12871" class="Symbol">:</a> <a id="12873" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a><a id="12874" class="Symbol">)</a> <a id="12876" class="Symbol">→</a> <a id="12878" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="12885" class="Symbol">(</a><a id="12886" href="coinduction-part-1.html#11491" class="Function">map</a> <a id="12890" href="coinduction-part-1.html#1062" class="Generalizable">f</a> <a id="12892" href="coinduction-part-1.html#1078" class="Generalizable">s</a><a id="12893" class="Symbol">)</a> <a id="12895" href="coinduction-part-1.html#12869" class="Bound">i</a> <a id="12897" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="12899" href="coinduction-part-1.html#1062" class="Generalizable">f</a> <a id="12901" class="Symbol">(</a><a id="12902" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="12909" href="coinduction-part-1.html#1078" class="Generalizable">s</a> <a id="12911" href="coinduction-part-1.html#12869" class="Bound">i</a><a id="12912" class="Symbol">)</a>
</pre>
<details>
<summary>
<strong>Solution.</strong>
</summary>
<pre class="Agda">  <a id="12970" href="coinduction-part-1.html#12855" class="Function">lookup-map</a> <a id="12981" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>    <a id="12989" class="Symbol">=</a> <a id="12991" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
  <a id="12998" href="coinduction-part-1.html#12855" class="Function">lookup-map</a> <a id="13009" class="Symbol">(</a><a id="13010" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="13014" href="coinduction-part-1.html#13014" class="Bound">i</a><a id="13015" class="Symbol">)</a> <a id="13017" class="Symbol">=</a> <a id="13019" href="coinduction-part-1.html#12855" class="Function">lookup-map</a> <a id="13030" href="coinduction-part-1.html#13014" class="Bound">i</a>
</pre>
</details>
<p><strong>Exercise.</strong> When defining the stream of Fibonacci numbers, we run into a similar problem as with defining <code>nats</code>:</p>
<pre class="Agda">  <a id="GuardedCoinduction.zipWith"></a><a id="13172" href="coinduction-part-1.html#13172" class="Function">zipWith</a> <a id="13180" class="Symbol">:</a> <a id="13182" class="Symbol">(</a><a id="13183" href="coinduction-part-1.html#13183" class="Bound">f</a> <a id="13185" class="Symbol">:</a> <a id="13187" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="13189" class="Symbol">→</a> <a id="13191" href="coinduction-part-1.html#1038" class="Generalizable">B</a> <a id="13193" class="Symbol">→</a> <a id="13195" href="coinduction-part-1.html#1040" class="Generalizable">C</a><a id="13196" class="Symbol">)</a>
          <a id="13208" class="Symbol">→</a> <a id="13210" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="13217" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="13219" class="Symbol">→</a> <a id="13221" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="13228" href="coinduction-part-1.html#1038" class="Generalizable">B</a> <a id="13230" class="Symbol">→</a> <a id="13232" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="13239" href="coinduction-part-1.html#1040" class="Generalizable">C</a>
  <a id="13243" href="coinduction-part-1.html#13172" class="Function">zipWith</a> <a id="13251" href="coinduction-part-1.html#13251" class="Bound">f</a> <a id="13253" href="coinduction-part-1.html#13253" class="Bound">xs</a> <a id="13256" href="coinduction-part-1.html#13256" class="Bound">ys</a> <a id="13259" class="Symbol">.</a><a id="13260" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="13265" class="Symbol">=</a> <a id="13267" href="coinduction-part-1.html#13251" class="Bound">f</a> <a id="13269" class="Symbol">(</a><a id="13270" href="coinduction-part-1.html#13253" class="Bound">xs</a> <a id="13273" class="Symbol">.</a><a id="13274" href="coinduction-part-1.html#7923" class="Field">head</a><a id="13278" class="Symbol">)</a> <a id="13280" class="Symbol">(</a><a id="13281" href="coinduction-part-1.html#13256" class="Bound">ys</a> <a id="13284" class="Symbol">.</a><a id="13285" href="coinduction-part-1.html#7923" class="Field">head</a><a id="13289" class="Symbol">)</a>
  <a id="13293" href="coinduction-part-1.html#13172" class="Function">zipWith</a> <a id="13301" href="coinduction-part-1.html#13301" class="Bound">f</a> <a id="13303" href="coinduction-part-1.html#13303" class="Bound">xs</a> <a id="13306" href="coinduction-part-1.html#13306" class="Bound">ys</a> <a id="13309" class="Symbol">.</a><a id="13310" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="13315" class="Symbol">=</a> <a id="13317" href="coinduction-part-1.html#13172" class="Function">zipWith</a> <a id="13325" href="coinduction-part-1.html#13301" class="Bound">f</a> <a id="13327" class="Symbol">(</a><a id="13328" href="coinduction-part-1.html#13303" class="Bound">xs</a> <a id="13331" class="Symbol">.</a><a id="13332" href="coinduction-part-1.html#7939" class="Field">tail</a><a id="13336" class="Symbol">)</a> <a id="13338" class="Symbol">(</a><a id="13339" href="coinduction-part-1.html#13306" class="Bound">ys</a> <a id="13342" class="Symbol">.</a><a id="13343" href="coinduction-part-1.html#7939" class="Field">tail</a><a id="13347" class="Symbol">)</a>

  <a id="13352" class="Keyword">module</a> <a id="GuardedCoinduction.FailingFibonacci"></a><a id="13359" href="coinduction-part-1.html#13359" class="Module">FailingFibonacci</a> <a id="13376" class="Keyword">where</a>
    <a id="13386" class="Symbol">{-#</a> <a id="13390" class="Keyword">TERMINATING</a> <a id="13402" class="Symbol">#-}</a>
    <a id="GuardedCoinduction.FailingFibonacci.fibonacci"></a><a id="13410" href="coinduction-part-1.html#13410" class="Function">fibonacci</a> <a id="13420" class="Symbol">:</a> <a id="13422" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="13429" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a>
    <a id="13435" href="coinduction-part-1.html#13410" class="Function">fibonacci</a> <a id="13445" class="Symbol">.</a><a id="13446" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="13451" class="Symbol">=</a> <a id="13453" class="Number">0</a>
    <a id="13459" href="coinduction-part-1.html#13410" class="Function">fibonacci</a> <a id="13469" class="Symbol">.</a><a id="13470" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="13475" class="Symbol">.</a><a id="13476" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="13481" class="Symbol">=</a> <a id="13483" class="Number">1</a>
    <a id="13489" href="coinduction-part-1.html#13410" class="Function">fibonacci</a> <a id="13499" class="Symbol">.</a><a id="13500" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="13505" class="Symbol">.</a><a id="13506" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="13511" class="Symbol">=</a>
      <a id="13519" href="coinduction-part-1.html#13172" class="Function">zipWith</a> <a id="13527" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">_+_</a> <a id="13531" href="coinduction-part-1.html#13410" class="Function">fibonacci</a> <a id="13541" class="Symbol">(</a><a id="13542" href="coinduction-part-1.html#13410" class="Function">fibonacci</a> <a id="13552" class="Symbol">.</a><a id="13553" href="coinduction-part-1.html#7939" class="Field">tail</a><a id="13557" class="Symbol">)</a>
</pre>
<p>A more general way to work around the limitations of syntactic guardedness is to
use the <code>tabulate</code> function, which is the inverse to <code>lookup</code>. Implement
<code>tabulate</code> and use it to define <code>fibonacci</code>.</p>
<pre class="Agda">  <a id="GuardedCoinduction.tabulate"></a><a id="13774" href="coinduction-part-1.html#13774" class="Function">tabulate</a> <a id="13783" class="Symbol">:</a> <a id="13785" class="Symbol">(</a><a id="13786" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="13788" class="Symbol">→</a> <a id="13790" href="coinduction-part-1.html#1036" class="Generalizable">A</a><a id="13791" class="Symbol">)</a> <a id="13793" class="Symbol">→</a> <a id="13795" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="13802" href="coinduction-part-1.html#1036" class="Generalizable">A</a>
  <a id="GuardedCoinduction.fibonacci"></a><a id="13806" href="coinduction-part-1.html#13806" class="Function">fibonacci</a> <a id="13816" class="Symbol">:</a> <a id="13818" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="13825" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a>
</pre>
<details>
<summary>
<strong>Solution.</strong>
</summary>
<pre class="Agda">  <a id="13884" href="coinduction-part-1.html#13774" class="Function">tabulate</a> <a id="13893" href="coinduction-part-1.html#13893" class="Bound">f</a> <a id="13895" class="Symbol">.</a><a id="13896" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="13901" class="Symbol">=</a> <a id="13903" href="coinduction-part-1.html#13893" class="Bound">f</a> <a id="13905" class="Number">0</a>
  <a id="13909" href="coinduction-part-1.html#13774" class="Function">tabulate</a> <a id="13918" href="coinduction-part-1.html#13918" class="Bound">f</a> <a id="13920" class="Symbol">.</a><a id="13921" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="13926" class="Symbol">=</a> <a id="13928" href="coinduction-part-1.html#13774" class="Function">tabulate</a> <a id="13937" class="Symbol">(</a><a id="13938" href="coinduction-part-1.html#13918" class="Bound">f</a> <a id="13940" href="Function.Base.html#1134" class="Function Operator">∘</a> <a id="13942" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a><a id="13945" class="Symbol">)</a>

  <a id="13950" href="coinduction-part-1.html#13806" class="Function">fibonacci</a> <a id="13960" class="Symbol">=</a> <a id="13962" href="coinduction-part-1.html#13774" class="Function">tabulate</a> <a id="13971" href="coinduction-part-1.html#13991" class="Function">fib</a>
    <a id="13979" class="Keyword">where</a>
      <a id="13991" href="coinduction-part-1.html#13991" class="Function">fib</a> <a id="13995" class="Symbol">:</a> <a id="13997" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="13999" class="Symbol">→</a> <a id="14001" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a>
      <a id="14009" href="coinduction-part-1.html#13991" class="Function">fib</a> <a id="14013" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a> <a id="14018" class="Symbol">=</a> <a id="14020" class="Number">1</a>
      <a id="14028" href="coinduction-part-1.html#13991" class="Function">fib</a> <a id="14032" class="Symbol">(</a><a id="14033" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="14037" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a><a id="14041" class="Symbol">)</a> <a id="14043" class="Symbol">=</a> <a id="14045" class="Number">1</a>
      <a id="14053" href="coinduction-part-1.html#13991" class="Function">fib</a> <a id="14057" class="Symbol">(</a><a id="14058" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="14062" class="Symbol">(</a><a id="14063" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="14067" href="coinduction-part-1.html#14067" class="Bound">x</a><a id="14068" class="Symbol">))</a> <a id="14071" class="Symbol">=</a> <a id="14073" href="coinduction-part-1.html#13991" class="Function">fib</a> <a id="14077" href="coinduction-part-1.html#14067" class="Bound">x</a> <a id="14079" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">+</a> <a id="14081" href="coinduction-part-1.html#13991" class="Function">fib</a> <a id="14085" class="Symbol">(</a><a id="14086" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="14090" href="coinduction-part-1.html#14067" class="Bound">x</a><a id="14091" class="Symbol">)</a>
</pre>
</details>
<p><strong>Exercise.</strong> A stream can contain elements of any type, including the type of
streams itself. We can think of a stream of streams as a two-dimensional matrix
that is infinite in both directions. It is a fun exercise to implement a
<code>transpose</code> function for infinite matrices and prove its defining property. You
probably need the <code>lookup-map</code> property you used before. It might also be
useful to use the equational reasoning syntax from the module
<a href="https://agda.github.io/agda-stdlib/v2.3/Relation.Binary.PropositionalEquality.Properties.html#6850">≡-Reasoning</a>
which is defined in <code>Relation.Binary.PropositionalEquality.Properties</code> in the
<a href="https://github.com/agda/agda-stdlib/">standard library</a>.</p>
<pre class="Agda">  <a id="GuardedCoinduction.transpose"></a><a id="14818" href="coinduction-part-1.html#14818" class="Function">transpose</a> <a id="14828" class="Symbol">:</a> <a id="14830" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="14837" class="Symbol">(</a><a id="14838" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="14845" href="coinduction-part-1.html#1036" class="Generalizable">A</a><a id="14846" class="Symbol">)</a> <a id="14848" class="Symbol">→</a> <a id="14850" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="14857" class="Symbol">(</a><a id="14858" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="14865" href="coinduction-part-1.html#1036" class="Generalizable">A</a><a id="14866" class="Symbol">)</a>
  <a id="GuardedCoinduction.transpose-flips-lookup"></a><a id="14870" href="coinduction-part-1.html#14870" class="Function">transpose-flips-lookup</a>
    <a id="14897" class="Symbol">:</a> <a id="14899" class="Symbol">(</a><a id="14900" href="coinduction-part-1.html#14900" class="Bound">xss</a> <a id="14904" class="Symbol">:</a> <a id="14906" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="14913" class="Symbol">(</a><a id="14914" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="14921" href="coinduction-part-1.html#1036" class="Generalizable">A</a><a id="14922" class="Symbol">))</a> <a id="14925" class="Symbol">(</a><a id="14926" href="coinduction-part-1.html#14926" class="Bound">i</a> <a id="14928" href="coinduction-part-1.html#14928" class="Bound">j</a> <a id="14930" class="Symbol">:</a> <a id="14932" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a><a id="14933" class="Symbol">)</a>
    <a id="14939" class="Symbol">→</a> <a id="14941" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="14948" class="Symbol">(</a><a id="14949" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="14956" class="Symbol">(</a><a id="14957" href="coinduction-part-1.html#14818" class="Function">transpose</a> <a id="14967" href="coinduction-part-1.html#14900" class="Bound">xss</a><a id="14970" class="Symbol">)</a> <a id="14972" href="coinduction-part-1.html#14926" class="Bound">i</a><a id="14973" class="Symbol">)</a> <a id="14975" href="coinduction-part-1.html#14928" class="Bound">j</a>
      <a id="14983" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="14985" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="14992" class="Symbol">(</a><a id="14993" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="15000" href="coinduction-part-1.html#14900" class="Bound">xss</a> <a id="15004" href="coinduction-part-1.html#14928" class="Bound">j</a><a id="15005" class="Symbol">)</a> <a id="15007" href="coinduction-part-1.html#14926" class="Bound">i</a>
</pre>
<details>
<summary>
<strong>Solution.</strong>
</summary>
<pre class="Agda">  <a id="15066" href="coinduction-part-1.html#14818" class="Function">transpose</a> <a id="15076" href="coinduction-part-1.html#15076" class="Bound">xss</a> <a id="15080" class="Symbol">.</a><a id="15081" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="15086" class="Symbol">=</a> <a id="15088" href="coinduction-part-1.html#11491" class="Function">map</a> <a id="15092" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="15097" href="coinduction-part-1.html#15076" class="Bound">xss</a>
  <a id="15103" href="coinduction-part-1.html#14818" class="Function">transpose</a> <a id="15113" href="coinduction-part-1.html#15113" class="Bound">xss</a> <a id="15117" class="Symbol">.</a><a id="15118" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="15123" class="Symbol">=</a> <a id="15125" href="coinduction-part-1.html#14818" class="Function">transpose</a> <a id="15135" class="Symbol">(</a><a id="15136" href="coinduction-part-1.html#11491" class="Function">map</a> <a id="15140" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="15145" href="coinduction-part-1.html#15113" class="Bound">xss</a><a id="15148" class="Symbol">)</a>

  <a id="15153" href="coinduction-part-1.html#14870" class="Function">transpose-flips-lookup</a> <a id="15176" href="coinduction-part-1.html#15176" class="Bound">xss</a> <a id="15180" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a> <a id="15185" href="coinduction-part-1.html#15185" class="Bound">j</a> <a id="15187" class="Symbol">=</a> <a id="15189" href="coinduction-part-1.html#12855" class="Function">lookup-map</a> <a id="15200" href="coinduction-part-1.html#15185" class="Bound">j</a>
  <a id="15204" href="coinduction-part-1.html#14870" class="Function">transpose-flips-lookup</a> <a id="15227" href="coinduction-part-1.html#15227" class="Bound">xss</a> <a id="15231" class="Symbol">(</a><a id="15232" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="15236" href="coinduction-part-1.html#15236" class="Bound">i</a><a id="15237" class="Symbol">)</a> <a id="15239" href="coinduction-part-1.html#15239" class="Bound">j</a> <a id="15241" class="Symbol">=</a>
    <a id="15247" href="Relation.Binary.Reasoning.Syntax.html#1572" class="Function Operator">begin</a>
      <a id="15259" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="15266" class="Symbol">(</a><a id="15267" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="15274" class="Symbol">(</a><a id="15275" href="coinduction-part-1.html#14818" class="Function">transpose</a> <a id="15285" href="coinduction-part-1.html#15227" class="Bound">xss</a><a id="15288" class="Symbol">)</a> <a id="15290" class="Symbol">(</a><a id="15291" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="15295" href="coinduction-part-1.html#15236" class="Bound">i</a><a id="15296" class="Symbol">))</a> <a id="15299" href="coinduction-part-1.html#15239" class="Bound">j</a>
    <a id="15305" href="Relation.Binary.Reasoning.Syntax.html#11079" class="Function">≡⟨⟩</a>
      <a id="15315" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="15322" class="Symbol">(</a><a id="15323" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="15330" class="Symbol">(</a><a id="15331" href="coinduction-part-1.html#14818" class="Function">transpose</a> <a id="15341" href="coinduction-part-1.html#15227" class="Bound">xss</a> <a id="15345" class="Symbol">.</a><a id="15346" href="coinduction-part-1.html#7939" class="Field">tail</a><a id="15350" class="Symbol">)</a> <a id="15352" href="coinduction-part-1.html#15236" class="Bound">i</a><a id="15353" class="Symbol">)</a> <a id="15355" href="coinduction-part-1.html#15239" class="Bound">j</a>
    <a id="15361" href="Relation.Binary.Reasoning.Syntax.html#11048" class="Function">≡⟨</a> <a id="15364" href="coinduction-part-1.html#14870" class="Function">transpose-flips-lookup</a> <a id="15387" class="Symbol">(</a><a id="15388" href="coinduction-part-1.html#11491" class="Function">map</a> <a id="15392" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="15397" href="coinduction-part-1.html#15227" class="Bound">xss</a><a id="15400" class="Symbol">)</a> <a id="15402" href="coinduction-part-1.html#15236" class="Bound">i</a> <a id="15404" href="coinduction-part-1.html#15239" class="Bound">j</a> <a id="15406" href="Relation.Binary.Reasoning.Syntax.html#11048" class="Function">⟩</a>
      <a id="15414" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="15421" class="Symbol">(</a><a id="15422" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="15429" class="Symbol">(</a><a id="15430" href="coinduction-part-1.html#11491" class="Function">map</a> <a id="15434" class="Symbol">(λ</a> <a id="15437" href="coinduction-part-1.html#15437" class="Bound">r</a> <a id="15439" class="Symbol">→</a> <a id="15441" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="15446" href="coinduction-part-1.html#15437" class="Bound">r</a><a id="15447" class="Symbol">)</a> <a id="15449" href="coinduction-part-1.html#15227" class="Bound">xss</a><a id="15452" class="Symbol">)</a> <a id="15454" href="coinduction-part-1.html#15239" class="Bound">j</a><a id="15455" class="Symbol">)</a> <a id="15457" href="coinduction-part-1.html#15236" class="Bound">i</a>
    <a id="15463" href="Relation.Binary.Reasoning.Syntax.html#11048" class="Function">≡⟨</a> <a id="15466" href="Relation.Binary.PropositionalEquality.Core.html#1481" class="Function">cong</a> <a id="15471" class="Symbol">(λ</a> <a id="15474" href="coinduction-part-1.html#15474" class="Bound">yss</a> <a id="15478" class="Symbol">→</a> <a id="15480" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="15487" href="coinduction-part-1.html#15474" class="Bound">yss</a> <a id="15491" href="coinduction-part-1.html#15236" class="Bound">i</a><a id="15492" class="Symbol">)</a> <a id="15494" class="Symbol">(</a><a id="15495" href="coinduction-part-1.html#12855" class="Function">lookup-map</a> <a id="15506" href="coinduction-part-1.html#15239" class="Bound">j</a><a id="15507" class="Symbol">)</a> <a id="15509" href="Relation.Binary.Reasoning.Syntax.html#11048" class="Function">⟩</a>
      <a id="15517" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="15524" class="Symbol">(</a><a id="15525" href="coinduction-part-1.html#7939" class="Field">tail</a> <a id="15530" class="Symbol">(</a><a id="15531" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="15538" href="coinduction-part-1.html#15227" class="Bound">xss</a> <a id="15542" href="coinduction-part-1.html#15239" class="Bound">j</a><a id="15543" class="Symbol">))</a> <a id="15546" href="coinduction-part-1.html#15236" class="Bound">i</a>
    <a id="15552" href="Relation.Binary.Reasoning.Syntax.html#11079" class="Function">≡⟨⟩</a>
      <a id="15562" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="15569" class="Symbol">(</a><a id="15570" href="coinduction-part-1.html#9870" class="Function">lookup</a> <a id="15577" href="coinduction-part-1.html#15227" class="Bound">xss</a> <a id="15581" href="coinduction-part-1.html#15239" class="Bound">j</a><a id="15582" class="Symbol">)</a> <a id="15584" class="Symbol">(</a><a id="15585" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="15589" href="coinduction-part-1.html#15236" class="Bound">i</a><a id="15590" class="Symbol">)</a>
    <a id="15596" href="Relation.Binary.Reasoning.Syntax.html#12345" class="Function Operator">∎</a>
    <a id="15602" class="Keyword">where</a> <a id="15608" class="Keyword">open</a> <a id="15613" href="Relation.Binary.PropositionalEquality.Properties.html#6850" class="Module">≡-Reasoning</a>
</pre>
</details>
<h1 id="mixing-induction-and-coinduction">Mixing induction and coinduction</h1>
<p>Streams are a nice first example of a coinductive type, but they are also a bit boring
because they all have exactly the same structure, the only difference is in the
values. To define more interesting types with potentially infinite values, we
can mix induction and coinduction by mutually defining a data type and a
coinductive record type. For example, we define a type of potentially
infinite lists or <em>colists</em>:</p>
<pre class="Agda">  <a id="16105" class="Keyword">mutual</a>
    <a id="16116" class="Keyword">data</a> <a id="GuardedCoinduction.Colist"></a><a id="16121" href="coinduction-part-1.html#16121" class="Datatype">Colist</a> <a id="16128" class="Symbol">(</a><a id="16129" href="coinduction-part-1.html#16129" class="Bound">A</a> <a id="16131" class="Symbol">:</a> <a id="16133" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="16136" class="Symbol">)</a> <a id="16138" class="Symbol">:</a> <a id="16140" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="16144" class="Keyword">where</a>
      <a id="GuardedCoinduction.Colist.[]"></a><a id="16156" href="coinduction-part-1.html#16156" class="InductiveConstructor">[]</a>   <a id="16161" class="Symbol">:</a> <a id="16163" href="coinduction-part-1.html#16121" class="Datatype">Colist</a> <a id="16170" href="coinduction-part-1.html#16129" class="Bound">A</a>
      <a id="GuardedCoinduction.Colist._∷_"></a><a id="16178" href="coinduction-part-1.html#16178" class="InductiveConstructor Operator">_∷_</a>  <a id="16183" class="Symbol">:</a> <a id="16185" href="coinduction-part-1.html#16129" class="Bound">A</a> <a id="16187" class="Symbol">→</a> <a id="16189" href="coinduction-part-1.html#16222" class="Record">Colist'</a> <a id="16197" href="coinduction-part-1.html#16129" class="Bound">A</a> <a id="16199" class="Symbol">→</a> <a id="16201" href="coinduction-part-1.html#16121" class="Datatype">Colist</a> <a id="16208" href="coinduction-part-1.html#16129" class="Bound">A</a>

    <a id="16215" class="Keyword">record</a> <a id="GuardedCoinduction.Colist'"></a><a id="16222" href="coinduction-part-1.html#16222" class="Record">Colist'</a> <a id="16230" class="Symbol">(</a><a id="16231" href="coinduction-part-1.html#16231" class="Bound">A</a> <a id="16233" class="Symbol">:</a> <a id="16235" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="16238" class="Symbol">)</a> <a id="16240" class="Symbol">:</a> <a id="16242" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="16246" class="Keyword">where</a>
      <a id="16258" class="Keyword">coinductive</a>
      <a id="16276" class="Keyword">field</a>
        <a id="GuardedCoinduction.Colist'.force"></a><a id="16290" href="coinduction-part-1.html#16290" class="Field">force</a> <a id="16296" class="Symbol">:</a> <a id="16298" href="coinduction-part-1.html#16121" class="Datatype">Colist</a> <a id="16305" href="coinduction-part-1.html#16231" class="Bound">A</a>
  <a id="16309" class="Keyword">open</a> <a id="16314" href="coinduction-part-1.html#16222" class="Module">Colist'</a> <a id="16322" class="Keyword">public</a>
</pre>
<p>This pattern of defining a datatype together with a coinductive record with a
single field called <code>force</code> is quite common when defining coinductive types in
Agda.</p>
<p>We convert a list to a (finite) colist:</p>
<pre class="Agda">  <a id="GuardedCoinduction.fromList"></a><a id="16550" href="coinduction-part-1.html#16550" class="Function">fromList</a> <a id="16559" class="Symbol">:</a> <a id="16561" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="16566" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="16568" class="Symbol">→</a> <a id="16570" href="coinduction-part-1.html#16121" class="Datatype">Colist</a> <a id="16577" href="coinduction-part-1.html#1036" class="Generalizable">A</a>
  <a id="16581" href="coinduction-part-1.html#16550" class="Function">fromList</a> <a id="16590" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a>       <a id="16599" class="Symbol">=</a> <a id="16601" href="coinduction-part-1.html#16156" class="InductiveConstructor">[]</a>
  <a id="16606" href="coinduction-part-1.html#16550" class="Function">fromList</a> <a id="16615" class="Symbol">(</a><a id="16616" href="coinduction-part-1.html#16616" class="Bound">x</a> <a id="16618" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="16620" href="coinduction-part-1.html#16620" class="Bound">xs</a><a id="16622" class="Symbol">)</a> <a id="16624" class="Symbol">=</a> <a id="16626" href="coinduction-part-1.html#16616" class="Bound">x</a> <a id="16628" href="coinduction-part-1.html#16178" class="InductiveConstructor Operator">∷</a> <a id="16630" class="Keyword">record</a> <a id="16637" class="Symbol">{</a> <a id="16639" href="coinduction-part-1.html#16290" class="Field">force</a> <a id="16645" class="Symbol">=</a> <a id="16647" href="coinduction-part-1.html#16550" class="Function">fromList</a> <a id="16656" href="coinduction-part-1.html#16620" class="Bound">xs</a> <a id="16659" class="Symbol">}</a>
</pre>
<p>Despite the fact that <code>fromList</code> produces a colist, the reason why it passes the Agda termination checker is because it is structurally recursive on the input list. In other words, this function is defined by <em>induction</em>, not coinduction.</p>
<p>In contrast, converting a stream to an (infinite) colist needs to use a
copattern to make it pass the guardedness check:</p>
<pre class="Agda">  <a id="GuardedCoinduction.fromStream"></a><a id="17038" href="coinduction-part-1.html#17038" class="Function">fromStream</a> <a id="17049" class="Symbol">:</a> <a id="17051" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="17058" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="17060" class="Symbol">→</a> <a id="17062" href="coinduction-part-1.html#16121" class="Datatype">Colist</a> <a id="17069" href="coinduction-part-1.html#1036" class="Generalizable">A</a>
  <a id="17073" href="coinduction-part-1.html#17038" class="Function">fromStream</a> <a id="17084" class="Symbol">{</a><a id="17085" href="coinduction-part-1.html#17085" class="Bound">A</a><a id="17086" class="Symbol">}</a> <a id="17088" href="coinduction-part-1.html#17088" class="Bound">xs</a> <a id="17091" class="Symbol">=</a> <a id="17093" href="coinduction-part-1.html#17088" class="Bound">xs</a> <a id="17096" class="Symbol">.</a><a id="17097" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="17102" href="coinduction-part-1.html#16178" class="InductiveConstructor Operator">∷</a> <a id="17104" href="coinduction-part-1.html#17125" class="Function">rest</a>
    <a id="17113" class="Keyword">where</a>
      <a id="17125" href="coinduction-part-1.html#17125" class="Function">rest</a> <a id="17130" class="Symbol">:</a> <a id="17132" href="coinduction-part-1.html#16222" class="Record">Colist'</a> <a id="17140" href="coinduction-part-1.html#17085" class="Bound">A</a>
      <a id="17148" href="coinduction-part-1.html#17125" class="Function">rest</a> <a id="17153" class="Symbol">.</a><a id="17154" href="coinduction-part-1.html#16290" class="Field">force</a> <a id="17160" class="Symbol">=</a> <a id="17162" href="coinduction-part-1.html#17038" class="Function">fromStream</a> <a id="17173" class="Symbol">(</a><a id="17174" href="coinduction-part-1.html#17088" class="Bound">xs</a> <a id="17177" class="Symbol">.</a><a id="17178" href="coinduction-part-1.html#7939" class="Field">tail</a><a id="17182" class="Symbol">)</a>
</pre>
<p>To make the definition a bit less verbose, we inline the definition of
<code>rest</code> by using a <a href="https://agda.readthedocs.io/en/v2.8.0/language/lambda-abstraction.html#pattern-lambda"><strong>(co)pattern lambda</strong></a>:</p>
<pre class="Agda">  <a id="GuardedCoinduction.fromStream'"></a><a id="17402" href="coinduction-part-1.html#17402" class="Function">fromStream'</a> <a id="17414" class="Symbol">:</a> <a id="17416" href="coinduction-part-1.html#7862" class="Record">Stream</a> <a id="17423" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="17425" class="Symbol">→</a> <a id="17427" href="coinduction-part-1.html#16121" class="Datatype">Colist</a> <a id="17434" href="coinduction-part-1.html#1036" class="Generalizable">A</a>
  <a id="17438" href="coinduction-part-1.html#17402" class="Function">fromStream'</a> <a id="17450" class="Symbol">{</a><a id="17451" href="coinduction-part-1.html#17451" class="Bound">A</a><a id="17452" class="Symbol">}</a> <a id="17454" href="coinduction-part-1.html#17454" class="Bound">xs</a> <a id="17457" class="Symbol">=</a> <a id="17459" href="coinduction-part-1.html#17454" class="Bound">xs</a> <a id="17462" class="Symbol">.</a><a id="17463" href="coinduction-part-1.html#7923" class="Field">head</a> <a id="17468" href="coinduction-part-1.html#16178" class="InductiveConstructor Operator">∷</a>
    <a id="17474" class="Symbol">(λ</a> <a id="17477" class="Keyword">where</a> <a id="17483" class="Symbol">.</a><a id="17484" href="coinduction-part-1.html#16290" class="Field">force</a> <a id="17490" class="Symbol">→</a> <a id="17492" href="coinduction-part-1.html#17402" class="Function">fromStream'</a> <a id="17504" class="Symbol">(</a><a id="17505" href="coinduction-part-1.html#17454" class="Bound">xs</a> <a id="17508" class="Symbol">.</a><a id="17509" href="coinduction-part-1.html#7939" class="Field">tail</a><a id="17513" class="Symbol">))</a>
</pre>
<p>Unfortunately, the syntactic noise of <code>λ where .force →</code> is not avoidable
because the guardedness criterion requires a copattern to appear syntactically
in the definition.</p>
<p>Another example of a mixed induction/coinduction is the type of co-natural
numbers, which is the type of regular Peano numbers plus infinity <code>∞</code>:</p>
<pre class="Agda">  <a id="17851" class="Keyword">mutual</a>
    <a id="17862" class="Keyword">data</a> <a id="GuardedCoinduction.Coℕ"></a><a id="17867" href="coinduction-part-1.html#17867" class="Datatype">Coℕ</a> <a id="17871" class="Symbol">:</a> <a id="17873" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="17877" class="Keyword">where</a>
      <a id="GuardedCoinduction.Coℕ.zero"></a><a id="17889" href="coinduction-part-1.html#17889" class="InductiveConstructor">zero</a>  <a id="17895" class="Symbol">:</a> <a id="17897" href="coinduction-part-1.html#17867" class="Datatype">Coℕ</a>
      <a id="GuardedCoinduction.Coℕ.suc"></a><a id="17907" href="coinduction-part-1.html#17907" class="InductiveConstructor">suc</a>   <a id="17913" class="Symbol">:</a> <a id="17915" href="coinduction-part-1.html#17938" class="Record">Coℕ'</a> <a id="17920" class="Symbol">→</a> <a id="17922" href="coinduction-part-1.html#17867" class="Datatype">Coℕ</a>

    <a id="17931" class="Keyword">record</a> <a id="GuardedCoinduction.Coℕ'"></a><a id="17938" href="coinduction-part-1.html#17938" class="Record">Coℕ'</a> <a id="17943" class="Symbol">:</a> <a id="17945" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="17949" class="Keyword">where</a>
      <a id="17961" class="Keyword">coinductive</a>
      <a id="17979" class="Keyword">field</a> <a id="GuardedCoinduction.Coℕ'.force"></a><a id="17985" href="coinduction-part-1.html#17985" class="Field">force</a> <a id="17991" class="Symbol">:</a> <a id="17993" href="coinduction-part-1.html#17867" class="Datatype">Coℕ</a>
  <a id="17999" class="Keyword">open</a> <a id="18004" href="coinduction-part-1.html#17938" class="Module">Coℕ'</a> <a id="18009" class="Keyword">public</a>

  <a id="GuardedCoinduction.∞"></a><a id="18019" href="coinduction-part-1.html#18019" class="Function">∞</a> <a id="18021" class="Symbol">:</a> <a id="18023" href="coinduction-part-1.html#17867" class="Datatype">Coℕ</a>
  <a id="18029" href="coinduction-part-1.html#18019" class="Function">∞</a> <a id="18031" class="Symbol">=</a> <a id="18033" href="coinduction-part-1.html#17907" class="InductiveConstructor">suc</a> <a id="18037" class="Symbol">λ</a> <a id="18039" class="Keyword">where</a> <a id="18045" class="Symbol">.</a><a id="18046" href="coinduction-part-1.html#17985" class="Field">force</a> <a id="18052" class="Symbol">→</a> <a id="18054" href="coinduction-part-1.html#18019" class="Function">∞</a>
</pre>
<p><strong>Exercise.</strong> Define the following functions:</p>
<pre class="Agda">  <a id="GuardedCoinduction.fromℕ"></a><a id="18118" href="coinduction-part-1.html#18118" class="Function">fromℕ</a> <a id="18124" class="Symbol">:</a> <a id="18126" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="18128" class="Symbol">→</a> <a id="18130" href="coinduction-part-1.html#17867" class="Datatype">Coℕ</a>
  <a id="GuardedCoinduction.colength"></a><a id="18136" href="coinduction-part-1.html#18136" class="Function">colength</a> <a id="18145" class="Symbol">:</a> <a id="18147" href="coinduction-part-1.html#16121" class="Datatype">Colist</a> <a id="18154" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="18156" class="Symbol">→</a> <a id="18158" href="coinduction-part-1.html#17867" class="Datatype">Coℕ</a>
</pre>
<details>
<summary>
<strong>Solution.</strong>
</summary>
<pre class="Agda">
  <a id="18220" href="coinduction-part-1.html#18118" class="Function">fromℕ</a> <a id="18226" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a> <a id="18231" class="Symbol">=</a> <a id="18233" href="coinduction-part-1.html#17889" class="InductiveConstructor">zero</a>
  <a id="18240" href="coinduction-part-1.html#18118" class="Function">fromℕ</a> <a id="18246" class="Symbol">(</a><a id="18247" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="18251" href="coinduction-part-1.html#18251" class="Bound">n</a><a id="18252" class="Symbol">)</a> <a id="18254" class="Symbol">=</a> <a id="18256" href="coinduction-part-1.html#17907" class="InductiveConstructor">suc</a> <a id="18260" class="Symbol">λ</a> <a id="18262" class="Keyword">where</a> <a id="18268" class="Symbol">.</a><a id="18269" href="coinduction-part-1.html#17985" class="Field">force</a> <a id="18275" class="Symbol">→</a> <a id="18277" href="coinduction-part-1.html#18118" class="Function">fromℕ</a> <a id="18283" href="coinduction-part-1.html#18251" class="Bound">n</a>

  <a id="18288" href="coinduction-part-1.html#18136" class="Function">colength</a> <a id="18297" href="coinduction-part-1.html#16156" class="InductiveConstructor">[]</a> <a id="18300" class="Symbol">=</a> <a id="18302" href="coinduction-part-1.html#17889" class="InductiveConstructor">zero</a>
  <a id="18309" href="coinduction-part-1.html#18136" class="Function">colength</a> <a id="18318" class="Symbol">(</a><a id="18319" href="coinduction-part-1.html#18319" class="Bound">x</a> <a id="18321" href="coinduction-part-1.html#16178" class="InductiveConstructor Operator">∷</a> <a id="18323" href="coinduction-part-1.html#18323" class="Bound">xs</a><a id="18325" class="Symbol">)</a> <a id="18327" class="Symbol">=</a> <a id="18329" href="coinduction-part-1.html#17907" class="InductiveConstructor">suc</a> <a id="18333" class="Symbol">λ</a> <a id="18335" class="Keyword">where</a>
    <a id="18345" class="Symbol">.</a><a id="18346" href="coinduction-part-1.html#17985" class="Field">force</a> <a id="18352" class="Symbol">→</a> <a id="18354" href="coinduction-part-1.html#18136" class="Function">colength</a> <a id="18363" class="Symbol">(</a><a id="18364" href="coinduction-part-1.html#18323" class="Bound">xs</a> <a id="18367" class="Symbol">.</a><a id="18368" href="coinduction-part-1.html#16290" class="Field">force</a><a id="18373" class="Symbol">)</a>
</pre>
</details>
<p>A more substantial example of mixing induction and coinduction is the type of
streams of bits <code>Zero</code> and <code>One</code> that have infinitely many zeroes:</p>
<pre class="Agda">  <a id="18547" class="Keyword">data</a> <a id="GuardedCoinduction.ZeroOne"></a><a id="18552" href="coinduction-part-1.html#18552" class="Datatype">ZeroOne</a> <a id="18560" class="Symbol">:</a> <a id="18562" href="Agda.Primitive.html#388" class="Primitive">Set</a>
  <a id="18568" class="Keyword">record</a> <a id="GuardedCoinduction.ZeroOne'"></a><a id="18575" href="coinduction-part-1.html#18575" class="Record">ZeroOne'</a> <a id="18584" class="Symbol">:</a> <a id="18586" href="Agda.Primitive.html#388" class="Primitive">Set</a>

  <a id="18593" class="Keyword">data</a> <a id="18598" href="coinduction-part-1.html#18552" class="Datatype">ZeroOne</a> <a id="18606" class="Keyword">where</a>
    <a id="GuardedCoinduction.ZeroOne.Zero_"></a><a id="18616" href="coinduction-part-1.html#18616" class="InductiveConstructor Operator">Zero_</a> <a id="18622" class="Symbol">:</a> <a id="18624" href="coinduction-part-1.html#18575" class="Record">ZeroOne'</a> <a id="18633" class="Symbol">→</a> <a id="18635" href="coinduction-part-1.html#18552" class="Datatype">ZeroOne</a>
    <a id="GuardedCoinduction.ZeroOne.One_"></a><a id="18647" href="coinduction-part-1.html#18647" class="InductiveConstructor Operator">One_</a>  <a id="18653" class="Symbol">:</a> <a id="18655" href="coinduction-part-1.html#18552" class="Datatype">ZeroOne</a>  <a id="18664" class="Symbol">→</a> <a id="18666" href="coinduction-part-1.html#18552" class="Datatype">ZeroOne</a>

  <a id="18677" class="Keyword">record</a> <a id="18684" href="coinduction-part-1.html#18575" class="Record">ZeroOne'</a> <a id="18693" class="Keyword">where</a>
    <a id="18703" class="Keyword">coinductive</a>
    <a id="18719" class="Keyword">field</a> <a id="GuardedCoinduction.ZeroOne'.force"></a><a id="18725" href="coinduction-part-1.html#18725" class="Field">force</a> <a id="18731" class="Symbol">:</a> <a id="18733" href="coinduction-part-1.html#18552" class="Datatype">ZeroOne</a>
  <a id="18743" class="Keyword">open</a> <a id="18748" href="coinduction-part-1.html#18575" class="Module">ZeroOne'</a> <a id="18757" class="Keyword">public</a>
</pre>
<p>Since the recursive argument of the <code>One</code> constructor has type <code>ZeroOne</code> rather
than <code>ZeroOne'</code>, the constructor is considered to be inductive and hence it can
only be applied a finite number of times before we get another <code>Zero</code>
constructor.</p>
<h1 id="coinduction-with-sized-types">Coinduction with sized types</h1>
<p>The guardedness criterion has the advantage of being fairly simple and easy to
check, but we have also seen that it can be annoying and rule out natural
definitions of coinductive values.
<a href="https://agda.readthedocs.io/en/v2.8.0/language/sized-types.html"><strong>Sized types</strong></a>
are an alternative to the
syntactic guardedness checker that annotates the size of expressions in their
types. They are enabled by putting <code>{-# OPTIONS --sized-types #-}</code> at the top
of our file (using <code>--guardedness</code> and <code>--sized-types</code> together is
inconsistent, see <a href="https://github.com/agda/agda/issues/1209">issue #1209</a> on the
Agda bug tracker).</p>
<p>To use sized types, we should import the builtin module <code>Size</code> (or
<code>Agda.Builtin.Size</code> if you are not using the standard library):</p>
<pre class="Agda"><a id="19806" class="Keyword">module</a> <a id="SizedCoinduction"></a><a id="19813" href="coinduction-part-1.html#19813" class="Module">SizedCoinduction</a> <a id="19830" class="Keyword">where</a>
  <a id="19838" class="Keyword">open</a> <a id="19843" class="Keyword">import</a> <a id="19850" href="Size.html" class="Module">Size</a> <a id="19855" class="Keyword">using</a> <a id="19861" class="Symbol">(</a><a id="19862" href="Agda.Builtin.Size.html#213" class="Postulate">Size</a><a id="19866" class="Symbol">;</a> <a id="19868" href="Agda.Builtin.Size.html#247" class="Postulate Operator">Size&lt;_</a><a id="19874" class="Symbol">;</a> <a id="19876" href="Agda.Builtin.Size.html#315" class="Postulate">∞</a><a id="19877" class="Symbol">)</a>
  <a id="19881" class="Keyword">variable</a> <a id="19890" href="coinduction-part-1.html#19890" class="Generalizable">i</a> <a id="19892" class="Symbol">:</a> <a id="19894" href="Agda.Builtin.Size.html#213" class="Postulate">Size</a>
</pre>
<p>The module <code>Size</code> provides:</p>
<ul>
<li>The type <code>Size : Set</code></li>
<li>The family of types <code>Size&lt; i : Set</code> for every <code>i : Size</code></li>
<li>The size <code>∞ : Size</code></li>
<li>Some more operations on sizes that are not relevant here.</li>
</ul>
<p>We can think of sizes as natural numbers extended with <code>∞</code>, but pattern matching
on sizes is not allowed. The type <code>Size&lt; i</code> is similar to the <code>Fin n</code> type of
natural numbers less than <code>n</code>. A special property of these types is that we have
subtyping <code>Size&lt; i &lt;: Size</code> and <code>Size&lt; i &lt;: Size&lt; j</code> when <code>i ≤ j</code>.</p>
<p>To make use of sizes, we should parametrize our coinductive types by a size
representing the number of observations we can safely make, i.e. the “depth”
until where the coinductive value has been defined.
For example, we parametrize a stream by its size:</p>
<pre class="Agda">  <a id="20673" class="Keyword">record</a> <a id="SizedCoinduction.Stream"></a><a id="20680" href="coinduction-part-1.html#20680" class="Record">Stream</a> <a id="20687" class="Symbol">(</a><a id="20688" href="coinduction-part-1.html#20688" class="Bound">A</a> <a id="20690" class="Symbol">:</a> <a id="20692" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="20695" class="Symbol">)</a> <a id="20697" class="Symbol">(</a><a id="20698" href="coinduction-part-1.html#20698" class="Bound">i</a> <a id="20700" class="Symbol">:</a> <a id="20702" href="Agda.Builtin.Size.html#213" class="Postulate">Size</a><a id="20706" class="Symbol">)</a> <a id="20708" class="Symbol">:</a> <a id="20710" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="20714" class="Keyword">where</a>
    <a id="20724" class="Keyword">coinductive</a>
    <a id="20740" class="Keyword">field</a>
      <a id="SizedCoinduction.Stream.head"></a><a id="20752" href="coinduction-part-1.html#20752" class="Field">head</a> <a id="20757" class="Symbol">:</a> <a id="20759" href="coinduction-part-1.html#20688" class="Bound">A</a>
      <a id="SizedCoinduction.Stream.tail"></a><a id="20767" href="coinduction-part-1.html#20767" class="Field">tail</a> <a id="20772" class="Symbol">:</a> <a id="20774" class="Symbol">{</a><a id="20775" href="coinduction-part-1.html#20775" class="Bound">j</a> <a id="20777" class="Symbol">:</a> <a id="20779" href="Agda.Builtin.Size.html#247" class="Postulate Operator">Size&lt;</a> <a id="20785" href="coinduction-part-1.html#20698" class="Bound">i</a><a id="20786" class="Symbol">}</a> <a id="20788" class="Symbol">→</a> <a id="20790" href="coinduction-part-1.html#20680" class="Record">Stream</a> <a id="20797" href="coinduction-part-1.html#20688" class="Bound">A</a> <a id="20799" href="coinduction-part-1.html#20775" class="Bound">j</a>
  <a id="20803" class="Keyword">open</a> <a id="20808" href="coinduction-part-1.html#20680" class="Module">Stream</a>
</pre>
<p>When taking the tail of a stream of size <code>i</code>, we should pick any size <code>j</code> that
is strictly smaller than <code>i</code> and we get a stream of that size.</p>
<p>When writing a function that takes a stream as <em>input</em> we usually assume
that the stream is already fully defined, which means we use size <code>∞</code>:</p>
<pre class="Agda">  <a id="SizedCoinduction.take"></a><a id="21118" href="coinduction-part-1.html#21118" class="Function">take</a> <a id="21123" class="Symbol">:</a> <a id="21125" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="21127" class="Symbol">→</a> <a id="21129" href="coinduction-part-1.html#20680" class="Record">Stream</a> <a id="21136" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="21138" href="Agda.Builtin.Size.html#315" class="Postulate">∞</a> <a id="21140" class="Symbol">→</a> <a id="21142" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="21147" href="coinduction-part-1.html#1036" class="Generalizable">A</a>
  <a id="21151" href="coinduction-part-1.html#21118" class="Function">take</a> <a id="21156" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>    <a id="21164" href="coinduction-part-1.html#21164" class="Bound">s</a> <a id="21166" class="Symbol">=</a> <a id="21168" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a>
  <a id="21173" href="coinduction-part-1.html#21118" class="Function">take</a> <a id="21178" class="Symbol">(</a><a id="21179" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="21183" href="coinduction-part-1.html#21183" class="Bound">n</a><a id="21184" class="Symbol">)</a> <a id="21186" href="coinduction-part-1.html#21186" class="Bound">s</a> <a id="21188" class="Symbol">=</a> <a id="21190" href="coinduction-part-1.html#21186" class="Bound">s</a> <a id="21192" class="Symbol">.</a><a id="21193" href="coinduction-part-1.html#20752" class="Field">head</a> <a id="21198" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="21200" href="coinduction-part-1.html#21118" class="Function">take</a> <a id="21205" href="coinduction-part-1.html#21183" class="Bound">n</a> <a id="21207" class="Symbol">(</a><a id="21208" href="coinduction-part-1.html#21186" class="Bound">s</a> <a id="21210" class="Symbol">.</a><a id="21211" href="coinduction-part-1.html#20767" class="Field">tail</a><a id="21215" class="Symbol">)</a>

  <a id="SizedCoinduction.drop"></a><a id="21220" href="coinduction-part-1.html#21220" class="Function">drop</a> <a id="21225" class="Symbol">:</a> <a id="21227" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="21229" class="Symbol">→</a> <a id="21231" href="coinduction-part-1.html#20680" class="Record">Stream</a> <a id="21238" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="21240" href="Agda.Builtin.Size.html#315" class="Postulate">∞</a> <a id="21242" class="Symbol">→</a> <a id="21244" href="coinduction-part-1.html#20680" class="Record">Stream</a> <a id="21251" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="21253" href="Agda.Builtin.Size.html#315" class="Postulate">∞</a>
  <a id="21257" href="coinduction-part-1.html#21220" class="Function">drop</a> <a id="21262" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>    <a id="21270" href="coinduction-part-1.html#21270" class="Bound">s</a> <a id="21272" class="Symbol">=</a> <a id="21274" href="coinduction-part-1.html#21270" class="Bound">s</a>
  <a id="21278" href="coinduction-part-1.html#21220" class="Function">drop</a> <a id="21283" class="Symbol">(</a><a id="21284" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="21288" href="coinduction-part-1.html#21288" class="Bound">n</a><a id="21289" class="Symbol">)</a> <a id="21291" href="coinduction-part-1.html#21291" class="Bound">s</a> <a id="21293" class="Symbol">=</a> <a id="21295" href="coinduction-part-1.html#21220" class="Function">drop</a> <a id="21300" href="coinduction-part-1.html#21288" class="Bound">n</a> <a id="21302" class="Symbol">(</a><a id="21303" href="coinduction-part-1.html#21291" class="Bound">s</a> <a id="21305" class="Symbol">.</a><a id="21306" href="coinduction-part-1.html#20767" class="Field">tail</a><a id="21310" class="Symbol">)</a>
</pre>
<p>On the other hand, when <em>defining</em> a new stream we should define it at an
arbitrary size <code>i</code>:</p>
<pre class="Agda">  <a id="SizedCoinduction.zeroes"></a><a id="21422" href="coinduction-part-1.html#21422" class="Function">zeroes</a> <a id="21429" class="Symbol">:</a> <a id="21431" href="coinduction-part-1.html#20680" class="Record">Stream</a> <a id="21438" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="21440" href="coinduction-part-1.html#19890" class="Generalizable">i</a>
  <a id="21444" href="coinduction-part-1.html#21422" class="Function">zeroes</a> <a id="21451" class="Symbol">.</a><a id="21452" href="coinduction-part-1.html#20752" class="Field">head</a>  <a id="21458" class="Symbol">=</a> <a id="21460" class="Number">0</a>
  <a id="21464" href="coinduction-part-1.html#21422" class="Function">zeroes</a> <a id="21471" class="Symbol">.</a><a id="21472" href="coinduction-part-1.html#20767" class="Field">tail</a>  <a id="21478" class="Symbol">=</a> <a id="21480" href="coinduction-part-1.html#21422" class="Function">zeroes</a>
</pre>
<p>We can understand this definition better by making all the implicit sizes
explicit:</p>
<pre class="Agda">  <a id="SizedCoinduction.zeroes'"></a><a id="21587" href="coinduction-part-1.html#21587" class="Function">zeroes'</a> <a id="21595" class="Symbol">:</a> <a id="21597" class="Symbol">{</a><a id="21598" href="coinduction-part-1.html#21598" class="Bound">i</a> <a id="21600" class="Symbol">:</a> <a id="21602" href="Agda.Builtin.Size.html#213" class="Postulate">Size</a><a id="21606" class="Symbol">}</a> <a id="21608" class="Symbol">→</a> <a id="21610" href="coinduction-part-1.html#20680" class="Record">Stream</a> <a id="21617" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="21619" href="coinduction-part-1.html#21598" class="Bound">i</a>
  <a id="21623" href="coinduction-part-1.html#21587" class="Function">zeroes'</a> <a id="21631" class="Symbol">{</a><a id="21632" href="coinduction-part-1.html#21632" class="Bound">i</a><a id="21633" class="Symbol">}</a> <a id="21635" class="Symbol">.</a><a id="21636" href="coinduction-part-1.html#20752" class="Field">head</a>      <a id="21646" class="Symbol">=</a> <a id="21648" class="Number">0</a>
  <a id="21652" href="coinduction-part-1.html#21587" class="Function">zeroes'</a> <a id="21660" class="Symbol">{</a><a id="21661" href="coinduction-part-1.html#21661" class="Bound">i</a><a id="21662" class="Symbol">}</a> <a id="21664" class="Symbol">.</a><a id="21665" href="coinduction-part-1.html#20767" class="Field">tail</a> <a id="21670" class="Symbol">{</a><a id="21671" href="coinduction-part-1.html#21671" class="Bound">j</a><a id="21672" class="Symbol">}</a>  <a id="21675" class="Symbol">=</a> <a id="21677" href="coinduction-part-1.html#21422" class="Function">zeroes</a> <a id="21684" class="Symbol">{</a><a id="21685" href="coinduction-part-1.html#21671" class="Bound">j</a><a id="21686" class="Symbol">}</a>
</pre>
<p>In the definition of <code>zeroes' {i} .tail</code>, we have to give a function of type
<code>{j : Size&lt; i} → Stream ℕ j</code>. Since <code>j &lt; i</code>, the recursive call <code>zeroes {j}</code>
is made at a size strictly smaller than <code>i</code>, which is why it is accepted by
Agda’s productivity checker for sized types.</p>
<p>Using sizes, we now give a more precise type to <code>map</code> that makes it clear
that it preserves the depth for which the stream is defined:</p>
<pre class="Agda">  <a id="SizedCoinduction.map"></a><a id="22115" href="coinduction-part-1.html#22115" class="Function">map</a> <a id="22119" class="Symbol">:</a> <a id="22121" class="Symbol">(</a><a id="22122" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="22124" class="Symbol">→</a> <a id="22126" href="coinduction-part-1.html#1038" class="Generalizable">B</a><a id="22127" class="Symbol">)</a> <a id="22129" class="Symbol">→</a> <a id="22131" href="coinduction-part-1.html#20680" class="Record">Stream</a> <a id="22138" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="22140" href="coinduction-part-1.html#19890" class="Generalizable">i</a> <a id="22142" class="Symbol">→</a> <a id="22144" href="coinduction-part-1.html#20680" class="Record">Stream</a> <a id="22151" href="coinduction-part-1.html#1038" class="Generalizable">B</a> <a id="22153" href="coinduction-part-1.html#19890" class="Generalizable">i</a>
  <a id="22157" href="coinduction-part-1.html#22115" class="Function">map</a> <a id="22161" href="coinduction-part-1.html#22161" class="Bound">f</a> <a id="22163" href="coinduction-part-1.html#22163" class="Bound">s</a> <a id="22165" class="Symbol">.</a><a id="22166" href="coinduction-part-1.html#20752" class="Field">head</a> <a id="22171" class="Symbol">=</a> <a id="22173" href="coinduction-part-1.html#22161" class="Bound">f</a> <a id="22175" class="Symbol">(</a><a id="22176" href="coinduction-part-1.html#22163" class="Bound">s</a> <a id="22178" class="Symbol">.</a><a id="22179" href="coinduction-part-1.html#20752" class="Field">head</a><a id="22183" class="Symbol">)</a>
  <a id="22187" href="coinduction-part-1.html#22115" class="Function">map</a> <a id="22191" href="coinduction-part-1.html#22191" class="Bound">f</a> <a id="22193" href="coinduction-part-1.html#22193" class="Bound">s</a> <a id="22195" class="Symbol">.</a><a id="22196" href="coinduction-part-1.html#20767" class="Field">tail</a> <a id="22201" class="Symbol">=</a> <a id="22203" href="coinduction-part-1.html#22115" class="Function">map</a> <a id="22207" href="coinduction-part-1.html#22191" class="Bound">f</a> <a id="22209" class="Symbol">(</a><a id="22210" href="coinduction-part-1.html#22193" class="Bound">s</a> <a id="22212" class="Symbol">.</a><a id="22213" href="coinduction-part-1.html#20767" class="Field">tail</a><a id="22217" class="Symbol">)</a>
</pre>
<p>This allows us to give a direct definition of <code>nats</code> using <code>map</code>, showing that
sized types allow more definitions than the guardedness criterion:</p>
<pre class="Agda">  <a id="SizedCoinduction.nats"></a><a id="22377" href="coinduction-part-1.html#22377" class="Function">nats</a> <a id="22382" class="Symbol">:</a> <a id="22384" href="coinduction-part-1.html#20680" class="Record">Stream</a> <a id="22391" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="22393" href="coinduction-part-1.html#19890" class="Generalizable">i</a>
  <a id="22397" href="coinduction-part-1.html#22377" class="Function">nats</a> <a id="22402" class="Symbol">.</a><a id="22403" href="coinduction-part-1.html#20752" class="Field">head</a>  <a id="22409" class="Symbol">=</a> <a id="22411" class="Number">0</a>
  <a id="22415" href="coinduction-part-1.html#22377" class="Function">nats</a> <a id="22420" class="Symbol">.</a><a id="22421" href="coinduction-part-1.html#20767" class="Field">tail</a>  <a id="22427" class="Symbol">=</a> <a id="22429" href="coinduction-part-1.html#22115" class="Function">map</a> <a id="22433" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="22437" href="coinduction-part-1.html#22377" class="Function">nats</a>
</pre>
<p><strong>Exercise.</strong> Define <code>zipWith</code> for sized streams with the proper size annotations and use it to define <code>fibonacci</code> without using <code>tabulate</code>.</p>
<pre class="Agda">  <a id="SizedCoinduction.fibonacci"></a><a id="22599" href="coinduction-part-1.html#22599" class="Function">fibonacci</a> <a id="22609" class="Symbol">:</a> <a id="22611" href="coinduction-part-1.html#20680" class="Record">Stream</a> <a id="22618" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="22620" href="coinduction-part-1.html#19890" class="Generalizable">i</a>
</pre>
<details>
<summary>
<strong>Solution.</strong>
</summary>
<pre class="Agda">  <a id="SizedCoinduction.zipWith"></a><a id="22679" href="coinduction-part-1.html#22679" class="Function">zipWith</a> <a id="22687" class="Symbol">:</a> <a id="22689" class="Symbol">(</a><a id="22690" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="22692" class="Symbol">→</a> <a id="22694" href="coinduction-part-1.html#1038" class="Generalizable">B</a> <a id="22696" class="Symbol">→</a> <a id="22698" href="coinduction-part-1.html#1040" class="Generalizable">C</a><a id="22699" class="Symbol">)</a>
          <a id="22711" class="Symbol">→</a> <a id="22713" href="coinduction-part-1.html#20680" class="Record">Stream</a> <a id="22720" href="coinduction-part-1.html#1036" class="Generalizable">A</a> <a id="22722" href="coinduction-part-1.html#19890" class="Generalizable">i</a> <a id="22724" class="Symbol">→</a> <a id="22726" href="coinduction-part-1.html#20680" class="Record">Stream</a> <a id="22733" href="coinduction-part-1.html#1038" class="Generalizable">B</a> <a id="22735" href="coinduction-part-1.html#19890" class="Generalizable">i</a> <a id="22737" class="Symbol">→</a> <a id="22739" href="coinduction-part-1.html#20680" class="Record">Stream</a> <a id="22746" href="coinduction-part-1.html#1040" class="Generalizable">C</a> <a id="22748" href="coinduction-part-1.html#19890" class="Generalizable">i</a>
  <a id="22752" href="coinduction-part-1.html#22679" class="Function">zipWith</a> <a id="22760" href="coinduction-part-1.html#22760" class="Bound">f</a> <a id="22762" href="coinduction-part-1.html#22762" class="Bound">xs</a> <a id="22765" href="coinduction-part-1.html#22765" class="Bound">ys</a> <a id="22768" class="Symbol">.</a><a id="22769" href="coinduction-part-1.html#20752" class="Field">head</a> <a id="22774" class="Symbol">=</a> <a id="22776" href="coinduction-part-1.html#22760" class="Bound">f</a> <a id="22778" class="Symbol">(</a><a id="22779" href="coinduction-part-1.html#22762" class="Bound">xs</a> <a id="22782" class="Symbol">.</a><a id="22783" href="coinduction-part-1.html#20752" class="Field">head</a><a id="22787" class="Symbol">)</a> <a id="22789" class="Symbol">(</a><a id="22790" href="coinduction-part-1.html#22765" class="Bound">ys</a> <a id="22793" class="Symbol">.</a><a id="22794" href="coinduction-part-1.html#20752" class="Field">head</a><a id="22798" class="Symbol">)</a>
  <a id="22802" href="coinduction-part-1.html#22679" class="Function">zipWith</a> <a id="22810" href="coinduction-part-1.html#22810" class="Bound">f</a> <a id="22812" href="coinduction-part-1.html#22812" class="Bound">xs</a> <a id="22815" href="coinduction-part-1.html#22815" class="Bound">ys</a> <a id="22818" class="Symbol">.</a><a id="22819" href="coinduction-part-1.html#20767" class="Field">tail</a> <a id="22824" class="Symbol">=</a> <a id="22826" href="coinduction-part-1.html#22679" class="Function">zipWith</a> <a id="22834" href="coinduction-part-1.html#22810" class="Bound">f</a> <a id="22836" class="Symbol">(</a><a id="22837" href="coinduction-part-1.html#22812" class="Bound">xs</a> <a id="22840" class="Symbol">.</a><a id="22841" href="coinduction-part-1.html#20767" class="Field">tail</a><a id="22845" class="Symbol">)</a> <a id="22847" class="Symbol">(</a><a id="22848" href="coinduction-part-1.html#22815" class="Bound">ys</a> <a id="22851" class="Symbol">.</a><a id="22852" href="coinduction-part-1.html#20767" class="Field">tail</a><a id="22856" class="Symbol">)</a>

  <a id="22861" href="coinduction-part-1.html#22599" class="Function">fibonacci</a> <a id="22871" class="Symbol">.</a><a id="22872" href="coinduction-part-1.html#20752" class="Field">head</a> <a id="22877" class="Symbol">=</a> <a id="22879" class="Number">1</a>
  <a id="22883" href="coinduction-part-1.html#22599" class="Function">fibonacci</a> <a id="22893" class="Symbol">.</a><a id="22894" href="coinduction-part-1.html#20767" class="Field">tail</a> <a id="22899" class="Symbol">.</a><a id="22900" href="coinduction-part-1.html#20752" class="Field">head</a> <a id="22905" class="Symbol">=</a> <a id="22907" class="Number">1</a>
  <a id="22911" href="coinduction-part-1.html#22599" class="Function">fibonacci</a> <a id="22921" class="Symbol">.</a><a id="22922" href="coinduction-part-1.html#20767" class="Field">tail</a> <a id="22927" class="Symbol">.</a><a id="22928" href="coinduction-part-1.html#20767" class="Field">tail</a> <a id="22933" class="Symbol">=</a>
    <a id="22939" href="coinduction-part-1.html#22679" class="Function">zipWith</a> <a id="22947" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">_+_</a> <a id="22951" href="coinduction-part-1.html#22599" class="Function">fibonacci</a> <a id="22961" class="Symbol">(</a><a id="22962" href="coinduction-part-1.html#22599" class="Function">fibonacci</a> <a id="22972" class="Symbol">.</a><a id="22973" href="coinduction-part-1.html#20767" class="Field">tail</a><a id="22977" class="Symbol">)</a>
</pre>
</details>
<p>This was just a basic introduction to sized types, we will see more
examples using them in parts 2 and 3 of this series.</p>
<p>Unfortunately, despite their appeal there is a whole list of issues with sized
types, or at least with their current implementation in Agda.</p>
<details>
<summary>
Long list of currently open issues with sized types in Agda
</summary>
<ul>
<li><p>First, as we have seen it takes additional work to annotate types and
functions with sizes, and the resulting definitions are not compatible with
Agda code that does not uses sized types because of the additional arguments.</p></li>
<li><p>Second, Agda has a heuristic for assigning default values to implicit sizes
if there are no constraints on them, but the current implementation of this
heuristic is too eager, forcing us to give explicit values to sizes that
should be inferrable (see issues
<a href="https://github.com/agda/agda/issues/992">#992</a>,
<a href="https://github.com/agda/agda/issues/2439">#2439</a>,
<a href="https://github.com/agda/agda/issues/2551">#2551</a>, and
<a href="https://github.com/agda/agda/issues/2930">#2930</a>).</p></li>
<li><p>Third, the fact that sized types make use of subtyping (which is not used in
other parts of Agda aside from the rarely-used <code>--cumulativity</code> flag) also
causes a number of spurious errors (see issues
<a href="https://github.com/agda/agda/issues/1579">#1579</a>,
<a href="https://github.com/agda/agda/issues/2409">#2409</a>,
<a href="https://github.com/agda/agda/issues/2440">#2440</a>, and
<a href="https://github.com/agda/agda/issues/3039">#3039</a>).</p></li>
<li><p>Third, there are several other cases where the termination/productivity checker for sized
types is more restrictive than it should be,
though there is not a clear pattern as far as I can tell (see issues
<a href="https://github.com/agda/agda/issues/300">#300</a>,
<a href="https://github.com/agda/agda/issues/1417">#1515</a>,
<a href="https://github.com/agda/agda/issues/1869">#1869</a>,
<a href="https://github.com/agda/agda/issues/1894">#1894</a>,
<a href="https://github.com/agda/agda/issues/2041">#2041</a>,
<a href="https://github.com/agda/agda/issues/2098">#2098</a>,
<a href="https://github.com/agda/agda/issues/2331">#2331</a>,
<a href="https://github.com/agda/agda/issues/2651">#2651</a>, and
<a href="https://github.com/agda/agda/issues/2903">#2903</a>).</p></li>
<li><p>Fourth, there are some examples that make Agda’s type checker loop in the
presence of sized types (see issues
<a href="https://github.com/agda/agda/issues/1417">#1417</a>,
<a href="https://github.com/agda/agda/issues/1428">#1428</a>,
<a href="https://github.com/agda/agda/issues/1523">#1523</a>,
<a href="https://github.com/agda/agda/issues/3144">#3144</a>, and
<a href="https://github.com/agda/agda/issues/4376">#4376</a>).</p></li>
<li><p>Finally and most worryingly, there are several known inconsistencies in the
current implementation of sized types, most (but not all) follow from the
fact that Agda considers <code>∞</code> to be strictly smaller than itself (see issues
<a href="https://github.com/agda/agda/issues/1201">#1201</a>,
<a href="https://github.com/agda/agda/issues/1946">#1946</a>,
<a href="https://github.com/agda/agda/issues/2820">#2820</a>,
<a href="https://github.com/agda/agda/issues/3026">#3026</a>,
<a href="https://github.com/agda/agda/issues/6002">#6002</a>, and
<a href="https://github.com/agda/agda/issues/7178">#7178</a>).</p></li>
</ul>
It has been prophesized that one day we
will get a new implementation of sized types that avoids these issues (or at
least the most severe ones). Great honor will be bestowed on the one
implementing this. We also pay our respect to the heroes who have fallen on
their <a href="https://github.com/agda/agda/pull/7152">quest for this holy grail</a>.
</details>
<p>While it is unlikely that you run into these issues when using sized types in
the “indended” way, this state of affairs is not ideal and has naturally
hindered the adoption of sized types.</p>
<p>In the mean time, Isaac Elliott has a great blog post on <a href="https://blog.ielliott.io/sized-types-and-coinduction-in-safe-agda">Sized types and
coinduction in Safe Agda</a>
where he shows a way to “fake” sized types without using the <code>--sized-types</code> flag.
While you lose some convenience such as subtyping and heuristics for inferring
sizes, it could be a good alternative if you want to use a kind of sized types
in the <code>--safe</code> fragment of Agda.</p>
<p>That’s all for this post! Thank you for reading it, and look forward to the
second part of this series where I’ll write about how to state and prove
properties of coinductive structures.</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Thu, 22 Jan 2026 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/coinduction-part-1.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>Going Vegan, or How I Ran All Out Of Excuses</title>
    <link>https://jesper.sikanda.be/posts/going-vegan.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Going Vegan, or How I Ran All Out Of Excuses</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Going Vegan, or How I Ran All Out Of Excuses</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on January  3, 2026
    </p>
    <p>It’s been clear to me for a while now that our diet can have a big impact on climate change. Up until 2019, I consequently called myself a “flexitarian” and tried to avoid eating meat as long as doing so was not too inconvenient to myself or the people around me. That was until the 2019 EUTypes Summer School on Types for Programming and Verification in Ohrid (Macedonia), where the vegetarian options were truly appalling. Here I was in great admiration of the small number of brave and persistent vegetarians who bravely endured and kept improvising to find something edible. I realized that I could have a similar influence on other people, and this inspired me to take the next step and declare myself a vegetarian and stop eating meat and fish altogether.</p>
<p>In the years since then, I’ve been slowly gathering more reasons to avoid animal products and I’ve been slowly reducing the amount of them in my diet as a consequence.
In particular, my brother and his wife were already fully vegan and they introduced me to new exciting flavors such as seitan and cashew cheese.
I replaced my cow milk with oat or soy milk and stopped buying eggs.
I also started to discover the joy of cooking dishes with tofu, beans, lentils, tempeh, seitan, jackfruit, and many other ingredients I’d never used before.
However, even as I was trying to go fully vegan I noticed myself making many different excuses all the time:</p>
<ul>
<li>“As long as I consume less animal products than others, I cannot be blamed.”</li>
<li>“I’m already vegetarian so no animals are killed for my food.”</li>
<li>“I just like cheese too much.”</li>
<li>“It would be awkward to tell my friends I’ve gone vegan.”</li>
<li>“It’s too hard to find restaurants with vegan options.”</li>
<li>“I don’t want to force my choices on my friends when they invite me for dinner.”</li>
<li>“I don’t know how to stay healthy on a vegan diet.”</li>
<li>“I forgot to send advance notice that I’d like a vegan option and now it’s either eating food with animal products or nothing.”</li>
</ul>
<p>Writing down these excuses and doing some research, I found that on reflection none of them really held up.
Either they did not provide sufficient justification, or they were just flat-out wrong.
So after dragging my feet for way too long, I would like to take the start of 2026 as the opportunity to finally commit 100% to being vegan.</p>
<h1 id="reasons-for-going-vegan">10 reasons for going vegan</h1>
<p>One question that I get quite regularly and that might also be on your mind right now is: “why?”
Why do I think it is so important to be vegan?
It’s always a challenge to answer that question, not because I don’t have a reason but because I have too many.
So let me give you my top 10 reasons for going vegan:</p>
<ol type="1">
<li>Animal farming is one of the biggest contributors to global warming.</li>
<li>It is also the main cause of deforestation and environmental collapse.</li>
<li>It is also the main cause of habitat loss and species extinction.</li>
<li>It is also the highest risk factor for the emergence of new pandemics such as Covid-19.</li>
<li>It also causes immense amounts of pain and suffering to billions of animals on a daily basis.</li>
<li>It also robs farmed animals of the right to live their lives in freedom and free from abuse and exploitation that they have as sentient beings.</li>
<li>Factory farms and industrial slaughterhouses are horrible places that not only exploit animals but the humans working in them and living around them too.</li>
<li>Plant-based products are more healthy than animal products.</li>
<li>It is easier to cook vegan food, as there is much lower risk of food poisoning.</li>
<li>There are tons of very tasty plant-based foods that I would probably never have tried otherwise.</li>
</ol>
<p>I am not providing sources here, but many of the links at the bottom of this post do provide them. I am always happy to look them up for you on request.</p>
<p>To be honest, the real question should be ‘why are you not yet vegan?’
I understand that I’m speaking from a position of privilege and for some people there will be very good reasons why they can’t.
Yet does that apply to you, the individual reading this? And if not, what are the objections or obstacles stopping you from going vegan? If you do some research on these, do they actually hold up or are they just excuses you tell to yourself?</p>
<p>At this point in writing this post, I do realize that I’m probably coming across as being terribly preachy and entitled, which I don’t particularly want.
Yet at the same time, I genuinely think not transitioning to a more plant-based food system is one of the biggest mistakes that our current society is making (and yes, I do realize that’s saying a lot).
Yet it’s rare for me to hear a honest and solid argument for why we are not correcting this mistake.
While I don’t think this is the case, it’s possible that I’m living in a bubble and I’m wrong about all of this, so if you have some genuinely good counterarguments I would be really interested to hear them.</p>
<h1 id="a-few-common-objections-and-responses">A few common objections and responses</h1>
<p>To help with addressing many of the arguments that non-vegans have raised, I can highly recommend Ed Winter’s book <a href="https://www.goodreads.com/book/show/124846667-how-to-argue-with-a-meat-eater">How to Argue With a Meat Eater (and Win Every Time)</a> that I finished reading recently.
It starts with a chapter on how to communicate effectively by showing genuine curiosity and compassion, but the main bulk of the book is made up of a long list of all the different arguments that people use to argue against veganism, and a detailed and well-researched rebuttal of each of them.
Despite the title, I believe it is also a very useful book for non-vegans who would like to challenge their beliefs.
Below, I picked a few quotes here that I found most relevant or interesting, but the book has many, many more arguments and responses.</p>
<h4 id="animal-products-taste-good.">“Animal products taste good.”</h4>
<blockquote>
<p>Our sensory pleasure is not more important than the lives and experiences of the animals who are killed to satisfy our tastebuds.</p>
</blockquote>
<h4 id="there-are-bad-apples-but-animal-farming-isnt-like-what-we-see-in-the-exposés.">“There are bad apples but animal farming isn’t like what we see in the exposés.”</h4>
<blockquote>
Animal farming is not a case of a few bad apples acting cruelly - mistreatment and abuse is systemic.
<details>
<summary>
Content warning: graphic descriptions of animal abuse
</summary>
<p>Male animals are coerced into ejaculating. Female animals are penetrated and forcibly impregnated. Newborn animals are mutilated, castrated and then taken away from their mothers. Animals are kept in cages, concrete pens and ammonia-riddled barns. They’re selectively bred to make them grow larger, to produce more milk and eggs, or to have more babies, all of which negatively impacts their bodies and wellbeing. They’re shot, have their necks snapped, and are slammed against floors and walls for being too weak or for not growing fast enough. They’re crammed into small boxes or forced into trucks that take them to facilities that exist with the sole purpose of killing them. They’re herded onto kill floors, into metal boxes or into gondolas in gas chambers. They have bolts fired into their skulls, electricity forced into their brains or carbon dioxide pumped into their lungs. And all so that we can then pull a blade across their throats, drain them of the blood in their bodies and cut them open, pull out all of their organs, cut off their heads, slice up the parts we want to wrap in plastic before then rendering down everything else that’s left.</p>
This isn’t just factory farming. Remove the cages and concrete pens, and animals raised outdoors still face these horrors as well. They still have their tails docked and rubber bands wrapped around their testicles. They’re still ear-tagged, still selectively bred, still impregnated. Does an outdoor pig farmer spend money and time on a sick and ill pig who won’t make them any money, or do they kill them on the farm just like the pig farmers who use farrowing crates? Factory farming might be worse, but just because some animals get to feel the sunshine doesn’t make everything else that we do to them moral as a consequence.
</details>
</blockquote>
<h4 id="veganism-is-too-extreme.">“Veganism is too extreme.”</h4>
<blockquote>
<p>Should it not be viewed as extreme to inflict suffering on someone else, particularly when you can avoid doing so? Is it not extreme to fund places that exist for the sole purpose of slaughtering feeling, conscious beings? Are gas chambers not extreme? Isn’t causing animals to scream out in pain or to shake in terror an extreme thing to do?</p>
</blockquote>
<h4 id="we-can-compromise-and-just-reduce-the-amount-of-animal-products-we-eat.">“We can compromise and just reduce the amount of animal products we eat.”</h4>
<blockquote>
<p>Just because humans will always have some impact doesn’t mean that we shouldn’t aim to minimise that impact as far as possible.
While reduction is great news for the animals who will be spared, for those who are still being exploited it means nothing.</p>
</blockquote>
<h4 id="veganism-is-classist-and-privileged">“Veganism is classist and privileged”</h4>
<blockquote>
<p>Of course, being in a position where you have different food options to pick from is a privilege. But none of that invalidates the merits of veganism.
Research has shown that a whole-foods plant-based diet in high-income nations can actually cut a third off your food budget.</p>
<p>In areas where there is a genuine lack of plant-foods, meaning that someone can’t be vegan, that is a failure on a societal and food policy level to ensure people have access to food.
The only way that veganism will become more accessible, thereby allowing more people to make the change, is if those of us who can become vegan do so and further normalise it and make it more accessible and affordable through simple supply and demand.</p>
</blockquote>
<h4 id="shouldnt-we-try-and-end-all-human-suffering-before-worrying-about-animals">“Shouldn’t we try and end all human suffering before worrying about animals?”</h4>
<blockquote>
<p>Going vegan doesn’t mean we can’t tackle human suffering too, or even that doing so will be slowed down if we tackle animal suffering as well.
We don’t have to become campaigners and activists to make a difference — we just need to change how we eat and consume.</p>
</blockquote>
<h4 id="we-couldnt-feed-everyone-on-a-plant-based-diet.">“We couldn’t feed everyone on a plant-based diet.”</h4>
<blockquote>
<p>83 per cent of all farmland is used to produce animal products, yet it only provides us with 37 per cent of the protein consumed globally and 18 per cent of the calories.
A global shift to a plant-based diet would mean that we could feed every mouth on the planet and free up 76 per cent of current agricultural land.
The real question should be: ‘Can we feed every mouth on the planet if we don’t stop eating animal products?’</p>
</blockquote>
<h4 id="vegan-diets-dont-contain-a-natural-source-of-vitamin-b12">Vegan diets don’t contain a natural source of vitamin B12</h4>
<blockquote>
<p>The B12 that animals we farm get also comes from fortified foods and supplements. It makes zero sense to consume B12 filtered through the body of an animal when we could just take the supplements ourselves.</p>
</blockquote>
<h4 id="vegans-are-more-depressed">Vegans are more depressed</h4>
<blockquote>
<p>Does not eating meat cause mental health issues? Or is your mental health adversely affected by being emotionally invested in the suffering of tens of billions of animals, watching footage of them being abused, while at the same time realising that the vast majority of people in the world are paying for these things to happen to them, including your friends and family?</p>
</blockquote>
<h4 id="i-dont-know-how-to-cook">I don’t know how to cook</h4>
<blockquote>
<p>Cooking vegan meals is no more complicated or time-consuming than cooking non-vegan meals. In fact, it can often be easier, as you don’t have to worry about food poisoning from raw meat.
You can find vegan recipes for more or less every meal that you can think of these days. It is often just as simple as replacing one or two ingredients from the recipe we would normally cook anyway.</p>
</blockquote>
<h1 id="some-of-my-favorite-vegan-dishes">Some of my favorite vegan dishes</h1>
<p>When you first go vegan, it can be a challenge to build up a reasonable repertoire of dishes to cook. I wish I could provide you with some amazing advice here, but the fact is that most of the time I’m a pretty lazy cook. Many days, I will throw some tofu or tempeh in a pan together with some precut vegetables, add noodles or rice, and call it a meal. I also like to buy a pizza base in the store and throw some vegetables and (vegan) cheese on top. Or I go for a classic AVG (potato-meat-vegetable, the “standard” warm meal in Netherlands and Belgium) with some meat replacement from the store.</p>
<p>When I’m feeling slightly fancier, I like to take a recipe from a website such as <a href="https://theveganatlas.com/">The Vegan Atlas</a> or <a href="https://lovingitvegan.com/">Loving It Vegan</a> or <a href="https://veggiesociety.com/">Veggie Society</a>, which all have lots of excellent vegan recipes. Here are a couple recipes that I managed to turn into something pretty edible without too much effort:</p>
<ul>
<li><a href="https://lovingitvegan.com/vegan-steak/">Vegan steak</a> (made this for a barbecue)</li>
<li><a href="https://lovingitvegan.com/vegan-corn-fritters/">Zucchini fritters</a> (made this for a potluck)</li>
<li><a href="https://theveganatlas.com/beefy-vegan-seitan-stew-with-potatoes-carrots/">“Beefy” seitan stew</a></li>
<li><a href="https://lovingitvegan.com/jackfruit-curry/">Jackfruit curry</a></li>
<li><a href="https://lovingitvegan.com/tofu-and-eggplant-bowls/">Eggplant tofu stir fry</a></li>
<li><a href="https://lovingitvegan.com/vegan-green-curry/">Thai green curry</a></li>
<li><a href="https://veggiesociety.com/vegan-miso-noodle-soup-recipe/">Miso noodle soup</a></li>
<li><a href="https://lovingitvegan.com/vegan-cowboy-cookies/">Cowboy cookies</a></li>
<li><a href="https://lovingitvegan.com/vegan-chocolate-peanut-butter-cookies/">Chocolate peanut butter cookies</a></li>
</ul>
<h1 id="staying-healthy-as-a-vegan">Staying healthy as a vegan</h1>
<p>There is a lot of scaremongering about the health risks of a full vegan diet.
If you read the evidence, most of these risks are greatly overblown and in fact a vegan diet has a lot of health benefits.
However, especially when transitioning it can be good to pay attention to a few nutrients.
Please keep in mind that I’m not a nutritionist and it is a good idea to get advice from a professional if you have any concerns about this.
However, here are the most commonly discussed nutrients in the context of vegan diets:</p>
<ul>
<li><strong>Protein</strong>: You can easily get protein from plant sources such as beans, lentils, chickpeas, tofu, tempeh, seitan, nuts or nut butters.</li>
<li><strong>Vitamin B12</strong>: You absolutely do need to take a supplement of this as a vegan. Many vegan foods such as plant milks are also fortified with B12.</li>
<li><strong>Iron</strong>: You can get this from wholegrains, legumes, dark leafy greens, seeds and dried fruits.</li>
<li><strong>Calcium</strong>: You can get this from fortified plant milks or tofu, legumes, almonds and Brazil nuts, seeds like chia and flax, tahini, dried fruits, and oats.</li>
<li><strong>Omega-3</strong>: You can get ALA, a short-chain omega-3 fat, from plant-foods such as flaxseed, chia seeds, hemp seeds and walnuts. It’s advisable to take an algae-oil supplement to make sure you are getting a good amount of EPA and DHA.</li>
</ul>
<p>I personally take supplements for vitamin B12, vitamin D (like many people here in the Netherlands, not just vegans), omega-3, and calcium on a daily basis. When I think about all the benefits that come with a vegan diet, I think this is a very reasonable trade-off.</p>
<h1 id="further-reading-and-watching">Further reading and watching</h1>
<p>I get that just reading this one blog post will probably not convince you to go vegan all by itself. However, I do encourage you to actually sit down and make a list of the reasons why you would or would not make the transition, and see how they stack up against each other. You could also just try one of the dishes I listed above this week. Finally, if you’re still undecided but would like to read more, below are a few sources that really helped me personally on my journey:</p>
<ul>
<li>The illustrated essay <a href="https://archive.is/N4Yvf">I gave up meat and gained so much more: The delightful abundance of going vegan</a> by Marina Bolotnikova and Christine Mi (if you read just one thing on this list, let it be this one!)</li>
<li>The article <a href="https://newrepublic.com/article/185445/confessions-former-carnivore-future-vegan">Confessions of a Former Carnivore</a> by Aaron Gell</li>
<li>The video <a href="https://www.youtube.com/watch?v=eAB5w_i8orw">The Biggest Lie About Veganism</a> by David Ramms</li>
<li>The video <a href="https://www.youtube.com/watch?v=byTxzzztRBU">Every Argument Against Veganism</a> by Ed Winters</li>
<li>The artwork <a href="https://www.barbaradanielsart.com/dominion-over-man/">Dominion over Man</a> and <a href="https://www.barbaradanielsart.com/happy-farms/">Happy Farms</a> by Barbara Daniels (content warning: pretty graphic)</li>
<li>The documentary <a href="https://www.youtube.com/watch?v=PBoDQeWxQLE">Dominion</a> (content warning: very graphic)</li>
</ul>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Sat, 03 Jan 2026 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/going-vegan.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>The good places to submit your papers</title>
    <link>https://jesper.sikanda.be/posts/the-good-places-for-your-papers.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - The good places to submit your papers</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>The good places to submit your papers</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on December 19, 2025
    </p>
    <p>This week, the ACM made the monumental(ly stupid) decision to replace the
abstracts of papers on their Digital Library website by AI-written summaries.
While this did not apply to all papers, and it was only visible to “premium
members” (which includes anyone logging in from the network of a university that
has an ACM subscription), it was not just annoying but actively harmful to
science, as explained in much more detail in this <a href="https://anil.recoil.org/notes/acm-ai-recs">blog post by Anil
Madhavapeddy</a>. Because of some
significant backlash from the community, it was quickly decided to stop
presenting the AI summaries as the default view and to add a disclaimer. Still,
the fact that the people in charge at ACM decided this was a good idea in the
first place should be pretty worrying to the computer science community.</p>
<p>Unfortunately, this is not the first time that the ACM has made some
questionable decisions either. I can highly recommend reading this <a href="https://www.williamjbowman.com/blog/2025/10/03/are-the-acm-s-profits-supporting-its-mission-yet/">blog post by
William
Bowman</a>
if you want to understand more about the harmful decisions that have been made
from a profit-seeking motive over the past few years.</p>
<p>So what can we do about this? Well, since the ACM is supposed to be a
<em>community</em> of computer science researchers, it makes sense to try to argue for
the ACM to adapt its policies and improve its organization so these decisions
are made in a better (more democratic and less profit-seeking) way in the
future. However, this approach has its limitations, as was already pointed out
clearly in this <a href="https://mathstodon.xyz/@jonmsterling/111579307990734432">Mathstodon post by Jon Sterling from
2023</a>, which I will
quote here in full:</p>
<blockquote>
<p>I think it is so interesting that whenever anyone criticises ACM, someone
comes out of the woodwork to say “ACM is a democracy of its membership, if you
want to change it, vote or join a committee!”</p>
<p>We already tried that. Some of our very best researchers already serve on
these committees and are doing their best to solve these problems, but there
has been literally no change and no indication that changes are likely on many
important issues (I recognise that some things have improved). If you are
doubtful, ask yourself whether ACM is still farming out your papers’
typesetting to expensive and incompetent firms that replace your (somewhat)
accessible vector-art mathematical figures with blurry screenshots in raster
format…</p>
<p>If there were any way to resolve this through ACM’s democracy, that would have
happened already. I have too much respect for the community members serving on
the pertinent committees to conclude otherwise…</p>
<p>What is really happening is that people with legitimate complaints are being
told to “feed the beast” — there is no better way to put someone out of action
is to get them stuffed into a committee somewhere.</p>
</blockquote>
<p>A more radical approach would be to vote with our feet and move away from ACM as
the central point of organization of our community. I’m not (necessarily)
calling for a full boycott, but we should at least be aware that a better way of
publishing papers exist and support those alternatives by submitting papers to
them and reviewing for them when we are in a position to do so. To make this
process a little easier, I made a list of all the journals, conferences, and
workshops that set the right example. In particular, I believe the following
publishers are doing a great job at publishing open access papers in a way that
is affordable (or even free) and transparent to authors and readers alike:</p>
<ul>
<li><p><a href="https://www.dagstuhl.de/en/publishing">Schloss Dagstuhl</a></p></li>
<li><p><a href="https://www.episciences.org/">Episciences</a></p></li>
<li><p>The <a href="https://opa.eptcs.org/">Open Publishing Association (OPA)</a></p></li>
</ul>
<p>Besides being a publisher, Schloss Dagstuhl also runs the invaluable dblp
bibliography website, which is currently <a href="https://www.dagstuhl.de/en/dblp/donate">looking for
support</a>.
While Schloss Dagstuhl publishes papers independently, Episciences and OPA both
rely heavily on arXiv (supported by Cornell, other universities and
<a href="https://info.arxiv.org/about/donate.html">you</a>) and <a href="https://hal.science/">HAL</a>
(supported by CNRS, Inria, and INRAE).</p>
<p>So without further ado, below are the <em>good</em> places to send your papers in the
field of type theory, interactive theorem proving, and dependently typed
programming. If you are in a different subfield of computer science, I encourage
you to make your own list and publish it somewhere, I would be happy to link it
here!</p>
<h4 id="journals">Journals</h4>
<ul>
<li><a href="https://lmcs.episciences.org/">Logical Methods in Computer Science (LMCS)</a>
<ul>
<li>Published by Episciences</li>
<li>Papers can be submitted at any time</li>
</ul></li>
<li>The <a href="https://www.cambridge.org/core/journals/journal-of-functional-programming">Journal of Functional Programming</a>
<ul>
<li>(Soon to be) published by Episciences
(<a href="https://types.pl/@maxsnew/115364252561704389">source</a>)</li>
<li>Submission is currently not possible due to the transfer from Cambridge University Press to Episciences</li>
</ul></li>
<li>The <a href="https://programming-journal.org/">Programming journal</a>
<ul>
<li>Independent arXiv overlay with diamond open access (no fees for readers <em>or</em> authors)</li>
<li>Deadlines: 1 October, 1 February, and 1 June</li>
<li>Accepted papers can be presented at the <a href="https://programming-conference.org/">‹Programming› conference</a></li>
</ul></li>
</ul>
<h4 id="conferences-and-workshops">Conferences and workshops</h4>
<ul>
<li>The <a href="https://drops.dagstuhl.de/entities/conference/TYPES">TYPES post-proceedings</a>
<ul>
<li>Published by Schloss Dagstuhl in the LIPIcs series</li>
<li>Last deadline: 21 November 2025 (abstracts) / 5 December 2025 (full papers)</li>
<li>Also open to papers that were not presented at the conference</li>
</ul></li>
<li>The <a href="https://2026.ecoop.org/">ECOOP conference</a>
<ul>
<li>Published by Schloss Dagstuhl in the LIPIcs series</li>
<li>Next deadline: 27 November 2025 (round 1) / 12 February 2026 (round 2)</li>
</ul></li>
<li>The <a href="https://fscd-conference.org/">FSCD conference</a>
<ul>
<li>Published by Schloss Dagstuhl in the LIPIcs series</li>
<li>Next deadline: 23 January 2026 (abstracts) / 30 January 2026 (full papers)</li>
</ul></li>
<li>The <a href="https://www.eacsl.org/csl-conferences/">CSL conference</a>
<ul>
<li>Published by Schloss Dagstuhl in the LIPIcs series</li>
<li>Last deadline: 15 July 2025 (abstracts) / 21 July 2025 (full papers)</li>
</ul></li>
<li>The <a href="https://itp-conference.github.io/">ITP conference</a>
<ul>
<li>Published by Schloss Dagstuhl in the LIPIcs series</li>
<li>Next deadline: 12 February 2026 (abstracts) / 19 February 2026 (full papers)</li>
</ul></li>
<li>The <a href="https://coalg.org/events/calco/">CALCO conference</a>
<ul>
<li>Published by Schloss Dagstuhl in the LIPIcs series</li>
<li>Last deadline: 10 March 2025 (abstracts) / 13 March 2025 (full papers)</li>
</ul></li>
<li>The <a href="https://mfpsconf.org/">MFPS conference</a>
<ul>
<li>Published by EpiSciences in the ENTICS series</li>
<li>Next deadline: 5 March 2026</li>
</ul></li>
<li>The <a href="https://msfp-workshop.github.io/">MSFP workshop</a>
<ul>
<li>Published by OPA in the EPTCS series</li>
<li>Last deadline: 26 April 2024 (abstract) / 30 April 2024 (full paper)</li>
</ul></li>
<li>The <a href="https://lfmtp.github.io/lfmtp-page/">LFMTP workshop</a>
<ul>
<li>Published by OPA in the EPTCS series</li>
<li>Next deadline: 2 May 2026 (abstract) / 9 May 2026 (full paper)</li>
</ul></li>
<li>The <a href="https://lsfa-workshop.github.io/">LSFA workshop</a>
<ul>
<li>Published by OPA in the EPTCS series</li>
<li>Last deadline: 30 May 2025 (abstract) / 1 June 2025 (full paper)</li>
</ul></li>
<li>The <a href="https://fromsymposium.github.io/">FROM symposium</a>
<ul>
<li>Published by OPA in the EPTCS series</li>
<li>Last deadline: 22 June 2025</li>
</ul></li>
</ul>
<p>I would like to thank <a href="https://lipn.info/@mevenlennonbertrand">Meven</a>,
<a href="https://functional.cafe/@jer_gib">Jeremy</a>, and
<a href="https://mathstodon.xyz/@nmvdw">Niels</a> for their contributions to this list!</p>
<p>It was also suggested that I should add the <a href="https://etaps.org/">ETAPS</a>
conferences (ESOP, FASE, FoSSaCS, and TACAS) to this list. While they are
published by a large traditional publisher (Springer), they have a strong open
access policy and have negotiated a reasonable rate (180€ per paper) which is
fully covered by the conference registrations, so they are no direct costs for
authors other than the conference registration (which is mandatory). Notably,
SpringerLink does not include any “premium” features such as AI summaries.
However, Niels pointed me to an <a href="https://archive.is/uO6OK">interview with the CEO of
Springer</a> from January where he mentions AI as “one of
his three strategic priorities”, so I take this with a large grain of salt.
Personally, I would not hesitate to send a paper to one of the ETAPS conferences
but I don’t think they really set an example of what publishing <em>could</em> be like
the options I listed above.</p>
<p>On a personal note, curating this list was a positive way for me to deal with my frustration at AI
anti-features being added to more and more services. It feels better to focus on
examples of who is doing things <em>right</em> instead of everything that is going
<em>wrong</em>.
You might have noticed that I have not written anything on
my blog here for over a year. I do still get messages from people who got
something out of reading one of my older posts (especially the one on <a href="https://jesper.cx/posts/being-autistic.html">being
autistic</a>), for which I am really
grateful. I hope to come back to blogging more frequently soon, and perhaps even
write something about the causes of that hiatus in the next one. In the mean
time, please follow me on the <a href="https://agda.club/@jesper">Fediverse</a> for
slightly more frequent updates!</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Fri, 19 Dec 2025 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/the-good-places-for-your-papers.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>Reflective journaling prompts</title>
    <link>https://jesper.sikanda.be/posts/reflective-journaling.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Reflective journaling prompts</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Reflective journaling prompts</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on September 15, 2024
    </p>
    <p>This is a post about the practice of reflective journaling. I’m someone who likes to think about the world and myself and the relationship between the two, and writing down these thoughts makes them clearer and more concrete. However, sitting down in front of an empty page can be discouraging, and there is only so many times you can write about the feeling of sitting in front of an empty page before it gets really old. Journaling prompts are a great way to skip that part and get the ink flowing. So here is a list of prompts I’ve used over the past two years of (irregular) reflective journaling. You can easily find hundreds of prompts online (just search for `reflective journaling prompts’) and there’s nothing that makes these ones special, except that these are mine.</p>
<p>Look, it’s none of my business whether you keep a journal or not, but if you also like to journal or are open to the idea, feel free to give these a try. And if you have prompts of your own, feel free to share them with me!</p>
<ul>
<li>What are some of the things you are curious about? How can you learn more about them?</li>
<li>What does courage mean to you? What is a situation where you showed real courage?</li>
<li>What is the thing that you most need to hear in this moment?</li>
<li>How is your relationship with your creativity? Would you like to be more creative? Are there any negative thoughts you have around creativity?</li>
<li>Think of one of the elements Air, Water, Earth or Fire. What does this element represent to you? What is there to be grateful for?</li>
<li>How do you feel about being in a position of power over another person? Does it feel good or bad, or both?</li>
<li>What objects are there around you? What is their history? What do they mean to you?</li>
<li>What are the things in your life you are trying to control, and are there any that you can let go of?</li>
<li>Don’t write anything today and don’t ask yourself any questions. Instead, just draw something silly for your own eyes only.</li>
<li>Are you keeping any secrets from the people close to you? Does keeping these secrets cause more suffering than spilling them would?</li>
<li>What are the things in your life you are unhappy about? Try telling yourself that these things are actually okay the way they are. How does that feel?</li>
<li>Do you have any recurring thoughts that you are trying to suppress? What would happen if you would just give them some space and listen to them?</li>
<li>Do you have an Inner Critic who always knows exactly what you did wrong and how everything is your fault? How is your relation with them?</li>
<li>Do you have an Inner Fanboy who reminds you of all the things you did well, how much you have grown, and whose lives are better because of you? How is your relation with them?</li>
<li>Do you have an Inner Rascal who just likes to do whatever they feel like, be crazy and play pranks on people? How is your relation with them?</li>
<li>Do you have an Inner Deity who quietly observes your life and watches over you, without any judgement? How is your relation with them?</li>
<li>Do you have an Inner Artist who lives in a world of fantasy and stories and colors and magic? How is your relation with them?</li>
<li>Do you have an Inner Warrior who is determined, defiant, fierce, and uncompromising? How is your relation with them?</li>
<li>Do you have an Inner Narrator who is continuously observing your thoughts and actions and turns them into a story? How is your relation with them?</li>
<li>Are you an emotional person? How do you react when you feel strong emotions? Do you push them away, or do you embrace them?</li>
<li>What are some things in your life that you could use help with? Are there any people in your life who you could ask for help with them?</li>
<li>How has your life influenced the lives of others living now and in the future, directly or indirectly?</li>
<li>How do you have conversations with others? Do you listen and ask questions? Do you think about what the other person needs?</li>
<li>What is something you worry about often? What is the worst thing that could happen if it comes to pass?</li>
<li>Is there an opposition between having self-compassion and wanting to grow into a stronger person, or can these two exist side by side?</li>
<li>When given a choice between a conflict with someone else and a conflict with your own values, which do you usually choose?</li>
<li>What are the things you consider yourself addicted to? What is their importance to you, and what do they allow you to get away from?</li>
<li>What would you do if you were free from expectations of other people and yourself?</li>
<li>Are there any projects where perfectionism is stopping you from continuing them? How can you take one messy and imperfect step towards finishing it?</li>
<li>What is intimacy to you? Why do we need it?</li>
<li>What is your style of leadership? In what parts of your life could you show more of it?</li>
<li>Are there any things from your past you keep blaming yourself for? Can you forgive yourself for them?</li>
<li>Do you think feeling uncertain is a good or a bad thing? Why?</li>
<li>Is there anything you miss about yourself when you were young? Can you find ways to bring them back into your life?</li>
<li>How do you deal with criticism from people close to you? Do you reject it or embrace it?</li>
<li>What does optimism mean to you? Is it a blind trust that things will go well, or the courage to believe that the things we do make a difference?</li>
<li>Is there anything about yourself that you consider abnormal? Do you view these things with shame or with pride?</li>
<li>Which groups, identities, or movements do you consider yourself a part of? How do they influence the way you think about yourself?</li>
<li>Are there aspects of your life where you feel “stuck”? Do you ever feel frustration or hopelessness about them? Is there someone who you can share these feelings with?</li>
<li>What are the values that you care most about, that you want to live by, and that you want to protect?</li>
<li>When you think about your future self, do you look at them with suspicion or with trust?</li>
<li>Is there anything you are currently angry or sad about? Can you recognize the source of love at the root of these feelings?</li>
<li>How can you tell the difference between things you really want and things that society expects of you? Is it even necessary to want anything?</li>
<li>What are things you enjoy talking about with others? Do you do so?</li>
<li>How can you make others feel safe and have trust in you? How do you give them space to think and listen?</li>
<li>When was the last time you used your imagination to dream of a brighter and kinder future? Did you share that dream with anyone?</li>
<li>Be quiet and listen. What do you hear right here and now in the present moment? What does it sound like?</li>
<li>What is your number one priority in life? What concrete things can you do to make sure it does not get buried beneath the daily routine?</li>
<li>Is it true that thoughts cannot hurt people? Or are we hurting ourselves by holding on to old thoughts about ourselves? Does the same hold for positive thoughts?</li>
<li>Imagine you are in a zombie apocalypse. What are the 100 things you want to do before you turn into a zombie? (This prompt brought to you by the Zom100 anime.)</li>
<li>What are the ways in which you take care of yourself? What are some ways you do not, but wish you would?</li>
<li>How can you help people who are stuck in their assumptions to rediscover their imagination?</li>
<li>Who is your ideal partner or best friend?</li>
<li>What does it mean to exist, apart from any assumptions or judgements or goals or desires?</li>
<li>In which ways have you grown or changed over the last month? The last year? The last ten years? Since you were a child?</li>
<li>Which parts of your parents and grandparents do you recognize in yourself? Is there any trauma that they were unable to heal and have passed on to you? Can you heal it in their stead?</li>
<li>Imagine you have the opportunity to meet a wise teacher, what questions would you ask them? Imagine someone came to you with these questions, how would you answer them?</li>
<li>Do you ever stop and listen to what is going on inside you? Do you accept what you hear and feel in that moment?</li>
<li>How often do you judge things as good or bad, happy or sad, loving or hating? Do you need to?</li>
<li>Imagine yourself camping out in nature. What do you see, hear, smell, feel, and taste?</li>
<li>Think of two opposite concepts, such as life and death, or interesting and boring, or love and hate. Are they really opposites, or can you find one in the other?</li>
<li>Imagine yourself 10, 20, or 30 years in the future. How have you changed? How do you look back on yourself now?</li>
<li>Is the opposite of love hate? Or is it ignorance, indifference, or the feeling of inevitability?</li>
<li>Where do you find inspiration? What can you do to become more inspired?</li>
<li>What stories do you tell about yourself? Where did these stories come from? Are there any stories that no longer apply and you could let go of?</li>
<li>Is there anything you are afraid of telling to someone close to you? What is missing for you to allow yourself to be more vulnerable?</li>
<li>Do you have any desires that you’d rather be rid of or you judge yourself for? What happens if you suspend that judgement for a moment and instead approach the desire with curiosity?</li>
<li>Do you consider yourself a humble person? What does humility mean to you? When is humility fake and when is it real?</li>
<li>How do you decide what is the right thing to do in any given situation? Do you follow your intuition or do you follow a moral framework?</li>
<li>Are there things in your life that you enjoy doing, but not so much as the things you value most? What would it take to let go of them?</li>
<li>How would your life be different if you did not have any plans or goals or ambitions? How would you spend your time differently?</li>
<li>Which person who is no longer in your life do you miss a lot? What are the things you learned from them?</li>
<li>What are your dreams for the future? Do your dreams make you feel empowered or overwhelmed? Are there dreams that no longer serve you?</li>
<li>What are the things you feel responsible for? Are they within your sphere of influence, or outside it? Where can you make a real difference?</li>
<li>When you are feeling down, what are the things that make you feel better again? How can you make them easier to remember at moments when you need them most?</li>
<li>What makes a story different from just a list of events? Why do we tell each other stories?</li>
<li>Think of a good friend you haven’t spoken to in a while, and write them a letter. Consider whether to send them this letter, or keep it to yourself.</li>
</ul>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Sun, 15 Sep 2024 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/reflective-journaling.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>On erasure annotations and agda2hs</title>
    <link>https://jesper.sikanda.be/posts/agda2hs-erasure.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - On erasure annotations and agda2hs</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>On erasure annotations and agda2hs</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on July 30, 2024
    </p>
    <!--
<pre class="Agda"><a id="98" class="Symbol">{-#</a> <a id="102" class="Keyword">OPTIONS</a> <a id="110" class="Pragma">--sized-types</a> <a id="124" class="Pragma">--erasure</a> <a id="134" class="Symbol">#-}</a>

<a id="139" class="Keyword">module</a> <a id="146" href="agda2hs-erasure.html" class="Module">agda2hs-erasure</a> <a id="162" class="Keyword">where</a>

<a id="169" class="Keyword">open</a> <a id="174" class="Keyword">import</a> <a id="181" href="Haskell.Prelude.html" class="Module">Haskell.Prelude</a>
<a id="197" class="Keyword">open</a> <a id="202" class="Keyword">import</a> <a id="209" href="Haskell.Law.Equality.html" class="Module">Haskell.Law.Equality</a>

<a id="Name"></a><a id="231" href="agda2hs-erasure.html#231" class="Function">Name</a> <a id="236" class="Symbol">=</a> <a id="238" href="Haskell.Prim.String.html#344" class="Function">String</a>
<a id="Var"></a><a id="245" href="agda2hs-erasure.html#245" class="Function">Var</a> <a id="249" class="Symbol">:</a> <a id="251" class="Symbol">@</a><a id="252" class="Symbol">0</a> <a id="254" href="Haskell.Prim.String.html#344" class="Function">String</a> <a id="261" class="Symbol">→</a> <a id="263" class="Symbol">@</a><a id="264" class="Symbol">0</a> <a id="266" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="271" href="Haskell.Prim.String.html#344" class="Function">String</a> <a id="278" class="Symbol">→</a> <a id="280" href="Agda.Primitive.html#388" class="Primitive">Set</a>

<a id="285" class="Keyword">postulate</a> <a id="_!?_"></a><a id="295" href="agda2hs-erasure.html#295" class="Postulate Operator">_!?_</a> <a id="300" class="Symbol">:</a> <a id="302" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="307" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="309" class="Symbol">→</a> <a id="311" href="Haskell.Prim.Int.html#367" class="Datatype">Int</a> <a id="315" class="Symbol">→</a> <a id="317" href="Haskell.Prim.Maybe.html#126" class="Datatype">Maybe</a> <a id="323" href="Haskell.Prim.html#1214" class="Generalizable">a</a>

<a id="326" class="Keyword">postulate</a> <a id="⋯"></a><a id="336" href="agda2hs-erasure.html#336" class="Postulate">⋯</a> <a id="338" class="Symbol">:</a> <a id="340" href="Haskell.Prim.html#1214" class="Generalizable">a</a>
</pre>-->
<p>As I wrote in a <a href="https://jesper.cx/posts/agda2hs.html">previous blog post</a>,
<code>agda2hs</code> is a tool for producing verified and readable Haskell code by
extracting it from a (lightly annotated) Agda program. In this blog post, I will
dig a bit deeper into how <code>agda2hs</code> decides which parts of an Agda program to
compile to Haskell, and which parts to drop. In the second part, I also want to
dream a bit about how ornaments (or something like it) could help to reason in a
principled way about some of the features of <code>agda2hs</code> that currently feel
rather ad-hoc.</p>
<h1 id="erasure-annotations-in-agda2hs">Erasure annotations in <code>agda2hs</code></h1>
<p><code>agda2hs</code> relies heavily on <em>erasure annotations</em> (a.k.a. the <code>0</code> quantity from
Quantitative Type Theory) to determine which parts of an Agda program should be
preserved during compilation, and which parts are just “for show”, i.e.
enforcing some kind of invariant that is not enforced statically on the Haskell
side.</p>
<p>As an example, we can define a type of well-scoped syntax as follows:</p>
<pre class="Agda"><a id="1344" class="Keyword">data</a> <a id="Term"></a><a id="1349" href="agda2hs-erasure.html#1349" class="Datatype">Term</a> <a id="1354" class="Symbol">(@</a><a id="1356" class="Symbol">0</a> <a id="1358" href="agda2hs-erasure.html#1358" class="Bound">xs</a> <a id="1361" class="Symbol">:</a> <a id="1363" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="1368" href="agda2hs-erasure.html#231" class="Function">Name</a><a id="1372" class="Symbol">)</a> <a id="1374" class="Symbol">:</a> <a id="1376" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="1380" class="Keyword">where</a>
  <a id="Term.TVar"></a><a id="1388" href="agda2hs-erasure.html#1388" class="InductiveConstructor">TVar</a> <a id="1393" class="Symbol">:</a> <a id="1395" class="Symbol">(@</a><a id="1397" class="Symbol">0</a> <a id="1399" href="agda2hs-erasure.html#1399" class="Bound">x</a> <a id="1401" class="Symbol">:</a> <a id="1403" href="agda2hs-erasure.html#231" class="Function">Name</a><a id="1407" class="Symbol">)</a> <a id="1409" class="Symbol">→</a> <a id="1411" href="agda2hs-erasure.html#245" class="Function">Var</a> <a id="1415" href="agda2hs-erasure.html#1399" class="Bound">x</a> <a id="1417" href="agda2hs-erasure.html#1358" class="Bound">xs</a> <a id="1420" class="Symbol">→</a> <a id="1422" href="agda2hs-erasure.html#1349" class="Datatype">Term</a> <a id="1427" href="agda2hs-erasure.html#1358" class="Bound">xs</a>
  <a id="Term.TApp"></a><a id="1432" href="agda2hs-erasure.html#1432" class="InductiveConstructor">TApp</a> <a id="1437" class="Symbol">:</a> <a id="1439" href="agda2hs-erasure.html#1349" class="Datatype">Term</a> <a id="1444" href="agda2hs-erasure.html#1358" class="Bound">xs</a> <a id="1447" class="Symbol">→</a> <a id="1449" href="agda2hs-erasure.html#1349" class="Datatype">Term</a> <a id="1454" href="agda2hs-erasure.html#1358" class="Bound">xs</a> <a id="1457" class="Symbol">→</a> <a id="1459" href="agda2hs-erasure.html#1349" class="Datatype">Term</a> <a id="1464" href="agda2hs-erasure.html#1358" class="Bound">xs</a>
  <a id="Term.TLam"></a><a id="1469" href="agda2hs-erasure.html#1469" class="InductiveConstructor">TLam</a> <a id="1474" class="Symbol">:</a> <a id="1476" class="Symbol">(@</a><a id="1478" class="Symbol">0</a> <a id="1480" href="agda2hs-erasure.html#1480" class="Bound">x</a> <a id="1482" class="Symbol">:</a> <a id="1484" href="agda2hs-erasure.html#231" class="Function">Name</a><a id="1488" class="Symbol">)</a> <a id="1490" class="Symbol">→</a> <a id="1492" href="agda2hs-erasure.html#1349" class="Datatype">Term</a> <a id="1497" class="Symbol">(</a><a id="1498" href="agda2hs-erasure.html#1480" class="Bound">x</a> <a id="1500" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="1502" href="agda2hs-erasure.html#1358" class="Bound">xs</a><a id="1504" class="Symbol">)</a> <a id="1506" class="Symbol">→</a> <a id="1508" href="agda2hs-erasure.html#1349" class="Datatype">Term</a> <a id="1513" href="agda2hs-erasure.html#1358" class="Bound">xs</a>
</pre>
<p>This translates to the following Haskell code:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Term</span> <span class="ot">=</span> <span class="dt">TVar</span> <span class="dt">In</span> <span class="op">|</span> <span class="dt">TApp</span> <span class="dt">Term</span> <span class="dt">Term</span> <span class="op">|</span> <span class="dt">TLam</span> <span class="dt">Term</span></span></code></pre></div>
<p>The big advantage we get out of these (erased) indices is that we can define
functions that are guaranteed to respect the scope of terms by Agda’s type
system, which are then translated to Haskell functions operating on this bare
type of terms (which would be tricky to get right by hand). For example, a
substitution function might have type</p>
<pre class="Agda"><a id="substTop"></a><a id="1986" href="agda2hs-erasure.html#1986" class="Function">substTop</a> <a id="1995" class="Symbol">:</a> <a id="1997" class="Symbol">∀</a> <a id="1999" class="Symbol">{@</a><a id="2001" class="Symbol">0</a> <a id="2003" href="agda2hs-erasure.html#2003" class="Bound">x</a> <a id="2005" href="agda2hs-erasure.html#2005" class="Bound">xs</a><a id="2007" class="Symbol">}</a> <a id="2009" class="Symbol">→</a> <a id="2011" href="agda2hs-erasure.html#1349" class="Datatype">Term</a> <a id="2016" href="agda2hs-erasure.html#2005" class="Bound">xs</a> <a id="2019" class="Symbol">→</a> <a id="2021" href="agda2hs-erasure.html#1349" class="Datatype">Term</a> <a id="2026" class="Symbol">(</a><a id="2027" href="agda2hs-erasure.html#2003" class="Bound">x</a> <a id="2029" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="2031" href="agda2hs-erasure.html#2005" class="Bound">xs</a><a id="2033" class="Symbol">)</a> <a id="2035" class="Symbol">→</a> <a id="2037" href="agda2hs-erasure.html#1349" class="Datatype">Term</a> <a id="2042" href="agda2hs-erasure.html#2005" class="Bound">xs</a>
<a id="2045" href="agda2hs-erasure.html#1986" class="Function">substTop</a> <a id="2054" class="Symbol">=</a> <a id="2056" href="agda2hs-erasure.html#336" class="Postulate">⋯</a>
</pre>
<p>making it immediately obvious which term is substituted for which variable.</p>
<p>Using Agda’s erasure annotations for indicating which parts of the Agda program
<code>agda2hs</code> should remove during its translation is nice for several reasons:</p>
<ul>
<li><p>Agda ensures that we never accidentally use or pattern match on an argument that
doesn’t appear in the generated Haskell code.</p></li>
<li><p>We can be very precise in which parts of the Agda code should (not) appear in
the generated Haskell code, including for higher-order functions. For example,
in the definition of <code>if_then_else_</code> of <code>agda2hs</code>, the branches are provided
<em>erased</em> proofs that the boolean condition is respectively <code>True</code> or <code>False</code>.</p></li>
<li><p>Since erasure annotations are part of the Agda type system, the information
about which arguments of a type or function are erased is propagated
automatically throughout the program.</p></li>
</ul>
<p>Still, the fit is not perfect: <code>agda2hs</code> implements additional checks to ensure
that not too many arguments are marked as erased. For example, the following
datatype is perfectly valid Agda code</p>
<pre class="Agda"><a id="3144" class="Keyword">data</a> <a id="Box"></a><a id="3149" href="agda2hs-erasure.html#3149" class="Datatype">Box</a> <a id="3153" class="Symbol">(@</a><a id="3155" class="Symbol">0</a> <a id="3157" href="agda2hs-erasure.html#3157" class="Bound">a</a> <a id="3159" class="Symbol">:</a> <a id="3161" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="3164" class="Symbol">)</a> <a id="3166" class="Symbol">:</a> <a id="3168" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="3172" class="Keyword">where</a>
  <a id="Box.MkBox"></a><a id="3180" href="agda2hs-erasure.html#3180" class="InductiveConstructor">MkBox</a> <a id="3186" class="Symbol">:</a> <a id="3188" href="agda2hs-erasure.html#3157" class="Bound">a</a> <a id="3190" class="Symbol">→</a> <a id="3192" href="agda2hs-erasure.html#3149" class="Datatype">Box</a> <a id="3196" href="agda2hs-erasure.html#3157" class="Bound">a</a>
</pre>
<p>but would translate to the following Haskell code with an out-of-scope type variable:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Box</span> <span class="ot">=</span> <span class="dt">MkBox</span> a</span></code></pre></div>
<p>To avoid this problem, <code>agda2hs</code> requires that every type variable that appears
in the generated Haskell code is not marked as erased.</p>
<p>Another subtler problem pops up if we allow erased type arguments to functions:</p>
<pre class="Agda"><a id="cast"></a><a id="3550" href="agda2hs-erasure.html#3550" class="Function">cast</a> <a id="3555" class="Symbol">:</a> <a id="3557" class="Symbol">{</a><a id="3558" href="agda2hs-erasure.html#3558" class="Bound">a</a> <a id="3560" href="agda2hs-erasure.html#3560" class="Bound">b</a> <a id="3562" class="Symbol">:</a> <a id="3564" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="3567" class="Symbol">}</a> <a id="3569" class="Symbol">→</a> <a id="3571" class="Symbol">@</a><a id="3572" class="Symbol">0</a> <a id="3574" href="agda2hs-erasure.html#3558" class="Bound">a</a> <a id="3576" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="3578" href="agda2hs-erasure.html#3560" class="Bound">b</a> <a id="3580" class="Symbol">→</a> <a id="3582" href="agda2hs-erasure.html#3558" class="Bound">a</a> <a id="3584" class="Symbol">→</a> <a id="3586" href="agda2hs-erasure.html#3560" class="Bound">b</a>
<a id="3588" href="agda2hs-erasure.html#3550" class="Function">cast</a> <a id="3593" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a> <a id="3598" href="agda2hs-erasure.html#3598" class="Bound">x</a> <a id="3600" class="Symbol">=</a> <a id="3602" href="agda2hs-erasure.html#3598" class="Bound">x</a>
</pre>
<p>which translates to the ill-typed Haskell</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>cast <span class="op">:</span> a → b</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>cast x <span class="ot">=</span> x</span></code></pre></div>
<p>The way <code>agda2hs</code> prevents this second example is by requiring additionally that
no non-erased pattern variables are <em>forced</em> by pattern matching. In the
example, the pattern match on <code>refl</code> forces the (implicit) pattern variable <code>b</code>
to be equal to <code>a</code>, so the two rules together rule out this definition of
<code>cast</code>.</p>
<p>These restrictions seem to do their job, but are hardly satisfactory. The root
of the problem seems to be a mismatch between the intented use of erasure
annotations and how <code>agda2hs</code> actually uses them: erasure annotations assume
that the code is compiled to an <em>untyped</em> language and hence that all types can
be safely erased, but <code>agda2hs</code> is compiling Agda code to a <em>typed</em> language.
In other words, <code>agda2hs</code> uses erasure not to erase types, but merely to
erase <em>dependencies</em>.</p>
<p>An interesting question would thus be whether we can have an alternative version
of erasure annotations that do not assume by default that all types can be
erased. A first step would be to change the typing rule for top-level type
signatures so they cannot refer to erased things by default. But perhaps further
changes are needed too. Alternatively, it would be interesting to investigate
whether a different modality such as
<a href="https://anuyts.github.io/files/paper-reldtt.pdf">shape irrelevance</a> would be a
better fit for the purposes of <code>agda2hs</code>.</p>
<h1 id="erasing-more-than-just-arguments">Erasing more than just arguments</h1>
<p>Erasure annotations in Agda allow us to annotate arguments to functions,
top-level definitions, parameters and indices to data types, arguments to
constructors, and even specific constructors themselves. However, there are some
things that we would like to annotate in <code>agda2hs</code> that go beyond the current
capabilities of Agda. Let’s take a look at two examples.</p>
<p>Sometimes when working in a dependently typed language, we like to pair a value
of some type <code>a</code> together with a proof of a property <code>p</code> of this value. Since we
don’t want proofs to show up in our Haskell code, we mark it as erased:</p>
<pre class="Agda"><a id="5685" class="Keyword">record</a> <a id="∃"></a><a id="5692" href="agda2hs-erasure.html#5692" class="Record">∃</a> <a id="5694" class="Symbol">(</a><a id="5695" href="agda2hs-erasure.html#5695" class="Bound">a</a> <a id="5697" class="Symbol">:</a> <a id="5699" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="5702" class="Symbol">)</a> <a id="5704" class="Symbol">(@</a><a id="5706" class="Symbol">0</a> <a id="5708" href="agda2hs-erasure.html#5708" class="Bound">p</a> <a id="5710" class="Symbol">:</a> <a id="5712" href="agda2hs-erasure.html#5695" class="Bound">a</a> <a id="5714" class="Symbol">→</a> <a id="5716" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="5719" class="Symbol">)</a> <a id="5721" class="Symbol">:</a> <a id="5723" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="5727" class="Keyword">where</a>
  <a id="5735" class="Keyword">constructor</a> <a id="_⟨_⟩"></a><a id="5747" href="agda2hs-erasure.html#5747" class="InductiveConstructor Operator">_⟨_⟩</a>
  <a id="5754" class="Keyword">field</a>
    <a id="∃.value"></a><a id="5764" href="agda2hs-erasure.html#5764" class="Field">value</a>    <a id="5773" class="Symbol">:</a> <a id="5775" href="agda2hs-erasure.html#5695" class="Bound">a</a>
    <a id="5781" class="Symbol">@</a><a id="5782" class="Symbol">0</a> <a id="∃.proof"></a><a id="5784" href="agda2hs-erasure.html#5784" class="Field">proof</a> <a id="5790" class="Symbol">:</a> <a id="5792" href="agda2hs-erasure.html#5708" class="Bound">p</a> <a id="5794" href="agda2hs-erasure.html#5764" class="Field">value</a>
<a id="5800" class="Keyword">open</a> <a id="5805" href="agda2hs-erasure.html#5692" class="Module">∃</a> <a id="5807" class="Keyword">public</a>
</pre>
<p>For example, we could define the <code>Var</code> type from before as a natural number
together with a proof that looking up the element of that position results in
the given name:</p>
<pre class="Agda"><a id="5998" class="Comment">--Var : Name → List Name → Set</a>
<a id="6029" href="agda2hs-erasure.html#245" class="Function">Var</a> <a id="6033" href="agda2hs-erasure.html#6033" class="Bound">x</a> <a id="6035" href="agda2hs-erasure.html#6035" class="Bound">xs</a> <a id="6038" class="Symbol">=</a> <a id="6040" href="agda2hs-erasure.html#5692" class="Record">∃</a> <a id="6042" href="Haskell.Prim.Int.html#367" class="Datatype">Int</a> <a id="6046" class="Symbol">λ</a> <a id="6048" href="agda2hs-erasure.html#6048" class="Bound">n</a> <a id="6050" class="Symbol">→</a> <a id="6052" href="agda2hs-erasure.html#6035" class="Bound">xs</a> <a id="6055" href="agda2hs-erasure.html#295" class="Postulate Operator">!?</a> <a id="6058" href="agda2hs-erasure.html#6048" class="Bound">n</a> <a id="6060" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="6062" href="Haskell.Prim.Maybe.html#189" class="InductiveConstructor">Just</a> <a id="6067" href="agda2hs-erasure.html#6033" class="Bound">x</a>
</pre>
<p>This is also known as a refinement type from systems such as Liquid Haskell,
though Agda does not provide the same level of automation.</p>
<p>In the generated Haskell code, we would like values of this type to show up not
as having type <code>∃ a</code>, but simply as having type <code>a</code>. To make this translation
type-preserving, constructor applications <code>u ⟨ p ⟩</code> should be translated to <code>u</code>,
and <code>value x</code> should be translated to <code>x</code>. We can accomplish this with a pragma
marking <code>∃</code> as an <em>unboxed</em> record type (which is probably a bad name,
suggestions for better names are welcome):</p>
<pre class="Agda"><a id="6653" class="Symbol">{-#</a> <a id="6657" class="Keyword">COMPILE</a> <a id="6665" class="Keyword">AGDA2HS</a> <a id="6673" href="agda2hs-erasure.html#5692" class="Record">∃</a> <a id="6675" class="Pragma">unboxed</a> <a id="6683" class="Symbol">#-}</a>
</pre>
<p>The presence of unboxed types introduces an interesting prospect: we can have
(potentially many) different Agda types that are all translated to the same
Haskell type. But this also means that we can have functions that only
manipulate the “proof part” of their input but leave the value intact. For
example:</p>
<pre class="Agda"><a id="mapProof"></a><a id="7010" href="agda2hs-erasure.html#7010" class="Function">mapProof</a> <a id="7019" class="Symbol">:</a> <a id="7021" class="Symbol">∀</a> <a id="7023" class="Symbol">{@</a><a id="7025" class="Symbol">0</a> <a id="7027" href="agda2hs-erasure.html#7027" class="Bound">p</a> <a id="7029" href="agda2hs-erasure.html#7029" class="Bound">q</a> <a id="7031" class="Symbol">:</a> <a id="7033" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="7035" class="Symbol">→</a> <a id="7037" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="7040" class="Symbol">}</a>
          <a id="7052" class="Symbol">→</a> <a id="7054" class="Symbol">@</a><a id="7055" class="Symbol">0</a> <a id="7057" class="Symbol">(∀</a> <a id="7060" class="Symbol">{</a><a id="7061" href="agda2hs-erasure.html#7061" class="Bound">x</a><a id="7062" class="Symbol">}</a> <a id="7064" class="Symbol">→</a> <a id="7066" href="agda2hs-erasure.html#7027" class="Bound">p</a> <a id="7068" href="agda2hs-erasure.html#7061" class="Bound">x</a> <a id="7070" class="Symbol">→</a> <a id="7072" href="agda2hs-erasure.html#7029" class="Bound">q</a> <a id="7074" href="agda2hs-erasure.html#7061" class="Bound">x</a><a id="7075" class="Symbol">)</a>
          <a id="7087" class="Symbol">→</a> <a id="7089" href="agda2hs-erasure.html#5692" class="Record">∃</a> <a id="7091" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="7093" href="agda2hs-erasure.html#7027" class="Bound">p</a> <a id="7095" class="Symbol">→</a> <a id="7097" href="agda2hs-erasure.html#5692" class="Record">∃</a> <a id="7099" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="7101" href="agda2hs-erasure.html#7029" class="Bound">q</a>
<a id="7103" href="agda2hs-erasure.html#7010" class="Function">mapProof</a> <a id="7112" href="agda2hs-erasure.html#7112" class="Bound">f</a> <a id="7114" class="Symbol">(</a><a id="7115" href="agda2hs-erasure.html#7115" class="Bound">x</a> <a id="7117" href="agda2hs-erasure.html#5747" class="InductiveConstructor Operator">⟨</a> <a id="7119" href="agda2hs-erasure.html#7119" class="Bound">p</a> <a id="7121" href="agda2hs-erasure.html#5747" class="InductiveConstructor Operator">⟩</a><a id="7122" class="Symbol">)</a> <a id="7124" class="Symbol">=</a> <a id="7126" href="agda2hs-erasure.html#7115" class="Bound">x</a> <a id="7128" href="agda2hs-erasure.html#5747" class="InductiveConstructor Operator">⟨</a> <a id="7130" href="agda2hs-erasure.html#7112" class="Bound">f</a> <a id="7132" href="agda2hs-erasure.html#7119" class="Bound">p</a> <a id="7134" href="agda2hs-erasure.html#5747" class="InductiveConstructor Operator">⟩</a>
</pre>
<p>When compiled normally, this produces the rather boring definition
<code>mapProof x = x</code>. What’s worse, sometimes functions like this need to do some
pattern matching purely to put proofs in the right places. For example,
we can attach a proof to a value nested in a <code>Maybe</code> as follows:</p>
<pre class="Agda"><a id="refineMaybe"></a><a id="7432" href="agda2hs-erasure.html#7432" class="Function">refineMaybe</a> <a id="7444" class="Symbol">:</a> <a id="7446" class="Symbol">∀</a> <a id="7448" class="Symbol">{@</a><a id="7450" class="Symbol">0</a> <a id="7452" href="agda2hs-erasure.html#7452" class="Bound">p</a> <a id="7454" class="Symbol">:</a> <a id="7456" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="7458" class="Symbol">→</a> <a id="7460" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="7463" class="Symbol">}</a>
            <a id="7477" class="Symbol">→</a> <a id="7479" class="Symbol">(</a><a id="7480" href="agda2hs-erasure.html#7480" class="Bound">mx</a> <a id="7483" class="Symbol">:</a> <a id="7485" href="Haskell.Prim.Maybe.html#126" class="Datatype">Maybe</a> <a id="7491" href="Haskell.Prim.html#1214" class="Generalizable">a</a><a id="7492" class="Symbol">)</a>
            <a id="7506" class="Symbol">→</a> <a id="7508" class="Symbol">@</a><a id="7509" class="Symbol">0</a> <a id="7511" class="Symbol">(∀</a> <a id="7514" class="Symbol">{</a><a id="7515" href="agda2hs-erasure.html#7515" class="Bound">x</a><a id="7516" class="Symbol">}</a> <a id="7518" class="Symbol">→</a> <a id="7520" href="agda2hs-erasure.html#7480" class="Bound">mx</a> <a id="7523" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="7525" href="Haskell.Prim.Maybe.html#189" class="InductiveConstructor">Just</a> <a id="7530" href="agda2hs-erasure.html#7515" class="Bound">x</a> <a id="7532" class="Symbol">→</a> <a id="7534" href="agda2hs-erasure.html#7452" class="Bound">p</a> <a id="7536" href="agda2hs-erasure.html#7515" class="Bound">x</a><a id="7537" class="Symbol">)</a>
            <a id="7551" class="Symbol">→</a> <a id="7553" href="Haskell.Prim.Maybe.html#126" class="Datatype">Maybe</a> <a id="7559" class="Symbol">(</a><a id="7560" href="agda2hs-erasure.html#5692" class="Record">∃</a> <a id="7562" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="7564" href="agda2hs-erasure.html#7452" class="Bound">p</a><a id="7565" class="Symbol">)</a>
<a id="7567" href="agda2hs-erasure.html#7432" class="Function">refineMaybe</a> <a id="7579" href="Haskell.Prim.Maybe.html#169" class="InductiveConstructor">Nothing</a> <a id="7587" href="agda2hs-erasure.html#7587" class="Bound">f</a> <a id="7589" class="Symbol">=</a> <a id="7591" href="Haskell.Prim.Maybe.html#169" class="InductiveConstructor">Nothing</a>
<a id="7599" href="agda2hs-erasure.html#7432" class="Function">refineMaybe</a> <a id="7611" class="Symbol">(</a><a id="7612" href="Haskell.Prim.Maybe.html#189" class="InductiveConstructor">Just</a> <a id="7617" href="agda2hs-erasure.html#7617" class="Bound">x</a><a id="7618" class="Symbol">)</a> <a id="7620" href="agda2hs-erasure.html#7620" class="Bound">f</a> <a id="7622" class="Symbol">=</a> <a id="7624" href="Haskell.Prim.Maybe.html#189" class="InductiveConstructor">Just</a> <a id="7629" class="Symbol">(</a><a id="7630" href="agda2hs-erasure.html#7617" class="Bound">x</a> <a id="7632" href="agda2hs-erasure.html#5747" class="InductiveConstructor Operator">⟨</a> <a id="7634" href="agda2hs-erasure.html#7620" class="Bound">f</a> <a id="7636" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a> <a id="7641" href="agda2hs-erasure.html#5747" class="InductiveConstructor Operator">⟩</a><a id="7642" class="Symbol">)</a>
</pre>
<p>This compiles to the rather unfortunate Haskell</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">refineMaybe ::</span> <span class="dt">Maybe</span> a → <span class="dt">Maybe</span> a</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>refineMaybe <span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>refineMaybe (<span class="dt">Just</span> x) <span class="ot">=</span> <span class="dt">Just</span> x</span></code></pre></div>
<p>To avoid having these identity functions showing up in the Haskell code,
<code>agda2hs</code> allows you to mark a function as being “transparent”:</p>
<pre class="Agda"><a id="7949" class="Symbol">{-#</a> <a id="7953" class="Keyword">COMPILE</a> <a id="7961" class="Keyword">AGDA2HS</a> <a id="7969" href="agda2hs-erasure.html#7010" class="Function">mapProof</a> <a id="7978" class="Pragma">transparent</a> <a id="7990" class="Symbol">#-}</a>
<a id="7994" class="Symbol">{-#</a> <a id="7998" class="Keyword">COMPILE</a> <a id="8006" class="Keyword">AGDA2HS</a> <a id="8014" href="agda2hs-erasure.html#7432" class="Function">refineMaybe</a> <a id="8026" class="Pragma">transparent</a> <a id="8038" class="Symbol">#-}</a>
</pre>
<p>When checking a transparent function, <code>agda2hs</code> checks that it takes exactly one
(non-erased) argument and that each clause returns this argument unchanged
(after erasure). It then does not generate any Haskell code for this function,
but instead replaces each application of this transparent function by its
argument (and each lone appearance by <code>id</code>).</p>
<p>In my biased experience, unboxed record types and transparent functions are both
very useful features of <code>agda2hs</code>, and we use them extensively in the
implementation of <a href="https://github.com/jespercockx/agda-core/">Agda Core</a>.
However, they also feel like ad-hoc fixes to a deeper problem. A more
fundamental solution would be to introduce a notion of
<a href="https://doi.org/10.1017/S0956796816000356">ornaments</a> to the language, and
provide a mechanism to identify functions that only modify the “data-logic” of
an argument but preserve the “data-structure”.</p>
<p>I am obviously speculating here, but I believe - at least for the purposes of
<code>agda2hs</code> - ornaments would be at their most useful if they could also be
integrated at the type level. Concretely, the type system should be aware of the
<em>structure</em> of each type, and for each function whether it modifies the
structure or just the logical parts (i.e. whether or not it is the identity
function after erasing all proofs). How such a type system would work
concretely, I leave as an exercise to the reader (or perhaps as a topic for a
future blog post).</p>
<p>As always, feel free to send comments on the
<a href="https://agda.zulipchat.com">Agda Zulip</a>, to
<a href="https://agda.club/@jesper"><span class="citation" data-cites="jesper">@jesper</span><span class="citation" data-cites="agda.club">@agda.club</span></a> via any Fediverse portal, or
email me at <a href="mailto:jesper@sikanda.be">jesper@sikanda.be</a>.</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Tue, 30 Jul 2024 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/agda2hs-erasure.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>Functional Programming in the Netherlands</title>
    <link>https://jesper.sikanda.be/posts/fp-in-nl.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Functional Programming in the Netherlands</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Functional Programming in the Netherlands</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on July 17, 2024
    </p>
    <p>Back in January of this year, I had the honor of hosting the <a href="https://www.tudelft.nl/fpday-2024-1">`FP Dag’</a> – also known as the Dutch Functional Programming Day – here in Delft. Apart from several entertaining and thought-provoking talks, we also had a discussion around functional programming in education. During this discussion, I gathered input from the participants on four questions:</p>
<ol type="1">
<li>What courses about functional programming are we teaching in the Netherlands?</li>
<li>Which concepts are we teaching in these courses?</li>
<li>Which concepts should we be teaching (more)?</li>
<li>How could our FP education be improved?</li>
</ol>
<p>Recently I stumbled upon my notes from that meeting and thought it would be interesting to share them, so here you go.</p>
<h2 id="what-fp-courses-are-we-teaching">What FP courses are we teaching?</h2>
<p>Here is a list of all the courses that people mentioned, plus a few more that I found afterwards. I only included courses for which I could find some evidence that they actually exist, like a course description. Universities make basic information frustratingly hard to find, so I might have missed some.</p>
<p><strong>TU Delft</strong></p>
<ul>
<li><a href="https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=67569">Concepts of Programming Languages</a> (2nd year, using Scala)</li>
<li><a href="https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=64462">Functional Programming</a> (3rd year, using Haskell &amp; Agda)</li>
<li><a href="https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=70107">Formal Reasoning about Software</a> (MSc, using Coq)</li>
<li><a href="https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=70133">Advanced Functional Programming</a> (MSc, using Haskell)</li>
</ul>
<p><strong>Radboud Universiteit</strong></p>
<ul>
<li><a href="https://www.ru.nl/courseguides/science/vm/osirislinks/ipi/nwi-ipi004/">Logic and applications</a> (1st year, using Coq)</li>
<li><a href="https://www.ru.nl/courseguides/science/vm/osirislinks/ibc/nwi-ibc040/">Functional Programming</a> (2nd year, using Haskell)</li>
<li><a href="https://www.ru.nl/courseguides/science/vm/osirislinks/imc/nwi-imc010/">Type Theory and Coq</a> (MSc, using Coq)</li>
<li><a href="https://www.ru.nl/courseguides/science/vm/osirislinks/imc/nwi-imc060/">Program Verification with types and logic</a> (MSc, using Coq)</li>
</ul>
<p><strong>University of Groningen</strong></p>
<ul>
<li><a href="https://ocasys.rug.nl/current/catalog/course/WBCS002-05">Functional Programming</a> (2nd year, using Haskell)</li>
</ul>
<p><strong>TU Eindhoven</strong></p>
<ul>
<li><a href="https://www.win.tue.nl/~wstomv/edu/2iph0/">Functional Programming</a> (3rd year, using Haskell)</li>
<li><a href="https://www.win.tue.nl/~wstomv/edu/2imp05-afp/index.html">Capita selecta Advanced Functional Programming</a> (MSc, using Haskell)</li>
</ul>
<p><strong>Universiteit Twente</strong></p>
<ul>
<li><a href="https://utwente.osiris-student.nl/onderwijscatalogus/extern/cursus?cursuscode=202200191&amp;collegejaar=2023&amp;taal=en">Functional Programming</a> (3rd year, using Haskell)</li>
</ul>
<p><strong>Utrecht University</strong></p>
<ul>
<li><a href="https://osiris-student.uu.nl/onderwijscatalogus/extern/cursus?cursuscode=INFOFP&amp;taal=nl&amp;collegejaar=huidig">Functioneel Programmeren</a> (2nd year, using Haskell)</li>
<li><a href="https://osiris-student.uu.nl/onderwijscatalogus/extern/cursus?cursuscode=INFOB3CC&amp;taal=nl&amp;collegejaar=huidig">Concurrency</a> (2nd year, using Haskell)</li>
<li><a href="https://osiris-student.uu.nl/onderwijscatalogus/extern/cursus?cursuscode=INFOB3TC&amp;taal=nl&amp;collegejaar=huidig">Talen en compilers</a> (3rd year, using Haskell)</li>
<li><a href="https://ics.uu.nl/docs/vakken/afp/">Advanced Functional Programming</a> (MSc, using Haskell and Agda)</li>
</ul>
<p><strong>Universiteit van Amsterdam</strong></p>
<ul>
<li><a href="https://coursecatalogue.uva.nl/xmlpages/page/2024-2025-en/search-course/course/119745">Theory of functional programming</a></li>
<li><a href="https://coursecatalogue.uva.nl/xmlpages/page/2024-2025-en/search-course/course/119770">Functional Programming</a> (using Haskell)</li>
</ul>
<p><strong>Vrije Universiteit Amsterdam</strong></p>
<ul>
<li><a href="https://studiegids.vu.nl/EN/courses/2024-2025/XB_0019#/">Object-Oriented and Functional Programming</a> (2nd year, using Scala)</li>
<li><a href="https://studiegids.vu.nl/EN/courses/2024-2025/X_401011#/">Equational programming</a> (3rd year, using Haskell)</li>
<li><a href="https://studiegids.vu.nl/EN/courses/2024-2025/XM_0167#/">Logical Verification</a> (MSc, using Lean)</li>
</ul>
<p><strong>Open University</strong></p>
<ul>
<li><a href="https://www.ou.nl/en/-/ib2702_concepten-van-programmeertalen">Concepten van programmeertalen</a> (2nd year, using Haskell)</li>
<li><a href="https://www.ou.nl/en/-/IB1602_Functioneel-programmeren">Functioneel programmeren</a> (2nd year, using Haskell)</li>
</ul>
<p>The main languages used seem to be Haskell and Scala, with a mix of Coq, Lean, and Agda for more verification-focused courses.</p>
<h2 id="which-concepts-are-we-teaching">Which concepts are we teaching?</h2>
<p><strong>Basic FP techniques</strong></p>
<ul>
<li>Lambda calculus</li>
<li>Referential transparency / purity / immutability</li>
<li>Recursion</li>
<li>Currying and uncurrying</li>
<li>Higher-order functions</li>
<li>Static types and type inference</li>
<li>Parametric polymorphism</li>
<li>Algebraic datatypes and pattern matching</li>
<li>Type classes</li>
<li>Functors and monads</li>
<li>Laziness</li>
<li>Property-based testing (QuickCheck)</li>
</ul>
<p><strong>Advanced FP techniques</strong></p>
<ul>
<li>Datatype-generic programming</li>
<li>Embedded domain-specific languages</li>
<li>Task-oriented programming</li>
<li>Uniqueness types</li>
<li>Streaming and lazy IO</li>
<li>Lenses</li>
<li>Continuation-passing style</li>
<li>Array programming</li>
<li>Metaprogramming</li>
<li>Fusion</li>
</ul>
<p><strong>Program verification</strong></p>
<ul>
<li>Dependent types</li>
<li>Curry-Howard correspondence</li>
<li>Equational reasoning</li>
</ul>
<p><strong>Programming language theory related to functional programming</strong></p>
<ul>
<li>Parser combinators and generators</li>
<li>Homomorphisms</li>
<li>Folds and algebras / recursion schemes</li>
<li>Initial and final algebras</li>
<li>Lambda encodings of data</li>
<li>Lambda encodings of objects</li>
<li>Category theory</li>
<li>Combining static and dynamic typing</li>
</ul>
<h2 id="what-concepts-should-we-be-teaching-more">What concepts should we be teaching (more)?</h2>
<ul>
<li>Property-based testing</li>
<li>Generic programming</li>
<li>Continuation-passing style</li>
<li>Effect systems and free monads</li>
<li>Domain modeling using types</li>
<li>Reasoning about performance</li>
<li>Interacting with databases</li>
<li>Build systems</li>
<li>Concurrency</li>
<li>Functional reactive programming</li>
<li>Combining imperative and functional systems</li>
</ul>
<p>Out of these, I’m especially interested to teach effect systems, domain modelling, concurrency, and FRP (and learn more about those topics myself!).</p>
<h2 id="how-could-functional-programming-education-be-improved">How could functional programming education be improved?</h2>
<ul>
<li>Easier installation of compilers and IDEs on university PCs</li>
<li>Better error messages</li>
<li>Better tools for automatic grading and feedback</li>
<li>Sharing curricula, lecture notes, exercises, …</li>
<li>Having more use cases from industry</li>
</ul>
<p>So there you have it: a crowdsourced overview of some things we are teaching and some more things we could be teaching. I don’t have a proper conclusion, but I hope this will be interesting and useful for people studying and teaching functional programming around the world. It goes without saying that I think teaching functional programming is great and we should be doing even more of it! Speaking of which, I certainly got some inspiration for my new course on <a href="https://studiegids.tudelft.nl/a101_displayCourse.do?course_id=70133">Advanced Functional Programming</a> which I will teach for the first time in Q4 of the upcoming academic year.</p>
<p>If you have your own ideas or additions, let’s discuss on the <a href="https://agda.club/@jesper">Fediverse</a>, or feel free to send me an <a href="mailto:j.g.h.cockx@tudelft.nl">email</a>!</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Wed, 17 Jul 2024 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/fp-in-nl.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>A love letter to TTRPGs</title>
    <link>https://jesper.sikanda.be/posts/love-letter-to-ttrpgs.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - A love letter to TTRPGs</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>A love letter to TTRPGs</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on June 30, 2024
    </p>
    <p>While I mentioned my passion for tabletop role-playing games (TTRPGs) a <a href="https://jesper.cx/posts/being-autistic.html">few</a> <a href="https://jesper.cx/posts/ten-thinkers.html">times</a> before on this blog, I never dedicated a proper post to them. Let’s fix that!</p>
<p>In their essence, tabletop role-playing games are a kind of game where you and a few friends sit around a table and tell a story together. Traditionally, each player except for one embodies a single main character of the story, while one player (variously called the Game Master, Dungeon Master, Referee, Storyteller, Master of Ceremonies, or many other things) takes the role of all other characters and the world. The rules of the game help the players to create their characters and the game master to create the world.</p>
<p>Much of the actual game happens through a conversation between the players, describing or enacting how their characters respond to the situation they are in. The rules describe how to handle uncertain situations that can come up in the game, such as sneaking past a guard, piloting a spaceship, banishing a ghost, swinging a sword at an orc, or guessing a person’s secret feelings. However, unlike a typical board game, many things that happen in the story never require any of the game’s rules!</p>
<p>Why do I believe that TTRPGs are such a great and unique way to spend your time? Why would you play one, instead of - say - watching a series or going out for a beer? There are endless possible reasons, but here are my main ones:</p>
<ul>
<li>To have an excuse to gather with friends regularly and do something fun together.</li>
<li>To immerse yourself in the game world and imagine how it would be to live there.</li>
<li>To exercise your creativity by coming up with characters, places, and stories.</li>
<li>To explore what it would be like to be a different person living in different circumstances.</li>
<li>To practice skills such as problem solving, conflict resolution, organization, and planning in a group.</li>
<li>To have fun exploring game mechanics, how they interact, and how to optimize them for a specific goal.</li>
<li>To collect new game books full of beautiful art and innovative mechanics.</li>
<li>To use the set of abstractions that make up a game to look at the world in a new way.</li>
</ul>
<p>It’s hard to imagine another hobby that combines all of these aspects! In this world that sometimes feels like it’s nothing but gloom and doom, I feel there’s something special about a group of friends sitting around a table using their shared imaginations to come up with new worlds and stories.</p>
<p>In case you are curious or even eager to get started playing, here are a couple of games I can recommend:</p>
<ul>
<li><a href="https://www.risusiverse.com/">Risus</a>, a very short and simple RPG that you can get for free. It’s a universal system, which means it works for any kind of setting or story. Also, it has stick figures.</li>
<li><a href="https://www.adventure.game/">Quest</a>, the game that you’d imagine Dungeons &amp; Dragons to be if you never played it. You create fantasy characters, go on heroic quests, and roll a twenty-sided die. It pays a lot of attention to accessibility, so it’s perfect for first-time players and game masters.</li>
<li><a href="https://freeleaguepublishing.com/games/tales-from-the-loop-rpg/">Tales from the Loop</a>, a game set in an alternate history ‘80 filled with strange technologies, where you play as teenagers trying to solve mysteries while dealing with the ruts of everyday life. Especially recommended for fans of the TV series ’Stranger Things’ and ‘Dark’, and ’80 vibes more generally.</li>
<li><a href="https://magpiegames.com/pages/avatarrpg">Avatar Legends</a>, the official game of Avatar: The Last Airbender and The Legend of Korra, where you play as young heroes trying to save the world while struggling with their principles and feelings. It’s unique in that the story revolves completely around the characters and their motivations rather than being made up by the game master!</li>
<li><a href="https://possumcreekgames.com/pages/wanderhome">Wanderhome</a>, a peaceful game where you play as traveling animal-folk visiting different places as the seasons change. More than any of the games above, this one is pushing the definition of what a “game” even is. It is a GM-less game, so players have shared responsibility to embody other characters and the world itself. It challenges you to think about what kind of stories we tell each other, and what impact they have. It is beautiful and profound.</li>
</ul>
<p>Of course this list heavily reflects my personal tastes, and you might enjoy something grittier such as <a href="https://morkborg.com/">Mörk Borg</a>, something more futuristic such as <a href="https://www.drivethrurpg.com/en/product/198681/scum-and-villainy">Scum and Villainy</a>, or something more <em>gay</em> such as <a href="https://www.drivethrurpg.com/en/product/348096/thirsty-sword-lesbians">Thirsty Sword Lesbians</a>.</p>
<p>Note that I am not recommending what’s definitely the most well-known TTRPG, which is Dungeons and Dragons (D&amp;D). One reason is that it already gets plenty of attention. But another reason is that compared to all the games above (except <em>maybe</em> Avatar Legends) it is just way <em>way</em> more complicated and time-consuming. I enjoyed playing D&amp;D for many years, but now I have counted enough hit dice, 5-foot squares, spell slots, attribute points, and saving throws for a lifetime. I find that by having simpler rules, other games actually make more room for the parts that I enjoy the most: playing characters and telling stories. Still, there is plenty of fun to be had with it, so if a D&amp;D group is all you can find then just go for it!</p>
<p>Finally, let me close this post with an open invitation to play a TTRPG together. Playing a game together with someone you haven’t played with before is always a great way to be surprised by new ideas and perspectives. I would be honored if you’d join me on an adventure! Just reach out to me in person, over <a href="mailto:jesper@sikanda.be">email</a>, or over on Mastodon at <a href="https://dice.camp/@dregntael">dice.camp</a>.</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Sun, 30 Jun 2024 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/love-letter-to-ttrpgs.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>Agda Core: The Dream and the Reality</title>
    <link>https://jesper.sikanda.be/posts/agda-core.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Agda Core: The Dream and the Reality</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Agda Core: The Dream and the Reality</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on May 11, 2024
    </p>
    <!--
<pre class="Agda"><a id="98" class="Symbol">{-#</a> <a id="102" class="Keyword">OPTIONS</a> <a id="110" class="Pragma">--erasure</a> <a id="120" class="Symbol">#-}</a>

<a id="125" class="Keyword">module</a> <a id="132" href="agda-core.html" class="Module">agda-core</a> <a id="142" class="Keyword">where</a>

<a id="149" class="Keyword">open</a> <a id="154" class="Keyword">import</a> <a id="161" href="Haskell.Prelude.html" class="Module">Haskell.Prelude</a>
</pre>-->
<p>One important purpose of a type system
(and especially a <em>dependent</em> type system)
is to increase the trustworthiness of the objects the types are describing,
whether those objects are programs or proofs.
They do so by making the specification (or part of it) explicit
and statically checking that the specification is implemented according to the rules.
But then the question arises:
how far can we trust the correctness of the type system itself?
And what does it even mean for the type system to be correct,
i.e. what is its specification?</p>
<p>With each line added to the implementation of Agda and each new bug discovered,
this question becomes more and more relevant.
The traditional answer to this question for most proof assistants
as well as some programming languages (such as Haskell)
is to define a <em>core language</em> that is much smaller
and more trustworthy than the surface language implementation,
and to translate the surface language into this core
through a process called <em>elaboration</em>.
However, this has not been the case for Agda,
which instead has been defined only by its implementation.
This has caused people to rightfully ask questions
about what is precisely the type theory that Agda implements
and how all of its features fit in to it.</p>
<p>This blog post is about <strong>Agda Core</strong>, a project to build a
a formally specified core language for (a reasonable subset of) Agda
together with a reference implementation of a type checker for it.
If you have been following my work,
you might know that I have been working on this project on and off for the past few years,
yet the current version is still very much a work in progress.
Hence, in the second part of this post, I
will dive into a few examples of some of the more unexpected and interesting
obstacles we encountered while trying to turn Agda Core from a dream into reality.</p>
<h1 id="agda-core-the-dream">Agda Core: The Dream</h1>
<p>Since Agda does not already have a core language,
we have the opportunity to design one from scratch!
In my <a href="https://jesper.cx/posts/why-not-a-core-language.html">previous post</a> on
the topic of core languages, I went deeper into the reasons for wanting a core
language. Summarizing briefly, the main reasons are:</p>
<ul>
<li>To reduce the trusted code base</li>
<li>To implement independent checkers</li>
<li>To enable meta-theoretic study</li>
<li>To decouple surface syntax from the internal language</li>
<li>To use as a basis for meta-programming</li>
<li>To use as a basis for exporting programs and proofs</li>
</ul>
<p>From these six reasons, we can derive the main criteria our core language should satisfy:</p>
<ol type="1">
<li>It should have a <strong>formal specification</strong> of its static and dynamic semantics, so we can study it and implement independent checkers.</li>
<li>It should have a <strong>small type checker</strong> that can easily be verified to follow the specification, so we can use it as the main trusted component of a larger system.</li>
<li>It should <strong>support all features</strong> of the surface language, either directly or through elaboration, so that we can use it effectively for meta-programming and exporting proofs.</li>
</ol>
<p>Apart from these three, one final goal I have is to implement everything in Agda itself.
Agda is well suited for this kind of project that mixes specification and implementation.
Doing everything in Agda also is an excellent stress test for Agda itself,
and makes the end result more accessible to Agda users to read.
Also, Agda is just a nice language.</p>
<p>Having set all our goals and having picked an implementation language,
we can start implementing a very basic version of Agda Core!
For now, we will leave out most of Agda’s interesting/crazy features
and focus on the very basics: a dependently typed lambda calculus
with a universe hierarchy, data types, and pattern matching.
The main components we need are the following:</p>
<ul>
<li>A definition of the <a href="https://github.com/jespercockx/agda-core/blob/main/src/Agda/Core/Syntax.agda"><em>syntax</em></a>
for expressions and declarations of data types and functions.</li>
<li>An executable specification of
<a href="https://github.com/jespercockx/agda-core/blob/main/src/Agda/Core/Reduce.agda"><em>reduction</em></a>.</li>
<li>A specification of the rules for
<a href="https://github.com/jespercockx/agda-core/blob/main/src/Agda/Core/Typing.agda"><em>typing</em></a>
and <a href="https://github.com/jespercockx/agda-core/blob/main/src/Agda/Core/Conversion.agda"><em>conversion</em></a>.</li>
<li>An implementation of
<a href="https://github.com/jespercockx/agda-core/blob/main/src/Agda/Core/Typechecker.agda">type checking</a>
and <a href="https://github.com/jespercockx/agda-core/blob/main/src/Agda/Core/Converter.agda">conversion checking</a>
that produces <em>evidence</em> that the output is well-typed according to the rules as specified.</li>
</ul>
<p>The final bit here is really crucial:
because we have a formal specification of the typing rules
and the type checker outputs evidence of well-typedness,
we do not need to worry about bugs in the type checker but only in the typing rules themselves.
As the authors of the latest paper on <a href="https://metacoq.github.io/">MetaCoq</a> say:
<em>we move from a Trusted Code Base (TCB) to a Trusted Theory Base (TTB) paradigm</em>.
This is really cool and more people should be following this paradigm.
Apart from MetaCoq, the only other place where I’ve seen it is in the <a href="https://cakeml.org/">CakeML</a> project.</p>
<p>This is a good point to talk about MetaCoq, since the comparison will inevitably come up.
While some of the goals of MetaCoq and Agda Core are the same,
they are really quite different in scope.
Unlike MetaCoq, Agda Core is (currently) not meant to do formal proofs of metatheoretic properties
such as confluence, subject reduction, strong normalization, canonicity, or consistency.
Rather, the goal is to be ‘merely’ a formal specification of a possible core language
together with a correct-by-construction type checker for it.
The reason for this is simple: I was the only person working on Agda Core
(recently I started getting help from my two PhD students)
and I still want to work on other Agda-related projects, too.
Meanwhile, MetaCoq is a long-term project with quite a few very smart people working on it.
As you’ll see in the second half of this post,
even with this somewhat smaller scope there are still plenty of interesting challenges to figure out!</p>
<p>The final thing we need is a way to take our type checker
and actually <em>compile</em> and <em>run</em> it
so we can use it for example to double-check the output of the main Agda type checker.
Luckily (and in contrast to popular belief) it <em>is</em> possible to compile and run Agda programs.
The standard way to do this would be to use Agda’s built-in GHC backend.
Another option - which is the one I decided on - is to use <a href="https://github.com/agda/agda2hs"><code>agda2hs</code></a>,
an alternative backend that produces much more readable Haskell code that is guaranteed to contain no <code>unsafeCoerce</code>s.
In return, it requires you to write your Agda code in a Haskell-like style,
and in particular use <a href="https://agda.readthedocs.io/en/v2.6.4.3/language/runtime-irrelevance.html">erasure annotations</a>
to make sure no dependent types end up in the compiled code.
Erasure annotations play a similar role to <code>Prop</code> in Rocq:
they allow you to be explicit about which parts of your Agda program
are needed at runtime, and which parts are ‘just’ for ensuring correctness.
In Agda Core, erasure annotations are applied liberally to scoping and typing information.</p>
<h1 id="agda-core-the-reality">Agda Core: The Reality</h1>
<p>When I started working on Agda Core,
I had a plan very similar to the one outlined above
(minus the <code>agda2hs</code> part, which did not yet exist).
In my folly, I thought I would be able to finish a minimal bare-bones version of the whole pipeline relatively quickly.
However, actually implementing Agda Core turned out to be far more challenging than I expected.
One big reason for this was that I had just started in Delft,
and saw my research time roughly cut in half compared to my PhD and postdoc years.
While I might write more about that in another blog post,
here I would like to focus on the more technical challenges:
those related to the <strong>design</strong> of <code>agda2hs</code>
as well as those caused by the <strong>infrastructure</strong> we rely on.
Let us dive into some details.</p>
<h2 id="design-challenge-scoping-of-variables-and-defined-symbols">Design challenge: Scoping of variables and defined symbols</h2>
<p>In Agda’s surface syntax, there are various kinds of symbols that use the same namespace:
variables, functions, datatypes, constructors, record fields, and postulates.
Internally, variables are represented as de Bruijn indices,
while top-level symbols are represented as globally unique names.
We could certainly use the same choice for Agda Core,
but as we are doing this in Agda
there is also the option of defining a well-scoped syntax.
In fact there are so many options that a while back I wrote a
<a href="https://jesper.cx/posts/1001-syntax-representations.html">blog post</a>
to get a better understanding for myself.</p>
<p>After writing this blog post,
I ended up writing my own library for representing scopes and related concepts
based on the primitive notion of proof-relevant separation -
see my <a href="https://jesper.cx/files/scopes.pdf">TYPES ’23 abstract</a> for some details
or the <a href="https://github.com/jespercockx/scope/">source code</a> for many more details.
While I am reasonably happy with this library,
this is definitely one part that took a <em>lot</em> of time
and in hindsight a much simpler solution
(e.g. simply representing scopes as lists of names)
would have been good enough for a first prototype.</p>
<h2 id="design-challenge-representing-case-trees">Design challenge: representing case trees</h2>
<p>One of Agda’s most important and characteristic features
is its support for dependent pattern matching.
To add support for it to Agda Core,
we need to choose which stage of the elaboration process to adopt:</p>
<ul>
<li><p>The direct representation of definitions as a list of clauses is the most direct,
but has very complicated typing rules and does not naturally allow for enforcing completeness.
So it is not well suited for a core language.</p></li>
<li><p>On the other end of the spectrum are the <em>eliminators</em> associated to each datatype.
While theoretically elegant and minimal,
representing full dependent pattern matching in terms of them
takes a lot of work - especially to encode the unification process -
which leads to a complex elaboration and large proof terms (see my <a href="https://jesper.cx/files/thesis-final-digital.pdf">PhD thesis</a>).</p></li>
<li><p>In between these two extremes,
<a href="https://jesper.cx/files/elaborating-dependent-copattern-matching.pdf">case trees</a>
are the representation used by Agda’s internal syntax.
They strike a nice balance between theoretical elegance and efficiency,
and are thus well suited for a core language for Agda.</p></li>
</ul>
<p>Rather than creating a separate syntactic class for case trees like Agda does,
Agda Core simply embeds each kind of node as a term constructor.
In particular, there is a
<a href="https://github.com/jespercockx/agda-core/blob/2fb9574e78326ec532dcb2af8272631c765e947d/src/Agda/Core/Syntax.agda#L94"><code>case</code></a>
construct representing a single pattern match.
In contrast to <code>case</code> expressions in Rocq or Lean,
these <code>case</code> expressions can do unification
when the indices of the scrutinee are not fully general.
For example, a <code>case</code> can pattern match on a value of type <code>Vec A (suc n)</code>
with a single branch for the cons constructor <code>_∷_</code>.</p>
<p>Embedding <code>case</code> expressions into the syntax poses one problem,
which is that they do not fit neatly into a bidirectional typing discipline.
In particular, we can omit the type annotation of a case match
(a.k.a. the “motive”) only if the scrutinee is a variable.
However, “being a variable” is a property that is very much not stable under substitution,
which would be rather unfortunate.
At the moment, this is solved by always requiring a type annotation for each case expression.
However, this is a decision I would like to come back to later
to investigate further what other options there are.</p>
<h2 id="design-challenge-preserving-sharing-during-reduction">Design challenge: Preserving sharing during reduction</h2>
<p>One of the major flaws in the current implementation of Agda
(which I also wrote about in a
<a href="https://jesper.cx/posts/ten-agda-improvements.html">recent blog post</a>)
is that there is no good way to represent explicit sharing
in the internal syntax of Agda, through <code>let</code>-bindings or otherwise.
I decided to try to avoid this mistake in Agda Core
and so added a
<a href="https://github.com/jespercockx/agda-core/blob/2fb9574e78326ec532dcb2af8272631c765e947d/src/Agda/Core/Syntax.agda#L65"><code>let</code> constructor</a>
to the syntax,
even though it is not strictly necessary to represent the current implementation of Agda.</p>
<p>Little did I know that it is not enough
to merely add sharing to the syntax,
but that it should also be preserved during reduction
(okay, maybe I should have predicted this one).
Luckily there are good techniques for doing sharing-preserving reduction.
In particular, I am fond of Peter Sestoft’s
<a href="https://doi.org/10.1017/S0956796897002712">lazy abstract machine</a>
for striking a nice balance between simplicity and efficiency.
It defines reduction on an abstract machine consisting of
an <em>environment</em> of shared terms,
a <em>focus</em> term currently being evaluated,
and a <em>stack</em> of frames to continue reduction later.
This is what I used as the basis for defining
<a href="https://github.com/jespercockx/agda-core/blob/2fb9574e78326ec532dcb2af8272631c765e947d/src/Agda/Core/Reduce.agda#L116-L147">reduction for Agda Core</a>.</p>
<p>This allows us to preserve sharing during reduction,
but at some point we have to convert the abstract machine back into a regular term
(unless you are okay with having these abstract machines in your typing judgement).
At first I thought we could simply turn each shared term in the environment into a <code>let</code>-binding.
However, often these shared terms are only there as intermediate results of computation
and are not used in the final term.
Thus my strategy resulted in lots and lots of unused <code>let</code>-bindings.</p>
<p>To make this approach practical we would need
a procedure for garbage collection of unused <code>let</code>-bindings
(and perhaps inlining of linear <code>let</code>-bindings).
Implementing such a procedure in a well-scoped way
seems like a rather challenging and time-consuming task
which I have not yet attempted (though I’d like to try).
So for now, converting from an abstract machine back to an expression
instead relies on substitution rather than <code>let</code>-binding,
destroying any sharing in the process.</p>
<h2 id="design-challenge-dealing-with-non-termination">Design challenge: dealing with non-termination</h2>
<p>Another challenge that comes up when defining reduction and conversion
is how to deal with the possibility of non-terminating terms.
For reasons of modularity, we would like to define conversion separately from typing,
so we don’t yet know that a term is well-typed when reducing it.
Even if we did know it was well-typed,
Agda Core currently does not include a termination checker (yet).</p>
<p>So either way, we need some way to deal with the possibility of non-termination.
For declaring the conversion rules, this is straightforward:
we simply ask for
<a href="https://github.com/jespercockx/agda-core/blob/2fb9574e78326ec532dcb2af8272631c765e947d/src/Agda/Core/Conversion.agda#L93-L98">a proof</a>
that the reduction to weak-head normal form is terminating for a particular term.</p>
<p>In the implementation of the executable conversion checker
we need to actually construct this evidence.</p>
<ul>
<li><p>The simplest way to do this is to rely on a “fuel” argument
that gives an upper bound on the number of reduction steps that will be tried.
This is not very satisfactory because it means conversion checking
(and hence type checking) can now fail on well-typed terms if they run out of fuel.</p></li>
<li><p>Another possibility would be to use a <code>Delay</code> monad to model potential non-termination,
but Agda’s guardedness checker proved to be too restrictive
(and its sized types too buggy)
for this to work out.</p></li>
<li><p>For a while, I tried another solution that tried to compute in advance
the set of terms that needed to be normalized for a given typing/conversion problem.
However, this resulted essentially in running every typing and conversion check twice
so I abandoned it.</p></li>
<li><p>In MetaCoq, they solve this instead by only calling reduction on well-typed terms
and postulating strong normalization,
however Agda Core currently lacks a termination check so this is not an option either.</p></li>
</ul>
<p>So for a lack of better options,
the <a href="https://github.com/jespercockx/agda-core/blob/2fb9574e78326ec532dcb2af8272631c765e947d/src/Agda/Core/TCM.agda#L23-L35">type checking monad of Agda Core</a>
currently carries a global fuel value that is used for every conversion check.</p>
<h2 id="design-challenge-typed-vs-untyped-conversion">Design challenge: Typed vs untyped conversion</h2>
<p>One major difference between conversion checking in Agda and most other dependently typed languages
is that it uses a <em>typed</em> notion of conversion.
This means that Agda always keeps track of the type of two terms when comparing them
(with the exception of comparing two <em>types</em>, for which Agda does not care about their type).
As far as I know, this type information is actually used in three places:</p>
<ul>
<li><p>When checking equality at a function type
(and neither side of the equality is a neutral term),
Agda will extend the context with a fresh variable
and apply both sides of the equation to it.</p></li>
<li><p>When checking equality at a record type with eta-equality enabled
(and neither side of the equality is a neutral term)
Agda will compare the terms field-wise.
For example, for a pair type it will compare the first components and the second components.</p></li>
<li><p>When checking equality at an definitionally irrelevant type
(either the domain of an irrelevant function type, or a type in the <code>Prop</code> universe)
Agda will regard any terms as equal.</p></li>
</ul>
<p>Most of these uses of typed conversion are not really essential
and could be solved instead by more syntax-directed rules
(as demonstrated by Rocq and Lean).
However, the one big exception is the eta unit type <code>⊤</code>,
which is defined as a record type with no fields.
Since there are no fields,
the conversion rule says that <em>any</em> two terms at this type are equal.
This is the reason why this type is not supported in Rocq (I’m not sure about Lean),
and it is the cause of quite a bit of complexity in the implementation of Agda.</p>
<p>Since the eta unit type is an important and unique feature of Agda,
I would very much like to support it in Agda Core, too.
Unfortunately, trying to making the conversion rules type-directed
made them significantly more unweildy to write down
as each conversion rule essentially becomes
a two-sided version of the corresponding typing rule.
This became too annoying so we reverted back to
an untyped conversion judgement for the moment.</p>
<p>An alternative approach I would like to explore
is to locally require a typing derivation whenever conversion uses eta-equality,
which would make eta-equality much less invasive to the basic typing and conversion infrastructure.
Actually it would be sufficient to require a <em>re-typing</em> derivation
(i.e. a derivation that a term has a specific type, assuming that it is already well-typed)
which could easiby be computed in the conversion checker.
The main snag is that this would require the conversion judgement to maintain a local context for running the re-typing,
which might not be possible without adding type annotations to lambda expressions
which I was trying to avoid.</p>
<h2 id="infrastructure-challenge-working-with-erasure-annotations">Infrastructure challenge: working with erasure annotations</h2>
<p>Apart from the more conceptual design challenges I mentioned so far,
we also encountered plenty of more technical challenges.
Quite a few of these have to do with the <code>@0</code> erasure annotations,
which (if you remember) use to draw the line between
the erasable <em>specification</em> of the Agda Core typing rules
and the executable <em>implementation</em> of its type checker.
Because of Agda issue <a href="https://github.com/agda/agda/issues/5703">#5703</a>
the error messages when you forget an <code>@0</code> are often <em>horrendous</em>:
rather than a proper error message about a failed instantiation,
you get a long list of mostly irrelevant unsolved constraints.</p>
<p>(As a side note, I tried to solve this issue for a while
but got stuck because of an interaction between erasure and eta unit types
via the occurs checker.
A proper fix would require a type-directed reimplementation of
the occurs checking and pruning algorithms
used for solving higher-order unification problems.
Alas, apart from being really tricky to do,
<a href="https://github.com/jespercockx/agda/tree/Issue5703">my attempt</a>
also causes a performance regression significant enough for me to give up.)</p>
<p>The solution for working with erasure that I found to work
is to not use <code>@0</code> directly but instead define a
<a href="https://github.com/agda/agda2hs/blob/7b3e48a35448acff9bb5823ca22623eafb000d15/lib/Haskell/Extra/Erase.agda#L15-L18">record type <code>Erased A</code></a>
with a single <em>erased</em> field of type <code>A</code>.
We also found other types that are useful when working with erasure
such as the type <a href="https://github.com/agda/agda2hs/blob/7b3e48a35448acff9bb5823ca22623eafb000d15/lib/Haskell/Extra/Erase.agda#L31-L38"><code>Rezz x</code></a>
that carries a runtime representation of the erased value <code>x</code>
and <a href="https://github.com/jespercockx/agda-core/blob/2fb9574e78326ec532dcb2af8272631c765e947d/src/Agda/Core/Utils.agda#L7-L12">three variants of the <code>Σ</code> type</a>
with different erasure annotations.</p>
<h2 id="infrastructure-challenge-agda2hs-woes">Infrastructure challenge: agda2hs woes</h2>
<p>While I believe the choice to use <code>agda2hs</code> to compile Agda Core
rather than Agda’s GHC backend was a sensible one,
it is the first project of this size that uses <code>agda2hs</code>
and it shows.
In the process of making Agda Core compatible with <code>agda2hs</code>,
we encountered numerous compilation bugs, missing features,
and missing library functionality.
The biggest limitation was perhaps the lack of support for module parameters,
which we relied on heavily in Agda Core
to represent the global scope of definitions and datatypes.
A proper fix for all issues eventually required us to switch
to a type-directed compilation
(see <a href="https://github.com/agda/agda2hs/pull/270">#270</a> and <a href="https://github.com/agda/agda2hs/pull/304">#304</a>).
Do you start to notice a pattern?</p>
<p>So the bad news is that making Agda Core work with <code>agda2hs</code>
took a lot of work to improving <code>agda2hs</code>.
The good news is that <code>agda2hs</code> is now a much better and more robust tool than it was,
so if you are curious I would definitely recommend trying it out!</p>
<h2 id="infrastructure-challenge-awkward-representations-in-agdas-internal-syntax">Infrastructure challenge: awkward representations in Agda’s internal syntax</h2>
<p>The final technical challenge I want to mention has to do with Agda’s implementation itself.
As I mentioned in the first part of this post,
our ultimate goal is to link up Agda Core as a backend to the implementation of Agda
so it can be used to double-check the well-formedness of its output.
Since Agda is implemented in Haskell
and Agda Core can be translated to Haskell with <code>agda2hs</code>,
this should be easy!
Or well, possible at least.</p>
<p>Since this is currently the place where the most work still needs to be done,
I am unsure which further technical challenges will pop up.
But one challenge will definitely be to translate Agda’s internal case trees
to iterated <code>case</code> statements in Agda Core.
Agda’s case trees are optimized for efficient reduction
and thus omit all typing information.
For some reason they also use de Bruijn <em>levels</em> instead of de Bruijn <em>indices</em>
and without even knowing the context size translating between the two is not straightforward.</p>
<p>The main cause of the problem here is that
Agda builds a lot of typing information
while type checking definitions by pattern matching
but this information is not stored anywhere in the case tree.
So perhaps the right thing to do is
to add an intermediate <em>typed</em> representation of case trees to Agda’s pipeline.
Such a representation could even be useful for other tools besides Agda Core,
such as <a href="https://github.com/Deducteam/Agda2Dedukti">Agda2Dk</a>
and Agda’s own double-checker <a href="https://github.com/agda/agda/blob/master/src/full/Agda/TypeChecking/CheckInternal.hs"><code>CheckInternal</code></a>
(which currently only handles terms but not case trees).</p>
<h1 id="conclusions">Conclusions</h1>
<p>So, whew, now you have an idea of the overall goals of Agda Core
as well as some of the challenges that we ran into
while working on it.
I am personally quite disappointed with how long it took to get to this point
and how much work is still left to be done.
Still, it has been a fascinating project
and despite all of its shortcomings,
I find Agda truly a very satisfying language to work with.</p>
<p>So rather than seeing all these difficulties as something negative,
I would rather view them as pointing out places where there is still
possibility for growth, both in the implementation of Agda and its ecosystem
as well as our own knowledge and best practices of
how to implement correct-by-construction type checkers.
So what are we still waiting for?
Let’s go and find out!</p>
<p>As always, comments on this blog post are welcome
via Mastodon/Fediverse/ActivityPub at <a href="https://agda.club/@jesper"><span class="citation" data-cites="jesper">@jesper</span><span class="citation" data-cites="agda.club">@agda.club</span></a>,
on the <a href="https://agda.zulipchat.com/">Agda Zulip</a>,
or via email to <a href="mailto:jesper@sikanda.be">jesper@sikanda.be</a>.</p>
<p>Oh, and the next blog post will be something short and sweet, I promise!</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Sat, 11 May 2024 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/agda-core.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>Ten Thinkers Who Shaped My Worldview</title>
    <link>https://jesper.sikanda.be/posts/ten-thinkers.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Ten Thinkers Who Shaped My Worldview</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Ten Thinkers Who Shaped My Worldview</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on March 10, 2024
    </p>
    <p>I believe it is our responsibility as world citizens to help building a better world and to protect those who cannot easily protect themselves.
However, our world has become so complex and confusing that it is often not clear how we can help.
Well-intentioned action can miss their target or even have the opposite effect.
Everyone is either trying to convince you that they are on the good side or accusing you of being on the bad side.</p>
<p>In the midst of this chaos, I take refuge in books, blog posts, and long podcasts.
They do not hold all the answers either, but there are many nuggets of wisdom out there to be found.
To highlight some of these nuggets, I would like to introduce you to ten of my favorite authors, bloggers, podcasters, activists, and visionaries.
For each of them I also have a recommendation for a book or other piece of media for you to dive into.
Some of these recommendations are works of fiction, but I promise each one of them has something important to say about our own world.</p>
<p>If there is one thing that connects all of these people, it is their optimism.
Not optimism in the sense of “it will all be okay” (it won’t) but optimism in the sense of “it is not too late to make a difference” (it never is).
Rather than just pointing out problems, they all point out <em>solutions</em>.
So without further ado, here are ten people - in alphabetical order - whose ideas played a major role in the development of my current view on life and the world.</p>
<h2 id="ada-palmer">Ada Palmer</h2>
<p><strong>Recommendation.</strong> <em><a href="https://www.adapalmer.com/publication/too-like-the-lightning/">Too Like The Lightning</a></em> (book 1 of the <em>Terra Ignota</em> series)</p>
<p>Those who fail to study history are doomed to repeat it. Yet by only dwelling in the past we might lose sight of how tomorrow could be different.
Hence it is fitting that the first person on this list is a historian turned science fiction writer.</p>
<p>In particular, Ada Palmer’s <em>Terra Ignota</em> series is a work of <strong>political</strong> science fiction which clearly demonstrates her deep knowledge of the Renaissance, and the history of censorship in particular.
While the books have flying cars and space elevators and kitchen trees growing any kind of food you want, it is not really about those things.
Rather, it is about a society five centuries in our future, which feels as strange as our society would feel to someone from the 16th century.
It has different norms, different taboos, a different interpretation of gender, different organizations, different politics, and different laws.
And like all the best sci-fi, it gives the reader a new lens to look at our own society and question our assumptions on how these things <em>should</em> or even <em>could</em> be.</p>
<h2 id="audrey-tang">Audrey Tang</h2>
<p><strong>Recommendation.</strong> <em><a href="https://80000hours.org/podcast/episodes/audrey-tang-what-we-can-learn-from-taiwan/">What we can learn from Taiwan’s experiments with how to do democracy</a></em> (on the 80,000 Hours podcast)</p>
<p>Democracy is one of the greatest inventions of humankind, and yet it feels more fragile than ever.
Are we doomed to slide back into autocracy or worse in the coming years and decades?
I don’t think so, but then we will need to stop lamenting democracy’s inevitable demise and start updating it to the 21st century.</p>
<p>Audrey Tang is Taiwan’s minister of Digital Affairs and has big ideas on how to build a more direct, less polarized, and more digital democracy.
What’s more, she has been putting these ideas into practice, through the g0v project (showing how existing government services could be improved) and the vTaiwan project (building new social media models to build consensus rather than disagreement on big political questions).
Oh, and she is also the first transgender person in an executive position in Taiwanese government,
and she is involved in several open-source projects, among which GHC.
How could I not be a fan?</p>
<h2 id="becky-chambers">Becky Chambers</h2>
<p><strong>Recommendation.</strong> <em><a href="https://www.goodreads.com/book/show/40864002-a-psalm-for-the-wild-built">A Psalm for the Wild-Built</a></em> (book 1 of the <em>Monk and Robot</em> series)</p>
<p>Another science fiction writer on my list?
Well yes, but Becky Chambers’ sci-fi is of a different kind.
She tells stories that are small, personal, philosophical, cozy, and real.
Not real as in realistic, but real as in built from real people’s struggles and emotions.</p>
<p>In a pair of novella’s titled <em>Monk and Robot</em> (consisting of <em>A Psalm for the Wild-Built</em> and <em>A Prayer for the Crown-Shy</em>)
she tells the story of a traveling monk who offers tea and kindness to the people they encounter,
and a robot who has lived in the wilderness for a long time and has now returned with a simple question: “what do humans need?”
Through this story, Becky shows us a different way we could relate to the natural world, technology, and each other.
It is beautiful and thought-provoking, and I haven’t read anything else quite like it.</p>
<h2 id="brother-pháp-hữu">Brother Pháp Hữu</h2>
<p><strong>Recommendation.</strong> <em><a href="%5BSpace,%20Time,%20and%20the%20Ultimate%20Dimension%5D(https://plumvillage.org/podcast/space-time-and-the-ultimate-dimension-episode-54)">Space, Time, and the Ultimate Dimension</a></em> (on the <em>The Way Out Is In</em> podcast)</p>
<p>At first, this spot on my list was reserved for Thich Nhat Hanh,
the Zen master and peace activist who is often credited with “bringing mindfulness to the West”.
In a sense, it still is.
However, most of his lessons have not reached me directly but through one of his students.</p>
<p>Brother Pháp Hữu was a long-time student and attendant of Thich Nhat Hanh, and is the current abbot of the Plum Village Monastery in France.
He is also the co-host of <em>The Way Out Is In</em>, a podcast about mindfulness, activism, self-care, leadership, community building, transforming our suffering, and finding happiness.
During long conversations with journalist and leadership coach Jo Confino,
they take deep questions about what it means to live as a human being and how to make a difference in the world.
The answers to these questions draw upon the deep wisdom of thousands of years of Buddhist tradition, and update that wisdom to our present circumstances.
Since the Plum Village tradition is one of <em>engaged</em> Buddhism, peace and climate activism are also regular topics on the podcast.</p>
<h2 id="cory-doctorow">Cory Doctorow</h2>
<p><strong>Recommendation.</strong> <em><a href="https://pluralistic.net/2023/07/09/let-the-platforms-burn/">Let the platforms burn</a></em></p>
<p>I first encountered Cory Doctorow through his 2008 book <em>Little Brother</em>,
in which he tells a fictional story about a near-term future with constant surveillance, giant tech companies controlling the lives of people, and the decay of our civil rights.
We now live in that world.
Since then, he has written a collection of both fiction and non-fiction books on topics such as digital rights, copyright, surveillance capitalism, and climate change.
You might also know him for being the one who coined the term <em>enshittification</em> to describe the process in which big companies inevitably evolve to mistreat their customers and business partners alike.</p>
<p>Computers and the internet are only small a part of our lives, but it has become so integral to many other parts.
Hence I believe it is worth to fight for a free and open internet that works for us rather than the other way around.
More than any other person I know, Cory Doctorow is the one who can tell us how to build it.</p>
<h2 id="jay-dragon">Jay Dragon</h2>
<p><strong>Recommendation.</strong> <em><a href="https://possumcreekgames.itch.io/wanderhome">Wanderhome</a></em></p>
<p>Tabletop roleplaying games (TTRPGs) are one of my big hobbies and an important part of my life.
If you’ve only heard about one TTRPG, it is probably Dungeons and Dragons, a game about heroic action and violent magic and exploring trapped dungeons and fighting big monsters and taking their treasure.
However, there is so much more that TTRPGs can be,
and nowhere is this demonstrated better than in the games designed by Jay Dragon.</p>
<p>Jay designs games that are playful, nonviolent, radically inclusive, and intensely emotional.
Playing one of them is less like playing a board game and more like one of these elaborate games of make-believe you (or I, at least) played during the breaks at primary school.
My favorite of Jay’s games is <em>Wanderhome</em>, a game where you play as animalfolk traveling through a beautiful pastoral country that was recently ravaged by war but is now at peace.
It is a game where you tell stories about travel, meeting new people, helping each other, being vulnerable, and processing grief.
Even if you have never played any TTRPG before and have no intention of playing one,
it is still worth it to read through <em>Wanderhome</em> to absorb the vibes, enjoy the poetry, and admire the beautiful art and layout of the book.
And it you ever do get the itch to play, just let me know.</p>
<h2 id="julia-galef">Julia Galef</h2>
<p><strong>Recommendation.</strong> <em><a href="https://juliagalef.com/">The Scout Mindset</a></em></p>
<p>The way we think about the world around us has large effects on how we treat that world, and how it will treat us in turn.
Hence it makes sense to try to spot mistakes in our thinking and gradually come to more accurate beliefs.
This is the idea at the root of the rationality community, probably best known from the <em>Less Wrong</em> community blog.
A lot of ideas and projects - both good and bad - have arisen from this community (most notably Effective Altruism),
but in a sense much of this obscures the core ideas of rationality which I believe are quite interesting and useful.</p>
<p>Julia Galef is one of the leaders of the rationality community who has been teaching these core ideas incessantly over years, and she has written them down in her book <em>The Scout Mindset</em>.
In it’s essence, the book is about moving from a soldier’s mindset of “how can I best defeat my enemies” to a scout’s “how can we get the most accurate picture of reality?”
The book is full of practical lessons about how you can apply the scout mindset to notice your own biases, make more accurate predictions, motivate yourself without self-deception, influence others without misleading, and escape from echo chambers.
It is one of these books that I regularly think of in my daily life when I feel stuck or am faced with a difficult decision.
If you ever wished that the world would just make more sense, then this book is for you.</p>
<h2 id="rob-hopkins">Rob Hopkins</h2>
<p><strong>Recommendation.</strong> <em><a href="https://www.robhopkins.net/the-book/">From What Is To What If</a></em></p>
<p>Rob Hopkins is the founder of the global <em>Transition</em> community, a network of grassroots organizations of people who are unhappy with how humanity is handling the current climate and ecological crises.
Rather than getting angry and protest, these <em>Transition Towns</em> demonstrate that there are many solutions we can implement right now, if we can only imagine them.
It started in 2006 with <em>Transition Town Totnes</em> in the UK, and there are now over 1000 groups in over 50 countries (it’s hard to find precise numbers).</p>
<p>In his book <em>From What Is To What If</em>, Rob writes about the vital importance of imagination in tackling the largest challenges of our time.
After all, how can we solve a problem if we cannot even imagine how things might be different?
The book vividly illustrates this role of imaginations through examples of how it made a real difference in education, healthcare, social media, politics, storytelling, and of course taking care of nature.
Rob’s enthusiasm is infectious and will instantly cure you of your apathy or cynicism.
Just imagine that.</p>
<h2 id="scott-alexander">Scott Alexander</h2>
<p><strong>Recommendations.</strong> <em><a href="https://www.astralcodexten.com/p/my-presidential-platform">My Presidential Platform</a></em>, <em><a href="https://www.astralcodexten.com/p/in-continued-defense-of-effective">In Continued Defense of Effective Altruism</a></em>, <em><a href="https://www.astralcodexten.com/p/the-rise-and-fall-of-online-culture">The Rise and Fall of Online Culture Wars</a></em>, <em><a href="https://www.astralcodexten.com/p/idol-words">Idol Words</a></em></p>
<p>Scott Alexander is a psychiatrist and writes a very popular blog called Astral Codex Ten (formerly Star Slate Codex).
He writes a continuous torrent of blog posts about psychology, society, politics, economics, philosophy, rationality, and effective altruism, mixed with the occasional quasi-comprehensible fictional story.</p>
<p>What makes his blog really special to me is Scott’s skill at nuance and careful thinking without getting pulled into easy stories on either side of a controversial topic.
He consistently manages to question hidden assumptions and is never satisfied with easy answers.
If there is one thing about Scott to critique is that he writes <em>so damn much</em> that it is really hard to keep up with all the different topics he writes about.</p>
<h2 id="thomas-piketty">Thomas Piketty</h2>
<p><strong>Recommendation.</strong> <em><a href="https://en.wikipedia.org/wiki/A_Brief_History_of_Equality">A Brief History of Equality</a></em></p>
<p>Lots of ideas for a better future sound really nice and convincing, until you realize that they would never work in practice because of simple economics.
So let’s talk about economics.
The economy is what has more than doubled our average lifespan and increased our material standard of living beyond imagination over the past 150 years.
Yet it is also the source of the increasingly large gap between the haves and the have-nots of this world.
So talking about economics isn’t possible without also talking about inequality, and who better to talk about the economics of equality than Thomas Piketty?</p>
<p>Though many years of research, Piketty has traced the origins of wealth and inequality throughout history.
He is probably most famous for his big book <em>Capital in the 21st Century</em>, however I found out about his ideas through the more recent and much more accessible <em>A Brief History of Equality</em>, as well as by reading his blog.
What I admire most about Piketty is his ability to take seemingly radical ideas about how we could reshape our society and show them to be not just real options but actually the only reasonable course of action.
Some of these ideas are a progressive wealth tax, paying reparations to formerly colonized countries, and a universal inheritance for every person when they turn 18.
He shows us that while the economy that shapes much of our lives, it is us who shape the economy, and we have it within our reach to shape it for the better.</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Sun, 10 Mar 2024 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/ten-thinkers.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>6 Reasons in favor of a core language, and 5 against</title>
    <link>https://jesper.sikanda.be/posts/why-not-a-core-language.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - 6 Reasons in favor of a core language, and 5 against</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>6 Reasons in favor of a core language, and 5 against</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on February 10, 2024
    </p>
    <p>As a person who has worked quite a bit on Agda, I sometimes get the question why Agda does not have a proper core language. And it’s a valid question, given that most - if not all - closely related languages do have a (reasonably) well defined core language.</p>
<p>You might also have heard that I am working on implementing <a href="https://github.com/jespercockx/agda-core">a core language for Agda</a> - implementing it in Agda no less. The work on that is progressing slowly with fits and jumps, and I hope to tell you more about it soon. In the meantime, let’s look at some reasons why it would be a good idea to have a core language, and other reasons why it might not be such a good idea.</p>
<p>This post is mostly meant as an overview, not going very deep into any of the points. But I hope it’ll be useful as a reference and a starting point for further discussion.</p>
<h2 id="pro-1-it-reduces-the-trusted-code-base">PRO 1: It reduces the trusted code base</h2>
<p>The first and most obvious reason why you would want a core language is known as the <em>de Bruijn criterion</em>: if we can separate the generation of a proof from its verification, then we only need to care about the soundness of the checker and not the rest of the system. Since a core language is typically quite small, it is much easier to trust its implementation through either manual inspection or formal analysis.</p>
<h2 id="pro-2-you-can-implement-independent-checkers">PRO 2: You can implement independent checkers</h2>
<p>Related to the first point, even if you do not trust the result of the provided type checker for the core language, implementing an independent checker for a small core language is not a huge task: it will probably take days rather than years. One example of this is the <a href="https://github.com/01mf02/kontroli-rs">Kontroli</a> checker for the LambdaPi language. There are probably many other examples of independent checkers but (surprisingly?) I haven’t heard of them.</p>
<p><strong>Update:</strong> Sebastian Ullrich <a href="https://functional.cafe/@kha/111907745153466474">writes</a>:</p>
<blockquote>
<p>Regarding existing external checkers, Chris Bailey has not only implemented one for Lean 4 in Rust but also written a whole book on how to do that
https://ammkrn.github.io/type_checking_in_lean4/</p>
</blockquote>
<h2 id="pro-3-you-cant-do-meta-theory-without-one">PRO 3: You can’t do meta-theory without one</h2>
<p>In the same line as the previous two, for the ultimate trustworthiness of your language you might want to develop its formal meta-theory either on paper or - ideally - in a proof assistant. You might prove basic properties such as confluence, type preservation (i.e. subject reduction), and progress, or tackle the big questions of logical soundness and strong normalization. Either way, you will not get very far doing this to a full-fledged surface language intended to be convenient to use, so having a core language is a must.</p>
<h2 id="pro-4-syntactic-sugar-can-be-added-without-changing-the-backend">PRO 4: Syntactic sugar can be added without changing the backend</h2>
<p>Moving on to the more practical benefits of a core language, it provides a nice separation between the front-end of your language (which elaborates into the core language) and the back-end (which takes the core and compiles it to something executable). In particular, you can easily add new syntactic features to the surface language, as long as they can be desugared into the existing core, all without ever touching the core or backend.</p>
<h2 id="pro-5-it-serves-as-a-basis-for-metaprogramming">PRO 5: It serves as a basis for metaprogramming</h2>
<p>Another practical benefit of a core language is that the AST of the core language is much simpler than that of the surface language, so it is much easier to analyze or transform code in it. This is particularly useful for user-facing features that generate or transform code, variously known as tactic languages, metaprogramming APIs, or compile-time reflection frameworks.</p>
<h2 id="pro-6-it-enables-easier-export-to-other-languages">PRO 6: It enables easier export to other languages</h2>
<p>As a final practical benefit of a well-defined core language, it makes exporting your programs and proofs to other languages a much more feasible task. I’m not saying it becomes trivial: proof export still requires a lot of work for aligning or encoding language constructs, typing features, and library concepts. But the progress on the <a href="https://europroofnet.github.io/">EuroProofNet</a> objectives shows that it is not impossible either!</p>
<h2 id="contra-1-you-already-have-a-core-language">CONTRA 1: You already have a core language</h2>
<p>Even in a language that does not have an official core language (such as Agda), chances are that there will be something <em>very much like a core language</em> hiding in its implementation. In Agda’s case, that is its internal syntax - consisting among others of the <a href="https://github.com/agda/agda/blob/2816d755451ab97fb4c8021866dd557fc73354be/src/full/Agda/Syntax/Internal.hs#L217-L242"><code>Term</code></a> and <a href="https://github.com/agda/agda/blob/2816d755451ab97fb4c8021866dd557fc73354be/src/full/Agda/TypeChecking/Monad/Base.hs#L2313-L2328"><code>Defn</code></a> types. It certainly doesn’t count as a full core language because it is not separated from the rest of the codebase (failing PRO 1), there is no independent checker for <code>Defn</code> (failing PRO 2, though there is <a href="https://github.com/agda/agda/blob/master/src/full/Agda/TypeChecking/CheckInternal.hs">one for <code>Term</code></a>), and I haven’t met anyone crazy enough to do meta-theory for it (failing PRO 3). Nevertheless it is still used as a target for syntactic sugar such as <code>with</code>-abstraction and pattern-matching lambdas (PRO 4), it is the basis of Agda’s <a href="https://agda.readthedocs.io/en/v2.6.4.1/language/reflection.html">reflection API</a> (PRO 5), and it is used for exporting proofs to <a href="https://github.com/Deducteam/Agda2Dedukti">Dedukti</a> and programs to <a href="https://github.com/agda/agda2hs">Haskell</a> (PRO 6). So building a true core language is more a matter of <em>increasing trust</em> rather than <em>adding functionality</em>.</p>
<h2 id="contra-2-desugared-code-might-be-less-efficient">CONTRA 2: Desugared code might be less efficient</h2>
<p>While a small core language is good for increasing trust, making it <em>too</em> small can also mean we lose information that could help the compiler to produce more efficient code. While a sufficiently smart compiler could in theory reconstruct this information, in practice compilers are often not “sufficiently smart”. One example of this is the <a href="http://mattam82.github.io/Coq-Equations/">Equations plugin for Rocq</a>, which compiles pattern matching definitions to primitive case statements. In this process, it bakes in a specific order of case analysis in the term and produces large terms witnessing the unification steps (or at least, it did so when I looked at it a couple of years back, it might have improved since). So if you want to output efficient code it might make sense to start from a less minimalist representation of the program.</p>
<h2 id="contra-3-error-messages-become-harder-to-read">CONTRA 3: Error messages become harder to read</h2>
<p>Related to the previous point, if (some part of) our programs and proofs are only checked after they are translated to the core, then there is a risk that error messages will become harder to read as a result. This is not inevitable, as it is possible to carefully keep track of the origins of terms to they can be printed like the user wrote them, but that is not easy to do everywhere. In general, producing error messages for dependent type checkers that can actually be understood by someone unaware of the underlying type theory is very much an open problem, and one I would like to investigate more in the future.</p>
<p><strong>Update.</strong> Jan de Muijnck-Hughes <a href="https://discuss.systems/@jfdm/111907772356852121">writes</a>:</p>
<blockquote>
<p>idris2 does a good job in translating core terms back into the surface language syntax.
Also <span class="citation" data-cites="d_christiansen">@d_christiansen</span> implemented error reflection in idris1 and this allowed one to rewrite error messages for your eDSL in your surface language.</p>
</blockquote>
<h2 id="contra-4-non-sugar-features-become-harder-to-add">CONTRA 4: Non-sugar features become harder to add</h2>
<p>While adding new syntactic sugar that can be desugared into the existing core language is relatively easy, a monolithic core language does make it much harder to experiment with new features that change the type theory itself. Examples of this are definitional proof irrelevance, rewrite rules, quantitative types, sized types, universe polymorphism, and of course cubical type theory. As anecdotal evidence, Agda has all of these features while Rocq only has some (definitional irrelevance and universe polymorphism), and those took much more effort to integrate. But there is also such a thing as feature bloat, so having higher friction against adding new features might actually sometimes be a good thing!</p>
<h2 id="contra-5-it-distracts-from-other-things">CONTRA 5: It distracts from other things</h2>
<p>Perhaps my biggest hesitation against working towards a real core language for Agda is that it takes <em>a lot</em> of effort to build, especially since Agda was never really designed with a separate core in mind. This is effort that does not go towards other tasks that could end up having more impact towards the goal of actually having more (partially or fully) verified software. A few of these other tasks that might have a higher impact on the margin:</p>
<ul>
<li>Increasing the user-friendliness and accessibility (since a core is useless if no-one is using your language).</li>
<li>Making the task of writing formal specifications easier (since proving something is useless if we are not proving the right thing).</li>
<li>Verifying the correctness of the elaboration process (since even a correct specification could be elaborated to a wrong statement in the core language).</li>
</ul>
<p>None of these other goals invalidate the necessity of having a core language, but they do put it into perspective of the grander overall goal: <em>to make it more likely that we mean what we say by improving our ability to say what we mean</em> (thank you for that quote, Conor).</p>
<h1 id="conclusion">Conclusion</h1>
<p>So these are the six reasons why I’m working on a core language for Agda, and five pitfalls I’m trying to be mindful of while doing so. Let me know if you agree with these reasons or not, which ones you think weigh the strongest, and if there are any others I missed! You can send comments on the <a href="https://agda.zulipchat.com">Agda Zulip</a>, to <a href="https://agda.club/@jesper"><span class="citation" data-cites="jesper">@jesper</span><span class="citation" data-cites="agda.club">@agda.club</span></a> via any Fediverse portal, or email me at <a href="mailto:jesper@sikanda.be">jesper@sikanda.be</a>.</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Sat, 10 Feb 2024 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/why-not-a-core-language.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>Ten improvements to Agda's implementation</title>
    <link>https://jesper.sikanda.be/posts/ten-agda-improvements.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Ten improvements to Agda's implementation</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Ten improvements to Agda's implementation</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on January  1, 2024
    </p>
    <p>Happy 2024! I have (foolishly) resolved to write one blog post per month in this new year, so expect more frequent and less polished posts in the coming year. To give myself a head start, here is the first of twelve blog posts.</p>
<p>To the surprise of no-one who has used Agda, there are many things that could be improved. However, it is easy to get lost in thinking about new features or bug fixes, and forget about more architectural changes that could improve the usability, maintainability, and efficiency of Agda. Hence here is a list of ten ways in which I believe the Agda language - as it currently exists - could be improved. I believe most of them would require a few weeks to a few months of dedicated developer time to implement (though as always take these estimations with a large grain of salt) and would be very worthwhile. Sadly, the days that I could just dedicate a few weeks to months to a refactoring seem to be over (though never say never), but if you are interested to work on any of these please reach out and I will help you to get started!</p>
<h2 id="a-modern-api-for-ide-interaction">1. A modern API for IDE interaction</h2>
<p>Agda’s interactive mode has always been one of its important and unique features, and still most other languages could learn a thing or two from how interactive case splitting works in Agda. However, the evolution of IDEs hasn’t stopped since and nowadays many things feel outdated (e.g. having to load a file manually) or are simply missing (e.g. automatic import management). Moreover, the way Agda’s interaction works conflicts with the LSP (which didn’t exist yet when Agda was released), making it very cumbersome to add support for Agda to more editors. An updated interaction model for Agda could make it easier to integrate Agda into more IDEs and to add new features that developers expect in 2024.</p>
<h2 id="a-hygienic-and-efficient-reflection-api">2. A hygienic and efficient reflection API</h2>
<p>Agda’s reflection API is quite powerful and has a lot of potential for letting users implement their own tactics and interactive commands. However, it is being held back by its steep learning curve, its poor representation of variables, and its abysmal impact on performance. A more accessible and efficient implementation would open up many doors for libraries to provide more automation and convenience to their users.</p>
<h2 id="better-diagnostics-for-unsolved-metavariables">3. Better diagnostics for unsolved metavariables</h2>
<p>Many of the errors you get while writing Agda code have to do with unsolved metavariables and constraints. Currently it is a true art to track down these unsolved metavariables to the point in the code where they originated. Keeping track of the origins of metavariables and showing them to the user in a sensible format would go a long way towards giving concrete diagnostics for locating the source of these unsolved metavariables.</p>
<h2 id="discrimination-trees-and-memoization-for-instance-search">4. Discrimination trees and memoization for instance search</h2>
<p>The current implementation of instance arguments in Agda uses a lookup table based on the head symbol of the return type of each instance candidate, but otherwise uses a linear search through all possible candidates. Worse, filtering out invalid candidates currently requires saving and rolling back the whole type-checking state of Agda, which is obviously not ideal for performance. A more rational implementation of instance search would use discrimination trees for narrowing down the valid instances, and use memoization of candidates during recursive instance search to avoid exponential or even non-terminating instance search.</p>
<h2 id="let-bindings-in-the-internal-syntax">5. Let bindings in the internal syntax</h2>
<p>The internal syntax of Agda does not allow for representation of <code>let</code>-bindings or beta-redexes. This has some advantages for the parts of Agda working on the internal syntax, but comes with a heavy downside for efficiency, as all let-bindings and beta-redexes have to be inlined during elaboration to internal syntax. This destroys sharing and makes some error messages frustratingly difficult to read. A proper representation of let-bindings in the internal syntax would solve both problems.</p>
<h2 id="a-typeable-internal-representation-of-case-trees">6. A typeable internal representation of case trees</h2>
<p>The internal representation of case trees in Agda has really annoyed me for a while, specifically how it deals with variables:</p>
<ul>
<li>Arguments to the case tree are never explicitly introduced with a lambda or something similar, instead case trees are assumed to always take as many arguments as allowed by their type.</li>
<li>In contrast to the rest of Agda’s codebase, variables in a case tree are represented using de Bruijn <em>levels</em> instead of de Bruijn <em>indices</em>.</li>
<li>Dot patterns are counted as variables in the context, even though they are never used in the RHS.</li>
</ul>
<p>Switching to a representation that fits better with the rest of Agda (using de Bruijn indices and explicitly introducing variables) would make it easier to double-check Agda’s internal syntax and to implement backends for typed languages.</p>
<h2 id="proper-internal-representation-of-with-and-rewrite">7. Proper internal representation of <code>with</code> and <code>rewrite</code></h2>
<p>Left-hand side gadgets such as <code>with</code> and <code>rewrite</code> can be very useful to write Agda programs with fancy types without condemning yourself to writing excruciatingly complex helper functions. However, their current implementation is mere syntactic sugar for helper functions that Agda generates internally. That’s a sensible idea in principle but in practice it makes the feature very fragile and unpredictable. Having a proper notion of <code>with</code> in the internal representation of functions would make error messages easier to understand and the implementation easier to maintain.</p>
<h2 id="parametrized-modules-without-lambda-lifting">8. Parametrized modules without lambda-lifting</h2>
<p>The current implementation of parametrized modules in Agda uses lambda-lifting, i.e. internally module parameters are just extra arguments to each function call. When you open a module with specific parameters given, this means that those parameters are duplicated all through the internal syntax, causing slowdowns (sometimes exponentionally) and making it difficult to pretty-print terms in a way that the user recognizes. Having a proper notion of module parameters would make the implementation more efficient and easier to maintain.</p>
<p>(Yes, I realize that the last few improvements are basically “preserve more of the surface syntax in the internal syntax”, which has the disadvantage of increasing the size and complexity of the internal syntax. But I believe the tradeoff is worth it, as demonstrated by the many issues we’re having with the current desugarings.)</p>
<h2 id="a-clear-separation-between-constraint-solving-and-conversion-checking">9. A clear separation between constraint solving and conversion checking</h2>
<p>This might be surprising to those familiar with the implementation of the Rocq Prover (formerly known as Coq), but Agda has a single implementation of conversion checking and unification for constraint solving. This has the advantage of reducing code duplication, but the big disadvantage that the logic of constraint solving gets tangled up with the logic of conversion checking. This is bad because conversion checking needs to be part of the trusted core, but constraint solving doesn’t. A clearer separation between the two implementations would improve maintainability and trustworthiness of Agda.</p>
<h2 id="reduced-reliance-on-mtl-style-type-classes">10. Reduced reliance on MTL-style type classes</h2>
<p>The Agda implementation makes heavy use of MTL-style type classes (it defines <a href="https://ethercalc.net/gj0gb6afi1">43 in total</a>, in addition to the existing ones from <code>mtl</code>). This gives a great degree of control over abstractions and even enables effect polymorphism which we actually use in some cases. Sadly however, GHC does not seem to be well equipped to optimize code in this style, especially across modules. At the moment we mitigate this by relying on two compiler flags (<code>-fexpose-all-unfoldings</code> and <code>-fspecialise-aggressively</code>) but this leads to slow compile times, large binaries, and does not actually solve the problem in all cases. After a few discussions with the Agda developer team, I’ve become convinced that it would be better to move away from MTL-style type classes and towards a more lightweight way of enforcing some abstraction barriers that does not impact compilation or runtime as much.</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Mon, 01 Jan 2024 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/ten-agda-improvements.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>An Invitation to Mindfulness</title>
    <link>https://jesper.sikanda.be/posts/invitation-to-mindfulness.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - An Invitation to Mindfulness</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>An Invitation to Mindfulness</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on September 24, 2023
    </p>
    <p>If you are anything like me, you often crave for a bit of peace and clarity in your busy stressful life. Perhaps you often feel distracted by hundreds of things clamoring for your attention, and find it difficult to determine what is actually important. And maybe you also occasionally wonder what you are doing in this world, and what you could do to live a more fulfilling life.</p>
<p>There is one thing that has helped me with all of these questions, perhaps more than all other hacks and advice I’ve read combined. You’ve heard of it already, it is called mindfulness. Yet while the word is pretty well-known, I see many people who could benefit from mindfulness but currently do not because they do not know where to start, or because they tried it and had a bad experience, or they just do not see the point.</p>
<p>Today I am here to tell you that for me and many others, mindfulness is indeed as good as people say, and there is no need to sit still for hours on end or to practice for many years to get its benefits. I invite you to try if it can be of use for you, too.</p>
<p>So what <em>is</em> mindfulness, really? It is many different things to many different people, which makes it difficult to define. But if I had to try, I would define mindfulness as <em>the practice of paying close attention to your experiences, without making any judgement about them</em>. It is not a difficult thing to do, and yet we usually go through our lives paying attention to nothing and judging everything. If you can simply <em>stop doing that</em> for a couple of minutes, you are practicing mindfulness.</p>
<p>Practicing mindfulness is not complicated: the easiest way is to sit down somewhere quiet, close your eyes, and pay close attention to your breath or any other sensation or feeling. Then just observe what happens in your body and your thoughts and your environment, without wanting to change anything about them. That’s really it, there is nothing else to it, and yet it can transform your life.</p>
<p>When you repeat this practice often enough, eventually you might start to notice more and subtler forms of experience. These experiences do not suddenly appear, but by practicing you become able to notice them more often. Eventually, you will notice the wrong ideas that we all have and that lie at the root of our confusion, and you will be able to transform them or dissolve them entirely.</p>
<p>This could be the end of this post, so if you feel like this is enough for you, you can stop reading and go practice. But if you are curious and still uncertain about what you should actually <em>do</em>, there are some more things that I’ve learned about mindfulness and would like to share.</p>
<h1 id="why-practice-mindfulness">Why practice mindfulness?</h1>
<p>People practice mindfulness for all kinds of different reasons. Monks have practiced it for thousands of years for spiritual reasons, and psychologists have studied it as a tool for reducing stress and anxiety. I would personally classify the possible reasons to practice mindfulness into three categories: direct benefits, self-improvement, and curiosity.</p>
<p><strong>Direct benefits:</strong></p>
<ul>
<li>Because it’s relaxing.</li>
<li>Because it feels good.</li>
<li>To reduce stress.</li>
<li>Because it makes you feel happier.</li>
<li>To let go of old habits.</li>
</ul>
<p><strong>Self-improvement:</strong></p>
<ul>
<li>To feel more gratitude for little things.</li>
<li>To become more compassionate.</li>
<li>To train your mind to become more focused and clearer.</li>
<li>To build the skill to notice your thoughts as they appear.</li>
<li>To become aware of your negative thought patterns and transform them into something more helpful.</li>
</ul>
<p><strong>Curiosity:</strong></p>
<ul>
<li>To discover more about how your mind works.</li>
<li>To gain more awareness of your needs and desires.</li>
<li>To investigate your implicit expectations and assumptions and put them to question.</li>
<li>To become more aware of your unconscious thoughts.</li>
<li>To become Enlightened (though I am still not sure what, if anything, this actually means).</li>
</ul>
<p>You may have your own reasons for wanting to practice mindfulness, or you might start for one reason and discover another reason by practicing. This is all valid.</p>
<h1 id="the-wrong-way-to-meditate">The wrong way to meditate</h1>
<p>Some people will tell you that <em>“<a href="https://kripalu.org/resources/there-s-no-wrong-way-meditate">there</a> is <a href="https://www.mindfulwaycoaching.com/post/no-right-way-no-wrong-way">no wrong</a> way <a href="https://eu.recordonline.com/story/lifestyle/2020/11/24/meditation-there-no-wrong-way-meditate/6327079002/">to do</a> meditation”</em> but in fact, there <strong>is</strong>. In particular, if you have a lot of anxiety, anger, or depressive thoughts, there is a risk that instead of just noticing these feelings you instead become engulfed by them. Eventually you stop noticing them entirely and you <em>become</em> them. If this happens, you can try to return your attention to your body and just notice how you are feeling. Another difficult but potentially rewarding option is to try integrating these negative feelings into your meditation practice. But if this does not work and the negative thoughts keep getting more intense, it is important to <strong>stop practicing</strong> and take care of yourself: go for a walk, listen to some music, take a nap, eat your favorite snack, call a friend, or do whatever else makes you feel better. There are many ways to practice mindfulness and perhaps this one was not the right one for you at this moment, that’s perfectly okay. Next time, perhaps try a guided meditation (I have a few recommendations for meditation apps at the bottom of this post) or try meditating at a different time or in a different environment. If you continue to struggle with negative thoughts triggered by mindfulness, you could also read <a href="https://www.goodreads.com/book/show/32191672-trauma-sensitive-mindfulness">Trauma-sensitive Mindfulness</a> (I have not read it yet, but <a href="https://neurodifferent.me/@theautisticcoach">Matthew</a> recommends it). In the end, it might also be the case that meditation simply isn’t the right thing for you at this point in your life, and that is okay too.</p>
<h1 id="seven-common-misconceptions">Seven common misconceptions</h1>
<p>Apart from “there is no wrong way to meditate”, there are many other misconceptions that prevent some people from giving mindfulness a shot. Here is my attempt to rectify some of them:</p>
<ol type="1">
<li>The goal of mindfulness is not to stop having thoughts or feelings, but to notice that you are having them and to stop identifying with them or holding on to them.</li>
<li>Mindfulness is not inherently connected to religion or spirituality. It does not require any belief in the mystical or supernatural, and some of its benefits have been <a href="https://www.clearerthinking.org/post/2015/09/29/stressed-depressed-mindfulness-meditation-may-be-for-you">scientifically proven</a>.</li>
<li>Mindfulness is not really about reducing stress or becoming happier, though these are a result of mindfulness for many people. In particular, even if your life is already happy and stress-free you can still find many benefits in mindfulness, such as deeper insight into your needs and goals in life.</li>
<li>You don’t need to practice mindfulness for long stretches at a time or regularly for many years to get its benefits. You can really just make your next breath a mindful one, and <a href="https://www.clearerthinking.org/post/2019/10/30/we-put-some-simple-happiness-boosting-habits-to-the-test-here-s-what-we-found">you will instantly become more relaxed</a>.</li>
<li>You do not need to sit still to meditate, you can lie down or stand up or walk or move your body in any way you like, as long as you continue to pay attention to your perceptions. In fact, you can practice mindfulness at any moment of the day while doing something else. But especially at first, it is often easier to meditate when there are not too many distractions.</li>
<li>You do not need to focus on your breath to meditate, you can focus on other things such as the sounds around you, the feeling of your body, your visual field, a mental image of a good friend or loved one, an emotion, or your consciousness itself. Personally I had some success meditating by focusing completely on the sensations in my feet when other parts of my body were feeling sore. But focusing on the breath works well for many people, so it is recommended to try it first.</li>
<li>You do not need to force your breath into any particular rhythm to meditate. Stay away from any guided meditation that talks about “<a href="https://en.wikipedia.org/wiki/Breathwork">breathwork</a>” or instructs you to breathe in a way that feels unnatural. If your breath is fast, just notice that it is fast. If your breath is slow, notice that it is slow. You do not need to change anything.</li>
</ol>
<h1 id="the-four-elements-meditation">The Four Elements meditation</h1>
<p>While you can be mindful without any help or guidance, following a guided meditation often makes it a bit easier to get in the right mindset. Doing it from time to time can also really help deepen your experience. So to get you started, here is a self-guided meditation that I’ve put together. I often use it during a silent meditation when I feel the need for some direction for my thoughts. It is build from five stages inspired by the four elements and the spirits. You can read all stages in advance, read each one individually after you finish the last one, or just pick a single one. It usually takes me around 15 minutes to go through all five, but your experience may vary. Also be aware that it might have the side-effect of making you think you are the Avatar, and if this happens I deny all responsibility.</p>
<p><strong>Air</strong>. Take a deep breath. Notice how the air flows into your nose, fills your lungs, and raises your chest and belly. Slowly let it go. Continue following your breath for ten in- and out-breaths. Feel the oxygen reaching into every part of your lungs, and the carbondioxide flow back out through your nose. See if you can gently increase the length of your breath without forcing it. Like the air, you are empty but always present.</p>
<p><strong>Water</strong>. Imagine refreshing water pouring gently on top of your head. Feel it flow down your forehead, your face, your ears, your lips, your chin. Let it flow further down along your throat and neck to your chest, down your hands and your fingertips. Down along your body to your stomach and your hips. Finally, through your legs to your knees and feet and every little toe. Like the water, you are always in motion, never the same as the moment before.</p>
<p><strong>Earth</strong>. Notice the places where your body is touching your chair or the floor beneath you. Feel how the earth pulls you and holds you in place, inviting you to rest. Feel at the same time how the earth supports you and ensures you don’t fall, providing solidity and stability. Like the earth, each part of your body itself supports and holds the parts connected to it. Like the earth, you are allowed to just <em>be</em> without doing anything.</p>
<p><strong>Fire</strong>. Feel the temperature of your body. Which places are warm, which ones are cold? Your toes, your ears, your nose, your armpits, your belly, your heart? Inside of you is a gentle warmth that is with you for as long as you are alive. It surrounds you like a soft blanket, protecting you from the cold outside. Feel how it gives you energy and movement and life. Feel how at the same time, it consumes you from the inside. Like the fire, you are constantly dying and being reborn in every moment.</p>
<p><strong>Spirits</strong>. Pay attention to your thoughts themselves. Each thought is like a spirit creature: some are small and cute, others are scary or hidden away. Give each thought the time to manifest without judging it. Each thought has a reason for being there and wants the best for you, even if they are sometimes misguided. All they want is to be listened to and to be taken seriously. Embrace each of them like an old friend. Be grateful to each of them for being there for you. Like the spirits, the only thing you really need is to be listened to and to be loved.</p>
<h1 id="further-resources">Further resources</h1>
<p>Finally, let me point you to some resources for the practice of mindfulness that I found helpful.</p>
<ul>
<li><a href="https://insighttimer.com/">InsightTimer</a> is a free app with a vast collection of guided meditations. There is a lot of really good content on here, but you will sometimes need to filter through some less useful stuff.</li>
<li><a href="https://www.wakingup.com/">The Waking Up app</a> is a more focused and in-depth app that uses the practice of “non-dual meditation”, also known as “no-effort meditation”. I started using it recently and found it very helpful. It is paid but you can get a 30 day trial through <a href="https://dynamic.wakingup.com/shareOpenAccess/SC1F98F45">my referral link</a>.</li>
<li><a href="https://plumvillage.org/podcasts/the-way-out-is-in">The Way Out Is In</a> is a podcast about the practice of mindfulness featuring in-depth conversations between Brother Phap Huu, the abbot of Plum Village monastery in France, and journalist Jo Confino. Each episode also ends with a short guided meditation.</li>
<li><a href="https://www.goodreads.com/book/show/95747.The_Miracle_of_Mindfulness">The Miracle of Mindfulness</a> is the classic book written in 1975 by Zen master Thich Nhat Hanh, who is often credited with “bringing mindfulness to the West”. He has a large number of books on various topics, I particularly enjoyed <a href="https://www.goodreads.com/book/show/23149937-silence">Silence</a> and am currently cracking my brain on <a href="https://www.goodreads.com/book/show/121527371-cracking-the-walnut">Cracking the Walnut</a>. If you are into (climate) activism, you might also enjoy <a href="https://www.goodreads.com/book/show/52575747-zen-and-the-art-of-saving-the-planet">Zen and the Art of Saving the Planet</a>.</li>
<li><a href="https://www.lesswrong.com/posts/QqSNFcGSZdnARx56E/meditation-insight-and-rationality-part-1-of-3">This blog post on meditation, insight, and rationality</a> was one of the first things I read about mindfulness and explains the point of meditation from a rational perspective. While I don’t agree anymore with everything in it, it definitely helped me to get over that initial bump of confusion.</li>
</ul>
<p>From time to time, someone will (re)discover their own way of practicing mindfulness and loudly shout that they have found the True Path to Happiness. Some of these that I’ve noticed so far: <a href="https://www.goodreads.com/book/show/408265.The_Power_of_Focusing">focusing</a>, <a href="https://www.goodreads.com/book/show/58537365-unmasking-autism">unmasking</a>, <a href="https://www.lesswrong.com/posts/BfTW9jmDzujYkhjAb/you-are-probably-underestimating-how-good-self-love-can-be">self-love</a>, <a href="https://podcast.clearerthinking.org/episode/173/pia-callesen-using-metacognitive-therapy-to-break-the-habit-of-rumination/">meta-cognitive therapy</a>, <a href="https://www.authrev.org/what-is-authentic-relating">authentic relating</a>, <a href="https://www.lesswrong.com/posts/xYnnRmMmGRAwZoY25/for-happiness-keep-a-gratitude-journal">gratitude journaling</a>, and <a href="https://cannibalhalflinggaming.com/2023/07/15/the-ink-that-bleeds-review-an-immersive-dive-into-immersive-journaling/">immersive journaling games</a>. If you find the framing of mindfulness as meditation not working for you, one of these might be a better fit.</p>
<p>As always, feel free to send any comments about this blog post to me via <a href="mailto:jesper@sikanda.be">email</a> or to <a href="https://types.pl/@agdakx"><span class="citation" data-cites="agdakx">@agdakx</span><span class="citation" data-cites="types.pl">@types.pl</span></a>.</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Sun, 24 Sep 2023 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/invitation-to-mindfulness.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>Ten common writing issues in student papers</title>
    <link>https://jesper.sikanda.be/posts/writing-issues.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Ten common writing issues in student papers</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Ten common writing issues in student papers</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on August  1, 2023
    </p>
    <p>Good writing is important, and it takes time to get it right. Over the last couple of months, I have been reading and giving feedback on <em>way too many</em> papers written by bachelor students, master students, PhD students, and people who should really know better. To help both my students and my future self, I am thus inspired to write down some of the issues that I encountered again and again. I tried to keep them short and sweet, but I might come back to this post and expand it if there is interest (just shoot me an email or a toot). Also, I included some links to other sources that I find helpful at the bottom.</p>
<h2 id="lack-of-context">Lack of context</h2>
<p>When you write a paper you do so from a very specific context: you are at a specific university, working with a specific supervisor, working on a specific goal in mind. But if you want your paper to be read by people other than your supervisor or direct collaborators, you need to step outside of that context and think about questions that might be obvious to you. Where is this problem situated in the broader academic field? What are the questions that are considered hard or important in your sub-field? What kind of people would benefit if this problem were solved? What are commonly used techniques for working on these problems?</p>
<h2 id="lack-of-motivation">Lack of motivation</h2>
<p>It’s just as important to explain <em>why</em> you are writing this paper as it is to describe <em>what</em> you did. In fact, it’s more important, as a reader who’s not convinced of the goal of the paper won’t read any further. Readers usually do not yet know about the problem you want to solve, so you do really need to explain what you want to accomplish, why this is important, why this is useful, … So motivation should be your <em>first</em> concern when writing the paper, and should ideally already be clear from the abstract.</p>
<h2 id="lack-of-focus">Lack of focus</h2>
<p>Your paper should have at its core a <strong>main idea</strong> for which you want to convince the reader of its importance. All other parts of your paper should be assessed through the lens of this main idea: if it does not contribute to it, then it’s often better to throw it out.</p>
<h2 id="lack-of-examples">Lack of examples</h2>
<p>Examples are always good, especially when the general case of the thing you are explaining is complex or general. They force you to be concrete and precise. Make sure that each example is as simple as it can be and does not rely on anything that is unexplained or not relevant to the thing it is an example of.</p>
<h2 id="lack-of-signposting">Lack of signposting</h2>
<p>A good academic text needs to make its structure obvious. The reader should be able to navigate easily to the parts of the text that are most relevant to them. Of course some of this is accomplished by a proper structure of sections and subsections, but this on itself is not sufficient. Before jumping into the specific, you first need to explain the general thing. For example, if you have a section with three subsections identifying three different challenges, you should name the three challenges <em>before</em> the first subsection, and explain how they are connected.</p>
<p>This applies on the level of the whole paper as well as the level of an individual paragraph. When you explain a set of typing rules or some pseudocode, don’t just go through it from start to finish, but instead start from the high-level view of the overall structure and then zoom into details.</p>
<h2 id="keeping-the-reader-in-suspense">Keeping the reader in suspense</h2>
<p>Your text is not a work of fiction so you don’t have to worry about keeping the reader in suspense. If the reader has gotten out of your paper what they need after the first two pages and stops reading, then that’s a success. So put the most important results and conclusions front and center in the introduction of your paper so readers don’t have to look for them.</p>
<h2 id="explaining-all-solutions-that-do-not-work-before-giving-your-solution">Explaining all solutions that do not work before giving your solution</h2>
<p>I understand the urge to explain all the previous attempts at solving the same problem and where they went wrong. However, this is both confusing to readers unfamiliar with the previous work (since they don’t want to learn about solutions that don’t work) and frustrating to people who do know it (since there’s nothing new for them). Instead the right place for such comparisons is in the related work section, which should come <em>after</em> the main technical part of the paper.</p>
<h2 id="assuming-the-reader-already-knows-technical-terms">Assuming the reader already knows technical terms</h2>
<p>If you use a technical term, then you should introduce it either by explaining what it is and/or by giving a citation to where the reader can find it. What exactly is a “technical term” is dependent on the audience but it’s good to err on the side of safety. Your text might be read by someone from a different research area, or by someone reading this in 30 years when the terminology has changed.</p>
<h2 id="assuming-pictures-or-code-blocks-or-inference-rules-are-self-explanatory">Assuming pictures or code blocks or inference rules are self-explanatory</h2>
<p>Spoiler alert: they are not. Explain them in plain text.</p>
<h2 id="using-imprecise-or-convoluted-language">Using imprecise or convoluted language</h2>
<p>These are some more micro-level issues that seem inconsequential but can very much distract from the main point of the text. I recommend keeping a list of the ones that often appear in your own writing and doing a search-and-replace for them during proofreading.</p>
<ul>
<li>Using comparatives without a point of comparison: writing that your approach is “more expressive”, “simpler”, “more secure”, … without mentioning what is the point of comparison.</li>
<li>Imprecise language such as “some”, “a lot”, “many”, “significantly”, “greatly”, “drastically”, “extremely”, “a number of”, “very”, “important”, “crucial”, “something like”, “things”, … Instead, be precise about what you observe and how it compares and let the reader judge for themselves.</li>
<li>Superfluous turns of phrase: “The reader might have noticed that…”, “We argue that…”, “Note that…”, “It is important that…”, “We say that…”, “We know that…”, “As previously mentioned…”, …</li>
<li>Using passive voice: “our approach was evaluated” instead of “we evaluate our approach”.</li>
<li>Using future or past tense where present tense would be just fine: “In this paper, we will show…” and “In this paper, we have shown…” are both needlessly wordy. “In this paper, we show” is more direct and works just fine.</li>
<li>Using words that serve to make the reader feel stupid: “simple”, “elementary”, “straightforward”, “basic”, “trivial”, “just”, “of course”, …</li>
<li>Demonstrative pronouns without a clear referent: “This is…”, “these things are…”</li>
</ul>
<h1 id="other-sources">Other sources</h1>
<ul>
<li>Book: <a href="https://press.princeton.edu/books/paperback/9780691219189/the-scientists-guide-to-writing-2nd-edition">The Scientist’s Guide to Writing by Stephen Heard</a></li>
<li>Book: <a href="https://www.principiae.be/X0100.php">Trees, Maps, and Theorems by Jean-Luc Dumont</a></li>
<li>Video: <a href="https://www.youtube.com/watch?v=1AYxMbYZQ1Y">How to write a great research paper by Simon Peyton Jones</a></li>
<li>Video: <a href="https://www.youtube.com/watch?v=PM1Atui30qU">How to write papers so people can read them by Derek Dreyer</a></li>
<li>Video: <a href="https://www.youtube.com/watch?v=b-M2U3Jl1Cg">How to explain things real good by Nicki Case</a></li>
<li>Web page: <a href="https://eelcovisser.org/wiki/teaching/writing/">Writing tips by Eelco Visser</a></li>
<li>Blog post: <a href="https://avandeursen.com/2013/07/10/research-paper-writing-recommendations/">Some Research Paper Writing Recommendations by Arie van Deursen</a></li>
<li>Blog post: <a href="https://andreas-zeller.blogspot.com/2013/04/my-top-ten-presentation-issues-in.html">My top ten presentation issues in other’s papers by Andreas Zeller</a></li>
</ul>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Tue, 01 Aug 2023 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/writing-issues.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>I'm Autistic, and that's okay</title>
    <link>https://jesper.sikanda.be/posts/being-autistic.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - I'm Autistic, and that's okay</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>I'm Autistic, and that's okay</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on April 22, 2023
    </p>
    <p>I don’t expect this will be a surprise to people who know me, but at
the same time I have never told most people. So I’m making it official
now: I am Autistic (if you wonder about the capitalization of
Autistic: please go read <a href="https://humanparts.medium.com/im-not-differently-abled-i-m-disabled-4ed8637036c3">this
post</a>). I
was officially diagnosed when I was around 18 years old, though even
then it was not really a big surprise to me. Still, somehow I never
felt like telling people about it. Recently I finished reading the
book <a href="https://www.goodreads.com/book/show/58537365-unmasking-autism">Unmasking
Autism</a>
by Devon Price, which made me update my opinions on many of the
concerns I used to have and made me comfortable with calling myself
Autistic in public.</p>
<p>So why did I never tell anyone, even when I suspected they suspected?
There are many reasons, which I guess are relatively common: I didn’t
want to “put a label on myself”, I didn’t want to be treated
differently, I didn’t want to burden the people around me, I didn’t
feel like I was “autistic enough” , I was afraid to be mocked or
bullied, … But the most important reason was that I didn’t want to
view myself as disabled or less worthy than other people. Slowly over
the years, I’ve come to the realization that this view is problematic,
and it is actually okay to be Autistic (or otherwise disabled, or just
different from others). Price’s book helped to dispel the left-over
traces of that view in me.</p>
<p>As I mentioned, one of the reasons I used to have for not accepting
myself as Autistic is that I didn’t feel “autistic enough” (<a href="https://medium.com/autistic-advice/am-i-autistic-enough-to-count-as-autistic-6aa65817b118">whatever
that
means</a>). However,
while reading Price’s book I could recognize myself in a surprising
number of feelings and behaviours. The book even mentions that
thinking “oh, is <em>that</em> an Autistic thing too?” is itself a common
Autistic experience! I used to think that being able to successfully
hide some parts of my Autism (i.e. masking) meant that I was not
disabled or suffering from it, but obviously being continuously
exhausted from masking is itself a form of suffering.</p>
<p>My experience with having a wrong perception of Autism - despite being
diagnosed as Autistic myself! - suggests that many people still do not
have a good idea of the different ways in which people experience
being Autistic. So to help other people to expand their concept of
what it is like, here is a list of ten things that being Autistic
means to me:</p>
<ol type="1">
<li><p>I can get completely absorbed by one of my “special interests”. My
most enduring interest (apart from dependent type systems) is probably
tabletop role-playing games and story games, which I like to play,
collect, and analyze the rules of (according to my list, I have
purchased physical books of 34 different RPGs, and digital versions of
55 more). Every now and then a new special interest comes up and
causes me to spend anywhere from a few hours to a few months being
completely absorbed in them.</p></li>
<li><p>I am constantly worrying about what is or isn’t “appropriate” in
any given social context, and try to adapt to unspoken
assumptions. This drains energy and often leaves me feeling exhausted.</p></li>
<li><p>I’ve been fidgeting with things for all my life. I’ve been bullied
for it in school, reprimanded for it by my parents, and tried to
suppress it when I’m afraid people will judge me for it.</p></li>
<li><p>I can’t count the number of times I’ve been called “sensitive”,
“absent-minded”, “oblivious”, or “naive”, from when I was in primary
school to today.</p></li>
<li><p>I often have difficulty prioritizing, making decisions, or getting
a feeling of what I want to do. This leads to endless overthinking and
often stops me from taking action at all.</p></li>
<li><p>I often find it hard to maintain a two-sided conversation,
especially with people I don’t know well and/or don’t share many
interests with.</p></li>
<li><p>I am endlessly curious and able to absorb large amounts of
information and organize it in a more structured way.</p></li>
<li><p>In situations where I feel confident, I can be direct and even
blunt in saying things that other people were being afraid to say or
were having difficulty articulating.</p></li>
<li><p>I am often hesitant in a conversation to take initiative by asking
questions or talking about things that interest me, instead biding my
time and trying to mirror how other people are acting.</p></li>
<li><p>I keep most people in my life at a safe distance and avoid to talk
about my personal feelings, out of fear people might find me too weird
and distance themselves from me.</p></li>
</ol>
<p>For many of these points, I have already been in the process of
unmasking for a while now, so they may be less obvious to people who
I’ve only got to know in recent years. This process of unmasking has
been a very positive experience for me, and hence I want to encourage
other people who (suspect they) are Autistic to try the same! I
recommend you go read the book (here is a link to the <a href="https://www.devriesvanstockum.nl/unmasking-autism-devon-price-9781800960541.html">local bookstore
in The Hague where I bought
it</a>),
and, if you feel comfortable, feel free to share your stories with me
on Mastodon (<a href="https://types.pl/@agdakx"><span class="citation" data-cites="agdakx">@agdakx</span><span class="citation" data-cites="types.pl">@types.pl</span></a> or
<a href="https://dice.camp/@dregntael"><span class="citation" data-cites="dregntael">@dregntael</span><span class="citation" data-cites="dice.camp">@dice.camp</span></a>) or send me a
private message.</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Sat, 22 Apr 2023 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/being-autistic.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>Don't worry (about writing Haskell), be happy (writing Agda instead)!</title>
    <link>https://jesper.sikanda.be/posts/agda2hs.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Don't worry (about writing Haskell), be happy (writing Agda instead)!</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Don't worry (about writing Haskell), be happy (writing Agda instead)!</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on October  4, 2022
    </p>
    <!--
<pre class="Agda"><a id="129" class="Symbol">{-#</a> <a id="133" class="Keyword">OPTIONS</a> <a id="141" class="Pragma">--sized-types</a> <a id="155" class="Pragma">--erasure</a> <a id="165" class="Symbol">#-}</a>

<a id="170" class="Keyword">module</a> <a id="177" href="agda2hs.html" class="Module">agda2hs</a> <a id="185" class="Keyword">where</a>

<a id="192" class="Keyword">open</a> <a id="197" class="Keyword">import</a> <a id="204" href="Agda.Primitive.html" class="Module">Agda.Primitive</a> <a id="219" class="Keyword">using</a> <a id="225" class="Symbol">(</a><a id="226" href="Agda.Primitive.html#742" class="Postulate">Level</a><a id="231" class="Symbol">)</a>
<a id="233" class="Keyword">open</a> <a id="238" class="Keyword">import</a> <a id="245" href="Relation.Binary.PropositionalEquality.html" class="Module">Relation.Binary.PropositionalEquality</a>
  <a id="285" class="Keyword">using</a> <a id="291" class="Symbol">(</a><a id="292" href="Relation.Binary.PropositionalEquality.Core.html#1481" class="Function">cong</a><a id="296" class="Symbol">)</a>

<a id="299" class="Keyword">open</a> <a id="304" class="Keyword">import</a> <a id="311" href="Agda.Builtin.Size.html" class="Module">Agda.Builtin.Size</a>

<a id="330" class="Keyword">variable</a>
  <a id="341" href="agda2hs.html#341" class="Generalizable">ℓ</a> <a id="343" class="Symbol">:</a> <a id="345" href="Agda.Primitive.html#742" class="Postulate">Level</a>
  <a id="353" href="agda2hs.html#353" class="Generalizable">i</a> <a id="355" class="Symbol">:</a> <a id="357" href="Agda.Builtin.Size.html#213" class="Postulate">Size</a>
</pre>-->
<p>As we all know, static type systems are great to ensure correctness of
our programs. Sadly, in industry many people are forced to work in
languages with a weak type system, such as Haskell. What should you do
in such a situation? Quit your job? Give up and despair? Perhaps, but
I have another suggestion that I’d like to explain in this post: use
our tool <a href="https://github.com/agda/agda2hs"><code>agda2hs</code></a>.</p>
<p>What is this <code>agda2hs</code>, I hear you asking? Agda2hs is a tool for
producing verified and readable Haskell code by extracting it from a
(lightly annotated) Agda program. This means you can write your code
using Agda’s support for dependent types, interactive editing, and
termination checking, and from this <code>agda2hs</code> will generate clean and
simply typed Haskell code that looks like it was written by hand. Your
boss will be amazed that all of your code is correct from the first
try, and never even suspect that you secretly proved its correctness
in Agda!</p>
<h2 id="first-steps-verifying-list-insertion">First steps: verifying list insertion</h2>
<p>Let’s take a look at an example of how <strong>you</strong> can use <code>agda2hs</code> to
produce provably correct Haskell code. Suppose we want to insert an
element into a sorted list. That’s easy enough:</p>
<pre class="Agda"><a id="1564" class="Keyword">open</a> <a id="1569" class="Keyword">import</a> <a id="1576" href="Haskell.Prelude.html" class="Module">Haskell.Prelude</a>

<a id="insert"></a><a id="1593" href="agda2hs.html#1593" class="Function">insert</a> <a id="1600" class="Symbol">:</a> <a id="1602" class="Symbol">{{</a><a id="1604" href="Haskell.Prim.Ord.html#1004" class="Record">Ord</a> <a id="1608" href="Haskell.Prim.html#1214" class="Generalizable">a</a><a id="1609" class="Symbol">}}</a> <a id="1612" class="Symbol">→</a> <a id="1614" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="1616" class="Symbol">→</a> <a id="1618" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="1623" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="1625" class="Symbol">→</a> <a id="1627" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="1632" href="Haskell.Prim.html#1214" class="Generalizable">a</a>
<a id="1634" href="agda2hs.html#1593" class="Function">insert</a> <a id="1641" href="agda2hs.html#1641" class="Bound">x</a> <a id="1643" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a> <a id="1646" class="Symbol">=</a> <a id="1648" href="agda2hs.html#1641" class="Bound">x</a> <a id="1650" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="1652" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a>
<a id="1655" href="agda2hs.html#1593" class="Function">insert</a> <a id="1662" href="agda2hs.html#1662" class="Bound">x</a> <a id="1664" class="Symbol">(</a><a id="1665" href="agda2hs.html#1665" class="Bound">y</a> <a id="1667" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="1669" href="agda2hs.html#1669" class="Bound">ys</a><a id="1671" class="Symbol">)</a> <a id="1673" class="Symbol">=</a>
  <a id="1677" href="Haskell.Prim.html#1739" class="Function Operator">if</a> <a id="1680" href="agda2hs.html#1662" class="Bound">x</a> <a id="1682" href="Haskell.Prim.Ord.html#1075" class="Field Operator">&lt;</a> <a id="1684" href="agda2hs.html#1665" class="Bound">y</a>
  <a id="1688" href="Haskell.Prim.html#1739" class="Function Operator">then</a> <a id="1693" href="agda2hs.html#1662" class="Bound">x</a> <a id="1695" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="1697" href="agda2hs.html#1665" class="Bound">y</a> <a id="1699" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="1701" href="agda2hs.html#1669" class="Bound">ys</a>
  <a id="1706" href="Haskell.Prim.html#1739" class="Function Operator">else</a> <a id="1711" href="agda2hs.html#1665" class="Bound">y</a> <a id="1713" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="1715" href="agda2hs.html#1593" class="Function">insert</a> <a id="1722" href="agda2hs.html#1662" class="Bound">x</a> <a id="1724" href="agda2hs.html#1669" class="Bound">ys</a>
</pre>
<p>The syntax is deliberately chosen to be very close to the
corresponding Haskell syntax, except for the swapping of <code>:</code> and <code>::</code>.
I am using some definitions from the
<a href="https://github.com/agda/agda2hs/tree/master/lib/Haskell">prelude</a>
that is included with <code>agda2hs</code>, in particular the <code>Ord</code> type. The
double braces <code>{{}}</code> indicate an <a href="https://agda.readthedocs.io/en/v2.6.2.2/language/instance-arguments.html">instance
argument</a>,
which is Agda’s way of doing type classes.</p>
<p>To make <code>agda2hs</code> do its magic, there is just one more invocation
needed:</p>
<pre class="Agda"><a id="2284" class="Symbol">{-#</a> <a id="2288" class="Keyword">COMPILE</a> <a id="2296" class="Keyword">AGDA2HS</a> <a id="2304" href="agda2hs.html#1593" class="Function">insert</a> <a id="2311" class="Symbol">#-}</a>
</pre>
<p>Now, calling <code>agda2hs</code> on this file produces the corresponding Haskell
code:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>insert x [] <span class="ot">=</span> [x]</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>insert x (y <span class="op">:</span> ys) <span class="ot">=</span> <span class="kw">if</span> x <span class="op">&lt;</span> y <span class="kw">then</span> x <span class="op">:</span> (y <span class="op">:</span> ys) <span class="kw">else</span> y <span class="op">:</span> insert x ys</span></code></pre></div>
<p>So far, so Haskell. But this looks awfully complicated, how can we
ever know it is correct? Prove it, of course! One property that
certainly needs to hold is that when we insert an element into a list,
then that element should be in the resulting list.</p>
<pre class="Agda"><a id="2793" class="Keyword">data</a> <a id="_∈_"></a><a id="2798" href="agda2hs.html#2798" class="Datatype Operator">_∈_</a> <a id="2802" class="Symbol">(</a><a id="2803" href="agda2hs.html#2803" class="Bound">x</a> <a id="2805" class="Symbol">:</a> <a id="2807" href="Haskell.Prim.html#1214" class="Generalizable">a</a><a id="2808" class="Symbol">)</a> <a id="2810" class="Symbol">:</a> <a id="2812" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="2817" href="agda2hs.html#2807" class="Bound">a</a> <a id="2819" class="Symbol">→</a> <a id="2821" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="2825" class="Keyword">where</a>
  <a id="_∈_.here"></a><a id="2833" href="agda2hs.html#2833" class="InductiveConstructor">here</a>  <a id="2839" class="Symbol">:</a> <a id="2841" class="Symbol">∀</a> <a id="2843" class="Symbol">{</a><a id="2844" href="agda2hs.html#2844" class="Bound">ys</a><a id="2846" class="Symbol">}</a>            <a id="2859" class="Symbol">→</a> <a id="2861" href="agda2hs.html#2803" class="Bound">x</a> <a id="2863" href="agda2hs.html#2798" class="Datatype Operator">∈</a> <a id="2865" class="Symbol">(</a><a id="2866" href="agda2hs.html#2803" class="Bound">x</a> <a id="2868" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="2870" href="agda2hs.html#2844" class="Bound">ys</a><a id="2872" class="Symbol">)</a>
  <a id="_∈_.there"></a><a id="2876" href="agda2hs.html#2876" class="InductiveConstructor">there</a> <a id="2882" class="Symbol">:</a> <a id="2884" class="Symbol">∀</a> <a id="2886" class="Symbol">{</a><a id="2887" href="agda2hs.html#2887" class="Bound">y</a> <a id="2889" href="agda2hs.html#2889" class="Bound">ys</a><a id="2891" class="Symbol">}</a> <a id="2893" class="Symbol">→</a> <a id="2895" href="agda2hs.html#2803" class="Bound">x</a> <a id="2897" href="agda2hs.html#2798" class="Datatype Operator">∈</a> <a id="2899" href="agda2hs.html#2889" class="Bound">ys</a> <a id="2902" class="Symbol">→</a> <a id="2904" href="agda2hs.html#2803" class="Bound">x</a> <a id="2906" href="agda2hs.html#2798" class="Datatype Operator">∈</a> <a id="2908" class="Symbol">(</a><a id="2909" href="agda2hs.html#2887" class="Bound">y</a> <a id="2911" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="2913" href="agda2hs.html#2889" class="Bound">ys</a><a id="2915" class="Symbol">)</a>

<a id="insert-elem"></a><a id="2918" href="agda2hs.html#2918" class="Function">insert-elem</a> <a id="2930" class="Symbol">:</a> <a id="2932" class="Symbol">∀</a> <a id="2934" class="Symbol">{{</a><a id="2936" href="agda2hs.html#2936" class="Bound">_</a> <a id="2938" class="Symbol">:</a> <a id="2940" href="Haskell.Prim.Ord.html#1004" class="Record">Ord</a> <a id="2944" href="Haskell.Prim.html#1214" class="Generalizable">a</a><a id="2945" class="Symbol">}}</a> <a id="2948" class="Symbol">(</a><a id="2949" href="agda2hs.html#2949" class="Bound">x</a> <a id="2951" class="Symbol">:</a> <a id="2953" href="Haskell.Prim.html#1214" class="Generalizable">a</a><a id="2954" class="Symbol">)</a> <a id="2956" class="Symbol">(</a><a id="2957" href="agda2hs.html#2957" class="Bound">xs</a> <a id="2960" class="Symbol">:</a> <a id="2962" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="2967" href="Haskell.Prim.html#1214" class="Generalizable">a</a><a id="2968" class="Symbol">)</a>
            <a id="2982" class="Symbol">→</a> <a id="2984" href="agda2hs.html#2949" class="Bound">x</a> <a id="2986" href="agda2hs.html#2798" class="Datatype Operator">∈</a> <a id="2988" href="agda2hs.html#1593" class="Function">insert</a> <a id="2995" href="agda2hs.html#2949" class="Bound">x</a> <a id="2997" href="agda2hs.html#2957" class="Bound">xs</a>
<a id="3000" href="agda2hs.html#2918" class="Function">insert-elem</a> <a id="3012" href="agda2hs.html#3012" class="Bound">x</a> <a id="3014" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a> <a id="3017" class="Symbol">=</a> <a id="3019" href="agda2hs.html#2833" class="InductiveConstructor">here</a>
<a id="3024" href="agda2hs.html#2918" class="Function">insert-elem</a> <a id="3036" href="agda2hs.html#3036" class="Bound">x</a> <a id="3038" class="Symbol">(</a><a id="3039" href="agda2hs.html#3039" class="Bound">y</a> <a id="3041" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="3043" href="agda2hs.html#3043" class="Bound">ys</a><a id="3045" class="Symbol">)</a> <a id="3047" class="Keyword">with</a> <a id="3052" href="agda2hs.html#3036" class="Bound">x</a> <a id="3054" href="Haskell.Prim.Ord.html#1075" class="Field Operator">&lt;</a> <a id="3056" href="agda2hs.html#3039" class="Bound">y</a>
<a id="3058" class="Symbol">...</a> <a id="3062" class="Symbol">|</a> <a id="3064" href="Agda.Builtin.Bool.html#198" class="InductiveConstructor">True</a>  <a id="3070" class="Symbol">=</a> <a id="3072" href="agda2hs.html#2833" class="InductiveConstructor">here</a>
<a id="3077" class="Symbol">...</a> <a id="3081" class="Symbol">|</a> <a id="3083" href="Agda.Builtin.Bool.html#192" class="InductiveConstructor">False</a> <a id="3089" class="Symbol">=</a> <a id="3091" href="agda2hs.html#2876" class="InductiveConstructor">there</a> <a id="3097" class="Symbol">(</a><a id="3098" href="agda2hs.html#2918" class="Function">insert-elem</a> <a id="3110" class="Bound">x</a> <a id="3112" class="Bound">ys</a><a id="3114" class="Symbol">)</a>
</pre>
<p>Of course this isn’t enough: defining <code>insert x _ = x ∷ []</code> satisfies
this specification. Following the ancient tradition, I leave
identifying and proving the other properties of insertion as an
exercise to the interested reader.</p>
<h2 id="intrinsic-verification-with-agda2hs">Intrinsic verification with <code>agda2hs</code></h2>
<p>The proof above is an example of <em>extrinsic</em> verification: we first
write a simply-typed Haskell-like function and prove properties of it
after-the-fact. Another style of proof that is sometimes easier to use
is <em>intrinsic verification</em>: here we encode the properties directly in
the type of our data, so it becomes impossible to write an incorrect
function in the first place.</p>
<p>Avoiding the tired example of length-indexed vectors, let’s take a
look instead at the type of height-indexed trees, i.e. trees that are
indexed by the maximum length of the paths to their leaves. There are
two ways to construct a height-indexed tree: <code>Tip</code> produces a tree of
height <code>0</code>, while <code>Bin</code> takes an element of type <code>a</code> and two subtrees,
and produces a tree of height 1 + the <em>maximum</em> of the heights of the
two subtrees.</p>
<pre class="Agda"><a id="maxNat"></a><a id="4211" href="agda2hs.html#4211" class="Function">maxNat</a> <a id="4218" class="Symbol">:</a> <a id="4220" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a> <a id="4224" class="Symbol">→</a> <a id="4226" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a> <a id="4230" class="Symbol">→</a> <a id="4232" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a>
<a id="4236" href="agda2hs.html#4211" class="Function">maxNat</a> <a id="4243" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>    <a id="4251" href="agda2hs.html#4251" class="Bound">n</a>       <a id="4259" class="Symbol">=</a> <a id="4261" href="agda2hs.html#4251" class="Bound">n</a>
<a id="4263" href="agda2hs.html#4211" class="Function">maxNat</a> <a id="4270" class="Symbol">(</a><a id="4271" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="4275" href="agda2hs.html#4275" class="Bound">m</a><a id="4276" class="Symbol">)</a> <a id="4278" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>    <a id="4286" class="Symbol">=</a> <a id="4288" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="4292" href="agda2hs.html#4275" class="Bound">m</a>
<a id="4294" href="agda2hs.html#4211" class="Function">maxNat</a> <a id="4301" class="Symbol">(</a><a id="4302" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="4306" href="agda2hs.html#4306" class="Bound">m</a><a id="4307" class="Symbol">)</a> <a id="4309" class="Symbol">(</a><a id="4310" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="4314" href="agda2hs.html#4314" class="Bound">n</a><a id="4315" class="Symbol">)</a> <a id="4317" class="Symbol">=</a> <a id="4319" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="4323" class="Symbol">(</a><a id="4324" href="agda2hs.html#4211" class="Function">maxNat</a> <a id="4331" href="agda2hs.html#4306" class="Bound">m</a> <a id="4333" href="agda2hs.html#4314" class="Bound">n</a><a id="4334" class="Symbol">)</a>

<a id="4337" class="Keyword">data</a> <a id="Tree"></a><a id="4342" href="agda2hs.html#4342" class="Datatype">Tree</a> <a id="4347" class="Symbol">(</a><a id="4348" href="agda2hs.html#4348" class="Bound">a</a> <a id="4350" class="Symbol">:</a> <a id="4352" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="4355" class="Symbol">)</a> <a id="4357" class="Symbol">:</a> <a id="4359" class="Symbol">(@</a><a id="4361" class="Symbol">0</a> <a id="4363" href="agda2hs.html#4363" class="Bound">height</a> <a id="4370" class="Symbol">:</a> <a id="4372" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a><a id="4375" class="Symbol">)</a> <a id="4377" class="Symbol">→</a> <a id="4379" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="4383" class="Keyword">where</a>
  <a id="Tree.Tip"></a><a id="4391" href="agda2hs.html#4391" class="InductiveConstructor">Tip</a> <a id="4395" class="Symbol">:</a> <a id="4397" href="agda2hs.html#4342" class="Datatype">Tree</a> <a id="4402" href="agda2hs.html#4348" class="Bound">a</a> <a id="4404" class="Number">0</a>
  <a id="Tree.Bin"></a><a id="4408" href="agda2hs.html#4408" class="InductiveConstructor">Bin</a> <a id="4412" class="Symbol">:</a> <a id="4414" class="Symbol">∀</a> <a id="4416" class="Symbol">{@</a><a id="4418" class="Symbol">0</a> <a id="4420" href="agda2hs.html#4420" class="Bound">l</a> <a id="4422" href="agda2hs.html#4422" class="Bound">r</a><a id="4423" class="Symbol">}</a>
      <a id="4431" class="Symbol">→</a> <a id="4433" href="agda2hs.html#4348" class="Bound">a</a> <a id="4435" class="Symbol">→</a> <a id="4437" href="agda2hs.html#4342" class="Datatype">Tree</a> <a id="4442" href="agda2hs.html#4348" class="Bound">a</a> <a id="4444" href="agda2hs.html#4420" class="Bound">l</a> <a id="4446" class="Symbol">→</a> <a id="4448" href="agda2hs.html#4342" class="Datatype">Tree</a> <a id="4453" href="agda2hs.html#4348" class="Bound">a</a> <a id="4455" href="agda2hs.html#4422" class="Bound">r</a> <a id="4457" class="Symbol">→</a> <a id="4459" href="agda2hs.html#4342" class="Datatype">Tree</a> <a id="4464" href="agda2hs.html#4348" class="Bound">a</a> <a id="4466" class="Symbol">(</a><a id="4467" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="4471" class="Symbol">(</a><a id="4472" href="agda2hs.html#4211" class="Function">maxNat</a> <a id="4479" href="agda2hs.html#4420" class="Bound">l</a> <a id="4481" href="agda2hs.html#4422" class="Bound">r</a><a id="4482" class="Symbol">))</a>
<a id="4485" class="Symbol">{-#</a> <a id="4489" class="Keyword">COMPILE</a> <a id="4497" class="Keyword">AGDA2HS</a> <a id="4505" href="agda2hs.html#4342" class="Datatype">Tree</a> <a id="4510" class="Symbol">#-}</a>
</pre>
<p>Since Haskell tends to get confused by terms appearing at the type
level, we need some way to indicate to <code>agda2hs</code> that we do <em>not</em> want
the second argument to <code>Tree</code> (the <code>height : Nat</code>) to be translated to
Haskell. To do this, <code>agda2hs</code> makes use of the <a href="https://agda.readthedocs.io/en/v2.6.2.2/language/runtime-irrelevance.html">erasure
annotations</a>
<code>@0</code> that are built into Agda. The nice thing about these erasure
annotations is that Agda will check that you never return or pattern
match on an erased argument, so erasing them does not affect the
computational behaviour of your program. The output is a simple
Haskell implementation of binary trees:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a <span class="ot">=</span> <span class="dt">Tip</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="dt">Bin</span> a (<span class="dt">Tree</span> a) (<span class="dt">Tree</span> a)</span></code></pre></div>
<p>To implement functions on indexed datatypes, it is often needed to
<em>transport</em> an element between two types when we know that their
indices are provably equal. For this we can define the function
<code>transport</code> (sometimes also called <code>subst</code>):</p>
<pre class="Agda"><a id="transport"></a><a id="5496" href="agda2hs.html#5496" class="Function">transport</a> <a id="5506" class="Symbol">:</a> <a id="5508" class="Symbol">(@</a><a id="5510" class="Symbol">0</a> <a id="5512" href="agda2hs.html#5512" class="Bound">p</a> <a id="5514" class="Symbol">:</a> <a id="5516" class="Symbol">@</a><a id="5517" class="Symbol">0</a> <a id="5519" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="5521" class="Symbol">→</a> <a id="5523" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="5526" class="Symbol">)</a> <a id="5528" class="Symbol">{@</a><a id="5530" class="Symbol">0</a> <a id="5532" href="agda2hs.html#5532" class="Bound">m</a> <a id="5534" href="agda2hs.html#5534" class="Bound">n</a> <a id="5536" class="Symbol">:</a> <a id="5538" href="Haskell.Prim.html#1214" class="Generalizable">a</a><a id="5539" class="Symbol">}</a>
          <a id="5551" class="Symbol">→</a> <a id="5553" class="Symbol">@</a><a id="5554" class="Symbol">0</a> <a id="5556" href="agda2hs.html#5532" class="Bound">m</a> <a id="5558" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="5560" href="agda2hs.html#5534" class="Bound">n</a> <a id="5562" class="Symbol">→</a> <a id="5564" href="agda2hs.html#5512" class="Bound">p</a> <a id="5566" href="agda2hs.html#5532" class="Bound">m</a> <a id="5568" class="Symbol">→</a> <a id="5570" href="agda2hs.html#5512" class="Bound">p</a> <a id="5572" href="agda2hs.html#5534" class="Bound">n</a>
<a id="5574" href="agda2hs.html#5496" class="Function">transport</a> <a id="5584" href="agda2hs.html#5584" class="Bound">p</a> <a id="5586" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a> <a id="5591" href="agda2hs.html#5591" class="Bound">t</a> <a id="5593" class="Symbol">=</a> <a id="5595" href="agda2hs.html#5591" class="Bound">t</a>
<a id="5597" class="Symbol">{-#</a> <a id="5601" class="Keyword">COMPILE</a> <a id="5609" class="Keyword">AGDA2HS</a> <a id="5617" href="agda2hs.html#5496" class="Function">transport</a> <a id="5627" class="Symbol">#-}</a>
</pre>
<p>That’s surely a lot of erasure annotations! In particular, the type
operator <code>p</code> both needs to be erased itself, but also needs to accept
erased inputs <code>m</code> and <code>n</code> so we can erase them as well. The result is
that <code>transport</code> is compiled to a plain identity function:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">transport ::</span> p <span class="ot">-&gt;</span> p</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>transport t <span class="ot">=</span> t</span></code></pre></div>
<p>Now we can implement the <code>mirror</code> function which recursively flips the
left and right subtrees at each node.</p>
<pre class="Agda"><a id="6070" class="Symbol">@</a><a id="6071" class="Symbol">0</a> <a id="max-comm"></a><a id="6073" href="agda2hs.html#6073" class="Function">max-comm</a> <a id="6082" class="Symbol">:</a> <a id="6084" class="Symbol">(@</a><a id="6086" class="Symbol">0</a> <a id="6088" href="agda2hs.html#6088" class="Bound">l</a> <a id="6090" href="agda2hs.html#6090" class="Bound">r</a> <a id="6092" class="Symbol">:</a> <a id="6094" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a><a id="6097" class="Symbol">)</a> <a id="6099" class="Symbol">→</a> <a id="6101" href="agda2hs.html#4211" class="Function">maxNat</a> <a id="6108" href="agda2hs.html#6088" class="Bound">l</a> <a id="6110" href="agda2hs.html#6090" class="Bound">r</a> <a id="6112" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="6114" href="agda2hs.html#4211" class="Function">maxNat</a> <a id="6121" href="agda2hs.html#6090" class="Bound">r</a> <a id="6123" href="agda2hs.html#6088" class="Bound">l</a>
<a id="6125" href="agda2hs.html#6073" class="Function">max-comm</a> <a id="6134" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>    <a id="6142" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>    <a id="6150" class="Symbol">=</a> <a id="6152" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
<a id="6157" href="agda2hs.html#6073" class="Function">max-comm</a> <a id="6166" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>    <a id="6174" class="Symbol">(</a><a id="6175" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6179" href="agda2hs.html#6179" class="Bound">r</a><a id="6180" class="Symbol">)</a> <a id="6182" class="Symbol">=</a> <a id="6184" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
<a id="6189" href="agda2hs.html#6073" class="Function">max-comm</a> <a id="6198" class="Symbol">(</a><a id="6199" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6203" href="agda2hs.html#6203" class="Bound">l</a><a id="6204" class="Symbol">)</a> <a id="6206" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>    <a id="6214" class="Symbol">=</a> <a id="6216" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
<a id="6221" href="agda2hs.html#6073" class="Function">max-comm</a> <a id="6230" class="Symbol">(</a><a id="6231" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6235" href="agda2hs.html#6235" class="Bound">l</a><a id="6236" class="Symbol">)</a> <a id="6238" class="Symbol">(</a><a id="6239" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6243" href="agda2hs.html#6243" class="Bound">r</a><a id="6244" class="Symbol">)</a> <a id="6246" class="Symbol">=</a> <a id="6248" href="Relation.Binary.PropositionalEquality.Core.html#1481" class="Function">cong</a> <a id="6253" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6257" class="Symbol">(</a><a id="6258" href="agda2hs.html#6073" class="Function">max-comm</a> <a id="6267" href="agda2hs.html#6235" class="Bound">l</a> <a id="6269" href="agda2hs.html#6243" class="Bound">r</a><a id="6270" class="Symbol">)</a>

<a id="mirror"></a><a id="6273" href="agda2hs.html#6273" class="Function">mirror</a> <a id="6280" class="Symbol">:</a> <a id="6282" class="Symbol">∀</a> <a id="6284" class="Symbol">{@</a><a id="6286" class="Symbol">0</a> <a id="6288" href="agda2hs.html#6288" class="Bound">h</a><a id="6289" class="Symbol">}</a> <a id="6291" class="Symbol">→</a> <a id="6293" href="agda2hs.html#4342" class="Datatype">Tree</a> <a id="6298" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="6300" href="agda2hs.html#6288" class="Bound">h</a> <a id="6302" class="Symbol">→</a> <a id="6304" href="agda2hs.html#4342" class="Datatype">Tree</a> <a id="6309" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="6311" href="agda2hs.html#6288" class="Bound">h</a>
<a id="6313" href="agda2hs.html#6273" class="Function">mirror</a> <a id="6320" href="agda2hs.html#4391" class="InductiveConstructor">Tip</a> <a id="6324" class="Symbol">=</a>  <a id="6327" href="agda2hs.html#4391" class="InductiveConstructor">Tip</a>
<a id="6331" href="agda2hs.html#6273" class="Function">mirror</a> <a id="6338" class="Symbol">{</a><a id="6339" class="Argument">a</a> <a id="6341" class="Symbol">=</a> <a id="6343" href="agda2hs.html#6343" class="Bound">a</a><a id="6344" class="Symbol">}</a> <a id="6346" class="Symbol">(</a><a id="6347" href="agda2hs.html#4408" class="InductiveConstructor">Bin</a> <a id="6351" class="Symbol">{</a><a id="6352" href="agda2hs.html#6352" class="Bound">l</a><a id="6353" class="Symbol">}</a> <a id="6355" class="Symbol">{</a><a id="6356" href="agda2hs.html#6356" class="Bound">r</a><a id="6357" class="Symbol">}</a> <a id="6359" href="agda2hs.html#6359" class="Bound">x</a> <a id="6361" href="agda2hs.html#6361" class="Bound">lt</a> <a id="6364" href="agda2hs.html#6364" class="Bound">rt</a><a id="6366" class="Symbol">)</a>
  <a id="6370" class="Symbol">=</a> <a id="6372" href="agda2hs.html#5496" class="Function">transport</a> <a id="6382" class="Symbol">(</a><a id="6383" href="agda2hs.html#4342" class="Datatype">Tree</a> <a id="6388" href="agda2hs.html#6343" class="Bound">a</a><a id="6389" class="Symbol">)</a>
              <a id="6405" class="Symbol">(</a><a id="6406" href="Relation.Binary.PropositionalEquality.Core.html#1481" class="Function">cong</a> <a id="6411" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6415" class="Symbol">(</a><a id="6416" href="agda2hs.html#6073" class="Function">max-comm</a> <a id="6425" href="agda2hs.html#6356" class="Bound">r</a> <a id="6427" href="agda2hs.html#6352" class="Bound">l</a><a id="6428" class="Symbol">))</a>
              <a id="6445" class="Symbol">(</a><a id="6446" href="agda2hs.html#4408" class="InductiveConstructor">Bin</a> <a id="6450" href="agda2hs.html#6359" class="Bound">x</a> <a id="6452" class="Symbol">(</a><a id="6453" href="agda2hs.html#6273" class="Function">mirror</a> <a id="6460" href="agda2hs.html#6364" class="Bound">rt</a><a id="6462" class="Symbol">)</a> <a id="6464" class="Symbol">(</a><a id="6465" href="agda2hs.html#6273" class="Function">mirror</a> <a id="6472" href="agda2hs.html#6361" class="Bound">lt</a><a id="6474" class="Symbol">))</a>
<a id="6477" class="Symbol">{-#</a> <a id="6481" class="Keyword">COMPILE</a> <a id="6489" class="Keyword">AGDA2HS</a> <a id="6497" href="agda2hs.html#6273" class="Function">mirror</a> <a id="6504" class="Symbol">#-}</a>
</pre>
<p>In the recursive branch of the mirror function, we need to convert a
tree of type <code>Tree a (suc (max r l))</code> to type <code>Tree a (suc (max l r))</code>. To do this, we <code>transport</code> by the proof of commutativity of
<code>max</code>. We can now tell that <code>mirror</code> preserves the height of the tree
<em>by construction</em>, simply from its type.</p>
<p>Running <code>agda2hs</code> on this function produces the following:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">mirror ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>mirror <span class="dt">Tip</span> <span class="ot">=</span> <span class="dt">Tip</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>mirror (<span class="dt">Bin</span> x lt rt) <span class="ot">=</span> transport (<span class="dt">Bin</span> x (mirror rt) (mirror lt))</span></code></pre></div>
<p>While this is functional, the function <code>transport</code> still appears in
the Haskell code! GHC is probably smart enough to inline this
definition, but our boss might be able to tell that we’re not writing
this code by hand.</p>
<p>To avoid this problem, <code>agda2hs</code> allows us to annotate functions as
<code>transparent</code> if they become an identity function after erasing all
<code>@0</code> arguments:</p>
<pre class="noagda"><code>{-# COMPILE AGDA2HS transport transparent #-}</code></pre>
<p>With this change, <code>agda2hs</code> produces the code we want, and we are saved
from our boss. Phew!</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">mirror ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>mirror <span class="dt">Tip</span> <span class="ot">=</span> <span class="dt">Tip</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>mirror (<span class="dt">Bin</span> x lt rt) <span class="ot">=</span> <span class="dt">Bin</span> x (mirror rt) (mirror lt)</span></code></pre></div>
<h2 id="making-monads-obey-the-law">Making monads obey the law</h2>
<p>At the moment of writing this blog post, <code>agda2hs</code> is still in its
infancy, so it does not yet support all of Haskell’s main
features. One especially glaring omission at the moment is the lack of
support for <code>do</code>-notation:</p>
<pre class="Agda"><a id="headMaybe"></a><a id="7912" href="agda2hs.html#7912" class="Function">headMaybe</a> <a id="7922" class="Symbol">:</a> <a id="7924" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="7929" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="7931" class="Symbol">→</a> <a id="7933" href="Haskell.Prim.Maybe.html#126" class="Datatype">Maybe</a> <a id="7939" href="Haskell.Prim.html#1214" class="Generalizable">a</a>
<a id="7941" href="agda2hs.html#7912" class="Function">headMaybe</a> <a id="7951" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a> <a id="7954" class="Symbol">=</a> <a id="7956" href="Haskell.Prim.Maybe.html#169" class="InductiveConstructor">Nothing</a>
<a id="7964" href="agda2hs.html#7912" class="Function">headMaybe</a> <a id="7974" class="Symbol">(</a><a id="7975" href="agda2hs.html#7975" class="Bound">x</a> <a id="7977" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="7979" href="agda2hs.html#7979" class="Bound">xs</a><a id="7981" class="Symbol">)</a> <a id="7983" class="Symbol">=</a> <a id="7985" href="Haskell.Prim.Maybe.html#189" class="InductiveConstructor">Just</a> <a id="7990" href="agda2hs.html#7975" class="Bound">x</a>
<a id="7992" class="Symbol">{-#</a> <a id="7996" class="Keyword">COMPILE</a> <a id="8004" class="Keyword">AGDA2HS</a> <a id="8012" href="agda2hs.html#7912" class="Function">headMaybe</a> <a id="8022" class="Symbol">#-}</a>

<a id="tailMaybe"></a><a id="8027" href="agda2hs.html#8027" class="Function">tailMaybe</a> <a id="8037" class="Symbol">:</a> <a id="8039" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="8044" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="8046" class="Symbol">→</a> <a id="8048" href="Haskell.Prim.Maybe.html#126" class="Datatype">Maybe</a> <a id="8054" class="Symbol">(</a><a id="8055" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="8060" href="Haskell.Prim.html#1214" class="Generalizable">a</a><a id="8061" class="Symbol">)</a>
<a id="8063" href="agda2hs.html#8027" class="Function">tailMaybe</a> <a id="8073" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a> <a id="8076" class="Symbol">=</a> <a id="8078" href="Haskell.Prim.Maybe.html#169" class="InductiveConstructor">Nothing</a>
<a id="8086" href="agda2hs.html#8027" class="Function">tailMaybe</a> <a id="8096" class="Symbol">(</a><a id="8097" href="agda2hs.html#8097" class="Bound">x</a> <a id="8099" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="8101" href="agda2hs.html#8101" class="Bound">xs</a><a id="8103" class="Symbol">)</a> <a id="8105" class="Symbol">=</a> <a id="8107" href="Haskell.Prim.Maybe.html#189" class="InductiveConstructor">Just</a> <a id="8112" href="agda2hs.html#8101" class="Bound">xs</a>
<a id="8115" class="Symbol">{-#</a> <a id="8119" class="Keyword">COMPILE</a> <a id="8127" class="Keyword">AGDA2HS</a> <a id="8135" href="agda2hs.html#8027" class="Function">tailMaybe</a> <a id="8145" class="Symbol">#-}</a>

<a id="third"></a><a id="8150" href="agda2hs.html#8150" class="Function">third</a> <a id="8156" class="Symbol">:</a> <a id="8158" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="8163" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="8165" class="Symbol">→</a> <a id="8167" href="Haskell.Prim.Maybe.html#126" class="Datatype">Maybe</a> <a id="8173" href="Haskell.Prim.html#1214" class="Generalizable">a</a>
<a id="8175" href="agda2hs.html#8150" class="Function">third</a> <a id="8181" href="agda2hs.html#8181" class="Bound">xs</a> <a id="8184" class="Symbol">=</a> <a id="8186" class="Keyword">do</a>
  <a id="8191" href="agda2hs.html#8191" class="Bound">ys</a> <a id="8194" href="Haskell.Prim.Monad.html#564" class="Field Operator">←</a> <a id="8196" href="agda2hs.html#8027" class="Function">tailMaybe</a> <a id="8206" href="agda2hs.html#8181" class="Bound">xs</a>
  <a id="8211" href="agda2hs.html#8211" class="Bound">zs</a> <a id="8214" href="Haskell.Prim.Monad.html#564" class="Field Operator">←</a> <a id="8216" href="agda2hs.html#8027" class="Function">tailMaybe</a> <a id="8226" href="agda2hs.html#8191" class="Bound">ys</a>
  <a id="8231" href="agda2hs.html#8231" class="Bound">z</a>  <a id="8234" href="Haskell.Prim.Monad.html#564" class="Field Operator">←</a> <a id="8236" href="agda2hs.html#7912" class="Function">headMaybe</a> <a id="8246" href="agda2hs.html#8211" class="Bound">zs</a>
  <a id="8251" href="Haskell.Prim.Monad.html#640" class="Field">return</a> <a id="8258" href="agda2hs.html#8231" class="Bound">z</a>
<a id="8260" class="Symbol">{-#</a> <a id="8264" class="Keyword">COMPILE</a> <a id="8272" class="Keyword">AGDA2HS</a> <a id="8280" href="agda2hs.html#8150" class="Function">third</a> <a id="8286" class="Symbol">#-}</a>
</pre>
<p>While we can use <code>do</code> notation in Agda as shown in the example above,
this is not preserved in the translation to Haskell:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">headMaybe ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>headMaybe [] <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>headMaybe (x <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">Just</span> x</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a><span class="ot">tailMaybe ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> [a]</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>tailMaybe [] <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>tailMaybe (x <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">Just</span> xs</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a><span class="ot">third ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>third xs</span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> tailMaybe xs <span class="op">&gt;&gt;=</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>      \ ys <span class="ot">-&gt;</span> tailMaybe ys <span class="op">&gt;&gt;=</span> \ zs <span class="ot">-&gt;</span> headMaybe zs <span class="op">&gt;&gt;=</span> <span class="fu">return</span></span></code></pre></div>
<p>Still, we can already do things that would not be possible in Haskell,
e.g. prove the monad laws for each of our monads. To do this, we first
declare a typeclass <code>LawfulMonad</code> that is parametrized by a <code>Monad m</code>
instance and has three fields, one for each of the three monad laws:</p>
<pre class="Agda"><a id="9001" class="Keyword">record</a> <a id="LawfulMonad"></a><a id="9008" href="agda2hs.html#9008" class="Record">LawfulMonad</a> <a id="9020" class="Symbol">(</a><a id="9021" href="agda2hs.html#9021" class="Bound">m</a> <a id="9023" class="Symbol">:</a> <a id="9025" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="9029" class="Symbol">→</a> <a id="9031" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="9034" class="Symbol">)</a>
                   <a id="9055" class="Symbol">{{</a><a id="9057" href="agda2hs.html#9057" class="Bound">iMonad</a> <a id="9064" class="Symbol">:</a> <a id="9066" href="Haskell.Prim.Monad.html#510" class="Record">Monad</a> <a id="9072" href="agda2hs.html#9021" class="Bound">m</a><a id="9073" class="Symbol">}}</a> <a id="9076" class="Symbol">:</a> <a id="9078" href="Agda.Primitive.html#388" class="Primitive">Set₁</a> <a id="9083" class="Keyword">where</a>
  <a id="9091" class="Keyword">field</a>
    <a id="LawfulMonad.left-id"></a><a id="9101" href="agda2hs.html#9101" class="Field">left-id</a> <a id="9109" class="Symbol">:</a> <a id="9111" class="Symbol">∀</a> <a id="9113" class="Symbol">{</a><a id="9114" href="agda2hs.html#9114" class="Bound">a</a> <a id="9116" href="agda2hs.html#9116" class="Bound">b</a><a id="9117" class="Symbol">}</a> <a id="9119" class="Symbol">(</a><a id="9120" href="agda2hs.html#9120" class="Bound">x</a> <a id="9122" class="Symbol">:</a> <a id="9124" href="agda2hs.html#9114" class="Bound">a</a><a id="9125" class="Symbol">)</a> <a id="9127" class="Symbol">(</a><a id="9128" href="agda2hs.html#9128" class="Bound">f</a> <a id="9130" class="Symbol">:</a> <a id="9132" href="agda2hs.html#9114" class="Bound">a</a> <a id="9134" class="Symbol">→</a> <a id="9136" href="agda2hs.html#9021" class="Bound">m</a> <a id="9138" href="agda2hs.html#9116" class="Bound">b</a><a id="9139" class="Symbol">)</a>
            <a id="9153" class="Symbol">→</a> <a id="9155" class="Symbol">(</a><a id="9156" href="Haskell.Prim.Monad.html#640" class="Field">return</a> <a id="9163" href="agda2hs.html#9120" class="Bound">x</a> <a id="9165" href="Haskell.Prim.Monad.html#564" class="Field Operator">&gt;&gt;=</a> <a id="9169" href="agda2hs.html#9128" class="Bound">f</a><a id="9170" class="Symbol">)</a> <a id="9172" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="9174" href="agda2hs.html#9128" class="Bound">f</a> <a id="9176" href="agda2hs.html#9120" class="Bound">x</a>
    <a id="LawfulMonad.right-id"></a><a id="9182" href="agda2hs.html#9182" class="Field">right-id</a> <a id="9191" class="Symbol">:</a> <a id="9193" class="Symbol">∀</a> <a id="9195" class="Symbol">{</a><a id="9196" href="agda2hs.html#9196" class="Bound">a</a><a id="9197" class="Symbol">}</a> <a id="9199" class="Symbol">(</a><a id="9200" href="agda2hs.html#9200" class="Bound">k</a> <a id="9202" class="Symbol">:</a> <a id="9204" href="agda2hs.html#9021" class="Bound">m</a> <a id="9206" href="agda2hs.html#9196" class="Bound">a</a><a id="9207" class="Symbol">)</a>
             <a id="9222" class="Symbol">→</a> <a id="9224" class="Symbol">(</a><a id="9225" href="agda2hs.html#9200" class="Bound">k</a> <a id="9227" href="Haskell.Prim.Monad.html#564" class="Field Operator">&gt;&gt;=</a> <a id="9231" href="Haskell.Prim.Monad.html#640" class="Field">return</a><a id="9237" class="Symbol">)</a> <a id="9239" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="9241" href="agda2hs.html#9200" class="Bound">k</a>
    <a id="LawfulMonad.assoc"></a><a id="9247" href="agda2hs.html#9247" class="Field">assoc</a> <a id="9253" class="Symbol">:</a> <a id="9255" class="Symbol">∀</a> <a id="9257" class="Symbol">{</a><a id="9258" href="agda2hs.html#9258" class="Bound">a</a> <a id="9260" href="agda2hs.html#9260" class="Bound">b</a> <a id="9262" href="agda2hs.html#9262" class="Bound">c</a><a id="9263" class="Symbol">}</a> <a id="9265" class="Symbol">(</a><a id="9266" href="agda2hs.html#9266" class="Bound">k</a> <a id="9268" class="Symbol">:</a> <a id="9270" href="agda2hs.html#9021" class="Bound">m</a> <a id="9272" href="agda2hs.html#9258" class="Bound">a</a><a id="9273" class="Symbol">)</a>
          <a id="9285" class="Symbol">→</a> <a id="9287" class="Symbol">(</a><a id="9288" href="agda2hs.html#9288" class="Bound">f</a> <a id="9290" class="Symbol">:</a> <a id="9292" href="agda2hs.html#9258" class="Bound">a</a> <a id="9294" class="Symbol">→</a> <a id="9296" href="agda2hs.html#9021" class="Bound">m</a> <a id="9298" href="agda2hs.html#9260" class="Bound">b</a><a id="9299" class="Symbol">)</a> <a id="9301" class="Symbol">(</a><a id="9302" href="agda2hs.html#9302" class="Bound">g</a> <a id="9304" class="Symbol">:</a> <a id="9306" href="agda2hs.html#9260" class="Bound">b</a> <a id="9308" class="Symbol">→</a> <a id="9310" href="agda2hs.html#9021" class="Bound">m</a> <a id="9312" href="agda2hs.html#9262" class="Bound">c</a><a id="9313" class="Symbol">)</a>
          <a id="9325" class="Symbol">→</a> <a id="9327" class="Symbol">((</a><a id="9329" href="agda2hs.html#9266" class="Bound">k</a> <a id="9331" href="Haskell.Prim.Monad.html#564" class="Field Operator">&gt;&gt;=</a> <a id="9335" href="agda2hs.html#9288" class="Bound">f</a><a id="9336" class="Symbol">)</a> <a id="9338" href="Haskell.Prim.Monad.html#564" class="Field Operator">&gt;&gt;=</a> <a id="9342" href="agda2hs.html#9302" class="Bound">g</a><a id="9343" class="Symbol">)</a> <a id="9345" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="9347" class="Symbol">(</a><a id="9348" href="agda2hs.html#9266" class="Bound">k</a> <a id="9350" href="Haskell.Prim.Monad.html#564" class="Field Operator">&gt;&gt;=</a> <a id="9354" class="Symbol">(λ</a> <a id="9357" href="agda2hs.html#9357" class="Bound">x</a> <a id="9359" class="Symbol">→</a> <a id="9361" href="agda2hs.html#9288" class="Bound">f</a> <a id="9363" href="agda2hs.html#9357" class="Bound">x</a> <a id="9365" href="Haskell.Prim.Monad.html#564" class="Field Operator">&gt;&gt;=</a> <a id="9369" href="agda2hs.html#9302" class="Bound">g</a><a id="9370" class="Symbol">))</a>
<a id="9373" class="Keyword">open</a> <a id="9378" href="agda2hs.html#9008" class="Module">LawfulMonad</a>
</pre>
<p>We can then prove the monad laws for a monad by defining an instance
of this class, for example for the <code>Maybe</code> monad:</p>
<pre class="Agda"><a id="9519" class="Keyword">instance</a>
  <a id="9530" href="agda2hs.html#9530" class="Function">_</a> <a id="9532" class="Symbol">:</a> <a id="9534" href="agda2hs.html#9008" class="Record">LawfulMonad</a> <a id="9546" href="Haskell.Prim.Maybe.html#126" class="Datatype">Maybe</a>
  <a id="9554" class="Symbol">_</a> <a id="9556" class="Symbol">=</a> <a id="9558" class="Symbol">λ</a> <a id="9560" class="Keyword">where</a>
    <a id="9570" class="Symbol">.</a><a id="9571" href="agda2hs.html#9101" class="Field">left-id</a>  <a id="9580" href="agda2hs.html#9580" class="Bound">x</a>        <a id="9589" href="agda2hs.html#9589" class="Bound">f</a>   <a id="9593" class="Symbol">→</a> <a id="9595" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
    <a id="9604" class="Symbol">.</a><a id="9605" href="agda2hs.html#9182" class="Field">right-id</a> <a id="9614" href="Haskell.Prim.Maybe.html#169" class="InductiveConstructor">Nothing</a>      <a id="9627" class="Symbol">→</a> <a id="9629" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
    <a id="9638" class="Symbol">.</a><a id="9639" href="agda2hs.html#9182" class="Field">right-id</a> <a id="9648" class="Symbol">(</a><a id="9649" href="Haskell.Prim.Maybe.html#189" class="InductiveConstructor">Just</a> <a id="9654" href="agda2hs.html#9654" class="Bound">x</a><a id="9655" class="Symbol">)</a>     <a id="9661" class="Symbol">→</a> <a id="9663" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
    <a id="9672" class="Symbol">.</a><a id="9673" href="agda2hs.html#9247" class="Field">assoc</a>    <a id="9682" href="Haskell.Prim.Maybe.html#169" class="InductiveConstructor">Nothing</a>  <a id="9691" href="agda2hs.html#9691" class="Bound">f</a> <a id="9693" href="agda2hs.html#9693" class="Bound">g</a> <a id="9695" class="Symbol">→</a> <a id="9697" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
    <a id="9706" class="Symbol">.</a><a id="9707" href="agda2hs.html#9247" class="Field">assoc</a>    <a id="9716" class="Symbol">(</a><a id="9717" href="Haskell.Prim.Maybe.html#189" class="InductiveConstructor">Just</a> <a id="9722" href="agda2hs.html#9722" class="Bound">x</a><a id="9723" class="Symbol">)</a> <a id="9725" href="agda2hs.html#9725" class="Bound">f</a> <a id="9727" href="agda2hs.html#9727" class="Bound">g</a> <a id="9729" class="Symbol">→</a> <a id="9731" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
</pre>
<p>Thanks to Agda’s built-in support for eta-equality on function types,
proving the monad laws for the reader monad is especially
straightforward:</p>
<pre class="Agda"><a id="9891" class="Keyword">instance</a>
  <a id="9902" href="agda2hs.html#9902" class="Function">_</a> <a id="9904" class="Symbol">:</a> <a id="9906" class="Symbol">{</a><a id="9907" href="agda2hs.html#9907" class="Bound">r</a> <a id="9909" class="Symbol">:</a> <a id="9911" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="9914" class="Symbol">}</a> <a id="9916" class="Symbol">→</a> <a id="9918" href="agda2hs.html#9008" class="Record">LawfulMonad</a> <a id="9930" class="Symbol">(λ</a> <a id="9933" href="agda2hs.html#9933" class="Bound">a</a> <a id="9935" class="Symbol">→</a> <a id="9937" class="Symbol">(</a><a id="9938" href="agda2hs.html#9907" class="Bound">r</a> <a id="9940" class="Symbol">→</a> <a id="9942" href="agda2hs.html#9933" class="Bound">a</a><a id="9943" class="Symbol">))</a>
  <a id="9948" class="Symbol">_</a> <a id="9950" class="Symbol">=</a> <a id="9952" class="Symbol">λ</a> <a id="9954" class="Keyword">where</a>
    <a id="9964" class="Symbol">.</a><a id="9965" href="agda2hs.html#9101" class="Field">left-id</a>   <a id="9975" href="agda2hs.html#9975" class="Bound">x</a> <a id="9977" href="agda2hs.html#9977" class="Bound">f</a>   <a id="9981" class="Symbol">→</a> <a id="9983" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
    <a id="9992" class="Symbol">.</a><a id="9993" href="agda2hs.html#9182" class="Field">right-id</a>  <a id="10003" href="agda2hs.html#10003" class="Bound">k</a>     <a id="10009" class="Symbol">→</a> <a id="10011" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
    <a id="10020" class="Symbol">.</a><a id="10021" href="agda2hs.html#9247" class="Field">assoc</a>     <a id="10031" href="agda2hs.html#10031" class="Bound">k</a> <a id="10033" href="agda2hs.html#10033" class="Bound">f</a> <a id="10035" href="agda2hs.html#10035" class="Bound">g</a> <a id="10037" class="Symbol">→</a> <a id="10039" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
</pre>
<h2 id="coinduction-sizes-and-cubical-oh-my">Coinduction, sizes, and cubical, oh my!</h2>
<p>Working with <code>agda2hs</code> can be quite nice since you have the full power
of Agda at your disposal for writing proofs. As an example, let’s
implement coinductive (infinite) streams, and prove fusion of
subsequent maps on streams by using <a href="https://agda.readthedocs.io/en/v2.6.2.2/language/cubical.html">Cubical
Agda</a>!
As a warning: this is very much still an experiment, so expect some
rough edges. I’ve made a <a href="https://github.com/agda/agda2hs/pull/111">PR for improving compatibility between
<code>agda2hs</code> and Cubical Agda</a>,
which should be merged soon.</p>
<p>First, to define coinductive types in <code>agda2hs</code> we need to import the
<code>Thunk</code> type. This type is ‘transparent’ (i.e. not compiled to
Haskell) but it is necessary to make Agda understand that this is
really a coinductive structure, and it should do productivity checking
rather than termination checking.</p>
<pre class="Agda"><a id="10950" class="Keyword">open</a> <a id="10955" class="Keyword">import</a> <a id="10962" href="Haskell.Prim.Thunk.html" class="Module">Haskell.Prim.Thunk</a>
</pre>
<p>We can then use the <code>Thunk</code> type to mark constructor arguments that
should be treated ‘lazily’:</p>
<pre class="Agda"><a id="11087" class="Keyword">data</a> <a id="Stream"></a><a id="11092" href="agda2hs.html#11092" class="Datatype">Stream</a> <a id="11099" class="Symbol">(</a><a id="11100" href="agda2hs.html#11100" class="Bound">a</a> <a id="11102" class="Symbol">:</a> <a id="11104" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="11107" class="Symbol">)</a> <a id="11109" class="Symbol">(@</a><a id="11111" class="Symbol">0</a> <a id="11113" href="agda2hs.html#11113" class="Bound">i</a> <a id="11115" class="Symbol">:</a> <a id="11117" href="Agda.Builtin.Size.html#213" class="Postulate">Size</a><a id="11121" class="Symbol">)</a> <a id="11123" class="Symbol">:</a> <a id="11125" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="11129" class="Keyword">where</a>
  <a id="Stream._:&gt;_"></a><a id="11137" href="agda2hs.html#11137" class="InductiveConstructor Operator">_:&gt;_</a> <a id="11142" class="Symbol">:</a> <a id="11144" href="agda2hs.html#11100" class="Bound">a</a> <a id="11146" class="Symbol">→</a> <a id="11148" href="Haskell.Prim.Thunk.html#136" class="Record">Thunk</a> <a id="11154" class="Symbol">(</a><a id="11155" href="agda2hs.html#11092" class="Datatype">Stream</a> <a id="11162" href="agda2hs.html#11100" class="Bound">a</a><a id="11163" class="Symbol">)</a> <a id="11165" href="agda2hs.html#11113" class="Bound">i</a> <a id="11167" class="Symbol">→</a> <a id="11169" href="agda2hs.html#11092" class="Datatype">Stream</a> <a id="11176" href="agda2hs.html#11100" class="Bound">a</a> <a id="11178" href="agda2hs.html#11113" class="Bound">i</a>
<a id="11180" class="Symbol">{-#</a> <a id="11184" class="Keyword">COMPILE</a> <a id="11192" class="Keyword">AGDA2HS</a> <a id="11200" href="agda2hs.html#11092" class="Datatype">Stream</a> <a id="11207" class="Symbol">#-}</a>
</pre>
<p>We make use of <a href="https://agda.readthedocs.io/en/v2.6.2.2/language/sized-types.html">sized
types</a>
to indicate the size of a stream, i.e. the depth to which the stream
has been defined. This helps Agda’s productivity checker to determine
that the functions for producing streams we will define below are
productive. Since the size is marked as erased with <code>@0</code>, it does not
appear in the Haskell code:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Stream</span> a <span class="ot">=</span> (<span class="op">:&gt;</span>) a (<span class="dt">Stream</span> a)</span></code></pre></div>
<p>Defining functions that consume a stream is easy enough:</p>
<pre class="Agda"><a id="headS"></a><a id="11728" href="agda2hs.html#11728" class="Function">headS</a> <a id="11734" class="Symbol">:</a> <a id="11736" href="agda2hs.html#11092" class="Datatype">Stream</a> <a id="11743" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="11745" href="Agda.Builtin.Size.html#315" class="Postulate">∞</a> <a id="11747" class="Symbol">→</a> <a id="11749" href="Haskell.Prim.html#1214" class="Generalizable">a</a>
<a id="11751" href="agda2hs.html#11728" class="Function">headS</a> <a id="11757" class="Symbol">(</a><a id="11758" href="agda2hs.html#11758" class="Bound">x</a> <a id="11760" href="agda2hs.html#11137" class="InductiveConstructor Operator">:&gt;</a> <a id="11763" class="Symbol">_)</a> <a id="11766" class="Symbol">=</a> <a id="11768" href="agda2hs.html#11758" class="Bound">x</a>
<a id="11770" class="Symbol">{-#</a> <a id="11774" class="Keyword">COMPILE</a> <a id="11782" class="Keyword">AGDA2HS</a> <a id="11790" href="agda2hs.html#11728" class="Function">headS</a> <a id="11796" class="Symbol">#-}</a>
</pre>
<p>To force evaluation of a thunk, we use the syntax <code>.force</code>:</p>
<pre class="Agda"><a id="tailS"></a><a id="11870" href="agda2hs.html#11870" class="Function">tailS</a> <a id="11876" class="Symbol">:</a> <a id="11878" href="agda2hs.html#11092" class="Datatype">Stream</a> <a id="11885" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="11887" href="Agda.Builtin.Size.html#315" class="Postulate">∞</a> <a id="11889" class="Symbol">→</a> <a id="11891" href="agda2hs.html#11092" class="Datatype">Stream</a> <a id="11898" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="11900" href="Agda.Builtin.Size.html#315" class="Postulate">∞</a>
<a id="11902" href="agda2hs.html#11870" class="Function">tailS</a> <a id="11908" class="Symbol">(_</a> <a id="11911" href="agda2hs.html#11137" class="InductiveConstructor Operator">:&gt;</a> <a id="11914" href="agda2hs.html#11914" class="Bound">xs</a><a id="11916" class="Symbol">)</a> <a id="11918" class="Symbol">=</a> <a id="11920" href="agda2hs.html#11914" class="Bound">xs</a> <a id="11923" class="Symbol">.</a><a id="11924" href="Haskell.Prim.Thunk.html#240" class="Field">force</a>
<a id="11930" class="Symbol">{-#</a> <a id="11934" class="Keyword">COMPILE</a> <a id="11942" class="Keyword">AGDA2HS</a> <a id="11950" href="agda2hs.html#11870" class="Function">tailS</a> <a id="11956" class="Symbol">#-}</a>
</pre>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">headS ::</span> <span class="dt">Stream</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>headS (x <span class="op">:&gt;</span> _) <span class="ot">=</span> x</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="ot">tailS ::</span> <span class="dt">Stream</span> a <span class="ot">-&gt;</span> <span class="dt">Stream</span> a</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>tailS (_ <span class="op">:&gt;</span> xs) <span class="ot">=</span> xs</span></code></pre></div>
<p>To define a function that produces a stream, we need to define the
tail “lazily”. In Agda, that is done using the syntax <code>λ where .force → ...</code>.</p>
<pre class="Agda"><a id="repeat"></a><a id="12225" href="agda2hs.html#12225" class="Function">repeat</a> <a id="12232" class="Symbol">:</a> <a id="12234" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="12236" class="Symbol">→</a> <a id="12238" href="agda2hs.html#11092" class="Datatype">Stream</a> <a id="12245" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="12247" href="agda2hs.html#353" class="Generalizable">i</a>
<a id="12249" href="agda2hs.html#12225" class="Function">repeat</a> <a id="12256" href="agda2hs.html#12256" class="Bound">x</a> <a id="12258" class="Symbol">=</a> <a id="12260" href="agda2hs.html#12256" class="Bound">x</a> <a id="12262" href="agda2hs.html#11137" class="InductiveConstructor Operator">:&gt;</a> <a id="12265" class="Symbol">λ</a> <a id="12267" class="Keyword">where</a> <a id="12273" class="Symbol">.</a><a id="12274" href="Haskell.Prim.Thunk.html#240" class="Field">force</a> <a id="12280" class="Symbol">→</a> <a id="12282" href="agda2hs.html#12225" class="Function">repeat</a> <a id="12289" href="agda2hs.html#12256" class="Bound">x</a>
<a id="12291" class="Symbol">{-#</a> <a id="12295" class="Keyword">COMPILE</a> <a id="12303" class="Keyword">AGDA2HS</a> <a id="12311" href="agda2hs.html#12225" class="Function">repeat</a> <a id="12318" class="Symbol">#-}</a>
</pre>
<p>The function is compiled as expected, and any trace of <code>Thunk</code> and
<code>force</code> is gone:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="fu">repeat</span><span class="ot"> ::</span> a <span class="ot">-&gt;</span> <span class="dt">Stream</span> a</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="fu">repeat</span> x <span class="ot">=</span> x <span class="op">:&gt;</span> <span class="fu">repeat</span> x</span></code></pre></div>
<p>Similarly, we define a <code>map</code> function on streams:</p>
<pre class="Agda"><a id="mapS"></a><a id="12532" href="agda2hs.html#12532" class="Function">mapS</a>  <a id="12538" class="Symbol">:</a> <a id="12540" class="Symbol">(</a><a id="12541" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="12543" class="Symbol">→</a> <a id="12545" href="Haskell.Prim.html#1216" class="Generalizable">b</a><a id="12546" class="Symbol">)</a> <a id="12548" class="Symbol">→</a> <a id="12550" href="agda2hs.html#11092" class="Datatype">Stream</a> <a id="12557" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="12559" href="agda2hs.html#353" class="Generalizable">i</a> <a id="12561" class="Symbol">→</a> <a id="12563" href="agda2hs.html#11092" class="Datatype">Stream</a> <a id="12570" href="Haskell.Prim.html#1216" class="Generalizable">b</a> <a id="12572" href="agda2hs.html#353" class="Generalizable">i</a>
<a id="12574" href="agda2hs.html#12532" class="Function">mapS</a>  <a id="12580" href="agda2hs.html#12580" class="Bound">f</a> <a id="12582" class="Symbol">(</a><a id="12583" href="agda2hs.html#12583" class="Bound">x</a> <a id="12585" href="agda2hs.html#11137" class="InductiveConstructor Operator">:&gt;</a> <a id="12588" href="agda2hs.html#12588" class="Bound">xs</a><a id="12590" class="Symbol">)</a> <a id="12592" class="Symbol">=</a>
  <a id="12596" class="Symbol">(</a><a id="12597" href="agda2hs.html#12580" class="Bound">f</a> <a id="12599" href="agda2hs.html#12583" class="Bound">x</a><a id="12600" class="Symbol">)</a> <a id="12602" href="agda2hs.html#11137" class="InductiveConstructor Operator">:&gt;</a> <a id="12605" class="Symbol">λ</a> <a id="12607" class="Keyword">where</a> <a id="12613" class="Symbol">.</a><a id="12614" href="Haskell.Prim.Thunk.html#240" class="Field">force</a> <a id="12620" class="Symbol">→</a> <a id="12622" href="agda2hs.html#12532" class="Function">mapS</a> <a id="12627" href="agda2hs.html#12580" class="Bound">f</a> <a id="12629" class="Symbol">(</a><a id="12630" href="agda2hs.html#12588" class="Bound">xs</a> <a id="12633" class="Symbol">.</a><a id="12634" href="Haskell.Prim.Thunk.html#240" class="Field">force</a><a id="12639" class="Symbol">)</a>
<a id="12641" class="Symbol">{-#</a> <a id="12645" class="Keyword">COMPILE</a> <a id="12653" class="Keyword">AGDA2HS</a> <a id="12661" href="agda2hs.html#12532" class="Function">mapS</a> <a id="12666" class="Symbol">#-}</a>
</pre>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">mapS ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Stream</span> a <span class="ot">-&gt;</span> <span class="dt">Stream</span> b</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>mapS f (x <span class="op">:&gt;</span> xs) <span class="ot">=</span> f x <span class="op">:&gt;</span> mapS f xs</span></code></pre></div>
<p>As an example, we can use this to implement the infinite stream of
natural numbers:</p>
<pre class="Agda"><a id="nats"></a><a id="12857" href="agda2hs.html#12857" class="Function">nats</a> <a id="12862" class="Symbol">:</a> <a id="12864" href="agda2hs.html#11092" class="Datatype">Stream</a> <a id="12871" href="Haskell.Prim.Int.html#367" class="Datatype">Int</a> <a id="12875" href="agda2hs.html#353" class="Generalizable">i</a>
<a id="12877" href="agda2hs.html#12857" class="Function">nats</a> <a id="12882" class="Symbol">=</a> <a id="12884" class="Number">0</a> <a id="12886" href="agda2hs.html#11137" class="InductiveConstructor Operator">:&gt;</a> <a id="12889" class="Symbol">λ</a> <a id="12891" class="Keyword">where</a> <a id="12897" class="Symbol">.</a><a id="12898" href="Haskell.Prim.Thunk.html#240" class="Field">force</a> <a id="12904" class="Symbol">→</a> <a id="12906" href="agda2hs.html#12532" class="Function">mapS</a> <a id="12911" class="Symbol">(λ</a> <a id="12914" href="agda2hs.html#12914" class="Bound">x</a> <a id="12916" class="Symbol">→</a> <a id="12918" class="Number">1</a> <a id="12920" href="Haskell.Prim.Num.html#552" class="Field Operator">+</a> <a id="12922" href="agda2hs.html#12914" class="Bound">x</a><a id="12923" class="Symbol">)</a> <a id="12925" href="agda2hs.html#12857" class="Function">nats</a>
<a id="12930" class="Symbol">{-#</a> <a id="12934" class="Keyword">COMPILE</a> <a id="12942" class="Keyword">AGDA2HS</a> <a id="12950" href="agda2hs.html#12857" class="Function">nats</a> <a id="12955" class="Symbol">#-}</a>
</pre>
<p>Finally, let me make good on my promise and prove map fusion on
streams by using Cubical Agda. Step one: import the <code>PathP</code> type
and define the cubical equality type <code>_=P_</code> in terms of it:</p>
<pre class="Agda"><a id="13160" class="Keyword">open</a> <a id="13165" class="Keyword">import</a> <a id="13172" href="Agda.Primitive.Cubical.html" class="Module">Agda.Primitive.Cubical</a> <a id="13195" class="Keyword">using</a> <a id="13201" class="Symbol">(</a><a id="13202" href="Agda.Primitive.Cubical.html#2013" class="Postulate">PathP</a><a id="13207" class="Symbol">)</a>

<a id="_=P_"></a><a id="13210" href="agda2hs.html#13210" class="Function Operator">_=P_</a> <a id="13215" class="Symbol">:</a> <a id="13217" class="Symbol">{</a><a id="13218" href="agda2hs.html#13218" class="Bound">a</a> <a id="13220" class="Symbol">:</a> <a id="13222" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="13226" href="agda2hs.html#341" class="Generalizable">ℓ</a><a id="13227" class="Symbol">}</a> <a id="13229" class="Symbol">→</a> <a id="13231" class="Symbol">(</a><a id="13232" href="agda2hs.html#13232" class="Bound">x</a> <a id="13234" href="agda2hs.html#13234" class="Bound">y</a> <a id="13236" class="Symbol">:</a> <a id="13238" href="agda2hs.html#13218" class="Bound">a</a><a id="13239" class="Symbol">)</a> <a id="13241" class="Symbol">→</a> <a id="13243" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="13247" href="agda2hs.html#341" class="Generalizable">ℓ</a>
<a id="13249" href="agda2hs.html#13210" class="Function Operator">_=P_</a> <a id="13254" class="Symbol">{</a><a id="13255" class="Argument">a</a> <a id="13257" class="Symbol">=</a> <a id="13259" href="agda2hs.html#13259" class="Bound">a</a><a id="13260" class="Symbol">}</a> <a id="13262" class="Symbol">=</a> <a id="13264" href="Agda.Primitive.Cubical.html#2013" class="Postulate">PathP</a> <a id="13270" class="Symbol">(λ</a> <a id="13273" href="agda2hs.html#13273" class="Bound">_</a> <a id="13275" class="Symbol">→</a> <a id="13277" href="agda2hs.html#13259" class="Bound">a</a><a id="13278" class="Symbol">)</a>
</pre>
<p>Step two: <del><a href="https://knowyourmeme.com/memes/how-to-draw-an-owl">draw the
owl</a></del> prove the
fusion:</p>
<pre class="Agda"><a id="mapS-fusion"></a><a id="13388" href="agda2hs.html#13388" class="Function">mapS-fusion</a>  <a id="13401" class="Symbol">:</a> <a id="13403" class="Symbol">(</a><a id="13404" href="agda2hs.html#13404" class="Bound">f</a> <a id="13406" class="Symbol">:</a> <a id="13408" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="13410" class="Symbol">→</a> <a id="13412" href="Haskell.Prim.html#1216" class="Generalizable">b</a><a id="13413" class="Symbol">)</a> <a id="13415" class="Symbol">(</a><a id="13416" href="agda2hs.html#13416" class="Bound">g</a> <a id="13418" class="Symbol">:</a> <a id="13420" href="Haskell.Prim.html#1216" class="Generalizable">b</a> <a id="13422" class="Symbol">→</a> <a id="13424" href="Haskell.Prim.html#1218" class="Generalizable">c</a><a id="13425" class="Symbol">)</a> <a id="13427" class="Symbol">(</a><a id="13428" href="agda2hs.html#13428" class="Bound">s</a> <a id="13430" class="Symbol">:</a> <a id="13432" href="agda2hs.html#11092" class="Datatype">Stream</a> <a id="13439" href="Haskell.Prim.html#1214" class="Generalizable">a</a> <a id="13441" href="agda2hs.html#353" class="Generalizable">i</a><a id="13442" class="Symbol">)</a>
             <a id="13457" class="Symbol">→</a>  <a id="13460" href="agda2hs.html#12532" class="Function">mapS</a> <a id="13465" class="Symbol">{</a><a id="13466" class="Argument">i</a> <a id="13468" class="Symbol">=</a> <a id="13470" href="agda2hs.html#353" class="Generalizable">i</a><a id="13471" class="Symbol">}</a> <a id="13473" href="agda2hs.html#13416" class="Bound">g</a> <a id="13475" class="Symbol">(</a><a id="13476" href="agda2hs.html#12532" class="Function">mapS</a> <a id="13481" class="Symbol">{</a><a id="13482" class="Argument">i</a> <a id="13484" class="Symbol">=</a> <a id="13486" href="agda2hs.html#353" class="Generalizable">i</a><a id="13487" class="Symbol">}</a> <a id="13489" href="agda2hs.html#13404" class="Bound">f</a> <a id="13491" href="agda2hs.html#13428" class="Bound">s</a><a id="13492" class="Symbol">)</a>
             <a id="13507" href="agda2hs.html#13210" class="Function Operator">=P</a> <a id="13510" href="agda2hs.html#12532" class="Function">mapS</a> <a id="13515" class="Symbol">{</a><a id="13516" class="Argument">i</a> <a id="13518" class="Symbol">=</a> <a id="13520" href="agda2hs.html#353" class="Generalizable">i</a><a id="13521" class="Symbol">}</a> <a id="13523" class="Symbol">(λ</a> <a id="13526" href="agda2hs.html#13526" class="Bound">x</a> <a id="13528" class="Symbol">→</a> <a id="13530" href="agda2hs.html#13416" class="Bound">g</a> <a id="13532" class="Symbol">(</a><a id="13533" href="agda2hs.html#13404" class="Bound">f</a> <a id="13535" href="agda2hs.html#13526" class="Bound">x</a><a id="13536" class="Symbol">))</a> <a id="13539" href="agda2hs.html#13428" class="Bound">s</a>
<a id="13541" href="agda2hs.html#13388" class="Function">mapS-fusion</a>  <a id="13554" href="agda2hs.html#13554" class="Bound">f</a> <a id="13556" href="agda2hs.html#13556" class="Bound">g</a> <a id="13558" class="Symbol">(</a><a id="13559" href="agda2hs.html#13559" class="Bound">hd</a> <a id="13562" href="agda2hs.html#11137" class="InductiveConstructor Operator">:&gt;</a> <a id="13565" href="agda2hs.html#13565" class="Bound">tl</a><a id="13567" class="Symbol">)</a> <a id="13569" href="agda2hs.html#13569" class="Bound">i</a> <a id="13571" class="Symbol">=</a>
  <a id="13575" class="Symbol">(</a><a id="13576" href="agda2hs.html#13556" class="Bound">g</a> <a id="13578" class="Symbol">(</a><a id="13579" href="agda2hs.html#13554" class="Bound">f</a> <a id="13581" href="agda2hs.html#13559" class="Bound">hd</a><a id="13583" class="Symbol">))</a> <a id="13586" href="agda2hs.html#11137" class="InductiveConstructor Operator">:&gt;</a> <a id="13589" class="Symbol">λ</a> <a id="13591" class="Keyword">where</a> <a id="13597" class="Symbol">.</a><a id="13598" href="Haskell.Prim.Thunk.html#240" class="Field">force</a> <a id="13604" class="Symbol">→</a> <a id="13606" href="agda2hs.html#13388" class="Function">mapS-fusion</a> <a id="13618" href="agda2hs.html#13554" class="Bound">f</a> <a id="13620" href="agda2hs.html#13556" class="Bound">g</a> <a id="13622" class="Symbol">(</a><a id="13623" href="agda2hs.html#13565" class="Bound">tl</a> <a id="13626" class="Symbol">.</a><a id="13627" href="Haskell.Prim.Thunk.html#240" class="Field">force</a><a id="13632" class="Symbol">)</a> <a id="13634" href="agda2hs.html#13569" class="Bound">i</a>
</pre>
<p>If you haven’t seen Cubical Agda being used for proving bisimilarity
before, this probably looks like magic. But if it is magic, it is
magic provided by Cubical Agda, not by <code>agda2hs</code>. The <em>real</em> magic is
the fact that <code>agda2hs</code> does not even need to know anything about
Cubical Agda for this proof to work!</p>
<p>If you want to try out <code>agda2hs</code> for yourself, you can get it from
<a href="https://github.com/agda/agda2hs">Github</a>. If you are keen to see more
examples and learn of the design and implementation of <code>agda2hs</code>, you
can take a look at our recent <a href="https://dl.acm.org/doi/pdf/10.1145/3546189.3549920">paper at the Haskell
Symposium</a>.
And if you have any comments or suggestions about this post, you can
always send them to me on <a href="https://types.pl/agdakx">Mastodon</a> or via
<a href="mailto:jesper@sikanda.be">email</a>.</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Tue, 04 Oct 2022 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/agda2hs.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>1001 Representations of Syntax with Binding</title>
    <link>https://jesper.sikanda.be/posts/1001-syntax-representations.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - 1001 Representations of Syntax with Binding</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>1001 Representations of Syntax with Binding</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on November  4, 2021
    </p>
    <p>As a compiler developer or programming language researcher, one very
common question is how to represent the syntax of a programming
language in order to interpret, compile, analyze, optimize, and/or
transform it.</p>
<p>One of the first lessons you learn is to not represent syntax as the
literal string of characters written by the programmer, but rather
convert it to an <em>abstract syntax tree</em> (AST). This has a number of
advantages: it enforces structure on programs, makes the syntax easier
to traverse and transform, erases irrelevant details (e.g. whitespace
and comments), and allows for better separation of different
intermediate states of the syntax.</p>
<p>However, syntax is in fact not a tree but a <em>graph</em>: names (of
variables, functions, classes, modules, …) can point to potentially
far-away locations in the program’s text. The way these work is that
one occurrence of the name <em>binds</em> the name (aka the binder), and
other occurrences of the same name <em>mention</em> the name, thus pointing
to the binder.</p>
<p>Just as representing syntax as a string is not a good idea for most
purposes, representing names as strings is usually not a good idea
either. This will be clear to anyone who has ever implemented
capture-avoiding substitution for lambda-terms with strings as
variable names (and if you haven’t, I invite you to do so). Hence we
would like to have a generic and universal way to represent the
structure of binders-and-mentions, similar to how abstract syntax
trees represent the structure of
syntactical-constructs-and-their-components.</p>
<p>Unfortunately, in contrast to the case of abstract syntax, there are
countless different techniques, frameworks, and meta-languages for
dealing with name binding, none of which come close to be universally
accepted or clearly superior to the others. For the compiler developer
or PL researcher who just wants to define their syntax and move on to
more interesting things, this is frustrating, to say the least. Make
the wrong choice, and you are stuck with impossibly complex and buggy
code for manipulating variables, or proving an endless stream of
substitution lemmas, or figuring out too late that the thing you want
to do is just not possible with the chosen representation of names.</p>
<p>In this post, I will give an overview of all the different techniques
for implementing syntax with binders in Agda that I could find. With
each technique, I will show how to use it in Agda to represent the
syntax of (untyped) lambda calculus, and also explain briefly what the
main motivation is for using it. I hope this will be useful to you
for making an informed choice between these options.</p>
<p>Since there’s quite a few of them, I can only give a brief description
of each representation in this post. If you want to learn more about
any of them, you can find my full list of references <a href="https://researchr.org/bibliography/variable-binding/publications">on
Researchr</a>.
Also, since this is a blog post and not a book, I will limit this
overview to representations that can be defined and used in Agda or a
similar dependently-typed functional language (e.g. Coq or Haskell),
not in language features that could be added to Agda or in entire new
languages built for this specific purpose. In particular, this means
representations that require a (meta-)language with a built-in way to
assign unique identifiers are ruled out.</p>
<p>Finally, in this post I will not consider the problem of <em>name
resolution</em>, i.e. how to figure out which binder each occurrence of a
name points to. Instead, I focus on how to represent and manipulate
syntax where names are used correctly according to the rules of the
language. You can think of this as finding a good representation of
the <em>output</em> of name resolution, similar to how an AST is the output
of parsing.</p>
<p>With these disclaimers in place, it is time to start with the first
and possibly most ubiqitous representation: de Bruijn indices.</p>
<!--

<pre class="Agda"><a id="4027" class="Comment">-- This is Agda code. Whee!</a>
<a id="4055" class="Keyword">module</a> <a id="4062" href="1001-syntax-representations.html" class="Module">_</a> <a id="4064" class="Keyword">where</a>

<a id="4071" class="Keyword">open</a> <a id="4076" class="Keyword">import</a> <a id="4083" href="Data.Bool.html" class="Module">Data.Bool</a>
<a id="4093" class="Keyword">open</a> <a id="4098" class="Keyword">import</a> <a id="4105" href="Data.Empty.html" class="Module">Data.Empty</a>
<a id="4116" class="Keyword">open</a> <a id="4121" class="Keyword">import</a> <a id="4128" href="Data.Fin.html" class="Module">Data.Fin</a> <a id="4137" class="Keyword">using</a> <a id="4143" class="Symbol">(</a><a id="4144" href="Data.Fin.Base.html#1132" class="Datatype">Fin</a><a id="4147" class="Symbol">;</a> <a id="4149" href="Data.Fin.Base.html#1154" class="InductiveConstructor">zero</a><a id="4153" class="Symbol">;</a> <a id="4155" href="Data.Fin.Base.html#1175" class="InductiveConstructor">suc</a><a id="4158" class="Symbol">)</a>
<a id="4160" class="Keyword">open</a> <a id="4165" class="Keyword">import</a> <a id="4172" href="Data.List.html" class="Module">Data.List</a> <a id="4182" class="Keyword">using</a> <a id="4188" class="Symbol">(</a><a id="4189" href="Agda.Builtin.List.html#147" class="Datatype">List</a><a id="4193" class="Symbol">;</a> <a id="4195" href="Data.List.Base.html#7301" class="InductiveConstructor">[]</a><a id="4197" class="Symbol">;</a> <a id="4199" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">_∷_</a><a id="4202" class="Symbol">)</a>
<a id="4204" class="Keyword">open</a> <a id="4209" class="Keyword">import</a> <a id="4216" href="Data.Maybe.Base.html" class="Module">Data.Maybe.Base</a>
<a id="4232" class="Keyword">open</a> <a id="4237" class="Keyword">import</a> <a id="4244" href="Data.Nat.html" class="Module">Data.Nat</a> <a id="4253" class="Symbol">as</a> <a id="4256" class="Module">ℕ</a> <a id="4258" class="Keyword">hiding</a> <a id="4265" class="Symbol">(</a><a id="4266" href="Data.Nat.Properties.html#4093" class="Function Operator">_≟_</a><a id="4269" class="Symbol">)</a>
<a id="4271" class="Keyword">open</a> <a id="4276" class="Keyword">import</a> <a id="4283" href="Data.Nat.Show.html" class="Module">Data.Nat.Show</a> <a id="4297" class="Symbol">as</a> <a id="4300" class="Module">ℕ</a>
<a id="4302" class="Keyword">open</a> <a id="4307" class="Keyword">import</a> <a id="4314" href="Data.Product.html" class="Module">Data.Product</a>
<a id="4327" class="Keyword">open</a> <a id="4332" class="Keyword">import</a> <a id="4339" href="Data.String.html" class="Module">Data.String</a> <a id="4351" class="Symbol">as</a> <a id="4354" class="Module">String</a> <a id="4361" class="Keyword">hiding</a> <a id="4368" class="Symbol">(</a><a id="4369" href="Data.String.Properties.html#2741" class="Function Operator">_≟_</a><a id="4372" class="Symbol">)</a>
<a id="4374" class="Keyword">open</a> <a id="4379" class="Keyword">import</a> <a id="4386" href="Data.Sum.html" class="Module">Data.Sum</a>
<a id="4395" class="Keyword">open</a> <a id="4400" class="Keyword">import</a> <a id="4407" href="Data.Unit.html" class="Module">Data.Unit</a>
<a id="4417" class="Keyword">open</a> <a id="4422" class="Keyword">import</a> <a id="4429" href="Function.html" class="Module">Function</a> <a id="4438" class="Keyword">using</a> <a id="4444" class="Symbol">(</a><a id="4445" href="Function.Base.html#4061" class="Function Operator">case_of_</a><a id="4453" class="Symbol">)</a>
<a id="4455" class="Keyword">open</a> <a id="4460" class="Keyword">import</a> <a id="4467" href="Function.HalfAdjointEquivalence.html" class="Module">Function.HalfAdjointEquivalence</a>
<a id="4499" class="Keyword">open</a> <a id="4504" class="Keyword">import</a> <a id="4511" href="Relation.Nullary.html" class="Module">Relation.Nullary</a>
<a id="4528" class="Keyword">open</a> <a id="4533" class="Keyword">import</a> <a id="4540" href="Relation.Binary.html" class="Module">Relation.Binary</a> <a id="4556" class="Keyword">using</a> <a id="4562" class="Symbol">(</a><a id="4563" href="Relation.Binary.Definitions.html#1355" class="Function">Reflexive</a><a id="4572" class="Symbol">;</a> <a id="4574" href="Relation.Binary.Definitions.html#2030" class="Function">Transitive</a><a id="4584" class="Symbol">)</a>
<a id="4586" class="Keyword">open</a> <a id="4591" class="Keyword">import</a> <a id="4598" href="Relation.Binary.PropositionalEquality.html" class="Module">Relation.Binary.PropositionalEquality</a>
</pre>
-->
<h1 id="de-bruijn-indices">De Bruijn indices</h1>
<p><a href="https://www.win.tue.nl/automath/archive/pdf/aut029.pdf">De Bruijn indices</a> are
the most common <em>nameless</em> representation of name binding. A de Bruijn
index represents a name by counting how many binders need to be
skipped when traversing upwards through the AST before one reaches the
name’s binding site.</p>
<p>Here is the definition of lambda terms using de Bruijn indices, and a
representation of the term <code>λ f. λ x. f x</code>:</p>
<pre class="Agda"><a id="5114" class="Keyword">module</a> <a id="DeBruijnSyntax"></a><a id="5121" href="1001-syntax-representations.html#5121" class="Module">DeBruijnSyntax</a> <a id="5136" class="Keyword">where</a>
  <a id="5144" class="Keyword">data</a> <a id="DeBruijnSyntax.Term"></a><a id="5149" href="1001-syntax-representations.html#5149" class="Datatype">Term</a> <a id="5154" class="Symbol">:</a> <a id="5156" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="5160" class="Keyword">where</a>
    <a id="DeBruijnSyntax.Term.var"></a><a id="5170" href="1001-syntax-representations.html#5170" class="InductiveConstructor">var</a> <a id="5174" class="Symbol">:</a> <a id="5176" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="5178" class="Symbol">→</a> <a id="5180" href="1001-syntax-representations.html#5149" class="Datatype">Term</a>
    <a id="DeBruijnSyntax.Term.lam"></a><a id="5189" href="1001-syntax-representations.html#5189" class="InductiveConstructor">lam</a> <a id="5193" class="Symbol">:</a> <a id="5195" href="1001-syntax-representations.html#5149" class="Datatype">Term</a> <a id="5200" class="Symbol">→</a> <a id="5202" href="1001-syntax-representations.html#5149" class="Datatype">Term</a>
    <a id="DeBruijnSyntax.Term.app"></a><a id="5211" href="1001-syntax-representations.html#5211" class="InductiveConstructor">app</a> <a id="5215" class="Symbol">:</a> <a id="5217" href="1001-syntax-representations.html#5149" class="Datatype">Term</a> <a id="5222" class="Symbol">→</a> <a id="5224" href="1001-syntax-representations.html#5149" class="Datatype">Term</a> <a id="5229" class="Symbol">→</a> <a id="5231" href="1001-syntax-representations.html#5149" class="Datatype">Term</a>

  <a id="DeBruijnSyntax.ex"></a><a id="5239" href="1001-syntax-representations.html#5239" class="Function">ex</a> <a id="5242" class="Symbol">:</a> <a id="5244" href="1001-syntax-representations.html#5149" class="Datatype">Term</a>
  <a id="5251" href="1001-syntax-representations.html#5239" class="Function">ex</a> <a id="5254" class="Symbol">=</a> <a id="5256" href="1001-syntax-representations.html#5189" class="InductiveConstructor">lam</a> <a id="5260" class="Comment">{-f-}</a> <a id="5266" class="Symbol">(</a><a id="5267" href="1001-syntax-representations.html#5189" class="InductiveConstructor">lam</a> <a id="5271" class="Comment">{-x-}</a> <a id="5277" class="Symbol">(</a><a id="5278" href="1001-syntax-representations.html#5211" class="InductiveConstructor">app</a> <a id="5282" class="Symbol">(</a><a id="5283" href="1001-syntax-representations.html#5170" class="InductiveConstructor">var</a> <a id="5287" class="Comment">{-f-}</a> <a id="5293" class="Number">1</a><a id="5294" class="Symbol">)</a> <a id="5296" class="Symbol">(</a><a id="5297" href="1001-syntax-representations.html#5170" class="InductiveConstructor">var</a> <a id="5301" class="Comment">{-x-}</a> <a id="5307" class="Number">0</a><a id="5308" class="Symbol">)))</a>
</pre>
<p>De Bruijn syntax is used widely in the implementation and
formalization of programming languages, especially with functional
implementation languages. For example, Agda is implemented in Haskell
and the internal syntax represents variables (but not other names)
using de Bruijn indices.</p>
<p>The big advantage of de Bruijn syntax is that each lambda-expression
has a <em>unique</em> representation and hence any two α-equivalent terms
(e.g. <code>λ x. x</code> and <code>λ y. y</code>) are represented the same. It also leads
to a more uniform and - arguably - more pleasant implementation of
substitution than on syntax with strings for names. On the other
hand, it is often quoted as a good “reverse Turing test” because most
humans have a hard time grasping the meaning of a term and reasoning
about them correctly.</p>
<p>A variation on de Bruijn indices are de Bruijn <em>levels</em>, which count
the number of binders starting from the root node rather than from the
occurrence of the name. This simplifies the implementation of some
operations, but the assumption there exists a global ‘root node’
complicates others, so overall the choice between de Bruijn indices
and levels is kind of a wash.</p>
<h1 id="locally-nameless">Locally nameless</h1>
<p>One of the main problems with de Bruijn syntax is the absence of any
actual names when constructing syntax. One possible solution is to
distinguish between variables that are <em>bound</em> and those that are
<em>free</em>, and note that only bound variables need to be anonymous. This
leads to the class of syntax representations known as <a href="http://www.chargueraud.org/research/2009/ln/main.pdf"><em>locally
nameless</em></a>.</p>
<pre class="Agda"><a id="6920" class="Keyword">module</a> <a id="LocallyNameless"></a><a id="6927" href="1001-syntax-representations.html#6927" class="Module">LocallyNameless</a> <a id="6943" class="Keyword">where</a>

  <a id="LocallyNameless.Name"></a><a id="6952" href="1001-syntax-representations.html#6952" class="Function">Name</a> <a id="6957" class="Symbol">=</a> <a id="6959" href="Agda.Builtin.String.html#335" class="Postulate">String</a>

  <a id="6969" class="Keyword">data</a> <a id="LocallyNameless.Term"></a><a id="6974" href="1001-syntax-representations.html#6974" class="Datatype">Term</a> <a id="6979" class="Symbol">:</a> <a id="6981" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="6985" class="Keyword">where</a>
    <a id="LocallyNameless.Term.bound"></a><a id="6995" href="1001-syntax-representations.html#6995" class="InductiveConstructor">bound</a> <a id="7001" class="Symbol">:</a> <a id="7003" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="7005" class="Symbol">→</a> <a id="7007" href="1001-syntax-representations.html#6974" class="Datatype">Term</a>
    <a id="LocallyNameless.Term.free"></a><a id="7016" href="1001-syntax-representations.html#7016" class="InductiveConstructor">free</a>  <a id="7022" class="Symbol">:</a> <a id="7024" href="1001-syntax-representations.html#6952" class="Function">Name</a> <a id="7029" class="Symbol">→</a> <a id="7031" href="1001-syntax-representations.html#6974" class="Datatype">Term</a>
    <a id="LocallyNameless.Term.lam"></a><a id="7040" href="1001-syntax-representations.html#7040" class="InductiveConstructor">lam</a>   <a id="7046" class="Symbol">:</a> <a id="7048" href="1001-syntax-representations.html#6974" class="Datatype">Term</a> <a id="7053" class="Symbol">→</a> <a id="7055" href="1001-syntax-representations.html#6974" class="Datatype">Term</a>
    <a id="LocallyNameless.Term.app"></a><a id="7064" href="1001-syntax-representations.html#7064" class="InductiveConstructor">app</a>   <a id="7070" class="Symbol">:</a> <a id="7072" href="1001-syntax-representations.html#6974" class="Datatype">Term</a> <a id="7077" class="Symbol">→</a> <a id="7079" href="1001-syntax-representations.html#6974" class="Datatype">Term</a> <a id="7084" class="Symbol">→</a> <a id="7086" href="1001-syntax-representations.html#6974" class="Datatype">Term</a>
</pre>
<p>To mediate between bound and free variables (e.g. when going under a
binder), we define operations for <em>opening</em> and <em>closing</em> a term:</p>
<pre class="Agda">  <a id="LocallyNameless.openUnder"></a><a id="7238" href="1001-syntax-representations.html#7238" class="Function">openUnder</a> <a id="7248" class="Symbol">:</a> <a id="7250" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="7252" class="Symbol">→</a> <a id="7254" href="1001-syntax-representations.html#6952" class="Function">Name</a> <a id="7259" class="Symbol">→</a> <a id="7261" href="1001-syntax-representations.html#6974" class="Datatype">Term</a> <a id="7266" class="Symbol">→</a> <a id="7268" href="1001-syntax-representations.html#6974" class="Datatype">Term</a>
  <a id="7275" href="1001-syntax-representations.html#7238" class="Function">openUnder</a> <a id="7285" href="1001-syntax-representations.html#7285" class="Bound">k</a> <a id="7287" href="1001-syntax-representations.html#7287" class="Bound">x</a> <a id="7289" class="Symbol">(</a><a id="7290" href="1001-syntax-representations.html#6995" class="InductiveConstructor">bound</a> <a id="7296" href="1001-syntax-representations.html#7296" class="Bound">n</a><a id="7297" class="Symbol">)</a> <a id="7299" class="Symbol">=</a>
    <a id="7305" href="Data.Bool.Base.html#1515" class="Function Operator">if</a> <a id="7308" href="Relation.Nullary.Decidable.Core.html#2032" class="Field">does</a> <a id="7313" class="Symbol">(</a><a id="7314" href="1001-syntax-representations.html#7285" class="Bound">k</a> <a id="7316" href="Data.Nat.Properties.html#4093" class="Function Operator">ℕ.≟</a> <a id="7320" href="1001-syntax-representations.html#7296" class="Bound">n</a><a id="7321" class="Symbol">)</a> <a id="7323" href="Data.Bool.Base.html#1515" class="Function Operator">then</a> <a id="7328" href="1001-syntax-representations.html#7016" class="InductiveConstructor">free</a> <a id="7333" href="1001-syntax-representations.html#7287" class="Bound">x</a> <a id="7335" href="Data.Bool.Base.html#1515" class="Function Operator">else</a> <a id="7340" href="1001-syntax-representations.html#6995" class="InductiveConstructor">bound</a> <a id="7346" href="1001-syntax-representations.html#7296" class="Bound">n</a>
  <a id="7350" href="1001-syntax-representations.html#7238" class="Function">openUnder</a> <a id="7360" href="1001-syntax-representations.html#7360" class="Bound">k</a> <a id="7362" href="1001-syntax-representations.html#7362" class="Bound">x</a> <a id="7364" class="Symbol">(</a><a id="7365" href="1001-syntax-representations.html#7016" class="InductiveConstructor">free</a> <a id="7370" href="1001-syntax-representations.html#7370" class="Bound">y</a><a id="7371" class="Symbol">)</a>  <a id="7374" class="Symbol">=</a> <a id="7376" href="1001-syntax-representations.html#7016" class="InductiveConstructor">free</a> <a id="7381" href="1001-syntax-representations.html#7370" class="Bound">y</a>
  <a id="7385" href="1001-syntax-representations.html#7238" class="Function">openUnder</a> <a id="7395" href="1001-syntax-representations.html#7395" class="Bound">k</a> <a id="7397" href="1001-syntax-representations.html#7397" class="Bound">x</a> <a id="7399" class="Symbol">(</a><a id="7400" href="1001-syntax-representations.html#7040" class="InductiveConstructor">lam</a> <a id="7404" href="1001-syntax-representations.html#7404" class="Bound">u</a><a id="7405" class="Symbol">)</a>   <a id="7409" class="Symbol">=</a> <a id="7411" href="1001-syntax-representations.html#7040" class="InductiveConstructor">lam</a> <a id="7415" class="Symbol">(</a><a id="7416" href="1001-syntax-representations.html#7238" class="Function">openUnder</a> <a id="7426" class="Symbol">(</a><a id="7427" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="7431" href="1001-syntax-representations.html#7395" class="Bound">k</a><a id="7432" class="Symbol">)</a> <a id="7434" href="1001-syntax-representations.html#7397" class="Bound">x</a> <a id="7436" href="1001-syntax-representations.html#7404" class="Bound">u</a><a id="7437" class="Symbol">)</a>
  <a id="7441" href="1001-syntax-representations.html#7238" class="Function">openUnder</a> <a id="7451" href="1001-syntax-representations.html#7451" class="Bound">k</a> <a id="7453" href="1001-syntax-representations.html#7453" class="Bound">x</a> <a id="7455" class="Symbol">(</a><a id="7456" href="1001-syntax-representations.html#7064" class="InductiveConstructor">app</a> <a id="7460" href="1001-syntax-representations.html#7460" class="Bound">u</a> <a id="7462" href="1001-syntax-representations.html#7462" class="Bound">v</a><a id="7463" class="Symbol">)</a> <a id="7465" class="Symbol">=</a>
    <a id="7471" href="1001-syntax-representations.html#7064" class="InductiveConstructor">app</a> <a id="7475" class="Symbol">(</a><a id="7476" href="1001-syntax-representations.html#7238" class="Function">openUnder</a> <a id="7486" href="1001-syntax-representations.html#7451" class="Bound">k</a> <a id="7488" href="1001-syntax-representations.html#7453" class="Bound">x</a> <a id="7490" href="1001-syntax-representations.html#7460" class="Bound">u</a><a id="7491" class="Symbol">)</a> <a id="7493" class="Symbol">(</a><a id="7494" href="1001-syntax-representations.html#7238" class="Function">openUnder</a> <a id="7504" href="1001-syntax-representations.html#7451" class="Bound">k</a> <a id="7506" href="1001-syntax-representations.html#7453" class="Bound">x</a> <a id="7508" href="1001-syntax-representations.html#7462" class="Bound">v</a><a id="7509" class="Symbol">)</a>

  <a id="LocallyNameless.openT"></a><a id="7514" href="1001-syntax-representations.html#7514" class="Function">openT</a> <a id="7520" class="Symbol">=</a> <a id="7522" href="1001-syntax-representations.html#7238" class="Function">openUnder</a> <a id="7532" class="Number">0</a>

  <a id="LocallyNameless.closeUnder"></a><a id="7537" href="1001-syntax-representations.html#7537" class="Function">closeUnder</a> <a id="7548" class="Symbol">:</a> <a id="7550" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="7552" class="Symbol">→</a> <a id="7554" href="1001-syntax-representations.html#6952" class="Function">Name</a> <a id="7559" class="Symbol">→</a> <a id="7561" href="1001-syntax-representations.html#6974" class="Datatype">Term</a> <a id="7566" class="Symbol">→</a> <a id="7568" href="1001-syntax-representations.html#6974" class="Datatype">Term</a>
  <a id="7575" href="1001-syntax-representations.html#7537" class="Function">closeUnder</a> <a id="7586" href="1001-syntax-representations.html#7586" class="Bound">k</a> <a id="7588" href="1001-syntax-representations.html#7588" class="Bound">x</a> <a id="7590" class="Symbol">(</a><a id="7591" href="1001-syntax-representations.html#6995" class="InductiveConstructor">bound</a> <a id="7597" href="1001-syntax-representations.html#7597" class="Bound">n</a><a id="7598" class="Symbol">)</a> <a id="7600" class="Symbol">=</a> <a id="7602" href="1001-syntax-representations.html#6995" class="InductiveConstructor">bound</a> <a id="7608" href="1001-syntax-representations.html#7597" class="Bound">n</a>
  <a id="7612" href="1001-syntax-representations.html#7537" class="Function">closeUnder</a> <a id="7623" href="1001-syntax-representations.html#7623" class="Bound">k</a> <a id="7625" href="1001-syntax-representations.html#7625" class="Bound">x</a> <a id="7627" class="Symbol">(</a><a id="7628" href="1001-syntax-representations.html#7016" class="InductiveConstructor">free</a> <a id="7633" href="1001-syntax-representations.html#7633" class="Bound">y</a><a id="7634" class="Symbol">)</a>  <a id="7637" class="Symbol">=</a>
    <a id="7643" href="Data.Bool.Base.html#1515" class="Function Operator">if</a> <a id="7646" href="Relation.Nullary.Decidable.Core.html#2032" class="Field">does</a> <a id="7651" class="Symbol">(</a><a id="7652" href="1001-syntax-representations.html#7625" class="Bound">x</a> <a id="7654" href="Data.String.Properties.html#2741" class="Function Operator">String.≟</a> <a id="7663" href="1001-syntax-representations.html#7633" class="Bound">y</a><a id="7664" class="Symbol">)</a> <a id="7666" href="Data.Bool.Base.html#1515" class="Function Operator">then</a> <a id="7671" href="1001-syntax-representations.html#6995" class="InductiveConstructor">bound</a> <a id="7677" href="1001-syntax-representations.html#7623" class="Bound">k</a> <a id="7679" href="Data.Bool.Base.html#1515" class="Function Operator">else</a> <a id="7684" href="1001-syntax-representations.html#7016" class="InductiveConstructor">free</a> <a id="7689" href="1001-syntax-representations.html#7633" class="Bound">y</a>
  <a id="7693" href="1001-syntax-representations.html#7537" class="Function">closeUnder</a> <a id="7704" href="1001-syntax-representations.html#7704" class="Bound">k</a> <a id="7706" href="1001-syntax-representations.html#7706" class="Bound">x</a> <a id="7708" class="Symbol">(</a><a id="7709" href="1001-syntax-representations.html#7040" class="InductiveConstructor">lam</a> <a id="7713" href="1001-syntax-representations.html#7713" class="Bound">u</a><a id="7714" class="Symbol">)</a>   <a id="7718" class="Symbol">=</a> <a id="7720" href="1001-syntax-representations.html#7040" class="InductiveConstructor">lam</a> <a id="7724" class="Symbol">(</a><a id="7725" href="1001-syntax-representations.html#7537" class="Function">closeUnder</a> <a id="7736" class="Symbol">(</a><a id="7737" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="7741" href="1001-syntax-representations.html#7704" class="Bound">k</a><a id="7742" class="Symbol">)</a> <a id="7744" href="1001-syntax-representations.html#7706" class="Bound">x</a> <a id="7746" href="1001-syntax-representations.html#7713" class="Bound">u</a><a id="7747" class="Symbol">)</a>
  <a id="7751" href="1001-syntax-representations.html#7537" class="Function">closeUnder</a> <a id="7762" href="1001-syntax-representations.html#7762" class="Bound">k</a> <a id="7764" href="1001-syntax-representations.html#7764" class="Bound">x</a> <a id="7766" class="Symbol">(</a><a id="7767" href="1001-syntax-representations.html#7064" class="InductiveConstructor">app</a> <a id="7771" href="1001-syntax-representations.html#7771" class="Bound">u</a> <a id="7773" href="1001-syntax-representations.html#7773" class="Bound">v</a><a id="7774" class="Symbol">)</a> <a id="7776" class="Symbol">=</a>
    <a id="7782" href="1001-syntax-representations.html#7064" class="InductiveConstructor">app</a> <a id="7786" class="Symbol">(</a><a id="7787" href="1001-syntax-representations.html#7537" class="Function">closeUnder</a> <a id="7798" href="1001-syntax-representations.html#7762" class="Bound">k</a> <a id="7800" href="1001-syntax-representations.html#7764" class="Bound">x</a> <a id="7802" href="1001-syntax-representations.html#7771" class="Bound">u</a><a id="7803" class="Symbol">)</a> <a id="7805" class="Symbol">(</a><a id="7806" href="1001-syntax-representations.html#7537" class="Function">closeUnder</a> <a id="7817" href="1001-syntax-representations.html#7762" class="Bound">k</a> <a id="7819" href="1001-syntax-representations.html#7764" class="Bound">x</a> <a id="7821" href="1001-syntax-representations.html#7773" class="Bound">v</a><a id="7822" class="Symbol">)</a>

  <a id="LocallyNameless.closeT"></a><a id="7827" href="1001-syntax-representations.html#7827" class="Function">closeT</a> <a id="7834" class="Symbol">=</a> <a id="7836" href="1001-syntax-representations.html#7537" class="Function">closeUnder</a> <a id="7847" class="Number">0</a>
</pre>
<p>Using <code>closeT</code>, we can write down variables as strings but convert
them to de Bruijn indices on the fly:</p>
<pre class="Agda">  <a id="LocallyNameless.ex"></a><a id="7966" href="1001-syntax-representations.html#7966" class="Function">ex</a> <a id="7969" class="Symbol">=</a> <a id="7971" href="1001-syntax-representations.html#7040" class="InductiveConstructor">lam</a> <a id="7975" class="Symbol">(</a><a id="7976" href="1001-syntax-representations.html#7827" class="Function">closeT</a> <a id="7983" class="String">&quot;f&quot;</a> <a id="7987" class="Symbol">(</a>
         <a id="7998" href="1001-syntax-representations.html#7040" class="InductiveConstructor">lam</a> <a id="8002" class="Symbol">(</a><a id="8003" href="1001-syntax-representations.html#7827" class="Function">closeT</a> <a id="8010" class="String">&quot;x&quot;</a> <a id="8014" class="Symbol">(</a>
           <a id="8027" href="1001-syntax-representations.html#7064" class="InductiveConstructor">app</a> <a id="8031" class="Symbol">(</a><a id="8032" href="1001-syntax-representations.html#7016" class="InductiveConstructor">free</a> <a id="8037" class="String">&quot;f&quot;</a><a id="8040" class="Symbol">)</a> <a id="8042" class="Symbol">(</a><a id="8043" href="1001-syntax-representations.html#7016" class="InductiveConstructor">free</a> <a id="8048" class="String">&quot;x&quot;</a><a id="8051" class="Symbol">)</a>
         <a id="8062" class="Symbol">))</a>
       <a id="8072" class="Symbol">))</a>

  <a id="8078" href="1001-syntax-representations.html#8078" class="Function">_</a> <a id="8080" class="Symbol">:</a> <a id="8082" href="1001-syntax-representations.html#7966" class="Function">ex</a> <a id="8085" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="8087" href="1001-syntax-representations.html#7040" class="InductiveConstructor">lam</a> <a id="8091" class="Symbol">(</a><a id="8092" href="1001-syntax-representations.html#7040" class="InductiveConstructor">lam</a> <a id="8096" class="Symbol">(</a><a id="8097" href="1001-syntax-representations.html#7064" class="InductiveConstructor">app</a> <a id="8101" class="Symbol">(</a><a id="8102" href="1001-syntax-representations.html#6995" class="InductiveConstructor">bound</a> <a id="8108" class="Number">1</a><a id="8109" class="Symbol">)</a> <a id="8111" class="Symbol">(</a><a id="8112" href="1001-syntax-representations.html#6995" class="InductiveConstructor">bound</a> <a id="8118" class="Number">0</a><a id="8119" class="Symbol">)))</a>
  <a id="8125" class="Symbol">_</a> <a id="8127" class="Symbol">=</a> <a id="8129" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>

</pre>
<p>There are many possible variants of the locally nameless style, where
either the representation of either free or bound variables
differs. For example, representing both free and bound variables as
names (from two distinct types) leads to the <a href="https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.53.2065&amp;rep=rep1&amp;type=pdf"><em>locally
named</em></a>
representation, which was actually introduced first. In the other
direction, instead of representing free variables as strings one could
instead represent them as de Bruijn levels, which results in an
interesting combination of de Bruijn indices and de Bruijn levels.</p>
<p>Locally nameless syntax representations have been successfully used
for doing formal metatheory in Coq, including the formalization of
PCUIC for the <a href="https://github.com/MetaCoq/metacoq/blob/coq-8.11/pcuic/theories/PCUICAst.v">MetaCoq
project</a>. However,
using it successfully requires a lot of boilerplate for dealing with
opening and closing of terms, which might be prohibiting unless the
boilerplate can be generated automatically. Repeated opening and
closing of terms might also introduce a performance bottleneck when
this approach is used for a practical implementation and not just
doing metatheory.</p>
<h1 id="nominal-signatures">Nominal signatures</h1>
<p>Next to the broad family of nameless representations based on de
Bruijn’s representation, a wholly different way to think about names
is by relying on <a href="http://dx.doi.org/10.1016/j.tcs.2004.06.016"><em>nominal
techniques</em></a>. Very
briefly speaking, this means we rely on the presence of one or more
abstract sorts of <em>atoms</em> (i.e. names) together with an operation for
swapping two atoms in a term and a predicate expressing freshness of
an atom with respect to a term. On top of these, one can define a sort
constructor for abstracting over a single atom/name (I am deliberately
using the word ‘sort’ instead of ‘type’ since these are not regular
Agda types). We can then use name abstraction directly to write down a
signature of our syntax and its induction principle.</p>
<p>While nominal techniques provide a general approach to define and
reason about syntax with binders, I actually hesitate to include it
here because it seems to require special language support to use
effectively, which Agda does not have. However, we can work around
that problem by defining a record type that specifies an abstract
interface for working with atoms and (nominal) sorts (here I simplify
it to a single sort of atoms):</p>
<pre class="Agda"><a id="10608" class="Keyword">module</a> <a id="Nominal"></a><a id="10615" href="1001-syntax-representations.html#10615" class="Module">Nominal</a> <a id="10623" class="Keyword">where</a>
  <a id="10631" class="Keyword">record</a> <a id="Nominal.Nominal"></a><a id="10638" href="1001-syntax-representations.html#10638" class="Record">Nominal</a> <a id="10646" class="Symbol">:</a> <a id="10648" href="Agda.Primitive.html#388" class="Primitive">Set₂</a> <a id="10653" class="Keyword">where</a>
    <a id="10663" class="Keyword">field</a>
      <a id="Nominal.Nominal.Sort"></a><a id="10675" href="1001-syntax-representations.html#10675" class="Field">Sort</a>  <a id="10681" class="Symbol">:</a> <a id="10683" href="Agda.Primitive.html#388" class="Primitive">Set₁</a>
      <a id="Nominal.Nominal.Atom"></a><a id="10694" href="1001-syntax-representations.html#10694" class="Field">Atom</a>  <a id="10700" class="Symbol">:</a> <a id="10702" href="1001-syntax-representations.html#10675" class="Field">Sort</a>
      <a id="Nominal.Nominal.1ᵉ"></a><a id="10713" href="1001-syntax-representations.html#10713" class="Field">1ᵉ</a>    <a id="10719" class="Symbol">:</a> <a id="10721" href="1001-syntax-representations.html#10675" class="Field">Sort</a>
      <a id="Nominal.Nominal._×ᵉ_"></a><a id="10732" href="1001-syntax-representations.html#10732" class="Field Operator">_×ᵉ_</a>  <a id="10738" class="Symbol">:</a> <a id="10740" href="1001-syntax-representations.html#10675" class="Field">Sort</a> <a id="10745" class="Symbol">→</a> <a id="10747" href="1001-syntax-representations.html#10675" class="Field">Sort</a> <a id="10752" class="Symbol">→</a> <a id="10754" href="1001-syntax-representations.html#10675" class="Field">Sort</a>
      <a id="Nominal.Nominal._→ᵉ_"></a><a id="10765" href="1001-syntax-representations.html#10765" class="Field Operator">_→ᵉ_</a>  <a id="10771" class="Symbol">:</a> <a id="10773" href="1001-syntax-representations.html#10675" class="Field">Sort</a> <a id="10778" class="Symbol">→</a> <a id="10780" href="1001-syntax-representations.html#10675" class="Field">Sort</a> <a id="10785" class="Symbol">→</a> <a id="10787" href="Agda.Primitive.html#388" class="Primitive">Set</a>
      <a id="Nominal.Nominal.absᵉ"></a><a id="10797" href="1001-syntax-representations.html#10797" class="Field">absᵉ</a>  <a id="10803" class="Symbol">:</a> <a id="10805" href="1001-syntax-representations.html#10675" class="Field">Sort</a> <a id="10810" class="Symbol">→</a> <a id="10812" href="1001-syntax-representations.html#10675" class="Field">Sort</a>
      <a id="10823" class="Comment">-- lots of axioms omitted</a>
  <a id="10851" class="Keyword">open</a> <a id="10856" href="1001-syntax-representations.html#10638" class="Module">Nominal</a> <a id="10864" class="Symbol">{{...}}</a>
</pre>
<p>The interface first declares a type <code>Sort</code> of sorts, and a particular
sort <code>Atom</code> of atoms. It also contains fields for the analogues of
regular Agda type constructors on sorts, such as pairs, functions, and
predicates. We then declare that for each sort <code>A</code>, we have another
sort <code>absᵉ A</code> of elements of <code>A</code> abstracted over a single (unknown)
name. Finally, although I didn’t write them here, if you would
actually want to use this you would also need lots of other fields
with axioms to specify freshness, as well as how to instantiate an
element of <code>absᵉ A</code> with a fresh variable.</p>
<p>Once we have declared this abstract interface, we can use it to
declare our syntax. Since Agda does not allow defining datatypes in an
abstract type such as <code>Sort</code>, we once again resort to an abstract
interface for declaring the syntax.</p>
<pre class="Agda">  <a id="11706" class="Keyword">module</a> <a id="11713" href="1001-syntax-representations.html#11713" class="Module">_</a> <a id="11715" class="Symbol">{{</a><a id="11717" href="1001-syntax-representations.html#11717" class="Bound">_</a> <a id="11719" class="Symbol">:</a> <a id="11721" href="1001-syntax-representations.html#10638" class="Record">Nominal</a><a id="11728" class="Symbol">}}</a> <a id="11731" class="Keyword">where</a>
    <a id="11741" class="Keyword">record</a> <a id="11748" href="1001-syntax-representations.html#11748" class="Record">Syntax</a> <a id="11755" class="Symbol">:</a> <a id="11757" href="Agda.Primitive.html#388" class="Primitive">Set₁</a> <a id="11762" class="Keyword">where</a>
      <a id="11774" class="Keyword">field</a>
        <a id="11788" href="1001-syntax-representations.html#11788" class="Field">Term</a> <a id="11793" class="Symbol">:</a> <a id="11795" href="1001-syntax-representations.html#10675" class="Field">Sort</a>
        <a id="11808" href="1001-syntax-representations.html#11808" class="Field">var</a>  <a id="11813" class="Symbol">:</a> <a id="11815" href="1001-syntax-representations.html#10694" class="Field">Atom</a> <a id="11820" href="1001-syntax-representations.html#10765" class="Field Operator">→ᵉ</a> <a id="11823" href="1001-syntax-representations.html#11788" class="Field">Term</a>
        <a id="11836" href="1001-syntax-representations.html#11836" class="Field">app</a>  <a id="11841" class="Symbol">:</a> <a id="11843" class="Symbol">(</a><a id="11844" href="1001-syntax-representations.html#11788" class="Field">Term</a> <a id="11849" href="1001-syntax-representations.html#10732" class="Field Operator">×ᵉ</a> <a id="11852" href="1001-syntax-representations.html#11788" class="Field">Term</a><a id="11856" class="Symbol">)</a> <a id="11858" href="1001-syntax-representations.html#10765" class="Field Operator">→ᵉ</a> <a id="11861" href="1001-syntax-representations.html#11788" class="Field">Term</a>
        <a id="11874" href="1001-syntax-representations.html#11874" class="Field">lam</a>  <a id="11879" class="Symbol">:</a> <a id="11881" class="Symbol">(</a><a id="11882" href="1001-syntax-representations.html#10797" class="Field">absᵉ</a> <a id="11887" href="1001-syntax-representations.html#11788" class="Field">Term</a><a id="11891" class="Symbol">)</a> <a id="11893" href="1001-syntax-representations.html#10765" class="Field Operator">→ᵉ</a> <a id="11896" href="1001-syntax-representations.html#11788" class="Field">Term</a>
        <a id="11909" class="Comment">-- induction principle omitted</a>
</pre>
<p>Since these interfaces are abstract, an important question is whether
it is actually possible to implement them - otherwise they’d be pretty
useless. The traditional way to do this relies on the presence of
<em>nominal sets</em> - sets with built-in operations for swapping and
freshness - for which I am not sure how easy they are to define in
Agda. Luckily, we don’t have to, as there is an easier way to
implement the <code>Nominal</code> and <code>Syntax</code> interfaces in terms of the
“Namely, Painless” approach by Nicolas Pouillard (see the section on
it further down below).</p>
<h1 id="higher-order-abstract-syntax">Higher-order abstract syntax</h1>
<p>Instead of trying to find a good encoding of variables for our syntax,
it is tempting to instead try to re-use the existing variable binding
capabilities of our meta-language (Agda). This third approach (after
nameless and nominal techniques) is known as <a href="https://dl.acm.org/doi/pdf/10.1145/960116.54010"><em>higher-order abstract
syntax</em></a>. A naive
attempt at using this in Agda goes as follows:</p>
<pre class="Agda"><a id="12962" class="Keyword">module</a> <a id="‶HOAS″"></a><a id="12969" href="1001-syntax-representations.html#12969" class="Module">‶HOAS″</a> <a id="12976" class="Keyword">where</a>
  <a id="12984" class="Symbol">{-#</a> <a id="12988" class="Keyword">NO_POSITIVITY_CHECK</a> <a id="13008" class="Symbol">#-}</a>
  <a id="13014" class="Keyword">data</a> <a id="‶HOAS″.Term"></a><a id="13019" href="1001-syntax-representations.html#13019" class="Datatype">Term</a> <a id="13024" class="Symbol">:</a> <a id="13026" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="13030" class="Keyword">where</a>
    <a id="‶HOAS″.Term.lam"></a><a id="13040" href="1001-syntax-representations.html#13040" class="InductiveConstructor">lam</a> <a id="13044" class="Symbol">:</a> <a id="13046" class="Symbol">(</a><a id="13047" href="1001-syntax-representations.html#13019" class="Datatype">Term</a> <a id="13052" class="Symbol">→</a> <a id="13054" href="1001-syntax-representations.html#13019" class="Datatype">Term</a><a id="13058" class="Symbol">)</a> <a id="13060" class="Symbol">→</a> <a id="13062" href="1001-syntax-representations.html#13019" class="Datatype">Term</a>
    <a id="‶HOAS″.Term.app"></a><a id="13071" href="1001-syntax-representations.html#13071" class="InductiveConstructor">app</a> <a id="13075" class="Symbol">:</a> <a id="13077" href="1001-syntax-representations.html#13019" class="Datatype">Term</a> <a id="13082" class="Symbol">→</a> <a id="13084" href="1001-syntax-representations.html#13019" class="Datatype">Term</a> <a id="13089" class="Symbol">→</a> <a id="13091" href="1001-syntax-representations.html#13019" class="Datatype">Term</a>

  <a id="‶HOAS″.ex"></a><a id="13099" href="1001-syntax-representations.html#13099" class="Function">ex</a> <a id="13102" class="Symbol">:</a> <a id="13104" href="1001-syntax-representations.html#13019" class="Datatype">Term</a>
  <a id="13111" href="1001-syntax-representations.html#13099" class="Function">ex</a> <a id="13114" class="Symbol">=</a> <a id="13116" href="1001-syntax-representations.html#13040" class="InductiveConstructor">lam</a> <a id="13120" class="Symbol">(λ</a> <a id="13123" href="1001-syntax-representations.html#13123" class="Bound">f</a> <a id="13125" class="Symbol">→</a> <a id="13127" href="1001-syntax-representations.html#13040" class="InductiveConstructor">lam</a> <a id="13131" class="Symbol">(λ</a> <a id="13134" href="1001-syntax-representations.html#13134" class="Bound">x</a> <a id="13136" class="Symbol">→</a> <a id="13138" href="1001-syntax-representations.html#13071" class="InductiveConstructor">app</a> <a id="13142" href="1001-syntax-representations.html#13123" class="Bound">f</a> <a id="13144" href="1001-syntax-representations.html#13134" class="Bound">x</a><a id="13145" class="Symbol">))</a>
</pre>
<p>There is no explicit case for variables in the syntax, instead
variables are meta-level variables of type <code>Term</code>. The scoping
discipline of the meta-language thus enforces that variables cannot be
used outside of their scope, i.e. terms are well-scoped by
construction. In addition, we get the nice property of de Bruijn
syntax that any two α-equivalent terms are equal. Moreover,
substitution can be implemented simply by function application on the
meta-level.</p>
<p>But (and this is a very big but) this approach does not actually
work. First of all, this type of terms is not strictly positive (as
indicated by the big <code>NO_POSITIVITY_CHECK</code> pragma on top) and can in
fact easily be exploited to define a non-normalizing term, thus
breaking Agda’s termination guarantees. Another huge problem is that
it is not possible to match on a term to see if it is a variable, so
many algorithms on the syntax (such as checking syntactic equality)
are simply impossible to implement. In addition, this representation
allows defining so-called ‘exotic terms’ that pattern match on the
syntactic structure of a variable, which should not be possible in the
syntax of our language:</p>
<pre class="Agda">  <a id="‶HOAS″.exotic"></a><a id="14327" href="1001-syntax-representations.html#14327" class="Function">exotic</a> <a id="14334" class="Symbol">:</a> <a id="14336" href="1001-syntax-representations.html#13019" class="Datatype">Term</a>
  <a id="14343" href="1001-syntax-representations.html#14327" class="Function">exotic</a> <a id="14350" class="Symbol">=</a> <a id="14352" href="1001-syntax-representations.html#13040" class="InductiveConstructor">lam</a> <a id="14356" class="Symbol">(λ</a> <a id="14359" href="1001-syntax-representations.html#14359" class="Bound">x</a> <a id="14361" class="Symbol">→</a> <a id="14363" href="Function.Base.html#4061" class="Function Operator">case</a> <a id="14368" href="1001-syntax-representations.html#14359" class="Bound">x</a> <a id="14370" href="Function.Base.html#4061" class="Function Operator">of</a> <a id="14373" class="Symbol">λ</a> <a id="14375" class="Keyword">where</a>
                        <a id="14405" class="Symbol">(</a><a id="14406" href="1001-syntax-representations.html#13040" class="InductiveConstructor">lam</a> <a id="14410" class="Symbol">_)</a>   <a id="14415" class="Symbol">→</a> <a id="14417" href="1001-syntax-representations.html#14359" class="Bound">x</a>
                        <a id="14443" class="Symbol">(</a><a id="14444" href="1001-syntax-representations.html#13071" class="InductiveConstructor">app</a> <a id="14448" class="Symbol">_</a> <a id="14450" class="Symbol">_)</a> <a id="14453" class="Symbol">→</a> <a id="14455" href="1001-syntax-representations.html#13040" class="InductiveConstructor">lam</a> <a id="14459" class="Symbol">(λ</a> <a id="14462" href="1001-syntax-representations.html#14462" class="Bound">y</a> <a id="14464" class="Symbol">→</a> <a id="14466" href="1001-syntax-representations.html#14462" class="Bound">y</a><a id="14467" class="Symbol">))</a>
</pre>
<p>Because of all these problems, most people would not consider this
type to be ‘real’ HOAS, and instead reserve the term for languages
that actually support a weak function space, such as
<a href="http://www.twelf.org/">Twelf</a>,
<a href="http://complogic.cs.mcgill.ca/beluga/">Beluga</a>, or
<a href="https://deducteam.github.io/">Dedukti</a>.</p>
<p>A variant of HOAS that <em>can</em> be used effectively in a language without
a weak function space is <a href="http://doi.acm.org/10.1145/1411204.1411226"><em>parametric higher-order abstract
syntax</em></a> (PHOAS). Instead
of representing variables directly as meta-level variables of type
<code>Term</code>, they are instead encoded as elements of an abstract type <code>V</code>,
and there is an explicit constructor <code>var</code> for variables:</p>
<pre class="Agda"><a id="15190" class="Keyword">module</a> <a id="PHOAS"></a><a id="15197" href="1001-syntax-representations.html#15197" class="Module">PHOAS</a> <a id="15203" class="Keyword">where</a>
  <a id="15211" class="Keyword">data</a> <a id="PHOAS.Term"></a><a id="15216" href="1001-syntax-representations.html#15216" class="Datatype">Term</a> <a id="15221" class="Symbol">(</a><a id="15222" href="1001-syntax-representations.html#15222" class="Bound">V</a> <a id="15224" class="Symbol">:</a> <a id="15226" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="15229" class="Symbol">)</a> <a id="15231" class="Symbol">:</a> <a id="15233" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="15237" class="Keyword">where</a>
    <a id="PHOAS.Term.var"></a><a id="15247" href="1001-syntax-representations.html#15247" class="InductiveConstructor">var</a> <a id="15251" class="Symbol">:</a> <a id="15253" href="1001-syntax-representations.html#15222" class="Bound">V</a> <a id="15255" class="Symbol">→</a> <a id="15257" href="1001-syntax-representations.html#15216" class="Datatype">Term</a> <a id="15262" href="1001-syntax-representations.html#15222" class="Bound">V</a>
    <a id="PHOAS.Term.lam"></a><a id="15268" href="1001-syntax-representations.html#15268" class="InductiveConstructor">lam</a> <a id="15272" class="Symbol">:</a> <a id="15274" class="Symbol">(</a><a id="15275" href="1001-syntax-representations.html#15222" class="Bound">V</a> <a id="15277" class="Symbol">→</a> <a id="15279" href="1001-syntax-representations.html#15216" class="Datatype">Term</a> <a id="15284" href="1001-syntax-representations.html#15222" class="Bound">V</a><a id="15285" class="Symbol">)</a> <a id="15287" class="Symbol">→</a> <a id="15289" href="1001-syntax-representations.html#15216" class="Datatype">Term</a> <a id="15294" href="1001-syntax-representations.html#15222" class="Bound">V</a>
    <a id="PHOAS.Term.app"></a><a id="15300" href="1001-syntax-representations.html#15300" class="InductiveConstructor">app</a> <a id="15304" class="Symbol">:</a> <a id="15306" href="1001-syntax-representations.html#15216" class="Datatype">Term</a> <a id="15311" href="1001-syntax-representations.html#15222" class="Bound">V</a> <a id="15313" class="Symbol">→</a> <a id="15315" href="1001-syntax-representations.html#15216" class="Datatype">Term</a> <a id="15320" href="1001-syntax-representations.html#15222" class="Bound">V</a> <a id="15322" class="Symbol">→</a> <a id="15324" href="1001-syntax-representations.html#15216" class="Datatype">Term</a> <a id="15329" href="1001-syntax-representations.html#15222" class="Bound">V</a>

  <a id="PHOAS.ex"></a><a id="15334" href="1001-syntax-representations.html#15334" class="Function">ex</a> <a id="15337" class="Symbol">:</a> <a id="15339" class="Symbol">∀</a> <a id="15341" class="Symbol">{</a><a id="15342" href="1001-syntax-representations.html#15342" class="Bound">V</a><a id="15343" class="Symbol">}</a> <a id="15345" class="Symbol">→</a> <a id="15347" href="1001-syntax-representations.html#15216" class="Datatype">Term</a> <a id="15352" href="1001-syntax-representations.html#15342" class="Bound">V</a>
  <a id="15356" href="1001-syntax-representations.html#15334" class="Function">ex</a> <a id="15359" class="Symbol">=</a> <a id="15361" href="1001-syntax-representations.html#15268" class="InductiveConstructor">lam</a> <a id="15365" class="Symbol">(λ</a> <a id="15368" href="1001-syntax-representations.html#15368" class="Bound">f</a> <a id="15370" class="Symbol">→</a> <a id="15372" href="1001-syntax-representations.html#15268" class="InductiveConstructor">lam</a> <a id="15376" class="Symbol">(λ</a> <a id="15379" href="1001-syntax-representations.html#15379" class="Bound">x</a> <a id="15381" class="Symbol">→</a> <a id="15383" href="1001-syntax-representations.html#15300" class="InductiveConstructor">app</a> <a id="15387" class="Symbol">(</a><a id="15388" href="1001-syntax-representations.html#15247" class="InductiveConstructor">var</a> <a id="15392" href="1001-syntax-representations.html#15368" class="Bound">f</a><a id="15393" class="Symbol">)</a> <a id="15395" class="Symbol">(</a><a id="15396" href="1001-syntax-representations.html#15247" class="InductiveConstructor">var</a> <a id="15400" href="1001-syntax-representations.html#15379" class="Bound">x</a><a id="15401" class="Symbol">)))</a>
</pre>
<p>This type does not suffer from issues with positivity, it is possible
to check whether a term is a variable, and exotic terms are ruled out
since there is no way to pattern match on an element of the abstract
type parameter <code>V</code>. Yet it preserves the good property that terms are
well-scoped by construction and that α-equivalent terms are equal.</p>
<p>Still, just from the fact that it is a higher-order representation,
PHOAS can be challenging to use in practice. In particular, defining
simple operations involves coming up with clever ways to instantiate
the parameter <code>V</code>; for example pretty-printing a term can be done by
instantiating <code>V</code> to be <code>String</code>:</p>
<pre class="Agda">  <a id="PHOAS.pp"></a><a id="16073" href="1001-syntax-representations.html#16073" class="Function">pp</a> <a id="16076" class="Symbol">:</a> <a id="16078" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="16080" class="Symbol">→</a> <a id="16082" href="1001-syntax-representations.html#15216" class="Datatype">Term</a> <a id="16087" href="Agda.Builtin.String.html#335" class="Postulate">String</a> <a id="16094" class="Symbol">→</a> <a id="16096" href="Agda.Builtin.String.html#335" class="Postulate">String</a>
  <a id="16105" href="1001-syntax-representations.html#16073" class="Function">pp</a> <a id="16108" href="1001-syntax-representations.html#16108" class="Bound">fresh</a> <a id="16114" class="Symbol">(</a><a id="16115" href="1001-syntax-representations.html#15247" class="InductiveConstructor">var</a> <a id="16119" href="1001-syntax-representations.html#16119" class="Bound">x</a><a id="16120" class="Symbol">)</a>    <a id="16125" class="Symbol">=</a> <a id="16127" href="1001-syntax-representations.html#16119" class="Bound">x</a>
  <a id="16131" href="1001-syntax-representations.html#16073" class="Function">pp</a> <a id="16134" href="1001-syntax-representations.html#16134" class="Bound">fresh</a> <a id="16140" class="Symbol">(</a><a id="16141" href="1001-syntax-representations.html#15268" class="InductiveConstructor">lam</a> <a id="16145" href="1001-syntax-representations.html#16145" class="Bound">f</a><a id="16146" class="Symbol">)</a>    <a id="16151" class="Symbol">=</a>
    <a id="16157" class="Keyword">let</a> <a id="16161" href="1001-syntax-representations.html#16161" class="Bound">name</a> <a id="16166" class="Symbol">=</a> <a id="16168" class="String">&quot;x&quot;</a> <a id="16172" href="Data.String.Base.html#2425" class="Function Operator">++</a> <a id="16175" href="Data.Nat.Show.html#2025" class="Function">ℕ.show</a> <a id="16182" href="1001-syntax-representations.html#16134" class="Bound">fresh</a>
    <a id="16192" class="Keyword">in</a>  <a id="16196" class="String">&quot;λ &quot;</a> <a id="16201" href="Data.String.Base.html#2425" class="Function Operator">++</a> <a id="16204" href="1001-syntax-representations.html#16161" class="Bound">name</a> <a id="16209" href="Data.String.Base.html#2425" class="Function Operator">++</a> <a id="16212" class="String">&quot;. &quot;</a> <a id="16217" href="Data.String.Base.html#2425" class="Function Operator">++</a> <a id="16220" href="1001-syntax-representations.html#16073" class="Function">pp</a> <a id="16223" class="Symbol">(</a><a id="16224" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="16228" href="1001-syntax-representations.html#16134" class="Bound">fresh</a><a id="16233" class="Symbol">)</a> <a id="16235" class="Symbol">(</a><a id="16236" href="1001-syntax-representations.html#16145" class="Bound">f</a> <a id="16238" href="1001-syntax-representations.html#16161" class="Bound">name</a><a id="16242" class="Symbol">)</a>
  <a id="16246" href="1001-syntax-representations.html#16073" class="Function">pp</a> <a id="16249" href="1001-syntax-representations.html#16249" class="Bound">fresh</a> <a id="16255" class="Symbol">(</a><a id="16256" href="1001-syntax-representations.html#15300" class="InductiveConstructor">app</a> <a id="16260" href="1001-syntax-representations.html#16260" class="Bound">u</a> <a id="16262" href="1001-syntax-representations.html#16262" class="Bound">v</a><a id="16263" class="Symbol">)</a>  <a id="16266" class="Symbol">=</a> <a id="16268" href="Function.Base.html#4061" class="Function Operator">case</a> <a id="16273" href="1001-syntax-representations.html#16260" class="Bound">u</a> <a id="16275" href="Function.Base.html#4061" class="Function Operator">of</a> <a id="16278" class="Symbol">λ</a> <a id="16280" class="Keyword">where</a>
    <a id="16290" class="Symbol">(</a><a id="16291" href="1001-syntax-representations.html#15247" class="InductiveConstructor">var</a> <a id="16295" href="1001-syntax-representations.html#16295" class="Bound">x</a><a id="16296" class="Symbol">)</a> <a id="16298" class="Symbol">→</a> <a id="16300" href="1001-syntax-representations.html#16295" class="Bound">x</a> <a id="16302" href="Data.String.Base.html#2425" class="Function Operator">++</a> <a id="16305" class="String">&quot; &quot;</a> <a id="16309" href="Data.String.Base.html#2425" class="Function Operator">++</a> <a id="16312" href="1001-syntax-representations.html#16073" class="Function">pp</a> <a id="16315" href="1001-syntax-representations.html#16249" class="Bound">fresh</a> <a id="16321" href="1001-syntax-representations.html#16262" class="Bound">v</a>
    <a id="16327" class="CatchallClause Symbol">_</a>       <a id="16335" class="Symbol">→</a> <a id="16337" class="String">&quot;(&quot;</a> <a id="16341" href="Data.String.Base.html#2425" class="Function Operator">++</a> <a id="16344" href="1001-syntax-representations.html#16073" class="Function">pp</a> <a id="16347" href="1001-syntax-representations.html#16249" class="Bound">fresh</a> <a id="16353" href="1001-syntax-representations.html#16260" class="Bound">u</a> <a id="16355" href="Data.String.Base.html#2425" class="Function Operator">++</a> <a id="16358" class="String">&quot;) &quot;</a> <a id="16363" href="Data.String.Base.html#2425" class="Function Operator">++</a> <a id="16366" href="1001-syntax-representations.html#16073" class="Function">pp</a> <a id="16369" href="1001-syntax-representations.html#16249" class="Bound">fresh</a> <a id="16375" href="1001-syntax-representations.html#16262" class="Bound">v</a>

  <a id="16380" href="1001-syntax-representations.html#16380" class="Function">_</a> <a id="16382" class="Symbol">:</a> <a id="16384" href="1001-syntax-representations.html#16073" class="Function">pp</a> <a id="16387" class="Number">0</a> <a id="16389" href="1001-syntax-representations.html#15334" class="Function">ex</a> <a id="16392" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="16394" class="String">&quot;λ x0. λ x1. x0 x1&quot;</a>
  <a id="16416" class="Symbol">_</a> <a id="16418" class="Symbol">=</a> <a id="16420" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
</pre>
<p>Other algorithms might require functional extensionality or
parametricity results to reason correctly about the behaviour of the
syntax. Altogether, it seems to me these reasons imply PHOAS is less
well suited for implementing actual algorithms on syntax, as opposed
to purely doing metatheory (for which it was originally introduced).</p>
<h1 id="well-scoped-de-bruijn-indices">Well-scoped de Bruijn indices</h1>
<p>If all we want from PHOAS is the fact that terms are well-scoped by
construction, there is actually a much easier way to obtain that
guarantee with de Bruijn indices: we can simply index the type by the
number <code>n</code> of variables that are in scope, and require that indices
are elements of <code>Fin n</code>. This is known as <em>well-scoped de Bruijn
syntax</em>.</p>
<pre class="Agda"><a id="17181" class="Keyword">module</a> <a id="WellScopedDB"></a><a id="17188" href="1001-syntax-representations.html#17188" class="Module">WellScopedDB</a> <a id="17201" class="Keyword">where</a>
  <a id="17209" class="Keyword">data</a> <a id="WellScopedDB.Term"></a><a id="17214" href="1001-syntax-representations.html#17214" class="Datatype">Term</a> <a id="17219" class="Symbol">(</a><a id="17220" href="1001-syntax-representations.html#17220" class="Bound">n</a> <a id="17222" class="Symbol">:</a> <a id="17224" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a><a id="17225" class="Symbol">)</a> <a id="17227" class="Symbol">:</a> <a id="17229" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="17233" class="Keyword">where</a>
    <a id="WellScopedDB.Term.var"></a><a id="17243" href="1001-syntax-representations.html#17243" class="InductiveConstructor">var</a> <a id="17247" class="Symbol">:</a> <a id="17249" href="Data.Fin.Base.html#1132" class="Datatype">Fin</a> <a id="17253" href="1001-syntax-representations.html#17220" class="Bound">n</a> <a id="17255" class="Symbol">→</a> <a id="17257" href="1001-syntax-representations.html#17214" class="Datatype">Term</a> <a id="17262" href="1001-syntax-representations.html#17220" class="Bound">n</a>
    <a id="WellScopedDB.Term.lam"></a><a id="17268" href="1001-syntax-representations.html#17268" class="InductiveConstructor">lam</a> <a id="17272" class="Symbol">:</a> <a id="17274" href="1001-syntax-representations.html#17214" class="Datatype">Term</a> <a id="17279" class="Symbol">(</a><a id="17280" class="Number">1</a> <a id="17282" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">+</a> <a id="17284" href="1001-syntax-representations.html#17220" class="Bound">n</a><a id="17285" class="Symbol">)</a> <a id="17287" class="Symbol">→</a> <a id="17289" href="1001-syntax-representations.html#17214" class="Datatype">Term</a> <a id="17294" href="1001-syntax-representations.html#17220" class="Bound">n</a>
    <a id="WellScopedDB.Term.app"></a><a id="17300" href="1001-syntax-representations.html#17300" class="InductiveConstructor">app</a> <a id="17304" class="Symbol">:</a> <a id="17306" href="1001-syntax-representations.html#17214" class="Datatype">Term</a> <a id="17311" href="1001-syntax-representations.html#17220" class="Bound">n</a> <a id="17313" class="Symbol">→</a> <a id="17315" href="1001-syntax-representations.html#17214" class="Datatype">Term</a> <a id="17320" href="1001-syntax-representations.html#17220" class="Bound">n</a> <a id="17322" class="Symbol">→</a> <a id="17324" href="1001-syntax-representations.html#17214" class="Datatype">Term</a> <a id="17329" href="1001-syntax-representations.html#17220" class="Bound">n</a>

  <a id="WellScopedDB.ex"></a><a id="17334" href="1001-syntax-representations.html#17334" class="Function">ex</a> <a id="17337" class="Symbol">:</a> <a id="17339" href="1001-syntax-representations.html#17214" class="Datatype">Term</a> <a id="17344" class="Number">0</a>
  <a id="17348" href="1001-syntax-representations.html#17334" class="Function">ex</a> <a id="17351" class="Symbol">=</a> <a id="17353" href="1001-syntax-representations.html#17268" class="InductiveConstructor">lam</a> <a id="17357" class="Comment">{-f-}</a> <a id="17363" class="Symbol">(</a>
         <a id="17374" href="1001-syntax-representations.html#17268" class="InductiveConstructor">lam</a> <a id="17378" class="Comment">{-x-}</a> <a id="17384" class="Symbol">(</a>
           <a id="17397" href="1001-syntax-representations.html#17300" class="InductiveConstructor">app</a> <a id="17401" class="Symbol">(</a><a id="17402" href="1001-syntax-representations.html#17243" class="InductiveConstructor">var</a> <a id="17406" class="Comment">{-f-}</a> <a id="17412" class="Symbol">(</a><a id="17413" href="Data.Fin.Base.html#1175" class="InductiveConstructor">suc</a> <a id="17417" href="Data.Fin.Base.html#1154" class="InductiveConstructor">zero</a><a id="17421" class="Symbol">))</a>
               <a id="17439" class="Symbol">(</a><a id="17440" href="1001-syntax-representations.html#17243" class="InductiveConstructor">var</a> <a id="17444" class="Comment">{-x-}</a> <a id="17450" href="Data.Fin.Base.html#1154" class="InductiveConstructor">zero</a><a id="17454" class="Symbol">)</a>
         <a id="17465" class="Symbol">)</a>
       <a id="17474" class="Symbol">)</a>
</pre>
<p>One could criticize this for relying on dependent types in the
meta-language. However, we can obtain a variant of well-typed de
Bruijn syntax that does not require the use of dependent types by
indexing directly by the set of variables in scope:</p>
<pre class="Agda"><a id="17732" class="Keyword">module</a> <a id="PoorMansWellScoped"></a><a id="17739" href="1001-syntax-representations.html#17739" class="Module">PoorMansWellScoped</a> <a id="17758" class="Keyword">where</a>
  <a id="17766" class="Keyword">data</a> <a id="PoorMansWellScoped.Term"></a><a id="17771" href="1001-syntax-representations.html#17771" class="Datatype">Term</a> <a id="17776" class="Symbol">(</a><a id="17777" href="1001-syntax-representations.html#17777" class="Bound">V</a> <a id="17779" class="Symbol">:</a> <a id="17781" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="17784" class="Symbol">)</a> <a id="17786" class="Symbol">:</a> <a id="17788" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="17792" class="Keyword">where</a>
    <a id="PoorMansWellScoped.Term.var"></a><a id="17802" href="1001-syntax-representations.html#17802" class="InductiveConstructor">var</a> <a id="17806" class="Symbol">:</a> <a id="17808" href="1001-syntax-representations.html#17777" class="Bound">V</a> <a id="17810" class="Symbol">→</a> <a id="17812" href="1001-syntax-representations.html#17771" class="Datatype">Term</a> <a id="17817" href="1001-syntax-representations.html#17777" class="Bound">V</a>
    <a id="PoorMansWellScoped.Term.lam"></a><a id="17823" href="1001-syntax-representations.html#17823" class="InductiveConstructor">lam</a> <a id="17827" class="Symbol">:</a> <a id="17829" href="1001-syntax-representations.html#17771" class="Datatype">Term</a> <a id="17834" class="Symbol">(</a><a id="17835" href="Agda.Builtin.Maybe.html#135" class="Datatype">Maybe</a> <a id="17841" href="1001-syntax-representations.html#17777" class="Bound">V</a><a id="17842" class="Symbol">)</a> <a id="17844" class="Symbol">→</a> <a id="17846" href="1001-syntax-representations.html#17771" class="Datatype">Term</a> <a id="17851" href="1001-syntax-representations.html#17777" class="Bound">V</a>
    <a id="PoorMansWellScoped.Term.app"></a><a id="17857" href="1001-syntax-representations.html#17857" class="InductiveConstructor">app</a> <a id="17861" class="Symbol">:</a> <a id="17863" href="1001-syntax-representations.html#17771" class="Datatype">Term</a> <a id="17868" href="1001-syntax-representations.html#17777" class="Bound">V</a> <a id="17870" class="Symbol">→</a> <a id="17872" href="1001-syntax-representations.html#17771" class="Datatype">Term</a> <a id="17877" href="1001-syntax-representations.html#17777" class="Bound">V</a> <a id="17879" class="Symbol">→</a> <a id="17881" href="1001-syntax-representations.html#17771" class="Datatype">Term</a> <a id="17886" href="1001-syntax-representations.html#17777" class="Bound">V</a>

  <a id="PoorMansWellScoped.ex"></a><a id="17891" href="1001-syntax-representations.html#17891" class="Function">ex</a> <a id="17894" class="Symbol">:</a> <a id="17896" href="1001-syntax-representations.html#17771" class="Datatype">Term</a> <a id="17901" href="Data.Empty.html#914" class="Function">⊥</a>
  <a id="17905" href="1001-syntax-representations.html#17891" class="Function">ex</a> <a id="17908" class="Symbol">=</a> <a id="17910" href="1001-syntax-representations.html#17823" class="InductiveConstructor">lam</a> <a id="17914" class="Comment">{-f-}</a> <a id="17920" class="Symbol">(</a>
         <a id="17931" href="1001-syntax-representations.html#17823" class="InductiveConstructor">lam</a> <a id="17935" class="Comment">{-x-}</a> <a id="17941" class="Symbol">(</a>
           <a id="17954" href="1001-syntax-representations.html#17857" class="InductiveConstructor">app</a> <a id="17958" class="Symbol">(</a><a id="17959" href="1001-syntax-representations.html#17802" class="InductiveConstructor">var</a> <a id="17963" class="Comment">{-f-}</a> <a id="17969" class="Symbol">(</a><a id="17970" href="Agda.Builtin.Maybe.html#173" class="InductiveConstructor">just</a> <a id="17975" href="Agda.Builtin.Maybe.html#194" class="InductiveConstructor">nothing</a><a id="17982" class="Symbol">))</a>
               <a id="18000" class="Symbol">(</a><a id="18001" href="1001-syntax-representations.html#17802" class="InductiveConstructor">var</a> <a id="18005" class="Comment">{-x-}</a> <a id="18011" href="Agda.Builtin.Maybe.html#194" class="InductiveConstructor">nothing</a><a id="18018" class="Symbol">)</a>
         <a id="18029" class="Symbol">)</a>
       <a id="18038" class="Symbol">)</a>
</pre>
<p>This provides the same guarantees as well-scoped de Bruijn syntax, but
can be implemented in Haskell ’98. However, elements of nested <code>Maybe</code>
types are a bit harder to manipulate than elements of type <code>Fin</code>, and
may lead to worse performance if <code>Fin</code>s end up being represented as
machine integers. Also, you should just use a proper language that
supports dependent types instead.</p>
<p>A more serious criticism I have against this representation is that
while this representation makes it harder to write wrong
transformations on syntax that mess up the variables, it does not
really do anything to make <em>good</em> de Bruijn terms easier to produce or
understand for humans. For example, a term of type <code>Term 2</code> with two
variables <code>x</code> and <code>y</code> in scope does not indicate whether <code>x</code> is <code>var 0</code> and <code>y</code> is <code>var 1</code> or vice versa.</p>
<p>Still, well-scoped de Bruijn syntax is used quite often in practice,
for example in the <a href="https://github.com/gallais/generic-syntax">generic-syntax
library</a> for Agda. In fact,
this library goes beyond the subject of this blog post in many ways,
by providing a generic <em>universe</em> of syntaxes with generic operations
defined over them and by enforcing not just well-scopedness but also
well-typedness. While these features are orthogonal to the topic of
this blog post, I strongly encourage you to take a look at it.</p>
<!--
<pre class="Agda"><a id="19389" class="Keyword">module</a> <a id="UniverseOfSafeSyntax"></a><a id="19396" href="1001-syntax-representations.html#19396" class="Module">UniverseOfSafeSyntax</a> <a id="19417" class="Keyword">where</a>

  <a id="19426" class="Keyword">open</a> <a id="19431" class="Keyword">import</a> <a id="19438" href="Relation.Unary.html" class="Module">Relation.Unary</a>

  <a id="19456" class="Keyword">variable</a>
    <a id="19469" href="1001-syntax-representations.html#19469" class="Generalizable">I</a> <a id="19471" class="Symbol">:</a> <a id="19473" href="Agda.Primitive.html#388" class="Primitive">Set</a>
    <a id="19481" href="1001-syntax-representations.html#19481" class="Generalizable">i</a> <a id="19483" href="1001-syntax-representations.html#19483" class="Generalizable">σ</a> <a id="19485" href="1001-syntax-representations.html#19485" class="Generalizable">τ</a> <a id="19487" class="Symbol">:</a> <a id="19489" href="1001-syntax-representations.html#19469" class="Generalizable">I</a>

  <a id="UniverseOfSafeSyntax._─Scoped"></a><a id="19494" href="1001-syntax-representations.html#19494" class="Function Operator">_─Scoped</a> <a id="19503" class="Symbol">:</a> <a id="19505" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="19509" class="Symbol">→</a> <a id="19511" href="Agda.Primitive.html#388" class="Primitive">Set₂</a>
  <a id="19518" href="1001-syntax-representations.html#19518" class="Bound">I</a> <a id="19520" href="1001-syntax-representations.html#19494" class="Function Operator">─Scoped</a> <a id="19528" class="Symbol">=</a> <a id="19530" href="1001-syntax-representations.html#19518" class="Bound">I</a> <a id="19532" class="Symbol">→</a> <a id="19534" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="19539" href="1001-syntax-representations.html#19518" class="Bound">I</a> <a id="19541" class="Symbol">→</a> <a id="19543" href="Agda.Primitive.html#388" class="Primitive">Set₁</a>

  <a id="19551" class="Keyword">data</a> <a id="UniverseOfSafeSyntax.Var"></a><a id="19556" href="1001-syntax-representations.html#19556" class="Datatype">Var</a> <a id="19560" class="Symbol">:</a> <a id="19562" href="1001-syntax-representations.html#19469" class="Generalizable">I</a> <a id="19564" href="1001-syntax-representations.html#19494" class="Function Operator">─Scoped</a> <a id="19572" class="Keyword">where</a>
    <a id="UniverseOfSafeSyntax.Var.z"></a><a id="19582" href="1001-syntax-representations.html#19582" class="InductiveConstructor">z</a> <a id="19584" class="Symbol">:</a> <a id="19586" href="Relation.Unary.html#3793" class="Function">∀[</a> <a id="19589" class="Symbol">(</a><a id="19590" href="1001-syntax-representations.html#19483" class="Generalizable">σ</a> <a id="19592" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷_</a><a id="19594" class="Symbol">)</a> <a id="19596" href="Relation.Unary.html#5919" class="Function Operator">⊢</a> <a id="19598" href="1001-syntax-representations.html#19556" class="Datatype">Var</a> <a id="19602" href="1001-syntax-representations.html#19483" class="Generalizable">σ</a> <a id="19604" href="Relation.Unary.html#3793" class="Function">]</a>
    <a id="UniverseOfSafeSyntax.Var.s"></a><a id="19610" href="1001-syntax-representations.html#19610" class="InductiveConstructor">s</a> <a id="19612" class="Symbol">:</a> <a id="19614" href="Relation.Unary.html#3793" class="Function">∀[</a> <a id="19617" href="1001-syntax-representations.html#19556" class="Datatype">Var</a> <a id="19621" href="1001-syntax-representations.html#19483" class="Generalizable">σ</a> <a id="19623" href="Relation.Unary.html#5048" class="Function Operator">⇒</a> <a id="19625" class="Symbol">(</a><a id="19626" href="1001-syntax-representations.html#19485" class="Generalizable">τ</a> <a id="19628" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷_</a><a id="19630" class="Symbol">)</a> <a id="19632" href="Relation.Unary.html#5919" class="Function Operator">⊢</a> <a id="19634" href="1001-syntax-representations.html#19556" class="Datatype">Var</a> <a id="19638" href="1001-syntax-representations.html#19483" class="Generalizable">σ</a> <a id="19640" href="Relation.Unary.html#3793" class="Function">]</a>

  <a id="19645" class="Keyword">data</a> <a id="UniverseOfSafeSyntax.Term"></a><a id="19650" href="1001-syntax-representations.html#19650" class="Datatype">Term</a> <a id="19655" class="Symbol">:</a> <a id="19657" href="Agda.Builtin.Unit.html#175" class="Record">⊤</a> <a id="19659" href="1001-syntax-representations.html#19494" class="Function Operator">─Scoped</a> <a id="19667" class="Keyword">where</a>
    <a id="UniverseOfSafeSyntax.Term.var"></a><a id="19677" href="1001-syntax-representations.html#19677" class="InductiveConstructor">var</a> <a id="19681" class="Symbol">:</a> <a id="19683" href="Relation.Unary.html#3793" class="Function">∀[</a> <a id="19686" href="1001-syntax-representations.html#19556" class="Datatype">Var</a> <a id="19690" href="Agda.Builtin.Unit.html#212" class="InductiveConstructor">tt</a> <a id="19693" href="Relation.Unary.html#5048" class="Function Operator">⇒</a> <a id="19695" href="1001-syntax-representations.html#19650" class="Datatype">Term</a> <a id="19700" href="Agda.Builtin.Unit.html#212" class="InductiveConstructor">tt</a> <a id="19703" href="Relation.Unary.html#3793" class="Function">]</a>
    <a id="UniverseOfSafeSyntax.Term.lam"></a><a id="19709" href="1001-syntax-representations.html#19709" class="InductiveConstructor">lam</a> <a id="19713" class="Symbol">:</a> <a id="19715" href="Relation.Unary.html#3793" class="Function">∀[</a> <a id="19718" class="Symbol">(</a><a id="19719" href="Agda.Builtin.Unit.html#212" class="InductiveConstructor">tt</a> <a id="19722" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷_</a><a id="19724" class="Symbol">)</a> <a id="19726" href="Relation.Unary.html#5919" class="Function Operator">⊢</a> <a id="19728" href="1001-syntax-representations.html#19650" class="Datatype">Term</a> <a id="19733" href="Agda.Builtin.Unit.html#212" class="InductiveConstructor">tt</a> <a id="19736" href="Relation.Unary.html#5048" class="Function Operator">⇒</a> <a id="19738" href="1001-syntax-representations.html#19650" class="Datatype">Term</a> <a id="19743" href="Agda.Builtin.Unit.html#212" class="InductiveConstructor">tt</a> <a id="19746" href="Relation.Unary.html#3793" class="Function">]</a>
    <a id="UniverseOfSafeSyntax.Term.app"></a><a id="19752" href="1001-syntax-representations.html#19752" class="InductiveConstructor">app</a> <a id="19756" class="Symbol">:</a> <a id="19758" href="Relation.Unary.html#3793" class="Function">∀[</a> <a id="19761" href="1001-syntax-representations.html#19650" class="Datatype">Term</a> <a id="19766" href="Agda.Builtin.Unit.html#212" class="InductiveConstructor">tt</a> <a id="19769" href="Relation.Unary.html#5048" class="Function Operator">⇒</a> <a id="19771" href="1001-syntax-representations.html#19650" class="Datatype">Term</a> <a id="19776" href="Agda.Builtin.Unit.html#212" class="InductiveConstructor">tt</a> <a id="19779" href="Relation.Unary.html#5048" class="Function Operator">⇒</a> <a id="19781" href="1001-syntax-representations.html#19650" class="Datatype">Term</a> <a id="19786" href="Agda.Builtin.Unit.html#212" class="InductiveConstructor">tt</a> <a id="19789" href="Relation.Unary.html#3793" class="Function">]</a>

  <a id="UniverseOfSafeSyntax.ex"></a><a id="19794" href="1001-syntax-representations.html#19794" class="Function">ex</a> <a id="19797" class="Symbol">:</a> <a id="19799" href="1001-syntax-representations.html#19650" class="Datatype">Term</a> <a id="19804" href="Agda.Builtin.Unit.html#212" class="InductiveConstructor">tt</a> <a id="19807" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a>
  <a id="19812" href="1001-syntax-representations.html#19794" class="Function">ex</a> <a id="19815" class="Symbol">=</a> <a id="19817" href="1001-syntax-representations.html#19709" class="InductiveConstructor">lam</a> <a id="19821" class="Comment">{-f-}</a> <a id="19827" class="Symbol">(</a><a id="19828" href="1001-syntax-representations.html#19709" class="InductiveConstructor">lam</a> <a id="19832" class="Comment">{-x-}</a> <a id="19838" class="Symbol">(</a><a id="19839" href="1001-syntax-representations.html#19752" class="InductiveConstructor">app</a> <a id="19843" class="Symbol">(</a><a id="19844" href="1001-syntax-representations.html#19677" class="InductiveConstructor">var</a> <a id="19848" class="Symbol">(</a><a id="19849" href="1001-syntax-representations.html#19610" class="InductiveConstructor">s</a> <a id="19851" href="1001-syntax-representations.html#19582" class="InductiveConstructor">z</a><a id="19852" class="Symbol">))</a> <a id="19855" class="Symbol">(</a><a id="19856" href="1001-syntax-representations.html#19677" class="InductiveConstructor">var</a> <a id="19860" href="1001-syntax-representations.html#19582" class="InductiveConstructor">z</a><a id="19861" class="Symbol">)))</a>
</pre>-->
<h1 id="well-scoped-names">Well-scoped names</h1>
<p>One criticism we had of de Bruijn syntax is the fact that it is very
hard to understand by humans, and this problem is not really solved by
switching to the well-scoped variant. We can solve this problem by -
instead of indexing by just the number of variables in scope -
indexing by the <em>scope itself</em>, represented as a list of
names. Variables then contain two pieces of data: a name and a <em>proof</em>
that the name is in scope.</p>
<pre class="Agda"><a id="20348" class="Keyword">module</a> <a id="WellScopedNames"></a><a id="20355" href="1001-syntax-representations.html#20355" class="Module">WellScopedNames</a> <a id="20371" class="Keyword">where</a>
  <a id="20379" class="Keyword">open</a> <a id="20384" class="Keyword">import</a> <a id="20391" href="Data.List.Membership.Propositional.html" class="Module">Data.List.Membership.Propositional</a> <a id="20426" class="Keyword">using</a> <a id="20432" class="Symbol">(</a><a id="20433" href="Data.List.Membership.Setoid.html#925" class="Function Operator">_∈_</a><a id="20436" class="Symbol">)</a>
  <a id="20440" class="Keyword">open</a> <a id="20445" class="Keyword">import</a> <a id="20452" href="Data.List.Relation.Unary.Any.html" class="Module">Data.List.Relation.Unary.Any</a> <a id="20481" class="Keyword">using</a> <a id="20487" class="Symbol">(</a><a id="20488" href="Data.List.Relation.Unary.Any.html#1211" class="InductiveConstructor">here</a><a id="20492" class="Symbol">;</a> <a id="20494" href="Data.List.Relation.Unary.Any.html#1264" class="InductiveConstructor">there</a><a id="20499" class="Symbol">)</a>

  <a id="WellScopedNames.Scope"></a><a id="20504" href="1001-syntax-representations.html#20504" class="Function">Scope</a> <a id="20510" class="Symbol">=</a> <a id="20512" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="20517" href="Agda.Builtin.String.html#335" class="Postulate">String</a>

  <a id="20527" class="Keyword">data</a> <a id="WellScopedNames.Term"></a><a id="20532" href="1001-syntax-representations.html#20532" class="Datatype">Term</a> <a id="20537" class="Symbol">(</a><a id="20538" href="1001-syntax-representations.html#20538" class="Bound">s</a> <a id="20540" class="Symbol">:</a> <a id="20542" href="1001-syntax-representations.html#20504" class="Function">Scope</a><a id="20547" class="Symbol">)</a> <a id="20549" class="Symbol">:</a> <a id="20551" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="20555" class="Keyword">where</a>
    <a id="WellScopedNames.Term.var"></a><a id="20565" href="1001-syntax-representations.html#20565" class="InductiveConstructor">var</a> <a id="20569" class="Symbol">:</a> <a id="20571" class="Symbol">(</a><a id="20572" href="1001-syntax-representations.html#20572" class="Bound">x</a> <a id="20574" class="Symbol">:</a> <a id="20576" href="Agda.Builtin.String.html#335" class="Postulate">String</a><a id="20582" class="Symbol">)</a> <a id="20584" class="Symbol">→</a> <a id="20586" href="1001-syntax-representations.html#20572" class="Bound">x</a> <a id="20588" href="Data.List.Membership.Setoid.html#925" class="Function Operator">∈</a> <a id="20590" href="1001-syntax-representations.html#20538" class="Bound">s</a> <a id="20592" class="Symbol">→</a> <a id="20594" href="1001-syntax-representations.html#20532" class="Datatype">Term</a> <a id="20599" href="1001-syntax-representations.html#20538" class="Bound">s</a>
    <a id="WellScopedNames.Term.lam"></a><a id="20605" href="1001-syntax-representations.html#20605" class="InductiveConstructor">lam</a> <a id="20609" class="Symbol">:</a> <a id="20611" class="Symbol">(</a><a id="20612" href="1001-syntax-representations.html#20612" class="Bound">x</a> <a id="20614" class="Symbol">:</a> <a id="20616" href="Agda.Builtin.String.html#335" class="Postulate">String</a><a id="20622" class="Symbol">)</a> <a id="20624" class="Symbol">→</a> <a id="20626" href="1001-syntax-representations.html#20532" class="Datatype">Term</a> <a id="20631" class="Symbol">(</a><a id="20632" href="1001-syntax-representations.html#20612" class="Bound">x</a> <a id="20634" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="20636" href="1001-syntax-representations.html#20538" class="Bound">s</a><a id="20637" class="Symbol">)</a> <a id="20639" class="Symbol">→</a> <a id="20641" href="1001-syntax-representations.html#20532" class="Datatype">Term</a> <a id="20646" href="1001-syntax-representations.html#20538" class="Bound">s</a>
    <a id="WellScopedNames.Term.app"></a><a id="20652" href="1001-syntax-representations.html#20652" class="InductiveConstructor">app</a> <a id="20656" class="Symbol">:</a> <a id="20658" href="1001-syntax-representations.html#20532" class="Datatype">Term</a> <a id="20663" href="1001-syntax-representations.html#20538" class="Bound">s</a> <a id="20665" class="Symbol">→</a> <a id="20667" href="1001-syntax-representations.html#20532" class="Datatype">Term</a> <a id="20672" href="1001-syntax-representations.html#20538" class="Bound">s</a> <a id="20674" class="Symbol">→</a> <a id="20676" href="1001-syntax-representations.html#20532" class="Datatype">Term</a> <a id="20681" href="1001-syntax-representations.html#20538" class="Bound">s</a>

  <a id="WellScopedNames.ex"></a><a id="20686" href="1001-syntax-representations.html#20686" class="Function">ex</a> <a id="20689" class="Symbol">:</a> <a id="20691" href="1001-syntax-representations.html#20532" class="Datatype">Term</a> <a id="20696" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a>
  <a id="20701" href="1001-syntax-representations.html#20686" class="Function">ex</a> <a id="20704" class="Symbol">=</a> <a id="20706" href="1001-syntax-representations.html#20605" class="InductiveConstructor">lam</a> <a id="20710" class="String">&quot;f&quot;</a> <a id="20714" class="Symbol">(</a>
         <a id="20725" href="1001-syntax-representations.html#20605" class="InductiveConstructor">lam</a> <a id="20729" class="String">&quot;x&quot;</a> <a id="20733" class="Symbol">(</a>
           <a id="20746" href="1001-syntax-representations.html#20652" class="InductiveConstructor">app</a> <a id="20750" class="Symbol">(</a><a id="20751" href="1001-syntax-representations.html#20565" class="InductiveConstructor">var</a> <a id="20755" class="String">&quot;f&quot;</a> <a id="20759" class="Symbol">(</a><a id="20760" href="Data.List.Relation.Unary.Any.html#1264" class="InductiveConstructor">there</a> <a id="20766" class="Symbol">(</a><a id="20767" href="Data.List.Relation.Unary.Any.html#1211" class="InductiveConstructor">here</a> <a id="20772" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a><a id="20776" class="Symbol">)))</a>
               <a id="20795" class="Symbol">(</a><a id="20796" href="1001-syntax-representations.html#20565" class="InductiveConstructor">var</a> <a id="20800" class="String">&quot;x&quot;</a> <a id="20804" class="Symbol">(</a><a id="20805" href="Data.List.Relation.Unary.Any.html#1211" class="InductiveConstructor">here</a> <a id="20810" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a><a id="20814" class="Symbol">))</a>
         <a id="20826" class="Symbol">)</a>
       <a id="20835" class="Symbol">)</a>
</pre>
<p>The result we get is a combination of named variables with well-scoped
de Bruijn syntax. While the membership proofs are cumbersome to write
by hand, it wouldn’t take much effort to implement a
<a href="https://agda.readthedocs.io/en/v2.6.2/language/reflection.html#macros">macro</a>
that constructs them automatically.</p>
<p>While there is no fundamental difference in the guarantees offered by
this representation and well-scoped de Bruijn syntax, having the names
around is more intuitive for the programmer and can help to avoid
errors when changing the order of variables in scope. However, having
the names around also means we lose one advantage of de Bruijn syntax:
two α-equivalent terms can now be distinguished by looking at the
names of the variables.</p>
<p>One other thing one should keep in mind when using this representation
is that it allows referring to shadowed names. For example, it is
perfectly fine to name both variables <code>x</code> in the previous example:</p>
<pre class="Agda">  <a id="WellScopedNames.ex'"></a><a id="21802" href="1001-syntax-representations.html#21802" class="Function">ex'</a> <a id="21806" class="Symbol">:</a> <a id="21808" href="1001-syntax-representations.html#20532" class="Datatype">Term</a> <a id="21813" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a>
  <a id="21818" href="1001-syntax-representations.html#21802" class="Function">ex'</a> <a id="21822" class="Symbol">=</a> <a id="21824" href="1001-syntax-representations.html#20605" class="InductiveConstructor">lam</a> <a id="21828" class="String">&quot;x&quot;</a> <a id="21832" class="Symbol">(</a>
          <a id="21844" href="1001-syntax-representations.html#20605" class="InductiveConstructor">lam</a> <a id="21848" class="String">&quot;x&quot;</a> <a id="21852" class="Symbol">(</a>
            <a id="21866" href="1001-syntax-representations.html#20652" class="InductiveConstructor">app</a> <a id="21870" class="Symbol">(</a><a id="21871" href="1001-syntax-representations.html#20565" class="InductiveConstructor">var</a> <a id="21875" class="String">&quot;x&quot;</a> <a id="21879" class="Symbol">(</a><a id="21880" href="Data.List.Relation.Unary.Any.html#1264" class="InductiveConstructor">there</a> <a id="21886" class="Symbol">(</a><a id="21887" href="Data.List.Relation.Unary.Any.html#1211" class="InductiveConstructor">here</a> <a id="21892" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a><a id="21896" class="Symbol">)))</a>
                <a id="21916" class="Symbol">(</a><a id="21917" href="1001-syntax-representations.html#20565" class="InductiveConstructor">var</a> <a id="21921" class="String">&quot;x&quot;</a> <a id="21925" class="Symbol">(</a><a id="21926" href="Data.List.Relation.Unary.Any.html#1211" class="InductiveConstructor">here</a> <a id="21931" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a><a id="21935" class="Symbol">))</a>
          <a id="21948" class="Symbol">)</a>
        <a id="21958" class="Symbol">)</a>
</pre>
<p>The reason for this is that the membership proof <code>x ∈ s</code> is
<em>proof-relevant</em>: it consists of a path to the position where the
variable is bound in the scope. While this can be considered as either
a feature or a bug, it does mean one has to be careful with
pretty-printing, since a naive approach would print the above term as
<code>λ x. λ x. x x</code>, which is not correct. If desired, we could instead
use a more sophisticated representations of scopes that enforces
freshness as an <em>inductive-recursive type</em>:</p>
<pre class="Agda"><a id="22474" class="Keyword">module</a> <a id="WellScopedFresh"></a><a id="22481" href="1001-syntax-representations.html#22481" class="Module">WellScopedFresh</a> <a id="22497" class="Keyword">where</a>

  <a id="22506" class="Keyword">data</a> <a id="WellScopedFresh.FreshList"></a><a id="22511" href="1001-syntax-representations.html#22511" class="Datatype">FreshList</a> <a id="22521" class="Symbol">(</a><a id="22522" href="1001-syntax-representations.html#22522" class="Bound">A</a> <a id="22524" class="Symbol">:</a> <a id="22526" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="22529" class="Symbol">)</a> <a id="22531" class="Symbol">:</a> <a id="22533" href="Agda.Primitive.html#388" class="Primitive">Set</a>
  <a id="WellScopedFresh._#_"></a><a id="22539" href="1001-syntax-representations.html#22539" class="Function Operator">_#_</a> <a id="22543" class="Symbol">:</a> <a id="22545" class="Symbol">{</a><a id="22546" href="1001-syntax-representations.html#22546" class="Bound">A</a> <a id="22548" class="Symbol">:</a> <a id="22550" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="22553" class="Symbol">}</a> <a id="22555" class="Symbol">→</a> <a id="22557" href="1001-syntax-representations.html#22546" class="Bound">A</a> <a id="22559" class="Symbol">→</a> <a id="22561" href="1001-syntax-representations.html#22511" class="Datatype">FreshList</a> <a id="22571" href="1001-syntax-representations.html#22546" class="Bound">A</a> <a id="22573" class="Symbol">→</a> <a id="22575" href="Agda.Primitive.html#388" class="Primitive">Set</a>

  <a id="22582" class="Keyword">data</a> <a id="22587" href="1001-syntax-representations.html#22511" class="Datatype">FreshList</a> <a id="22597" href="1001-syntax-representations.html#22597" class="Bound">A</a> <a id="22599" class="Keyword">where</a>
    <a id="WellScopedFresh.FreshList.[]"></a><a id="22609" href="1001-syntax-representations.html#22609" class="InductiveConstructor">[]</a>    <a id="22615" class="Symbol">:</a> <a id="22617" href="1001-syntax-representations.html#22511" class="Datatype">FreshList</a> <a id="22627" href="1001-syntax-representations.html#22597" class="Bound">A</a>
    <a id="WellScopedFresh.FreshList._∷_&lt;_&gt;"></a><a id="22633" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">_∷_&lt;_&gt;</a> <a id="22640" class="Symbol">:</a> <a id="22642" class="Symbol">(</a><a id="22643" href="1001-syntax-representations.html#22643" class="Bound">x</a> <a id="22645" class="Symbol">:</a> <a id="22647" href="1001-syntax-representations.html#22597" class="Bound">A</a><a id="22648" class="Symbol">)</a> <a id="22650" class="Symbol">(</a><a id="22651" href="1001-syntax-representations.html#22651" class="Bound">xs</a> <a id="22654" class="Symbol">:</a> <a id="22656" href="1001-syntax-representations.html#22511" class="Datatype">FreshList</a> <a id="22666" href="1001-syntax-representations.html#22597" class="Bound">A</a><a id="22667" class="Symbol">)</a> <a id="22669" class="Symbol">→</a> <a id="22671" href="1001-syntax-representations.html#22643" class="Bound">x</a> <a id="22673" href="1001-syntax-representations.html#22539" class="Function Operator">#</a> <a id="22675" href="1001-syntax-representations.html#22651" class="Bound">xs</a> <a id="22678" class="Symbol">→</a> <a id="22680" href="1001-syntax-representations.html#22511" class="Datatype">FreshList</a> <a id="22690" href="1001-syntax-representations.html#22597" class="Bound">A</a>

  <a id="22695" href="1001-syntax-representations.html#22695" class="Bound">x</a> <a id="22697" href="1001-syntax-representations.html#22539" class="Function Operator">#</a> <a id="22699" href="1001-syntax-representations.html#22609" class="InductiveConstructor">[]</a> <a id="22702" class="Symbol">=</a> <a id="22704" href="Agda.Builtin.Unit.html#175" class="Record">⊤</a>
  <a id="22708" href="1001-syntax-representations.html#22708" class="Bound">x</a> <a id="22710" href="1001-syntax-representations.html#22539" class="Function Operator">#</a> <a id="22712" class="Symbol">(</a><a id="22713" href="1001-syntax-representations.html#22713" class="Bound">y</a> <a id="22715" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">∷</a> <a id="22717" href="1001-syntax-representations.html#22717" class="Bound">xs</a> <a id="22720" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">&lt;</a> <a id="22722" class="Symbol">_</a> <a id="22724" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">&gt;</a><a id="22725" class="Symbol">)</a> <a id="22727" class="Symbol">=</a> <a id="22729" href="1001-syntax-representations.html#22708" class="Bound">x</a> <a id="22731" href="Relation.Binary.PropositionalEquality.Core.html#1000" class="Function Operator">≢</a> <a id="22733" href="1001-syntax-representations.html#22713" class="Bound">y</a> <a id="22735" href="Data.Product.Base.html#1618" class="Function Operator">×</a> <a id="22737" class="Symbol">(</a><a id="22738" href="1001-syntax-representations.html#22708" class="Bound">x</a> <a id="22740" href="1001-syntax-representations.html#22539" class="Function Operator">#</a> <a id="22742" href="1001-syntax-representations.html#22717" class="Bound">xs</a><a id="22744" class="Symbol">)</a>

  <a id="22749" class="Keyword">data</a> <a id="WellScopedFresh._∈_"></a><a id="22754" href="1001-syntax-representations.html#22754" class="Datatype Operator">_∈_</a> <a id="22758" class="Symbol">{</a><a id="22759" href="1001-syntax-representations.html#22759" class="Bound">A</a> <a id="22761" class="Symbol">:</a> <a id="22763" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="22766" class="Symbol">}</a> <a id="22768" class="Symbol">(</a><a id="22769" href="1001-syntax-representations.html#22769" class="Bound">x</a> <a id="22771" class="Symbol">:</a> <a id="22773" href="1001-syntax-representations.html#22759" class="Bound">A</a><a id="22774" class="Symbol">)</a> <a id="22776" class="Symbol">:</a> <a id="22778" href="1001-syntax-representations.html#22511" class="Datatype">FreshList</a> <a id="22788" href="1001-syntax-representations.html#22759" class="Bound">A</a> <a id="22790" class="Symbol">→</a> <a id="22792" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="22796" class="Keyword">where</a>
    <a id="WellScopedFresh._∈_.here"></a><a id="22806" href="1001-syntax-representations.html#22806" class="InductiveConstructor">here</a>  <a id="22812" class="Symbol">:</a> <a id="22814" class="Symbol">∀</a> <a id="22816" class="Symbol">{</a><a id="22817" href="1001-syntax-representations.html#22817" class="Bound">xs</a> <a id="22820" href="1001-syntax-representations.html#22820" class="Bound">p</a><a id="22821" class="Symbol">}</a> <a id="22823" class="Symbol">→</a> <a id="22825" href="1001-syntax-representations.html#22769" class="Bound">x</a> <a id="22827" href="1001-syntax-representations.html#22754" class="Datatype Operator">∈</a> <a id="22829" class="Symbol">(</a><a id="22830" href="1001-syntax-representations.html#22769" class="Bound">x</a> <a id="22832" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">∷</a> <a id="22834" href="1001-syntax-representations.html#22817" class="Bound">xs</a> <a id="22837" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">&lt;</a> <a id="22839" href="1001-syntax-representations.html#22820" class="Bound">p</a> <a id="22841" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">&gt;</a><a id="22842" class="Symbol">)</a>
    <a id="WellScopedFresh._∈_.there"></a><a id="22848" href="1001-syntax-representations.html#22848" class="InductiveConstructor">there</a> <a id="22854" class="Symbol">:</a> <a id="22856" class="Symbol">∀</a> <a id="22858" class="Symbol">{</a><a id="22859" href="1001-syntax-representations.html#22859" class="Bound">y</a> <a id="22861" href="1001-syntax-representations.html#22861" class="Bound">xs</a> <a id="22864" href="1001-syntax-representations.html#22864" class="Bound">p</a><a id="22865" class="Symbol">}</a> <a id="22867" class="Symbol">→</a> <a id="22869" href="1001-syntax-representations.html#22769" class="Bound">x</a> <a id="22871" href="1001-syntax-representations.html#22754" class="Datatype Operator">∈</a> <a id="22873" href="1001-syntax-representations.html#22861" class="Bound">xs</a> <a id="22876" class="Symbol">→</a> <a id="22878" href="1001-syntax-representations.html#22769" class="Bound">x</a> <a id="22880" href="1001-syntax-representations.html#22754" class="Datatype Operator">∈</a> <a id="22882" class="Symbol">(</a><a id="22883" href="1001-syntax-representations.html#22859" class="Bound">y</a> <a id="22885" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">∷</a> <a id="22887" href="1001-syntax-representations.html#22861" class="Bound">xs</a> <a id="22890" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">&lt;</a> <a id="22892" href="1001-syntax-representations.html#22864" class="Bound">p</a> <a id="22894" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">&gt;</a><a id="22895" class="Symbol">)</a>

  <a id="WellScopedFresh.Scope"></a><a id="22900" href="1001-syntax-representations.html#22900" class="Function">Scope</a> <a id="22906" class="Symbol">=</a> <a id="22908" href="1001-syntax-representations.html#22511" class="Datatype">FreshList</a> <a id="22918" href="Agda.Builtin.String.html#335" class="Postulate">String</a>

  <a id="22928" class="Keyword">data</a> <a id="WellScopedFresh.Term"></a><a id="22933" href="1001-syntax-representations.html#22933" class="Datatype">Term</a> <a id="22938" class="Symbol">(</a><a id="22939" href="1001-syntax-representations.html#22939" class="Bound">s</a> <a id="22941" class="Symbol">:</a> <a id="22943" href="1001-syntax-representations.html#22900" class="Function">Scope</a><a id="22948" class="Symbol">)</a> <a id="22950" class="Symbol">:</a> <a id="22952" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="22956" class="Keyword">where</a>
    <a id="WellScopedFresh.Term.var"></a><a id="22966" href="1001-syntax-representations.html#22966" class="InductiveConstructor">var</a> <a id="22970" class="Symbol">:</a> <a id="22972" class="Symbol">(</a><a id="22973" href="1001-syntax-representations.html#22973" class="Bound">x</a> <a id="22975" class="Symbol">:</a> <a id="22977" href="Agda.Builtin.String.html#335" class="Postulate">String</a><a id="22983" class="Symbol">)</a> <a id="22985" class="Symbol">→</a> <a id="22987" href="1001-syntax-representations.html#22973" class="Bound">x</a> <a id="22989" href="1001-syntax-representations.html#22754" class="Datatype Operator">∈</a> <a id="22991" href="1001-syntax-representations.html#22939" class="Bound">s</a> <a id="22993" class="Symbol">→</a> <a id="22995" href="1001-syntax-representations.html#22933" class="Datatype">Term</a> <a id="23000" href="1001-syntax-representations.html#22939" class="Bound">s</a>
    <a id="WellScopedFresh.Term.lam"></a><a id="23006" href="1001-syntax-representations.html#23006" class="InductiveConstructor">lam</a> <a id="23010" class="Symbol">:</a> <a id="23012" class="Symbol">(</a><a id="23013" href="1001-syntax-representations.html#23013" class="Bound">x</a> <a id="23015" class="Symbol">:</a> <a id="23017" href="Agda.Builtin.String.html#335" class="Postulate">String</a><a id="23023" class="Symbol">)</a> <a id="23025" class="Symbol">(</a><a id="23026" href="1001-syntax-representations.html#23026" class="Bound">p</a> <a id="23028" class="Symbol">:</a> <a id="23030" href="1001-syntax-representations.html#23013" class="Bound">x</a> <a id="23032" href="1001-syntax-representations.html#22539" class="Function Operator">#</a> <a id="23034" href="1001-syntax-representations.html#22939" class="Bound">s</a><a id="23035" class="Symbol">)</a>
        <a id="23045" class="Symbol">→</a> <a id="23047" href="1001-syntax-representations.html#22933" class="Datatype">Term</a> <a id="23052" class="Symbol">(</a><a id="23053" href="1001-syntax-representations.html#23013" class="Bound">x</a> <a id="23055" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">∷</a> <a id="23057" href="1001-syntax-representations.html#22939" class="Bound">s</a> <a id="23059" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">&lt;</a> <a id="23061" href="1001-syntax-representations.html#23026" class="Bound">p</a> <a id="23063" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">&gt;</a><a id="23064" class="Symbol">)</a> <a id="23066" class="Symbol">→</a> <a id="23068" href="1001-syntax-representations.html#22933" class="Datatype">Term</a> <a id="23073" href="1001-syntax-representations.html#22939" class="Bound">s</a>
    <a id="WellScopedFresh.Term.app"></a><a id="23079" href="1001-syntax-representations.html#23079" class="InductiveConstructor">app</a> <a id="23083" class="Symbol">:</a> <a id="23085" href="1001-syntax-representations.html#22933" class="Datatype">Term</a> <a id="23090" href="1001-syntax-representations.html#22939" class="Bound">s</a> <a id="23092" class="Symbol">→</a> <a id="23094" href="1001-syntax-representations.html#22933" class="Datatype">Term</a> <a id="23099" href="1001-syntax-representations.html#22939" class="Bound">s</a> <a id="23101" class="Symbol">→</a> <a id="23103" href="1001-syntax-representations.html#22933" class="Datatype">Term</a> <a id="23108" href="1001-syntax-representations.html#22939" class="Bound">s</a>

  <a id="WellScopedFresh.ex"></a><a id="23113" href="1001-syntax-representations.html#23113" class="Function">ex</a> <a id="23116" class="Symbol">:</a> <a id="23118" href="1001-syntax-representations.html#22933" class="Datatype">Term</a> <a id="23123" href="1001-syntax-representations.html#22609" class="InductiveConstructor">[]</a>
  <a id="23128" href="1001-syntax-representations.html#23113" class="Function">ex</a> <a id="23131" class="Symbol">=</a> <a id="23133" href="1001-syntax-representations.html#23006" class="InductiveConstructor">lam</a> <a id="23137" class="String">&quot;f&quot;</a> <a id="23141" href="1001-syntax-representations.html#23273" class="Function">f#</a> <a id="23144" class="Symbol">(</a>
         <a id="23155" href="1001-syntax-representations.html#23006" class="InductiveConstructor">lam</a> <a id="23159" class="String">&quot;x&quot;</a> <a id="23163" href="1001-syntax-representations.html#23308" class="Function">x#f</a> <a id="23167" class="Symbol">(</a>
           <a id="23180" href="1001-syntax-representations.html#23079" class="InductiveConstructor">app</a> <a id="23184" class="Symbol">(</a><a id="23185" href="1001-syntax-representations.html#22966" class="InductiveConstructor">var</a> <a id="23189" class="String">&quot;f&quot;</a> <a id="23193" class="Symbol">(</a><a id="23194" href="1001-syntax-representations.html#22848" class="InductiveConstructor">there</a> <a id="23200" href="1001-syntax-representations.html#22806" class="InductiveConstructor">here</a><a id="23204" class="Symbol">))</a>
               <a id="23222" class="Symbol">(</a><a id="23223" href="1001-syntax-representations.html#22966" class="InductiveConstructor">var</a> <a id="23227" class="String">&quot;x&quot;</a> <a id="23231" href="1001-syntax-representations.html#22806" class="InductiveConstructor">here</a><a id="23235" class="Symbol">)</a>
         <a id="23246" class="Symbol">)</a>
       <a id="23255" class="Symbol">)</a>
    <a id="23261" class="Keyword">where</a>
      <a id="23273" href="1001-syntax-representations.html#23273" class="Function">f#</a> <a id="23276" class="Symbol">:</a> <a id="23278" class="String">&quot;f&quot;</a> <a id="23282" href="1001-syntax-representations.html#22539" class="Function Operator">#</a> <a id="23284" href="1001-syntax-representations.html#22609" class="InductiveConstructor">[]</a>
      <a id="23293" href="1001-syntax-representations.html#23273" class="Function">f#</a> <a id="23296" class="Symbol">=</a> <a id="23298" href="Agda.Builtin.Unit.html#212" class="InductiveConstructor">tt</a>

      <a id="23308" href="1001-syntax-representations.html#23308" class="Function">x#f</a> <a id="23312" class="Symbol">:</a> <a id="23314" class="String">&quot;x&quot;</a> <a id="23318" href="1001-syntax-representations.html#22539" class="Function Operator">#</a> <a id="23320" class="Symbol">(</a><a id="23321" class="String">&quot;f&quot;</a> <a id="23325" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">∷</a> <a id="23327" href="1001-syntax-representations.html#22609" class="InductiveConstructor">[]</a> <a id="23330" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">&lt;</a> <a id="23332" href="1001-syntax-representations.html#23273" class="Function">f#</a> <a id="23335" href="1001-syntax-representations.html#22633" class="InductiveConstructor Operator">&gt;</a><a id="23336" class="Symbol">)</a>
      <a id="23344" href="1001-syntax-representations.html#23308" class="Function">x#f</a> <a id="23348" class="Symbol">=</a> <a id="23350" class="Symbol">(λ</a> <a id="23353" class="Symbol">())</a> <a id="23357" href="Agda.Builtin.Sigma.html#235" class="InductiveConstructor Operator">,</a> <a id="23359" href="Agda.Builtin.Unit.html#212" class="InductiveConstructor">tt</a>
</pre>
<p>As you can see, this approach ensures that the names we bind are fresh
w.r.t. the current scope, at the cost of more complex types and having
to produce freshness proofs (although this could also be automated).</p>
<p>Despite its limitations I feel that the simple version using
a normal list of names strikes a nice balance between getting good
static guarantees and being easy to use. This is also attested by the
fact it is used in the <a href="https://github.com/idris-lang/Idris2/blob/21ca9066f13e3b9f8c6be28774a91f43bb68d51d/src/Core/TT.idr#L770-L778">bootstrapped implementation of Idris
2</a>.</p>
<h1 id="nameless-painless">Nameless, Painless</h1>
<p>When I explained the nominal approach to name binding, I made use of
an abstract interface exposing the operations. While this was done out
of necessity (since Agda does not have nominal types built-in),
working with an abstract interface for name binding actually has other
benefits: it allows us to avoid relying on the implementation details
of names by hiding them from the interface, and it even allows
swapping out a concrete implementation of variables for another one
(perhaps one that’s more efficient).</p>
<p>This is what the paper <a href="http://doi.acm.org/10.1145/2034773.2034817">“Nameless,
Painless”</a> does: it
provides an abstract interface to well-scoped de Bruijn indices. The
interface consists of an abstract type of <code>World</code>s (i.e. scopes), and
for each world <code>w</code> a set of names <code>Name w</code>. In the concrete
implementation of well-scoped de Bruijn syntax we gave above, these
were implemented as <code>World = ℕ</code> and <code>Name = Fin</code> respectively.</p>
<pre class="Agda"><a id="24943" class="Keyword">module</a> <a id="NamelessPainless"></a><a id="24950" href="1001-syntax-representations.html#24950" class="Module">NamelessPainless</a> <a id="24967" class="Keyword">where</a>

  <a id="24976" class="Keyword">record</a> <a id="NamelessPainless.NaPa"></a><a id="24983" href="1001-syntax-representations.html#24983" class="Record">NaPa</a> <a id="24988" class="Symbol">:</a> <a id="24990" href="Agda.Primitive.html#388" class="Primitive">Set₁</a> <a id="24995" class="Keyword">where</a>
    <a id="25005" class="Keyword">field</a>
      <a id="NamelessPainless.NaPa.World"></a><a id="25017" href="1001-syntax-representations.html#25017" class="Field">World</a>   <a id="25025" class="Symbol">:</a> <a id="25027" href="Agda.Primitive.html#388" class="Primitive">Set</a>
      <a id="NamelessPainless.NaPa.∅"></a><a id="25037" href="1001-syntax-representations.html#25037" class="Field">∅</a>       <a id="25045" class="Symbol">:</a> <a id="25047" href="1001-syntax-representations.html#25017" class="Field">World</a>
      <a id="NamelessPainless.NaPa._↑1"></a><a id="25059" href="1001-syntax-representations.html#25059" class="Field Operator">_↑1</a>     <a id="25067" class="Symbol">:</a> <a id="25069" href="1001-syntax-representations.html#25017" class="Field">World</a> <a id="25075" class="Symbol">→</a> <a id="25077" href="1001-syntax-representations.html#25017" class="Field">World</a>
      <a id="NamelessPainless.NaPa.Name"></a><a id="25089" href="1001-syntax-representations.html#25089" class="Field">Name</a>    <a id="25097" class="Symbol">:</a> <a id="25099" href="1001-syntax-representations.html#25017" class="Field">World</a> <a id="25105" class="Symbol">→</a> <a id="25107" href="Agda.Primitive.html#388" class="Primitive">Set</a>
      <a id="NamelessPainless.NaPa._⊆_"></a><a id="25117" href="1001-syntax-representations.html#25117" class="Field Operator">_⊆_</a>     <a id="25125" class="Symbol">:</a> <a id="25127" href="1001-syntax-representations.html#25017" class="Field">World</a> <a id="25133" class="Symbol">→</a> <a id="25135" href="1001-syntax-representations.html#25017" class="Field">World</a> <a id="25141" class="Symbol">→</a> <a id="25143" href="Agda.Primitive.html#388" class="Primitive">Set</a>
      <a id="NamelessPainless.NaPa.zeroᴺ"></a><a id="25153" href="1001-syntax-representations.html#25153" class="Field">zeroᴺ</a>   <a id="25161" class="Symbol">:</a> <a id="25163" class="Symbol">∀</a> <a id="25165" class="Symbol">{</a><a id="25166" href="1001-syntax-representations.html#25166" class="Bound">α</a><a id="25167" class="Symbol">}</a> <a id="25169" class="Symbol">→</a> <a id="25171" href="1001-syntax-representations.html#25089" class="Field">Name</a> <a id="25176" class="Symbol">(</a><a id="25177" href="1001-syntax-representations.html#25166" class="Bound">α</a> <a id="25179" href="1001-syntax-representations.html#25059" class="Field Operator">↑1</a><a id="25181" class="Symbol">)</a>
      <a id="NamelessPainless.NaPa.sucᴺ"></a><a id="25189" href="1001-syntax-representations.html#25189" class="Field">sucᴺ</a>    <a id="25197" class="Symbol">:</a> <a id="25199" class="Symbol">∀</a> <a id="25201" class="Symbol">{</a><a id="25202" href="1001-syntax-representations.html#25202" class="Bound">α</a><a id="25203" class="Symbol">}</a> <a id="25205" class="Symbol">→</a> <a id="25207" href="1001-syntax-representations.html#25089" class="Field">Name</a> <a id="25212" href="1001-syntax-representations.html#25202" class="Bound">α</a> <a id="25214" class="Symbol">→</a> <a id="25216" href="1001-syntax-representations.html#25089" class="Field">Name</a> <a id="25221" class="Symbol">(</a><a id="25222" href="1001-syntax-representations.html#25202" class="Bound">α</a> <a id="25224" href="1001-syntax-representations.html#25059" class="Field Operator">↑1</a><a id="25226" class="Symbol">)</a>
      <a id="NamelessPainless.NaPa._==ᴺ_"></a><a id="25234" href="1001-syntax-representations.html#25234" class="Field Operator">_==ᴺ_</a>   <a id="25242" class="Symbol">:</a> <a id="25244" class="Symbol">∀</a> <a id="25246" class="Symbol">{</a><a id="25247" href="1001-syntax-representations.html#25247" class="Bound">α</a><a id="25248" class="Symbol">}</a> <a id="25250" class="Symbol">→</a> <a id="25252" href="1001-syntax-representations.html#25089" class="Field">Name</a> <a id="25257" href="1001-syntax-representations.html#25247" class="Bound">α</a> <a id="25259" class="Symbol">→</a> <a id="25261" href="1001-syntax-representations.html#25089" class="Field">Name</a> <a id="25266" href="1001-syntax-representations.html#25247" class="Bound">α</a> <a id="25268" class="Symbol">→</a> <a id="25270" href="Agda.Builtin.Bool.html#173" class="Datatype">Bool</a>
      <a id="NamelessPainless.NaPa.exportᴺ"></a><a id="25281" href="1001-syntax-representations.html#25281" class="Field">exportᴺ</a> <a id="25289" class="Symbol">:</a> <a id="25291" class="Symbol">∀</a> <a id="25293" class="Symbol">{</a><a id="25294" href="1001-syntax-representations.html#25294" class="Bound">α</a><a id="25295" class="Symbol">}</a> <a id="25297" class="Symbol">→</a> <a id="25299" href="1001-syntax-representations.html#25089" class="Field">Name</a> <a id="25304" class="Symbol">(</a><a id="25305" href="1001-syntax-representations.html#25294" class="Bound">α</a> <a id="25307" href="1001-syntax-representations.html#25059" class="Field Operator">↑1</a><a id="25309" class="Symbol">)</a> <a id="25311" class="Symbol">→</a> <a id="25313" href="Agda.Builtin.Maybe.html#135" class="Datatype">Maybe</a> <a id="25319" class="Symbol">(</a><a id="25320" href="1001-syntax-representations.html#25089" class="Field">Name</a> <a id="25325" href="1001-syntax-representations.html#25294" class="Bound">α</a><a id="25326" class="Symbol">)</a>
      <a id="NamelessPainless.NaPa.coerce"></a><a id="25334" href="1001-syntax-representations.html#25334" class="Field">coerce</a>  <a id="25342" class="Symbol">:</a> <a id="25344" class="Symbol">∀</a> <a id="25346" class="Symbol">{</a><a id="25347" href="1001-syntax-representations.html#25347" class="Bound">α</a> <a id="25349" href="1001-syntax-representations.html#25349" class="Bound">β</a><a id="25350" class="Symbol">}</a> <a id="25352" class="Symbol">→</a> <a id="25354" href="1001-syntax-representations.html#25347" class="Bound">α</a> <a id="25356" href="1001-syntax-representations.html#25117" class="Field Operator">⊆</a> <a id="25358" href="1001-syntax-representations.html#25349" class="Bound">β</a> <a id="25360" class="Symbol">→</a> <a id="25362" href="1001-syntax-representations.html#25089" class="Field">Name</a> <a id="25367" href="1001-syntax-representations.html#25347" class="Bound">α</a> <a id="25369" class="Symbol">→</a> <a id="25371" href="1001-syntax-representations.html#25089" class="Field">Name</a> <a id="25376" href="1001-syntax-representations.html#25349" class="Bound">β</a>
      <a id="NamelessPainless.NaPa.¬Name∅"></a><a id="25384" href="1001-syntax-representations.html#25384" class="Field">¬Name∅</a>  <a id="25392" class="Symbol">:</a> <a id="25394" href="Relation.Nullary.Negation.Core.html#677" class="Function Operator">¬</a> <a id="25396" class="Symbol">(</a><a id="25397" href="1001-syntax-representations.html#25089" class="Field">Name</a> <a id="25402" href="1001-syntax-representations.html#25037" class="Field">∅</a><a id="25403" class="Symbol">)</a>


  <a id="25409" class="Keyword">open</a> <a id="25414" href="1001-syntax-representations.html#24983" class="Module">NaPa</a> <a id="25419" class="Symbol">{{...}}</a>
</pre>
<p>The operation <code>_==ᴺ_</code> allows us to compare two names in the same
scope, and the function <code>exportᴺ</code> allows us to do case analysis on
whether a name is bound by the top-level binder or one beneath it.</p>
<p>To actually define a syntax that uses this interface, we parametrize
our module with an instance argument of type <code>NaPa</code>:</p>
<pre class="Agda">  <a id="25761" class="Keyword">module</a> <a id="25768" href="1001-syntax-representations.html#25768" class="Module">_</a> <a id="25770" class="Symbol">{{</a><a id="25772" href="1001-syntax-representations.html#25772" class="Bound">_</a> <a id="25774" class="Symbol">:</a> <a id="25776" href="1001-syntax-representations.html#24983" class="Record">NaPa</a><a id="25780" class="Symbol">}}</a> <a id="25783" class="Keyword">where</a>

    <a id="25794" class="Keyword">data</a> <a id="25799" href="1001-syntax-representations.html#25799" class="Datatype">Term</a> <a id="25804" class="Symbol">(</a><a id="25805" href="1001-syntax-representations.html#25805" class="Bound">w</a> <a id="25807" class="Symbol">:</a> <a id="25809" href="1001-syntax-representations.html#25017" class="Field">World</a><a id="25814" class="Symbol">)</a> <a id="25816" class="Symbol">:</a> <a id="25818" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="25822" class="Keyword">where</a>
      <a id="25834" href="1001-syntax-representations.html#25834" class="InductiveConstructor">var</a> <a id="25838" class="Symbol">:</a> <a id="25840" href="1001-syntax-representations.html#25089" class="Field">Name</a> <a id="25845" href="1001-syntax-representations.html#25805" class="Bound">w</a> <a id="25847" class="Symbol">→</a> <a id="25849" href="1001-syntax-representations.html#25799" class="Datatype">Term</a> <a id="25854" href="1001-syntax-representations.html#25805" class="Bound">w</a>
      <a id="25862" href="1001-syntax-representations.html#25862" class="InductiveConstructor">lam</a> <a id="25866" class="Symbol">:</a> <a id="25868" href="1001-syntax-representations.html#25799" class="Datatype">Term</a> <a id="25873" class="Symbol">(</a><a id="25874" href="1001-syntax-representations.html#25805" class="Bound">w</a> <a id="25876" href="1001-syntax-representations.html#25059" class="Field Operator">↑1</a><a id="25878" class="Symbol">)</a> <a id="25880" class="Symbol">→</a> <a id="25882" href="1001-syntax-representations.html#25799" class="Datatype">Term</a> <a id="25887" href="1001-syntax-representations.html#25805" class="Bound">w</a>
      <a id="25895" href="1001-syntax-representations.html#25895" class="InductiveConstructor">app</a> <a id="25899" class="Symbol">:</a> <a id="25901" href="1001-syntax-representations.html#25799" class="Datatype">Term</a> <a id="25906" href="1001-syntax-representations.html#25805" class="Bound">w</a> <a id="25908" class="Symbol">→</a> <a id="25910" href="1001-syntax-representations.html#25799" class="Datatype">Term</a> <a id="25915" href="1001-syntax-representations.html#25805" class="Bound">w</a> <a id="25917" class="Symbol">→</a> <a id="25919" href="1001-syntax-representations.html#25799" class="Datatype">Term</a> <a id="25924" href="1001-syntax-representations.html#25805" class="Bound">w</a>

    <a id="25931" href="1001-syntax-representations.html#25931" class="Function">ex</a> <a id="25934" class="Symbol">:</a> <a id="25936" class="Symbol">∀</a> <a id="25938" class="Symbol">{</a><a id="25939" href="1001-syntax-representations.html#25939" class="Bound">w</a><a id="25940" class="Symbol">}</a> <a id="25942" class="Symbol">→</a> <a id="25944" href="1001-syntax-representations.html#25799" class="Datatype">Term</a> <a id="25949" href="1001-syntax-representations.html#25939" class="Bound">w</a>
    <a id="25955" href="1001-syntax-representations.html#25931" class="Function">ex</a> <a id="25958" class="Symbol">=</a> <a id="25960" href="1001-syntax-representations.html#25862" class="InductiveConstructor">lam</a> <a id="25964" class="Comment">{-f-}</a> <a id="25970" class="Symbol">(</a>
           <a id="25983" href="1001-syntax-representations.html#25862" class="InductiveConstructor">lam</a> <a id="25987" class="Comment">{-x-}</a> <a id="25993" class="Symbol">(</a>
             <a id="26008" href="1001-syntax-representations.html#25895" class="InductiveConstructor">app</a> <a id="26012" class="Symbol">(</a><a id="26013" href="1001-syntax-representations.html#25834" class="InductiveConstructor">var</a> <a id="26017" class="Comment">{-f-}</a> <a id="26023" class="Symbol">(</a><a id="26024" href="1001-syntax-representations.html#25189" class="Field">sucᴺ</a> <a id="26029" href="1001-syntax-representations.html#25153" class="Field">zeroᴺ</a><a id="26034" class="Symbol">))</a>
                 <a id="26054" class="Symbol">(</a><a id="26055" href="1001-syntax-representations.html#25834" class="InductiveConstructor">var</a> <a id="26059" class="Comment">{-x-}</a> <a id="26065" href="1001-syntax-representations.html#25153" class="Field">zeroᴺ</a><a id="26070" class="Symbol">)</a>
            <a id="26084" class="Symbol">)</a>
          <a id="26096" class="Symbol">)</a>
</pre>
<p>Apart from the benefits mentioned above, we also get additional <a href="https://dl.acm.org/doi/pdf/10.1145/99370.99404">free
theorems</a> as a result
of being parametric over the implementation of scopes and names. For
example, the paper shows that any world-polymorphic function commutes
with renaming of the free variables.</p>
<p>Despite these apparent strengths, I have not seen this approach being
used in practice. I’m not sure that’s because it has some important
downsides, or just because it is not well known.</p>
<h2 id="abstract-scope-graphs">Abstract scope graphs</h2>
<p><a href="https://doi.org/10.1145/3276484"><em>Scope graphs</em></a> provide a very
general interface for representing syntax with name binding and name
resolution. Broadly speaking, nodes in a scope graph represent scopes,
and edges determine reachability. Rather than formalize the full
theory of scope graphs here, we can take the same approach as before
and declare an abstract interface containing the pieces we need here
(I apologize to my colleagues in Delft if I am horribly
misrepresenting scope graphs):</p>
<pre class="Agda"><a id="27155" class="Keyword">module</a> <a id="AbstractScopeGraphs"></a><a id="27162" href="1001-syntax-representations.html#27162" class="Module">AbstractScopeGraphs</a> <a id="27182" class="Keyword">where</a>

  <a id="AbstractScopeGraphs.Name"></a><a id="27191" href="1001-syntax-representations.html#27191" class="Function">Name</a> <a id="27196" class="Symbol">=</a> <a id="27198" href="Agda.Builtin.String.html#335" class="Postulate">String</a> <a id="27205" class="Comment">-- just for concreteness</a>

  <a id="27233" class="Keyword">record</a> <a id="AbstractScopeGraphs.ScopeGraph"></a><a id="27240" href="1001-syntax-representations.html#27240" class="Record">ScopeGraph</a> <a id="27251" class="Symbol">:</a> <a id="27253" href="Agda.Primitive.html#388" class="Primitive">Set₁</a> <a id="27258" class="Keyword">where</a>
    <a id="27268" class="Keyword">field</a>
      <a id="27280" class="Comment">-- Structure of scope graphs we rely on:</a>
      <a id="27327" class="Comment">-- 1. a type of scopes (i.e. nodes in the graph)</a>
      <a id="AbstractScopeGraphs.ScopeGraph.Scope"></a><a id="27382" href="1001-syntax-representations.html#27382" class="Field">Scope</a> <a id="27388" class="Symbol">:</a> <a id="27390" href="Agda.Primitive.html#388" class="Primitive">Set</a>
      <a id="27400" class="Comment">-- 2. a predicate expressing reachability + visibility</a>
      <a id="AbstractScopeGraphs.ScopeGraph._∈_"></a><a id="27461" href="1001-syntax-representations.html#27461" class="Field Operator">_∈_</a>   <a id="27467" class="Symbol">:</a> <a id="27469" href="1001-syntax-representations.html#27191" class="Function">Name</a> <a id="27474" class="Symbol">→</a> <a id="27476" href="1001-syntax-representations.html#27382" class="Field">Scope</a> <a id="27482" class="Symbol">→</a> <a id="27484" href="Agda.Primitive.html#388" class="Primitive">Set</a>
      <a id="27494" class="Comment">-- 3. Binding a name, shadowing all previous occurrences</a>
      <a id="AbstractScopeGraphs.ScopeGraph.bind"></a><a id="27557" href="1001-syntax-representations.html#27557" class="Field">bind</a>  <a id="27563" class="Symbol">:</a> <a id="27565" href="1001-syntax-representations.html#27191" class="Function">Name</a> <a id="27570" class="Symbol">→</a> <a id="27572" href="1001-syntax-representations.html#27382" class="Field">Scope</a> <a id="27578" class="Symbol">→</a> <a id="27580" href="1001-syntax-representations.html#27382" class="Field">Scope</a>
      <a id="AbstractScopeGraphs.ScopeGraph.here"></a><a id="27592" href="1001-syntax-representations.html#27592" class="Field">here</a>  <a id="27598" class="Symbol">:</a> <a id="27600" class="Symbol">∀</a> <a id="27602" class="Symbol">{</a><a id="27603" href="1001-syntax-representations.html#27603" class="Bound">x</a> <a id="27605" href="1001-syntax-representations.html#27605" class="Bound">s</a><a id="27606" class="Symbol">}</a> <a id="27608" class="Symbol">→</a> <a id="27610" href="1001-syntax-representations.html#27603" class="Bound">x</a> <a id="27612" href="1001-syntax-representations.html#27461" class="Field Operator">∈</a> <a id="27614" href="1001-syntax-representations.html#27557" class="Field">bind</a> <a id="27619" href="1001-syntax-representations.html#27603" class="Bound">x</a> <a id="27621" href="1001-syntax-representations.html#27605" class="Bound">s</a>
      <a id="AbstractScopeGraphs.ScopeGraph.there"></a><a id="27629" href="1001-syntax-representations.html#27629" class="Field">there</a> <a id="27635" class="Symbol">:</a> <a id="27637" class="Symbol">∀</a> <a id="27639" class="Symbol">{</a><a id="27640" href="1001-syntax-representations.html#27640" class="Bound">x</a> <a id="27642" href="1001-syntax-representations.html#27642" class="Bound">y</a> <a id="27644" href="1001-syntax-representations.html#27644" class="Bound">s</a><a id="27645" class="Symbol">}</a> <a id="27647" class="Symbol">→</a> <a id="27649" href="1001-syntax-representations.html#27640" class="Bound">x</a> <a id="27651" href="Relation.Binary.PropositionalEquality.Core.html#1000" class="Function Operator">≢</a> <a id="27653" href="1001-syntax-representations.html#27642" class="Bound">y</a> <a id="27655" class="Symbol">→</a> <a id="27657" href="1001-syntax-representations.html#27640" class="Bound">x</a> <a id="27659" href="1001-syntax-representations.html#27461" class="Field Operator">∈</a> <a id="27661" href="1001-syntax-representations.html#27644" class="Bound">s</a> <a id="27663" class="Symbol">→</a> <a id="27665" href="1001-syntax-representations.html#27640" class="Bound">x</a> <a id="27667" href="1001-syntax-representations.html#27461" class="Field Operator">∈</a> <a id="27669" href="1001-syntax-representations.html#27557" class="Field">bind</a> <a id="27674" href="1001-syntax-representations.html#27642" class="Bound">y</a> <a id="27676" href="1001-syntax-representations.html#27644" class="Bound">s</a>

  <a id="27681" class="Keyword">open</a> <a id="27686" href="1001-syntax-representations.html#27240" class="Module">ScopeGraph</a> <a id="27697" class="Symbol">{{...}}</a>
</pre>
<p>The definition of a scope graph relies on two core notions of
<em>reachability</em> and <em>visibility</em> of a name in a scope. For simplicity
both of them are combined into a single predicate <code>_∈_</code> in this
interface. We can then define our syntax using <code>_∈_</code> and <code>bind</code>:</p>
<pre class="Agda">  <a id="27977" class="Keyword">module</a> <a id="27984" href="1001-syntax-representations.html#27984" class="Module">_</a> <a id="27986" class="Symbol">{{</a><a id="27988" href="1001-syntax-representations.html#27988" class="Bound">_</a> <a id="27990" class="Symbol">:</a> <a id="27992" href="1001-syntax-representations.html#27240" class="Record">ScopeGraph</a><a id="28002" class="Symbol">}}</a> <a id="28005" class="Keyword">where</a>

    <a id="28016" class="Keyword">data</a> <a id="28021" href="1001-syntax-representations.html#28021" class="Datatype">Term</a> <a id="28026" class="Symbol">(</a><a id="28027" href="1001-syntax-representations.html#28027" class="Bound">s</a> <a id="28029" class="Symbol">:</a> <a id="28031" href="1001-syntax-representations.html#27382" class="Field">Scope</a><a id="28036" class="Symbol">)</a> <a id="28038" class="Symbol">:</a> <a id="28040" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="28044" class="Keyword">where</a>
      <a id="28056" href="1001-syntax-representations.html#28056" class="InductiveConstructor">var</a> <a id="28060" class="Symbol">:</a> <a id="28062" class="Symbol">(</a><a id="28063" href="1001-syntax-representations.html#28063" class="Bound">x</a> <a id="28065" class="Symbol">:</a> <a id="28067" href="1001-syntax-representations.html#27191" class="Function">Name</a><a id="28071" class="Symbol">)</a> <a id="28073" class="Symbol">→</a> <a id="28075" href="1001-syntax-representations.html#28063" class="Bound">x</a> <a id="28077" href="1001-syntax-representations.html#27461" class="Field Operator">∈</a> <a id="28079" href="1001-syntax-representations.html#28027" class="Bound">s</a> <a id="28081" class="Symbol">→</a> <a id="28083" href="1001-syntax-representations.html#28021" class="Datatype">Term</a> <a id="28088" href="1001-syntax-representations.html#28027" class="Bound">s</a>
      <a id="28096" href="1001-syntax-representations.html#28096" class="InductiveConstructor">lam</a> <a id="28100" class="Symbol">:</a> <a id="28102" class="Symbol">(</a><a id="28103" href="1001-syntax-representations.html#28103" class="Bound">x</a> <a id="28105" class="Symbol">:</a> <a id="28107" href="1001-syntax-representations.html#27191" class="Function">Name</a><a id="28111" class="Symbol">)</a> <a id="28113" class="Symbol">→</a> <a id="28115" href="1001-syntax-representations.html#28021" class="Datatype">Term</a> <a id="28120" class="Symbol">(</a><a id="28121" href="1001-syntax-representations.html#27557" class="Field">bind</a> <a id="28126" href="1001-syntax-representations.html#28103" class="Bound">x</a> <a id="28128" href="1001-syntax-representations.html#28027" class="Bound">s</a><a id="28129" class="Symbol">)</a> <a id="28131" class="Symbol">→</a> <a id="28133" href="1001-syntax-representations.html#28021" class="Datatype">Term</a> <a id="28138" href="1001-syntax-representations.html#28027" class="Bound">s</a>
      <a id="28146" href="1001-syntax-representations.html#28146" class="InductiveConstructor">app</a> <a id="28150" class="Symbol">:</a> <a id="28152" href="1001-syntax-representations.html#28021" class="Datatype">Term</a> <a id="28157" href="1001-syntax-representations.html#28027" class="Bound">s</a> <a id="28159" class="Symbol">→</a> <a id="28161" href="1001-syntax-representations.html#28021" class="Datatype">Term</a> <a id="28166" href="1001-syntax-representations.html#28027" class="Bound">s</a> <a id="28168" class="Symbol">→</a> <a id="28170" href="1001-syntax-representations.html#28021" class="Datatype">Term</a> <a id="28175" href="1001-syntax-representations.html#28027" class="Bound">s</a>

    <a id="28182" href="1001-syntax-representations.html#28182" class="Function">ex</a> <a id="28185" class="Symbol">:</a> <a id="28187" class="Symbol">∀</a> <a id="28189" class="Symbol">{</a><a id="28190" href="1001-syntax-representations.html#28190" class="Bound">s</a><a id="28191" class="Symbol">}</a> <a id="28193" class="Symbol">→</a> <a id="28195" href="1001-syntax-representations.html#28021" class="Datatype">Term</a> <a id="28200" href="1001-syntax-representations.html#28190" class="Bound">s</a>
    <a id="28206" href="1001-syntax-representations.html#28182" class="Function">ex</a> <a id="28209" class="Symbol">{</a><a id="28210" href="1001-syntax-representations.html#28210" class="Bound">s</a><a id="28211" class="Symbol">}</a> <a id="28213" class="Symbol">=</a> <a id="28215" href="1001-syntax-representations.html#28096" class="InductiveConstructor">lam</a> <a id="28219" class="String">&quot;f&quot;</a> <a id="28223" class="Symbol">(</a>
               <a id="28240" href="1001-syntax-representations.html#28096" class="InductiveConstructor">lam</a> <a id="28244" class="String">&quot;x&quot;</a> <a id="28248" class="Symbol">(</a>
                 <a id="28267" href="1001-syntax-representations.html#28146" class="InductiveConstructor">app</a> <a id="28271" class="Symbol">(</a><a id="28272" href="1001-syntax-representations.html#28056" class="InductiveConstructor">var</a> <a id="28276" class="String">&quot;f&quot;</a> <a id="28280" class="Symbol">(</a><a id="28281" href="1001-syntax-representations.html#27629" class="Field">there</a> <a id="28287" class="Symbol">(λ</a> <a id="28290" class="Symbol">())</a> <a id="28294" href="1001-syntax-representations.html#27592" class="Field">here</a><a id="28298" class="Symbol">))</a>
                     <a id="28322" class="Symbol">(</a><a id="28323" href="1001-syntax-representations.html#28056" class="InductiveConstructor">var</a> <a id="28327" class="String">&quot;x&quot;</a> <a id="28331" href="1001-syntax-representations.html#27592" class="Field">here</a><a id="28335" class="Symbol">)</a>
               <a id="28352" class="Symbol">)</a>
             <a id="28367" class="Symbol">)</a>
</pre>
<p>The result is very similar to the approach using <code>FreshList</code> we
defined above, except that now we use an abstract interface as in the
Nameless, Painless approach. This means it is easier to extend the
interface with more fine-grained notions (e.g. the distinction between
reachability and visibility) that scope graphs allow us to model. It
also allows us to scale up more easily to more complex name binding
structures.</p>
<p>There’s still an issue that this approach shares with the <code>FreshList</code>
approach: since the syntax of a lambda expression contains an element
of type <code>Name</code>, it is possible to distinguish two α-equivalent
names. Another possible drawback is that much of the generality of
scope graphs is not actually needed, which might result in unneeded
complexity (though the use of an abstract interface means this does
not matter too much).</p>
<h2 id="the-namely-painless-approach">The ‘Namely, Painless’ approach</h2>
<p>In his <a href="https://nicolaspouillard.fr/publis/namely-painless-defense-version.pdf">PhD
thesis</a>,
Nicolas Pouillard (the main author of the “Nameless, Painless” paper)
presents another interface for programming with names and binders
called <code>NomPa</code> (for “Nominal, Painless”, I presume). In contrast to
<code>NaPa</code>, it models syntax with named variables. Yet it avoids the
problem discussed above, so <em>α-equivalent terms are
indistinguishable</em>. The trick here is to have separate types for names
and binders, and only expose equality checking of names in the
interface:</p>
<pre class="Agda"><a id="29857" class="Keyword">module</a> <a id="NamelyPainless"></a><a id="29864" href="1001-syntax-representations.html#29864" class="Module">NamelyPainless</a> <a id="29879" class="Keyword">where</a>

  <a id="29888" class="Keyword">record</a> <a id="NamelyPainless.NomPa"></a><a id="29895" href="1001-syntax-representations.html#29895" class="Record">NomPa</a> <a id="29901" class="Symbol">:</a> <a id="29903" href="Agda.Primitive.html#388" class="Primitive">Set₁</a> <a id="29908" class="Keyword">where</a>

    <a id="29919" class="Keyword">field</a>
      <a id="NamelyPainless.NomPa.World"></a><a id="29931" href="1001-syntax-representations.html#29931" class="Field">World</a>  <a id="29938" class="Symbol">:</a> <a id="29940" href="Agda.Primitive.html#388" class="Primitive">Set</a>
      <a id="NamelyPainless.NomPa.Name"></a><a id="29950" href="1001-syntax-representations.html#29950" class="Field">Name</a>   <a id="29957" class="Symbol">:</a> <a id="29959" href="1001-syntax-representations.html#29931" class="Field">World</a> <a id="29965" class="Symbol">→</a> <a id="29967" href="Agda.Primitive.html#388" class="Primitive">Set</a>
      <a id="NamelyPainless.NomPa.Binder"></a><a id="29977" href="1001-syntax-representations.html#29977" class="Field">Binder</a> <a id="29984" class="Symbol">:</a> <a id="29986" href="Agda.Primitive.html#388" class="Primitive">Set</a>
      <a id="NamelyPainless.NomPa._◃_"></a><a id="29996" href="1001-syntax-representations.html#29996" class="Field Operator">_◃_</a>    <a id="30003" class="Symbol">:</a> <a id="30005" href="1001-syntax-representations.html#29977" class="Field">Binder</a> <a id="30012" class="Symbol">→</a> <a id="30014" href="1001-syntax-representations.html#29931" class="Field">World</a> <a id="30020" class="Symbol">→</a> <a id="30022" href="1001-syntax-representations.html#29931" class="Field">World</a>

      <a id="NamelyPainless.NomPa.zeroᴮ"></a><a id="30035" href="1001-syntax-representations.html#30035" class="Field">zeroᴮ</a>  <a id="30042" class="Symbol">:</a> <a id="30044" href="1001-syntax-representations.html#29977" class="Field">Binder</a>
      <a id="NamelyPainless.NomPa.sucᴮ"></a><a id="30057" href="1001-syntax-representations.html#30057" class="Field">sucᴮ</a>   <a id="30064" class="Symbol">:</a> <a id="30066" href="1001-syntax-representations.html#29977" class="Field">Binder</a> <a id="30073" class="Symbol">→</a> <a id="30075" href="1001-syntax-representations.html#29977" class="Field">Binder</a>

      <a id="NamelyPainless.NomPa.nameᴮ"></a><a id="30089" href="1001-syntax-representations.html#30089" class="Field">nameᴮ</a>   <a id="30097" class="Symbol">:</a> <a id="30099" class="Symbol">∀</a> <a id="30101" class="Symbol">{</a><a id="30102" href="1001-syntax-representations.html#30102" class="Bound">α</a><a id="30103" class="Symbol">}</a> <a id="30105" href="1001-syntax-representations.html#30105" class="Bound">b</a> <a id="30107" class="Symbol">→</a> <a id="30109" href="1001-syntax-representations.html#29950" class="Field">Name</a> <a id="30114" class="Symbol">(</a><a id="30115" href="1001-syntax-representations.html#30105" class="Bound">b</a> <a id="30117" href="1001-syntax-representations.html#29996" class="Field Operator">◃</a> <a id="30119" href="1001-syntax-representations.html#30102" class="Bound">α</a><a id="30120" class="Symbol">)</a>
      <a id="NamelyPainless.NomPa.binderᴺ"></a><a id="30128" href="1001-syntax-representations.html#30128" class="Field">binderᴺ</a> <a id="30136" class="Symbol">:</a> <a id="30138" class="Symbol">∀</a> <a id="30140" class="Symbol">{</a><a id="30141" href="1001-syntax-representations.html#30141" class="Bound">α</a><a id="30142" class="Symbol">}</a> <a id="30144" class="Symbol">→</a> <a id="30146" href="1001-syntax-representations.html#29950" class="Field">Name</a> <a id="30151" href="1001-syntax-representations.html#30141" class="Bound">α</a> <a id="30153" class="Symbol">→</a> <a id="30155" href="1001-syntax-representations.html#29977" class="Field">Binder</a>

      <a id="NamelyPainless.NomPa.∅"></a><a id="30169" href="1001-syntax-representations.html#30169" class="Field">∅</a>      <a id="30176" class="Symbol">:</a> <a id="30178" href="1001-syntax-representations.html#29931" class="Field">World</a>
      <a id="NamelyPainless.NomPa.¬Name∅"></a><a id="30190" href="1001-syntax-representations.html#30190" class="Field">¬Name∅</a> <a id="30197" class="Symbol">:</a> <a id="30199" href="Relation.Nullary.Negation.Core.html#677" class="Function Operator">¬</a> <a id="30201" class="Symbol">(</a><a id="30202" href="1001-syntax-representations.html#29950" class="Field">Name</a> <a id="30207" href="1001-syntax-representations.html#30169" class="Field">∅</a><a id="30208" class="Symbol">)</a>

      <a id="NamelyPainless.NomPa._==ᴺ_"></a><a id="30217" href="1001-syntax-representations.html#30217" class="Field Operator">_==ᴺ_</a>   <a id="30225" class="Symbol">:</a> <a id="30227" class="Symbol">∀</a> <a id="30229" class="Symbol">{</a><a id="30230" href="1001-syntax-representations.html#30230" class="Bound">α</a><a id="30231" class="Symbol">}</a> <a id="30233" class="Symbol">(</a><a id="30234" href="1001-syntax-representations.html#30234" class="Bound">x</a> <a id="30236" href="1001-syntax-representations.html#30236" class="Bound">y</a> <a id="30238" class="Symbol">:</a> <a id="30240" href="1001-syntax-representations.html#29950" class="Field">Name</a> <a id="30245" href="1001-syntax-representations.html#30230" class="Bound">α</a><a id="30246" class="Symbol">)</a> <a id="30248" class="Symbol">→</a> <a id="30250" href="Agda.Builtin.Bool.html#173" class="Datatype">Bool</a>
      <a id="NamelyPainless.NomPa.exportᴺ"></a><a id="30261" href="1001-syntax-representations.html#30261" class="Field">exportᴺ</a> <a id="30269" class="Symbol">:</a> <a id="30271" class="Symbol">∀</a> <a id="30273" class="Symbol">{</a><a id="30274" href="1001-syntax-representations.html#30274" class="Bound">α</a> <a id="30276" href="1001-syntax-representations.html#30276" class="Bound">b</a><a id="30277" class="Symbol">}</a> <a id="30279" class="Symbol">→</a> <a id="30281" href="1001-syntax-representations.html#29950" class="Field">Name</a> <a id="30286" class="Symbol">(</a><a id="30287" href="1001-syntax-representations.html#30276" class="Bound">b</a> <a id="30289" href="1001-syntax-representations.html#29996" class="Field Operator">◃</a> <a id="30291" href="1001-syntax-representations.html#30274" class="Bound">α</a><a id="30292" class="Symbol">)</a>
              <a id="30308" class="Symbol">→</a> <a id="30310" href="1001-syntax-representations.html#29950" class="Field">Name</a> <a id="30315" class="Symbol">(</a><a id="30316" href="1001-syntax-representations.html#30276" class="Bound">b</a> <a id="30318" href="1001-syntax-representations.html#29996" class="Field Operator">◃</a> <a id="30320" href="1001-syntax-representations.html#30169" class="Field">∅</a><a id="30321" class="Symbol">)</a> <a id="30323" href="Data.Sum.Base.html#625" class="Datatype Operator">⊎</a> <a id="30325" href="1001-syntax-representations.html#29950" class="Field">Name</a> <a id="30330" href="1001-syntax-representations.html#30274" class="Bound">α</a>

      <a id="NamelyPainless.NomPa._#_"></a><a id="30339" href="1001-syntax-representations.html#30339" class="Field Operator">_#_</a>  <a id="30344" class="Symbol">:</a> <a id="30346" href="1001-syntax-representations.html#29977" class="Field">Binder</a> <a id="30353" class="Symbol">→</a> <a id="30355" href="1001-syntax-representations.html#29931" class="Field">World</a> <a id="30361" class="Symbol">→</a> <a id="30363" href="Agda.Primitive.html#388" class="Primitive">Set</a>
      <a id="NamelyPainless.NomPa._#∅"></a><a id="30373" href="1001-syntax-representations.html#30373" class="Field Operator">_#∅</a>  <a id="30378" class="Symbol">:</a> <a id="30380" class="Symbol">∀</a> <a id="30382" href="1001-syntax-representations.html#30382" class="Bound">b</a> <a id="30384" class="Symbol">→</a> <a id="30386" href="1001-syntax-representations.html#30382" class="Bound">b</a> <a id="30388" href="1001-syntax-representations.html#30339" class="Field Operator">#</a> <a id="30390" href="1001-syntax-representations.html#30169" class="Field">∅</a>
      <a id="NamelyPainless.NomPa.suc#"></a><a id="30398" href="1001-syntax-representations.html#30398" class="Field">suc#</a> <a id="30403" class="Symbol">:</a> <a id="30405" class="Symbol">∀</a> <a id="30407" class="Symbol">{</a><a id="30408" href="1001-syntax-representations.html#30408" class="Bound">α</a> <a id="30410" href="1001-syntax-representations.html#30410" class="Bound">b</a><a id="30411" class="Symbol">}</a> <a id="30413" class="Symbol">→</a> <a id="30415" href="1001-syntax-representations.html#30410" class="Bound">b</a> <a id="30417" href="1001-syntax-representations.html#30339" class="Field Operator">#</a> <a id="30419" href="1001-syntax-representations.html#30408" class="Bound">α</a> <a id="30421" class="Symbol">→</a> <a id="30423" class="Symbol">(</a><a id="30424" href="1001-syntax-representations.html#30057" class="Field">sucᴮ</a> <a id="30429" href="1001-syntax-representations.html#30410" class="Bound">b</a><a id="30430" class="Symbol">)</a> <a id="30432" href="1001-syntax-representations.html#30339" class="Field Operator">#</a> <a id="30434" class="Symbol">(</a><a id="30435" href="1001-syntax-representations.html#30410" class="Bound">b</a> <a id="30437" href="1001-syntax-representations.html#29996" class="Field Operator">◃</a> <a id="30439" href="1001-syntax-representations.html#30408" class="Bound">α</a><a id="30440" class="Symbol">)</a>

      <a id="NamelyPainless.NomPa._⊆_"></a><a id="30449" href="1001-syntax-representations.html#30449" class="Field Operator">_⊆_</a>     <a id="30457" class="Symbol">:</a> <a id="30459" href="1001-syntax-representations.html#29931" class="Field">World</a> <a id="30465" class="Symbol">→</a> <a id="30467" href="1001-syntax-representations.html#29931" class="Field">World</a> <a id="30473" class="Symbol">→</a> <a id="30475" href="Agda.Primitive.html#388" class="Primitive">Set</a>
      <a id="NamelyPainless.NomPa.coerceᴺ"></a><a id="30485" href="1001-syntax-representations.html#30485" class="Field">coerceᴺ</a> <a id="30493" class="Symbol">:</a> <a id="30495" class="Symbol">∀</a> <a id="30497" class="Symbol">{</a><a id="30498" href="1001-syntax-representations.html#30498" class="Bound">α</a> <a id="30500" href="1001-syntax-representations.html#30500" class="Bound">b</a><a id="30501" class="Symbol">}</a> <a id="30503" class="Symbol">→</a> <a id="30505" href="1001-syntax-representations.html#30498" class="Bound">α</a> <a id="30507" href="1001-syntax-representations.html#30449" class="Field Operator">⊆</a> <a id="30509" href="1001-syntax-representations.html#30500" class="Bound">b</a> <a id="30511" class="Symbol">→</a> <a id="30513" href="1001-syntax-representations.html#29950" class="Field">Name</a> <a id="30518" href="1001-syntax-representations.html#30498" class="Bound">α</a> <a id="30520" class="Symbol">→</a> <a id="30522" href="1001-syntax-representations.html#29950" class="Field">Name</a> <a id="30527" href="1001-syntax-representations.html#30500" class="Bound">b</a>
      <a id="NamelyPainless.NomPa.⊆-refl"></a><a id="30535" href="1001-syntax-representations.html#30535" class="Field">⊆-refl</a>  <a id="30543" class="Symbol">:</a> <a id="30545" href="Relation.Binary.Definitions.html#1355" class="Function">Reflexive</a> <a id="30555" href="1001-syntax-representations.html#30449" class="Field Operator">_⊆_</a>
      <a id="NamelyPainless.NomPa.⊆-trans"></a><a id="30565" href="1001-syntax-representations.html#30565" class="Field">⊆-trans</a> <a id="30573" class="Symbol">:</a> <a id="30575" href="Relation.Binary.Definitions.html#2030" class="Function">Transitive</a> <a id="30586" href="1001-syntax-representations.html#30449" class="Field Operator">_⊆_</a>
      <a id="NamelyPainless.NomPa.⊆-∅"></a><a id="30596" href="1001-syntax-representations.html#30596" class="Field">⊆-∅</a>     <a id="30604" class="Symbol">:</a> <a id="30606" class="Symbol">∀</a> <a id="30608" class="Symbol">{</a><a id="30609" href="1001-syntax-representations.html#30609" class="Bound">α</a><a id="30610" class="Symbol">}</a> <a id="30612" class="Symbol">→</a> <a id="30614" href="1001-syntax-representations.html#30169" class="Field">∅</a> <a id="30616" href="1001-syntax-representations.html#30449" class="Field Operator">⊆</a> <a id="30618" href="1001-syntax-representations.html#30609" class="Bound">α</a>
      <a id="NamelyPainless.NomPa.⊆-◃"></a><a id="30626" href="1001-syntax-representations.html#30626" class="Field">⊆-◃</a>     <a id="30634" class="Symbol">:</a> <a id="30636" class="Symbol">∀</a> <a id="30638" class="Symbol">{</a><a id="30639" href="1001-syntax-representations.html#30639" class="Bound">α</a> <a id="30641" href="1001-syntax-representations.html#30641" class="Bound">β</a><a id="30642" class="Symbol">}</a> <a id="30644" href="1001-syntax-representations.html#30644" class="Bound">b</a> <a id="30646" class="Symbol">→</a> <a id="30648" href="1001-syntax-representations.html#30639" class="Bound">α</a> <a id="30650" href="1001-syntax-representations.html#30449" class="Field Operator">⊆</a> <a id="30652" href="1001-syntax-representations.html#30641" class="Bound">β</a> <a id="30654" class="Symbol">→</a> <a id="30656" class="Symbol">(</a><a id="30657" href="1001-syntax-representations.html#30644" class="Bound">b</a> <a id="30659" href="1001-syntax-representations.html#29996" class="Field Operator">◃</a> <a id="30661" href="1001-syntax-representations.html#30639" class="Bound">α</a><a id="30662" class="Symbol">)</a> <a id="30664" href="1001-syntax-representations.html#30449" class="Field Operator">⊆</a> <a id="30666" class="Symbol">(</a><a id="30667" href="1001-syntax-representations.html#30644" class="Bound">b</a> <a id="30669" href="1001-syntax-representations.html#29996" class="Field Operator">◃</a> <a id="30671" href="1001-syntax-representations.html#30641" class="Bound">β</a><a id="30672" class="Symbol">)</a>
      <a id="NamelyPainless.NomPa.⊆-#"></a><a id="30680" href="1001-syntax-representations.html#30680" class="Field">⊆-#</a>     <a id="30688" class="Symbol">:</a> <a id="30690" class="Symbol">∀</a> <a id="30692" class="Symbol">{</a><a id="30693" href="1001-syntax-representations.html#30693" class="Bound">α</a> <a id="30695" href="1001-syntax-representations.html#30695" class="Bound">b</a><a id="30696" class="Symbol">}</a> <a id="30698" class="Symbol">→</a> <a id="30700" href="1001-syntax-representations.html#30695" class="Bound">b</a> <a id="30702" href="1001-syntax-representations.html#30339" class="Field Operator">#</a> <a id="30704" href="1001-syntax-representations.html#30693" class="Bound">α</a> <a id="30706" class="Symbol">→</a> <a id="30708" href="1001-syntax-representations.html#30693" class="Bound">α</a> <a id="30710" href="1001-syntax-representations.html#30449" class="Field Operator">⊆</a> <a id="30712" class="Symbol">(</a><a id="30713" href="1001-syntax-representations.html#30695" class="Bound">b</a> <a id="30715" href="1001-syntax-representations.html#29996" class="Field Operator">◃</a> <a id="30717" href="1001-syntax-representations.html#30693" class="Bound">α</a><a id="30718" class="Symbol">)</a>

  <a id="30723" class="Keyword">open</a> <a id="30728" href="1001-syntax-representations.html#29895" class="Module">NomPa</a> <a id="30734" class="Symbol">{{...}}</a>
</pre>
<p>Note that names are bound to a specific world, so there is no way to
compare names from different worlds.</p>
<pre class="Agda">  <a id="30860" class="Keyword">module</a> <a id="NamelyPainless.Syntax"></a><a id="30867" href="1001-syntax-representations.html#30867" class="Module">Syntax</a> <a id="30874" class="Symbol">{{</a><a id="30876" href="1001-syntax-representations.html#30876" class="Bound">_</a> <a id="30878" class="Symbol">:</a> <a id="30880" href="1001-syntax-representations.html#29895" class="Record">NomPa</a><a id="30885" class="Symbol">}}</a> <a id="30888" class="Keyword">where</a>

    <a id="30899" class="Keyword">data</a> <a id="NamelyPainless.Syntax.Term"></a><a id="30904" href="1001-syntax-representations.html#30904" class="Datatype">Term</a> <a id="30909" class="Symbol">(</a><a id="30910" href="1001-syntax-representations.html#30910" class="Bound">w</a> <a id="30912" class="Symbol">:</a> <a id="30914" href="1001-syntax-representations.html#29931" class="Field">World</a><a id="30919" class="Symbol">)</a> <a id="30921" class="Symbol">:</a> <a id="30923" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="30927" class="Keyword">where</a>
      <a id="NamelyPainless.Syntax.Term.var"></a><a id="30939" href="1001-syntax-representations.html#30939" class="InductiveConstructor">var</a> <a id="30943" class="Symbol">:</a> <a id="30945" href="1001-syntax-representations.html#29950" class="Field">Name</a> <a id="30950" href="1001-syntax-representations.html#30910" class="Bound">w</a> <a id="30952" class="Symbol">→</a> <a id="30954" href="1001-syntax-representations.html#30904" class="Datatype">Term</a> <a id="30959" href="1001-syntax-representations.html#30910" class="Bound">w</a>
      <a id="NamelyPainless.Syntax.Term.lam"></a><a id="30967" href="1001-syntax-representations.html#30967" class="InductiveConstructor">lam</a> <a id="30971" class="Symbol">:</a> <a id="30973" class="Symbol">(</a><a id="30974" href="1001-syntax-representations.html#30974" class="Bound">b</a> <a id="30976" class="Symbol">:</a> <a id="30978" href="1001-syntax-representations.html#29977" class="Field">Binder</a><a id="30984" class="Symbol">)</a> <a id="30986" class="Symbol">→</a> <a id="30988" href="1001-syntax-representations.html#30904" class="Datatype">Term</a> <a id="30993" class="Symbol">(</a><a id="30994" href="1001-syntax-representations.html#30974" class="Bound">b</a> <a id="30996" href="1001-syntax-representations.html#29996" class="Field Operator">◃</a> <a id="30998" href="1001-syntax-representations.html#30910" class="Bound">w</a><a id="30999" class="Symbol">)</a> <a id="31001" class="Symbol">→</a> <a id="31003" href="1001-syntax-representations.html#30904" class="Datatype">Term</a> <a id="31008" href="1001-syntax-representations.html#30910" class="Bound">w</a>
      <a id="NamelyPainless.Syntax.Term.app"></a><a id="31016" href="1001-syntax-representations.html#31016" class="InductiveConstructor">app</a> <a id="31020" class="Symbol">:</a> <a id="31022" href="1001-syntax-representations.html#30904" class="Datatype">Term</a> <a id="31027" href="1001-syntax-representations.html#30910" class="Bound">w</a> <a id="31029" class="Symbol">→</a> <a id="31031" href="1001-syntax-representations.html#30904" class="Datatype">Term</a> <a id="31036" href="1001-syntax-representations.html#30910" class="Bound">w</a> <a id="31038" class="Symbol">→</a> <a id="31040" href="1001-syntax-representations.html#30904" class="Datatype">Term</a> <a id="31045" href="1001-syntax-representations.html#30910" class="Bound">w</a>

    <a id="NamelyPainless.Syntax.ex"></a><a id="31052" href="1001-syntax-representations.html#31052" class="Function">ex</a> <a id="31055" class="Symbol">:</a> <a id="31057" href="1001-syntax-representations.html#30904" class="Datatype">Term</a> <a id="31062" href="1001-syntax-representations.html#30169" class="Field">∅</a>
    <a id="31068" href="1001-syntax-representations.html#31052" class="Function">ex</a> <a id="31071" class="Symbol">=</a> <a id="31073" href="1001-syntax-representations.html#30967" class="InductiveConstructor">lam</a> <a id="31077" href="1001-syntax-representations.html#31131" class="Function">fb</a> <a id="31080" class="Symbol">(</a><a id="31081" href="1001-syntax-representations.html#30967" class="InductiveConstructor">lam</a> <a id="31085" href="1001-syntax-representations.html#31134" class="Function">xb</a> <a id="31088" class="Symbol">(</a><a id="31089" href="1001-syntax-representations.html#31016" class="InductiveConstructor">app</a> <a id="31093" class="Symbol">(</a><a id="31094" href="1001-syntax-representations.html#30939" class="InductiveConstructor">var</a> <a id="31098" href="1001-syntax-representations.html#31262" class="Function">f</a><a id="31099" class="Symbol">)</a> <a id="31101" class="Symbol">(</a><a id="31102" href="1001-syntax-representations.html#30939" class="InductiveConstructor">var</a> <a id="31106" href="1001-syntax-representations.html#31307" class="Function">x</a><a id="31107" class="Symbol">)))</a>
      <a id="31117" class="Keyword">where</a>
        <a id="31131" href="1001-syntax-representations.html#31131" class="Function">fb</a> <a id="31134" href="1001-syntax-representations.html#31134" class="Function">xb</a> <a id="31137" class="Symbol">:</a> <a id="31139" href="1001-syntax-representations.html#29977" class="Field">Binder</a>
        <a id="31154" href="1001-syntax-representations.html#31131" class="Function">fb</a> <a id="31157" class="Symbol">=</a> <a id="31159" href="1001-syntax-representations.html#30035" class="Field">zeroᴮ</a>
        <a id="31173" href="1001-syntax-representations.html#31134" class="Function">xb</a> <a id="31176" class="Symbol">=</a> <a id="31178" href="1001-syntax-representations.html#30057" class="Field">sucᴮ</a> <a id="31183" href="1001-syntax-representations.html#30035" class="Field">zeroᴮ</a>

        <a id="31198" href="1001-syntax-representations.html#31198" class="Function">x-fresh</a> <a id="31206" class="Symbol">:</a> <a id="31208" href="1001-syntax-representations.html#31134" class="Function">xb</a> <a id="31211" href="1001-syntax-representations.html#30339" class="Field Operator">#</a> <a id="31213" class="Symbol">(</a><a id="31214" href="1001-syntax-representations.html#31131" class="Function">fb</a> <a id="31217" href="1001-syntax-representations.html#29996" class="Field Operator">◃</a> <a id="31219" href="1001-syntax-representations.html#30169" class="Field">∅</a><a id="31220" class="Symbol">)</a>
        <a id="31230" href="1001-syntax-representations.html#31198" class="Function">x-fresh</a> <a id="31238" class="Symbol">=</a> <a id="31240" href="1001-syntax-representations.html#30398" class="Field">suc#</a> <a id="31245" class="Symbol">(</a><a id="31246" href="1001-syntax-representations.html#31131" class="Function">fb</a> <a id="31249" href="1001-syntax-representations.html#30373" class="Field Operator">#∅</a><a id="31251" class="Symbol">)</a>

        <a id="31262" href="1001-syntax-representations.html#31262" class="Function">f</a> <a id="31264" class="Symbol">=</a> <a id="31266" href="1001-syntax-representations.html#30485" class="Field">coerceᴺ</a> <a id="31274" class="Symbol">(</a><a id="31275" href="1001-syntax-representations.html#30680" class="Field">⊆-#</a> <a id="31279" href="1001-syntax-representations.html#31198" class="Function">x-fresh</a><a id="31286" class="Symbol">)</a> <a id="31288" class="Symbol">(</a><a id="31289" href="1001-syntax-representations.html#30089" class="Field">nameᴮ</a> <a id="31295" href="1001-syntax-representations.html#31131" class="Function">fb</a><a id="31297" class="Symbol">)</a>
        <a id="31307" href="1001-syntax-representations.html#31307" class="Function">x</a> <a id="31309" class="Symbol">=</a> <a id="31311" href="1001-syntax-representations.html#30089" class="Field">nameᴮ</a> <a id="31317" href="1001-syntax-representations.html#31134" class="Function">xb</a>
</pre>
<p>Just as with <code>NaPa</code>, we get nice free theorems by being parametric in
the implementation of <code>NomPa</code>. For example, the parametricity theorem
for <code>_==ᴺ_</code> tells us that checking equality commutes with renaming,
hence α-equivalent terms are indeed treated equally.</p>
<p>As promised earlier, <code>NomPa</code> can be used to implement the interface we
previously used for nominal signatures:</p>
<pre class="Agda">  <a id="31705" class="Keyword">module</a> <a id="NamelyPainless.NominalNomPa"></a><a id="31712" href="1001-syntax-representations.html#31712" class="Module">NominalNomPa</a> <a id="31725" class="Symbol">{{</a><a id="31727" href="1001-syntax-representations.html#31727" class="Bound">_</a> <a id="31729" class="Symbol">:</a> <a id="31731" href="1001-syntax-representations.html#29895" class="Record">NomPa</a><a id="31736" class="Symbol">}}</a> <a id="31739" class="Keyword">where</a>
    <a id="NamelyPainless.NominalNomPa.Sort"></a><a id="31749" href="1001-syntax-representations.html#31749" class="Function">Sort</a> <a id="31754" class="Symbol">:</a> <a id="31756" href="Agda.Primitive.html#388" class="Primitive">Set₁</a>
    <a id="31765" href="1001-syntax-representations.html#31749" class="Function">Sort</a> <a id="31770" class="Symbol">=</a> <a id="31772" href="1001-syntax-representations.html#29931" class="Field">World</a> <a id="31778" class="Symbol">→</a> <a id="31780" href="Agda.Primitive.html#388" class="Primitive">Set</a>

    <a id="NamelyPainless.NominalNomPa.Atom"></a><a id="31789" href="1001-syntax-representations.html#31789" class="Function">Atom</a> <a id="31794" class="Symbol">:</a> <a id="31796" href="1001-syntax-representations.html#31749" class="Function">Sort</a>
    <a id="31805" href="1001-syntax-representations.html#31789" class="Function">Atom</a> <a id="31810" class="Symbol">=</a> <a id="31812" href="1001-syntax-representations.html#29950" class="Field">Name</a>

    <a id="NamelyPainless.NominalNomPa.1ᵉ"></a><a id="31822" href="1001-syntax-representations.html#31822" class="Function">1ᵉ</a> <a id="31825" class="Symbol">:</a> <a id="31827" href="1001-syntax-representations.html#31749" class="Function">Sort</a>
    <a id="31836" href="1001-syntax-representations.html#31822" class="Function">1ᵉ</a> <a id="31839" class="Symbol">_</a> <a id="31841" class="Symbol">=</a> <a id="31843" href="Agda.Builtin.Unit.html#175" class="Record">⊤</a>

    <a id="NamelyPainless.NominalNomPa._×ᵉ_"></a><a id="31850" href="1001-syntax-representations.html#31850" class="Function Operator">_×ᵉ_</a> <a id="31855" class="Symbol">:</a> <a id="31857" href="1001-syntax-representations.html#31749" class="Function">Sort</a> <a id="31862" class="Symbol">→</a> <a id="31864" href="1001-syntax-representations.html#31749" class="Function">Sort</a> <a id="31869" class="Symbol">→</a> <a id="31871" href="1001-syntax-representations.html#31749" class="Function">Sort</a>
    <a id="31880" class="Symbol">(</a><a id="31881" href="1001-syntax-representations.html#31881" class="Bound">E₁</a> <a id="31884" href="1001-syntax-representations.html#31850" class="Function Operator">×ᵉ</a> <a id="31887" href="1001-syntax-representations.html#31887" class="Bound">E₂</a><a id="31889" class="Symbol">)</a> <a id="31891" href="1001-syntax-representations.html#31891" class="Bound">a</a> <a id="31893" class="Symbol">=</a> <a id="31895" href="1001-syntax-representations.html#31881" class="Bound">E₁</a> <a id="31898" href="1001-syntax-representations.html#31891" class="Bound">a</a> <a id="31900" href="Data.Product.Base.html#1618" class="Function Operator">×</a> <a id="31902" href="1001-syntax-representations.html#31887" class="Bound">E₂</a> <a id="31905" href="1001-syntax-representations.html#31891" class="Bound">a</a>

    <a id="NamelyPainless.NominalNomPa._→ᵉ_"></a><a id="31912" href="1001-syntax-representations.html#31912" class="Function Operator">_→ᵉ_</a> <a id="31917" class="Symbol">:</a> <a id="31919" href="1001-syntax-representations.html#31749" class="Function">Sort</a> <a id="31924" class="Symbol">→</a> <a id="31926" href="1001-syntax-representations.html#31749" class="Function">Sort</a> <a id="31931" class="Symbol">→</a> <a id="31933" href="Agda.Primitive.html#388" class="Primitive">Set</a>
    <a id="31941" class="Symbol">(</a><a id="31942" href="1001-syntax-representations.html#31942" class="Bound">E₁</a> <a id="31945" href="1001-syntax-representations.html#31912" class="Function Operator">→ᵉ</a> <a id="31948" href="1001-syntax-representations.html#31948" class="Bound">E₂</a><a id="31950" class="Symbol">)</a> <a id="31952" class="Symbol">=</a> <a id="31954" class="Symbol">∀</a> <a id="31956" class="Symbol">{</a><a id="31957" href="1001-syntax-representations.html#31957" class="Bound">a</a><a id="31958" class="Symbol">}</a> <a id="31960" class="Symbol">→</a> <a id="31962" href="1001-syntax-representations.html#31942" class="Bound">E₁</a> <a id="31965" href="1001-syntax-representations.html#31957" class="Bound">a</a> <a id="31967" class="Symbol">→</a> <a id="31969" href="1001-syntax-representations.html#31948" class="Bound">E₂</a> <a id="31972" href="1001-syntax-representations.html#31957" class="Bound">a</a>

    <a id="NamelyPainless.NominalNomPa.Pred"></a><a id="31979" href="1001-syntax-representations.html#31979" class="Function">Pred</a>   <a id="31986" class="Symbol">:</a> <a id="31988" href="1001-syntax-representations.html#31749" class="Function">Sort</a> <a id="31993" class="Symbol">→</a> <a id="31995" href="Agda.Primitive.html#388" class="Primitive">Set₁</a>
    <a id="32004" href="1001-syntax-representations.html#31979" class="Function">Pred</a> <a id="32009" href="1001-syntax-representations.html#32009" class="Bound">E</a> <a id="32011" class="Symbol">=</a> <a id="32013" class="Symbol">∀</a> <a id="32015" class="Symbol">{</a><a id="32016" href="1001-syntax-representations.html#32016" class="Bound">a</a><a id="32017" class="Symbol">}</a> <a id="32019" class="Symbol">→</a> <a id="32021" href="1001-syntax-representations.html#32009" class="Bound">E</a> <a id="32023" href="1001-syntax-representations.html#32016" class="Bound">a</a> <a id="32025" class="Symbol">→</a> <a id="32027" href="Agda.Primitive.html#388" class="Primitive">Set</a>

    <a id="NamelyPainless.NominalNomPa.absᵉ"></a><a id="32036" href="1001-syntax-representations.html#32036" class="Function">absᵉ</a> <a id="32041" class="Symbol">:</a> <a id="32043" href="1001-syntax-representations.html#31749" class="Function">Sort</a> <a id="32048" class="Symbol">→</a> <a id="32050" href="1001-syntax-representations.html#31749" class="Function">Sort</a>
    <a id="32059" class="Symbol">(</a><a id="32060" href="1001-syntax-representations.html#32036" class="Function">absᵉ</a> <a id="32065" href="1001-syntax-representations.html#32065" class="Bound">E</a><a id="32066" class="Symbol">)</a> <a id="32068" href="1001-syntax-representations.html#32068" class="Bound">a</a> <a id="32070" class="Symbol">=</a> <a id="32072" href="Data.Product.Base.html#1244" class="Function">Σ[</a> <a id="32075" href="1001-syntax-representations.html#32075" class="Bound">b</a> <a id="32077" href="Data.Product.Base.html#1244" class="Function">∈</a> <a id="32079" href="1001-syntax-representations.html#29977" class="Field">Binder</a> <a id="32086" href="Data.Product.Base.html#1244" class="Function">]</a> <a id="32088" class="Symbol">(</a><a id="32089" href="1001-syntax-representations.html#32065" class="Bound">E</a> <a id="32091" class="Symbol">(</a><a id="32092" href="1001-syntax-representations.html#32075" class="Bound">b</a> <a id="32094" href="1001-syntax-representations.html#29996" class="Field Operator">◃</a> <a id="32096" href="1001-syntax-representations.html#32068" class="Bound">a</a><a id="32097" class="Symbol">))</a>

    <a id="32105" class="Keyword">data</a> <a id="NamelyPainless.NominalNomPa.Term"></a><a id="32110" href="1001-syntax-representations.html#32110" class="Datatype">Term</a> <a id="32115" class="Symbol">:</a> <a id="32117" href="1001-syntax-representations.html#31749" class="Function">Sort</a> <a id="32122" class="Keyword">where</a>
      <a id="NamelyPainless.NominalNomPa.Term.var"></a><a id="32134" href="1001-syntax-representations.html#32134" class="InductiveConstructor">var</a> <a id="32138" class="Symbol">:</a> <a id="32140" href="1001-syntax-representations.html#31789" class="Function">Atom</a> <a id="32145" href="1001-syntax-representations.html#31912" class="Function Operator">→ᵉ</a> <a id="32148" href="1001-syntax-representations.html#32110" class="Datatype">Term</a>
      <a id="NamelyPainless.NominalNomPa.Term.app"></a><a id="32159" href="1001-syntax-representations.html#32159" class="InductiveConstructor">app</a> <a id="32163" class="Symbol">:</a> <a id="32165" class="Symbol">(</a><a id="32166" href="1001-syntax-representations.html#32110" class="Datatype">Term</a> <a id="32171" href="1001-syntax-representations.html#31850" class="Function Operator">×ᵉ</a> <a id="32174" href="1001-syntax-representations.html#32110" class="Datatype">Term</a><a id="32178" class="Symbol">)</a> <a id="32180" href="1001-syntax-representations.html#31912" class="Function Operator">→ᵉ</a> <a id="32183" href="1001-syntax-representations.html#32110" class="Datatype">Term</a>
      <a id="NamelyPainless.NominalNomPa.Term.lam"></a><a id="32194" href="1001-syntax-representations.html#32194" class="InductiveConstructor">lam</a> <a id="32198" class="Symbol">:</a> <a id="32200" class="Symbol">(</a><a id="32201" href="1001-syntax-representations.html#32036" class="Function">absᵉ</a> <a id="32206" href="1001-syntax-representations.html#32110" class="Datatype">Term</a><a id="32210" class="Symbol">)</a> <a id="32212" href="1001-syntax-representations.html#31912" class="Function Operator">→ᵉ</a> <a id="32215" href="1001-syntax-representations.html#32110" class="Datatype">Term</a>
</pre>
<p>To check that this indeed results in a valid implementation of the
nominal interfaces we wrote down before, we can instantiate the
interfaces elegantly using the little-known <a href="https://agda.readthedocs.io/en/v2.6.2/language/record-types.html#building-records-from-modules">syntax for building
record values from
modules</a>.</p>
<pre class="Agda">  <a id="32553" class="Keyword">instance</a>
    <a id="NamelyPainless.nominal"></a><a id="32566" href="1001-syntax-representations.html#32566" class="Function">nominal</a> <a id="32574" class="Symbol">:</a> <a id="32576" class="Symbol">{{</a><a id="32578" href="1001-syntax-representations.html#32578" class="Bound">_</a> <a id="32580" class="Symbol">:</a> <a id="32582" href="1001-syntax-representations.html#29895" class="Record">NomPa</a><a id="32587" class="Symbol">}}</a> <a id="32590" class="Symbol">→</a> <a id="32592" href="1001-syntax-representations.html#10638" class="Record">Nominal.Nominal</a>
    <a id="32612" href="1001-syntax-representations.html#32566" class="Function">nominal</a> <a id="32620" class="Symbol">=</a> <a id="32622" class="Keyword">record</a> <a id="32629" class="Symbol">{</a> <a id="32631" href="1001-syntax-representations.html#31712" class="Module">NominalNomPa</a> <a id="32644" class="Symbol">}</a>

    <a id="NamelyPainless.nominalSyntax"></a><a id="32651" href="1001-syntax-representations.html#32651" class="Function">nominalSyntax</a> <a id="32665" class="Symbol">:</a> <a id="32667" class="Symbol">{{</a><a id="32669" href="1001-syntax-representations.html#32669" class="Bound">_</a> <a id="32671" class="Symbol">:</a> <a id="32673" href="1001-syntax-representations.html#29895" class="Record">NomPa</a><a id="32678" class="Symbol">}}</a> <a id="32681" class="Symbol">→</a> <a id="32683" href="1001-syntax-representations.html#11748" class="Record">Nominal.Syntax</a>
    <a id="32702" href="1001-syntax-representations.html#32651" class="Function">nominalSyntax</a> <a id="32716" class="Symbol">=</a> <a id="32718" class="Keyword">record</a> <a id="32725" class="Symbol">{</a> <a id="32727" href="1001-syntax-representations.html#31712" class="Module">NominalNomPa</a> <a id="32740" class="Symbol">}</a>
</pre>
<p><code>NomPa</code> has all the desirable properties of the various approaches
mentioned before, and can in fact be used to model these
approaches. So, is it the ultimate approach to modelling name binding
in Agda? Well, who knows, as once again I have not found anywhere it
is actually used, despite it being published in 2012. My main worry is
that the interface is quite large, and hence could be complicated to
use in practice.</p>
<h2 id="co-de-bruijn-indices">Co-de Bruijn indices</h2>
<p>Since the invention of <code>NomPa</code>, there has been at least one more
exciting development in the area of syntax with binders. In his <a href="https://arxiv.org/abs/1807.04085v1">2018
paper “Everybody’s Got To Be
Somewhere”</a>, Conor McBride
describes <em>co-deBruijn syntax</em>, a nameless representation where
binding information is encoded completely in the structure of the
terms rather than at the variables themselves. In particular, each
term constructor remembers which variables are actually used by which
subterm, removing the rest from the scope. When we arrive at a
variable, all the unused variables have been removed from the scope,
so there is but a single variable to pick.</p>
<p>Brutally stripping all the categorical concepts from the paper, one
might end up with the following simplified type of scope coverings:</p>
<pre class="Agda"><a id="34023" class="Keyword">module</a> <a id="CoDeBruijn"></a><a id="34030" href="1001-syntax-representations.html#34030" class="Module">CoDeBruijn</a> <a id="34041" class="Keyword">where</a>

  <a id="34050" class="Keyword">variable</a>
    <a id="34063" href="1001-syntax-representations.html#34063" class="Generalizable">k</a> <a id="34065" href="1001-syntax-representations.html#34065" class="Generalizable">l</a> <a id="34067" href="1001-syntax-representations.html#34067" class="Generalizable">m</a> <a id="34069" href="1001-syntax-representations.html#34069" class="Generalizable">n</a> <a id="34071" class="Symbol">:</a> <a id="34073" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a>

  <a id="34078" class="Keyword">data</a> <a id="CoDeBruijn.Cover"></a><a id="34083" href="1001-syntax-representations.html#34083" class="Datatype">Cover</a> <a id="34089" class="Symbol">:</a> <a id="34091" class="Symbol">(</a><a id="34092" href="1001-syntax-representations.html#34092" class="Bound">k</a> <a id="34094" href="1001-syntax-representations.html#34094" class="Bound">l</a> <a id="34096" href="1001-syntax-representations.html#34096" class="Bound">m</a> <a id="34098" class="Symbol">:</a> <a id="34100" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a><a id="34101" class="Symbol">)</a> <a id="34103" class="Symbol">→</a> <a id="34105" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="34109" class="Keyword">where</a>
    <a id="CoDeBruijn.Cover.done"></a><a id="34119" href="1001-syntax-representations.html#34119" class="InductiveConstructor">done</a>   <a id="34126" class="Symbol">:</a>               <a id="34142" href="1001-syntax-representations.html#34083" class="Datatype">Cover</a>      <a id="34153" class="Number">0</a>       <a id="34161" class="Number">0</a>       <a id="34169" class="Number">0</a>
    <a id="CoDeBruijn.Cover.left"></a><a id="34175" href="1001-syntax-representations.html#34175" class="InductiveConstructor">left</a>   <a id="34182" class="Symbol">:</a> <a id="34184" href="1001-syntax-representations.html#34083" class="Datatype">Cover</a> <a id="34190" href="1001-syntax-representations.html#34063" class="Generalizable">k</a> <a id="34192" href="1001-syntax-representations.html#34065" class="Generalizable">l</a> <a id="34194" href="1001-syntax-representations.html#34067" class="Generalizable">m</a> <a id="34196" class="Symbol">→</a> <a id="34198" href="1001-syntax-representations.html#34083" class="Datatype">Cover</a> <a id="34204" class="Symbol">(</a><a id="34205" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="34209" href="1001-syntax-representations.html#34063" class="Generalizable">k</a><a id="34210" class="Symbol">)</a>      <a id="34217" href="1001-syntax-representations.html#34065" class="Generalizable">l</a>  <a id="34220" class="Symbol">(</a><a id="34221" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="34225" href="1001-syntax-representations.html#34067" class="Generalizable">m</a><a id="34226" class="Symbol">)</a>
    <a id="CoDeBruijn.Cover.right"></a><a id="34232" href="1001-syntax-representations.html#34232" class="InductiveConstructor">right</a>  <a id="34239" class="Symbol">:</a> <a id="34241" href="1001-syntax-representations.html#34083" class="Datatype">Cover</a> <a id="34247" href="1001-syntax-representations.html#34063" class="Generalizable">k</a> <a id="34249" href="1001-syntax-representations.html#34065" class="Generalizable">l</a> <a id="34251" href="1001-syntax-representations.html#34067" class="Generalizable">m</a> <a id="34253" class="Symbol">→</a> <a id="34255" href="1001-syntax-representations.html#34083" class="Datatype">Cover</a>      <a id="34266" href="1001-syntax-representations.html#34063" class="Generalizable">k</a>  <a id="34269" class="Symbol">(</a><a id="34270" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="34274" href="1001-syntax-representations.html#34065" class="Generalizable">l</a><a id="34275" class="Symbol">)</a> <a id="34277" class="Symbol">(</a><a id="34278" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="34282" href="1001-syntax-representations.html#34067" class="Generalizable">m</a><a id="34283" class="Symbol">)</a>
    <a id="CoDeBruijn.Cover.both"></a><a id="34289" href="1001-syntax-representations.html#34289" class="InductiveConstructor">both</a>   <a id="34296" class="Symbol">:</a> <a id="34298" href="1001-syntax-representations.html#34083" class="Datatype">Cover</a> <a id="34304" href="1001-syntax-representations.html#34063" class="Generalizable">k</a> <a id="34306" href="1001-syntax-representations.html#34065" class="Generalizable">l</a> <a id="34308" href="1001-syntax-representations.html#34067" class="Generalizable">m</a> <a id="34310" class="Symbol">→</a> <a id="34312" href="1001-syntax-representations.html#34083" class="Datatype">Cover</a> <a id="34318" class="Symbol">(</a><a id="34319" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="34323" href="1001-syntax-representations.html#34063" class="Generalizable">k</a><a id="34324" class="Symbol">)</a> <a id="34326" class="Symbol">(</a><a id="34327" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="34331" href="1001-syntax-representations.html#34065" class="Generalizable">l</a><a id="34332" class="Symbol">)</a> <a id="34334" class="Symbol">(</a><a id="34335" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="34339" href="1001-syntax-representations.html#34067" class="Generalizable">m</a><a id="34340" class="Symbol">)</a>
</pre>
<p>An element of type <code>Cover k l m</code> says for each of <code>m</code> variables
whether they are used just in the <code>left</code> subterm, just in the <code>right</code>
subterm, or in <code>both</code> subterms. The left and right subterms thus
should have <code>k</code> and <code>l</code> variables in scope respectively. Crucially
there is no case for <code>neither</code>, hence the slogan “everybody’s got to
be somewhere”.</p>
<p>We can then define our well-scoped co-deBruijn syntax using <code>Cover</code>:</p>
<pre class="Agda">  <a id="34774" class="Keyword">data</a> <a id="CoDeBruijn.Term"></a><a id="34779" href="1001-syntax-representations.html#34779" class="Datatype">Term</a> <a id="34784" class="Symbol">:</a> <a id="34786" href="Agda.Builtin.Nat.html#203" class="Datatype">ℕ</a> <a id="34788" class="Symbol">→</a> <a id="34790" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="34794" class="Keyword">where</a>
    <a id="CoDeBruijn.Term.var"></a><a id="34804" href="1001-syntax-representations.html#34804" class="InductiveConstructor">var</a>  <a id="34809" class="Symbol">:</a> <a id="34811" href="1001-syntax-representations.html#34779" class="Datatype">Term</a> <a id="34816" class="Number">1</a>
    <a id="CoDeBruijn.Term.lam"></a><a id="34822" href="1001-syntax-representations.html#34822" class="InductiveConstructor">lam</a>  <a id="34827" class="Symbol">:</a> <a id="34829" href="1001-syntax-representations.html#34779" class="Datatype">Term</a> <a id="34834" class="Symbol">(</a><a id="34835" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="34839" href="1001-syntax-representations.html#34069" class="Generalizable">n</a><a id="34840" class="Symbol">)</a> <a id="34842" class="Symbol">→</a> <a id="34844" href="1001-syntax-representations.html#34779" class="Datatype">Term</a> <a id="34849" href="1001-syntax-representations.html#34069" class="Generalizable">n</a>
    <a id="CoDeBruijn.Term.lam'"></a><a id="34855" href="1001-syntax-representations.html#34855" class="InductiveConstructor">lam'</a> <a id="34860" class="Symbol">:</a> <a id="34862" href="1001-syntax-representations.html#34779" class="Datatype">Term</a> <a id="34867" href="1001-syntax-representations.html#34069" class="Generalizable">n</a> <a id="34869" class="Symbol">→</a> <a id="34871" href="1001-syntax-representations.html#34779" class="Datatype">Term</a> <a id="34876" href="1001-syntax-representations.html#34069" class="Generalizable">n</a>  <a id="34879" class="Comment">-- argument is not used</a>
    <a id="CoDeBruijn.Term.app"></a><a id="34907" href="1001-syntax-representations.html#34907" class="InductiveConstructor">app</a>  <a id="34912" class="Symbol">:</a> <a id="34914" href="1001-syntax-representations.html#34083" class="Datatype">Cover</a> <a id="34920" href="1001-syntax-representations.html#34063" class="Generalizable">k</a> <a id="34922" href="1001-syntax-representations.html#34065" class="Generalizable">l</a> <a id="34924" href="1001-syntax-representations.html#34067" class="Generalizable">m</a> <a id="34926" class="Symbol">→</a> <a id="34928" href="1001-syntax-representations.html#34779" class="Datatype">Term</a> <a id="34933" href="1001-syntax-representations.html#34063" class="Generalizable">k</a> <a id="34935" class="Symbol">→</a> <a id="34937" href="1001-syntax-representations.html#34779" class="Datatype">Term</a> <a id="34942" href="1001-syntax-representations.html#34065" class="Generalizable">l</a> <a id="34944" class="Symbol">→</a> <a id="34946" href="1001-syntax-representations.html#34779" class="Datatype">Term</a> <a id="34951" href="1001-syntax-representations.html#34067" class="Generalizable">m</a>

  <a id="CoDeBruijn.ex"></a><a id="34956" href="1001-syntax-representations.html#34956" class="Function">ex</a> <a id="34959" class="Symbol">:</a> <a id="34961" href="1001-syntax-representations.html#34779" class="Datatype">Term</a> <a id="34966" class="Number">0</a>
  <a id="34970" href="1001-syntax-representations.html#34956" class="Function">ex</a> <a id="34973" class="Symbol">=</a> <a id="34975" href="1001-syntax-representations.html#34822" class="InductiveConstructor">lam</a> <a id="34979" class="Comment">{-f-}</a> <a id="34985" class="Symbol">(</a>
         <a id="34996" href="1001-syntax-representations.html#34822" class="InductiveConstructor">lam</a> <a id="35000" class="Comment">{-x-}</a> <a id="35006" class="Symbol">(</a>
           <a id="35019" href="1001-syntax-representations.html#34907" class="InductiveConstructor">app</a> <a id="35023" class="Symbol">(</a><a id="35024" href="1001-syntax-representations.html#34232" class="InductiveConstructor">right</a> <a id="35030" class="Symbol">(</a><a id="35031" href="1001-syntax-representations.html#34175" class="InductiveConstructor">left</a> <a id="35036" href="1001-syntax-representations.html#34119" class="InductiveConstructor">done</a><a id="35040" class="Symbol">))</a>
               <a id="35058" class="Symbol">(</a><a id="35059" href="1001-syntax-representations.html#34804" class="InductiveConstructor">var</a> <a id="35063" class="Comment">{-f-}</a><a id="35068" class="Symbol">)</a> <a id="35070" class="Symbol">(</a><a id="35071" href="1001-syntax-representations.html#34804" class="InductiveConstructor">var</a> <a id="35075" class="Comment">{-x-}</a><a id="35080" class="Symbol">)</a>
         <a id="35091" class="Symbol">)</a>
       <a id="35100" class="Symbol">)</a>
</pre>
<p>There are two constructors for lambda abstraction: one for functions
that use their argument and one for functions that don’t (I’m sure
there’s a more elegant way to do this, but this works).</p>
<p>The great advantage of using co-deBruijn syntax is that scopes are
always maximally precise: there is never any need to strengthen a term
to get rid of an unused variable. On the flip side, co-deBruijn
syntax is even more unintuitive and difficult to understand for humans
than regular de Bruijn syntax. Quoting the author: <em>“Co-de-Bruijn
representation is even less suited to human comprehension than de
Bruijn syntax, but its informative precision makes it all the more
useful for machines. Dependency checking is direct, so syntactic forms
like vacuous functions or η-redexes are easy to spot.”</em></p>
<p>To make the syntax more comprehensible to mere mortals, we can do the
same we did for de Bruijn syntax and represent scopes as lists of
names:</p>
<pre class="Agda"><a id="36049" class="Keyword">module</a> <a id="NamedCoDeBruijn"></a><a id="36056" href="1001-syntax-representations.html#36056" class="Module">NamedCoDeBruijn</a> <a id="36072" class="Keyword">where</a>

  <a id="NamedCoDeBruijn.Name"></a><a id="36081" href="1001-syntax-representations.html#36081" class="Function">Name</a>  <a id="36087" class="Symbol">=</a> <a id="36089" href="Agda.Builtin.String.html#335" class="Postulate">String</a>
  <a id="NamedCoDeBruijn.Scope"></a><a id="36098" href="1001-syntax-representations.html#36098" class="Function">Scope</a> <a id="36104" class="Symbol">=</a> <a id="36106" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="36111" href="1001-syntax-representations.html#36081" class="Function">Name</a>

  <a id="36119" class="Keyword">variable</a>
    <a id="36132" href="1001-syntax-representations.html#36132" class="Generalizable">x</a> <a id="36134" href="1001-syntax-representations.html#36134" class="Generalizable">y</a> <a id="36136" href="1001-syntax-representations.html#36136" class="Generalizable">z</a>    <a id="36141" class="Symbol">:</a> <a id="36143" href="1001-syntax-representations.html#36081" class="Function">Name</a>
    <a id="36152" href="1001-syntax-representations.html#36152" class="Generalizable">xs</a> <a id="36155" href="1001-syntax-representations.html#36155" class="Generalizable">ys</a> <a id="36158" href="1001-syntax-representations.html#36158" class="Generalizable">zs</a> <a id="36161" class="Symbol">:</a> <a id="36163" href="1001-syntax-representations.html#36098" class="Function">Scope</a>

  <a id="36172" class="Keyword">data</a> <a id="NamedCoDeBruijn.Cover"></a><a id="36177" href="1001-syntax-representations.html#36177" class="Datatype">Cover</a> <a id="36183" class="Symbol">:</a> <a id="36185" class="Symbol">(</a><a id="36186" href="1001-syntax-representations.html#36186" class="Bound">xs</a> <a id="36189" href="1001-syntax-representations.html#36189" class="Bound">ys</a> <a id="36192" href="1001-syntax-representations.html#36192" class="Bound">zs</a> <a id="36195" class="Symbol">:</a> <a id="36197" href="1001-syntax-representations.html#36098" class="Function">Scope</a><a id="36202" class="Symbol">)</a> <a id="36204" class="Symbol">→</a> <a id="36206" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="36210" class="Keyword">where</a>
    <a id="NamedCoDeBruijn.Cover.done"></a><a id="36220" href="1001-syntax-representations.html#36220" class="InductiveConstructor">done</a>   <a id="36227" class="Symbol">:</a>                  <a id="36246" href="1001-syntax-representations.html#36177" class="Datatype">Cover</a>      <a id="36257" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a>       <a id="36266" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a>       <a id="36275" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a>
    <a id="NamedCoDeBruijn.Cover.left"></a><a id="36282" href="1001-syntax-representations.html#36282" class="InductiveConstructor">left</a>   <a id="36289" class="Symbol">:</a> <a id="36291" href="1001-syntax-representations.html#36177" class="Datatype">Cover</a> <a id="36297" href="1001-syntax-representations.html#36152" class="Generalizable">xs</a> <a id="36300" href="1001-syntax-representations.html#36155" class="Generalizable">ys</a> <a id="36303" href="1001-syntax-representations.html#36158" class="Generalizable">zs</a> <a id="36306" class="Symbol">→</a> <a id="36308" href="1001-syntax-representations.html#36177" class="Datatype">Cover</a> <a id="36314" class="Symbol">(</a><a id="36315" href="1001-syntax-representations.html#36136" class="Generalizable">z</a> <a id="36317" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="36319" href="1001-syntax-representations.html#36152" class="Generalizable">xs</a><a id="36321" class="Symbol">)</a>      <a id="36328" href="1001-syntax-representations.html#36155" class="Generalizable">ys</a>  <a id="36332" class="Symbol">(</a><a id="36333" href="1001-syntax-representations.html#36136" class="Generalizable">z</a> <a id="36335" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="36337" href="1001-syntax-representations.html#36158" class="Generalizable">zs</a><a id="36339" class="Symbol">)</a>
    <a id="NamedCoDeBruijn.Cover.right"></a><a id="36345" href="1001-syntax-representations.html#36345" class="InductiveConstructor">right</a>  <a id="36352" class="Symbol">:</a> <a id="36354" href="1001-syntax-representations.html#36177" class="Datatype">Cover</a> <a id="36360" href="1001-syntax-representations.html#36152" class="Generalizable">xs</a> <a id="36363" href="1001-syntax-representations.html#36155" class="Generalizable">ys</a> <a id="36366" href="1001-syntax-representations.html#36158" class="Generalizable">zs</a> <a id="36369" class="Symbol">→</a> <a id="36371" href="1001-syntax-representations.html#36177" class="Datatype">Cover</a>      <a id="36382" href="1001-syntax-representations.html#36152" class="Generalizable">xs</a>  <a id="36386" class="Symbol">(</a><a id="36387" href="1001-syntax-representations.html#36136" class="Generalizable">z</a> <a id="36389" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="36391" href="1001-syntax-representations.html#36155" class="Generalizable">ys</a><a id="36393" class="Symbol">)</a> <a id="36395" class="Symbol">(</a><a id="36396" href="1001-syntax-representations.html#36136" class="Generalizable">z</a> <a id="36398" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="36400" href="1001-syntax-representations.html#36158" class="Generalizable">zs</a><a id="36402" class="Symbol">)</a>
    <a id="NamedCoDeBruijn.Cover.both"></a><a id="36408" href="1001-syntax-representations.html#36408" class="InductiveConstructor">both</a>   <a id="36415" class="Symbol">:</a> <a id="36417" href="1001-syntax-representations.html#36177" class="Datatype">Cover</a> <a id="36423" href="1001-syntax-representations.html#36152" class="Generalizable">xs</a> <a id="36426" href="1001-syntax-representations.html#36155" class="Generalizable">ys</a> <a id="36429" href="1001-syntax-representations.html#36158" class="Generalizable">zs</a> <a id="36432" class="Symbol">→</a> <a id="36434" href="1001-syntax-representations.html#36177" class="Datatype">Cover</a> <a id="36440" class="Symbol">(</a><a id="36441" href="1001-syntax-representations.html#36136" class="Generalizable">z</a> <a id="36443" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="36445" href="1001-syntax-representations.html#36152" class="Generalizable">xs</a><a id="36447" class="Symbol">)</a> <a id="36449" class="Symbol">(</a><a id="36450" href="1001-syntax-representations.html#36136" class="Generalizable">z</a> <a id="36452" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="36454" href="1001-syntax-representations.html#36155" class="Generalizable">ys</a><a id="36456" class="Symbol">)</a> <a id="36458" class="Symbol">(</a><a id="36459" href="1001-syntax-representations.html#36136" class="Generalizable">z</a> <a id="36461" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="36463" href="1001-syntax-representations.html#36158" class="Generalizable">zs</a><a id="36465" class="Symbol">)</a>
</pre>
<p>Doing this leads to a syntax that is much more pleasant to use (at
least if we pick unique names):</p>
<pre class="Agda">  <a id="36578" class="Keyword">data</a> <a id="NamedCoDeBruijn.Term"></a><a id="36583" href="1001-syntax-representations.html#36583" class="Datatype">Term</a> <a id="36588" class="Symbol">:</a> <a id="36590" href="1001-syntax-representations.html#36098" class="Function">Scope</a> <a id="36596" class="Symbol">→</a> <a id="36598" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="36602" class="Keyword">where</a>
    <a id="NamedCoDeBruijn.Term.var"></a><a id="36612" href="1001-syntax-representations.html#36612" class="InductiveConstructor">var</a>  <a id="36617" class="Symbol">:</a> <a id="36619" class="Symbol">(</a><a id="36620" href="1001-syntax-representations.html#36620" class="Bound">x</a> <a id="36622" class="Symbol">:</a> <a id="36624" href="1001-syntax-representations.html#36081" class="Function">Name</a><a id="36628" class="Symbol">)</a> <a id="36630" class="Symbol">→</a> <a id="36632" href="1001-syntax-representations.html#36583" class="Datatype">Term</a> <a id="36637" class="Symbol">(</a><a id="36638" href="1001-syntax-representations.html#36620" class="Bound">x</a> <a id="36640" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="36642" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a><a id="36644" class="Symbol">)</a>
    <a id="NamedCoDeBruijn.Term.lam"></a><a id="36650" href="1001-syntax-representations.html#36650" class="InductiveConstructor">lam</a>  <a id="36655" class="Symbol">:</a> <a id="36657" class="Symbol">(</a><a id="36658" href="1001-syntax-representations.html#36658" class="Bound">x</a> <a id="36660" class="Symbol">:</a> <a id="36662" href="1001-syntax-representations.html#36081" class="Function">Name</a><a id="36666" class="Symbol">)</a> <a id="36668" class="Symbol">→</a> <a id="36670" href="1001-syntax-representations.html#36583" class="Datatype">Term</a> <a id="36675" class="Symbol">(</a><a id="36676" href="1001-syntax-representations.html#36658" class="Bound">x</a> <a id="36678" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="36680" href="1001-syntax-representations.html#36152" class="Generalizable">xs</a><a id="36682" class="Symbol">)</a> <a id="36684" class="Symbol">→</a> <a id="36686" href="1001-syntax-representations.html#36583" class="Datatype">Term</a> <a id="36691" href="1001-syntax-representations.html#36152" class="Generalizable">xs</a>
    <a id="NamedCoDeBruijn.Term.lam'"></a><a id="36698" href="1001-syntax-representations.html#36698" class="InductiveConstructor">lam'</a> <a id="36703" class="Symbol">:</a> <a id="36705" class="Symbol">(</a><a id="36706" href="1001-syntax-representations.html#36706" class="Bound">x</a> <a id="36708" class="Symbol">:</a> <a id="36710" href="1001-syntax-representations.html#36081" class="Function">Name</a><a id="36714" class="Symbol">)</a> <a id="36716" class="Symbol">→</a> <a id="36718" href="1001-syntax-representations.html#36583" class="Datatype">Term</a> <a id="36723" href="1001-syntax-representations.html#36152" class="Generalizable">xs</a> <a id="36726" class="Symbol">→</a> <a id="36728" href="1001-syntax-representations.html#36583" class="Datatype">Term</a> <a id="36733" href="1001-syntax-representations.html#36152" class="Generalizable">xs</a>
    <a id="NamedCoDeBruijn.Term.app"></a><a id="36740" href="1001-syntax-representations.html#36740" class="InductiveConstructor">app</a>  <a id="36745" class="Symbol">:</a> <a id="36747" href="1001-syntax-representations.html#36177" class="Datatype">Cover</a> <a id="36753" href="1001-syntax-representations.html#36152" class="Generalizable">xs</a> <a id="36756" href="1001-syntax-representations.html#36155" class="Generalizable">ys</a> <a id="36759" href="1001-syntax-representations.html#36158" class="Generalizable">zs</a> <a id="36762" class="Symbol">→</a> <a id="36764" href="1001-syntax-representations.html#36583" class="Datatype">Term</a> <a id="36769" href="1001-syntax-representations.html#36152" class="Generalizable">xs</a> <a id="36772" class="Symbol">→</a> <a id="36774" href="1001-syntax-representations.html#36583" class="Datatype">Term</a> <a id="36779" href="1001-syntax-representations.html#36155" class="Generalizable">ys</a> <a id="36782" class="Symbol">→</a> <a id="36784" href="1001-syntax-representations.html#36583" class="Datatype">Term</a> <a id="36789" href="1001-syntax-representations.html#36158" class="Generalizable">zs</a>

  <a id="NamedCoDeBruijn.ex"></a><a id="36795" href="1001-syntax-representations.html#36795" class="Function">ex</a> <a id="36798" class="Symbol">:</a> <a id="36800" href="1001-syntax-representations.html#36583" class="Datatype">Term</a> <a id="36805" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a>
  <a id="36810" href="1001-syntax-representations.html#36795" class="Function">ex</a> <a id="36813" class="Symbol">=</a> <a id="36815" href="1001-syntax-representations.html#36650" class="InductiveConstructor">lam</a> <a id="36819" class="String">&quot;f&quot;</a> <a id="36823" class="Symbol">(</a>
         <a id="36834" href="1001-syntax-representations.html#36650" class="InductiveConstructor">lam</a> <a id="36838" class="String">&quot;x&quot;</a> <a id="36842" class="Symbol">(</a>
           <a id="36855" href="1001-syntax-representations.html#36740" class="InductiveConstructor">app</a> <a id="36859" class="Symbol">(</a><a id="36860" href="1001-syntax-representations.html#36345" class="InductiveConstructor">right</a> <a id="36866" class="Symbol">(</a><a id="36867" href="1001-syntax-representations.html#36282" class="InductiveConstructor">left</a> <a id="36872" href="1001-syntax-representations.html#36220" class="InductiveConstructor">done</a><a id="36876" class="Symbol">))</a>
               <a id="36894" class="Symbol">(</a><a id="36895" href="1001-syntax-representations.html#36612" class="InductiveConstructor">var</a> <a id="36899" class="String">&quot;f&quot;</a><a id="36902" class="Symbol">)</a> <a id="36904" class="Symbol">(</a><a id="36905" href="1001-syntax-representations.html#36612" class="InductiveConstructor">var</a> <a id="36909" class="String">&quot;x&quot;</a><a id="36912" class="Symbol">)</a>
         <a id="36923" class="Symbol">)</a>
       <a id="36932" class="Symbol">)</a>
</pre>
<p>The remaining ugliness is the <code>Cover</code> proof needed at each
application, however as before writing a macro that constructs these
automatically should not be difficult.</p>
<p>One could imagine generalizing this further and defining an abstract
interface like <code>NomPa</code> for working with co-deBruijn syntax. However,
this post is plenty long as it is, so I’ll leave that as an exercise
to the reader.</p>
<h1 id="overview-and-conclusion">Overview and conclusion</h1>
<p>The goal of this blog post was mainly to give an overview of the
various different approaches one could use when defining syntax with
binders in Agda. Below is a table summarizing with the approaches I
described, plus the benefits they provide to the programmer:</p>
<ul>
<li><p><strong>First-order representation</strong>: does the representation avoid the
use of meta-level functions as part of the data structure? If not,
it can be difficult or impossible to do things like checking
equality of terms or pretty-printing.</p></li>
<li><p><strong>Named variables</strong>: When I write down a piece of syntax, are
variables represented by their names or anonymously? This provides
some measure of readability by humans.</p></li>
<li><p><strong>Enforces α-equivalence</strong>: Does the representation enforce that two
α-equivalent terms are treated in the same way?</p></li>
<li><p><strong>Enforces well-scopedness</strong>: Does the representation enforce that
names can only be used when they are in fact in scope?</p></li>
<li><p><strong>No mixing of scopes</strong>: Does the representation enforce that a name
that comes from one scope is not used in a different scope?</p></li>
<li><p><strong>Abstract interface</strong>: Does the representation provide an abstract
interface that can be instantiated in different ways?</p></li>
<li><p><strong>Enforces freshness</strong>: Does the representation allow us to require
that names must be fresh at certain positions in the syntax?</p></li>
<li><p><strong>Strengthening is no-op</strong>: Can we remove unused names from the
scope without having to change the syntax?</p></li>
</ul>
<p>So here’s the full table:</p>
<table>
<thead>
<tr class="header">
<th></th>
<th style="text-align: center;">Bare</th>
<th style="text-align: center;">DeBr</th>
<th style="text-align: center;">LoNa</th>
<th style="text-align: center;">Nom</th>
<th style="text-align: center;">PHOAS</th>
<th style="text-align: center;">WTDB</th>
<th style="text-align: center;">WTDB+N</th>
<th style="text-align: center;">FreshL</th>
<th style="text-align: center;">NaPa</th>
<th style="text-align: center;">ASG</th>
<th style="text-align: center;">NomPa</th>
<th style="text-align: center;">CoDB</th>
<th style="text-align: center;">CoDB+N</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>First-order representation</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
</tr>
<tr class="even">
<td>Named variables</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
</tr>
<tr class="odd">
<td>Enforces α-equivalence</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
</tr>
<tr class="even">
<td>Enforces well-scopedness</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
</tr>
<tr class="odd">
<td>No mixing of scopes</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
</tr>
<tr class="even">
<td>Enforces freshness</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
</tr>
<tr class="odd">
<td>Abstract interface</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
</tr>
<tr class="even">
<td>Strengthening is no-op</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;"></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
</tr>
</tbody>
</table>
<p>As a next step, it would be interesting to perform a comparison of
(some of) these approaches on a practical application. My idea would
be to define variants of the <a href="https://agda.readthedocs.io/en/latest/language/reflection.html#terms">reflection syntax of
Agda</a>
using a few different approaches (it currently uses de Bruijn syntax),
and test which one makes macros easier to write. This would also
allow a proper performance evaluation to see the effect of the
variable representation on the performance of syntax transformations.
And of course my (not so) secret goal is to eventually use one of
these representations for the definition of <a href="https://jesper.sikanda.be/posts/veni-announcement.html">Agda
Core</a>!</p>
<p>I’m very curious to hear your thoughts about this overview, whether I
have missed any important criteria in this comparison, whether I have
seriously misrepresented some of the approaches, whether I skipped one
completely. In any of these cases, please let me know via
<a href="https://agda.zulipchat.com">Zulip</a>,
<a href="https://twitter.com/agdakx">Twitter</a>, or
<a href="mailto:jesper@sikanda.be">mail</a>.</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Thu, 04 Nov 2021 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/1001-syntax-representations.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>WITS '21: First International Workshop on the Implementation of Type Systems</title>
    <link>https://jesper.sikanda.be/posts/wits-announcement.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - WITS '21: First International Workshop on the Implementation of Type Systems</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>WITS '21: First International Workshop on the Implementation of Type Systems</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on October 15, 2021
    </p>
    <p>I am organizing the First International Workshop on the Implementation
of Type Systems together with the one and only Richard Eisenberg. The
goal of this workshop is to bring together the implementors of a
variety of languages with advanced type systems. The main focus is on
the practical issues that come up in the implementation of these
systems, rather than the theoretical frameworks that underlie them. In
particular, we want to encourage exchanging ideas between the
communities around specific systems that would otherwise be accessible
to only a very select group.</p>
<p>The workshop will be held on January 22, 2022, in Philadelphia, PA,
United States, co-located with POPL. If you are working on the
implementation of a cool type system or interested to do so, please
consider submitting a proposal for a talk or a discussion at the
workshop.</p>
<p>For more information, please visit <a href="https://popl22.sigplan.org/home/wits-2022">our official
webpage</a>.</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Fri, 15 Oct 2021 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/wits-announcement.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>EuroProofNet: the European research network on digital proofs</title>
    <link>https://jesper.sikanda.be/posts/europroofnet.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - EuroProofNet: the European research network on digital proofs</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>EuroProofNet: the European research network on digital proofs</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on October 15, 2021
    </p>
    <p>EuroProofNet is the European research network on digital proofs. It
aims at boosting the interoperability and usability of proof
systems. It gathers 190 researchers on proof systems and formal
proofs, from 30 different countries.</p>
<p>Together with Catherine Dubois, I am leading the working group on
Tools for Proof Systems Interoperability. In particular, we will
coordinate developers of various proof systems (dependently typed ones
like Coq and Agda, but also others such as Isabelle/HOL, Event-B, and
TLA+) who want to translate proofs between these systems using the
<a href="https://deducteam.github.io/">Dedukti</a> logical framework as an
intermediate language.</p>
<p>You can find more information about this and the other working groups
on <a href="https://europroofnet.github.io/wg1">our website</a> (still
work-in-progress at the moment of writing). If you are interested to
work on this, please consider applying to join the working group
and/or get in touch!</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Fri, 15 Oct 2021 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/europroofnet.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>The Taming of the Rew</title>
    <link>https://jesper.sikanda.be/posts/taming-of-the-rew.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - The Taming of the Rew</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>The Taming of the Rew</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on January  7, 2021
    </p>
    <p>Back in 2019, I wrote <a href="hack-your-type-theory.html">two</a> <a href="rewriting-type-theory.html">posts</a> about user-definable rewrite rules in Agda (which have since then been rewritten into <a href="https://drops.dagstuhl.de/opus/volltexte/2020/13066/">a TYPES paper</a>)
and promised a third one about how to make rewrite rules <em>safe</em> to use (or at least <em>safer</em>). At the time, I was hard at work together with Théo Winterhalter and Nicolas Tabareau from the Galinette group in Nantes to tackle the problem of checking safety of rewrite rules, and in particular trying to ensure subject reduction holds. Little did we know that the problem
would turn out a lot trickier than I expected, so much that we did not make it in time for the ICFP 2020 deadline.</p>
<p>However, now I am very glad to say our paper <strong>The Taming of the Rew: A Type Theory With Computational Assumptions</strong> is to appear at POPL 2021 on January 20, in less than two weeks time.
In fact, you can already read <a href="https://hal.archives-ouvertes.fr/hal-02901011">the paper</a>
as well as watch <a href="https://app.clowdr.org/conference/popl2021/item/71f31203-4790-422e-bd59-1dc4a2220f1a">our talks</a> (one 5 minute version by Théo and one 30 minute version by Théo and me). So in case you were still waiting for that post, go ahead and watch the talks or read the paper. And remember, when you do <code>--rewriting</code> in Agda don’t forget to also <code>--confluence-check</code>!</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Thu, 07 Jan 2021 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/taming-of-the-rew.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>Mijn uitdaging voor jou in 2021: Doe zoveel goed als je kan</title>
    <link>https://jesper.sikanda.be/posts/uitdaging-voor-2021.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Mijn uitdaging voor jou in 2021: Doe zoveel goed als je kan</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Mijn uitdaging voor jou in 2021: Doe zoveel goed als je kan</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on December 24, 2020
    </p>
    <p><em>(This post is also available in <a href="challenge-for-2021.html">English</a>.)</em></p>
<p>Deze post is iets heel anders dan wat ik hier normaal schrijf. Deze keer wil ik het hebben over een idee waarvan ik echt geloof dat het belangrijk is maar waar nog veel te weinig mensen van hebben gehoord, en ik dus graag met jullie wil delen. Ik heb op het einde ook een uitdaging voor je voor in 2021.</p>
<p>Als je een beetje op mij lijkt, heb je misschien ook dit terugkerend probleem: je leest, kijkt, of luistert naar het nieuws en leert over alle verschikkelijke dingen die gebeuren, zoals ziektes, armoede, de klimaatopwarming, en oorlogen. Dan denk je, was er maar iets dat ik kon doen om dat te stoppen en al dat lijden te voorkomen! Zeker in een jaar zoals 2020 voel ik meer dan ooit de drang om te helpen. Maar wat kunnen we toch doen?</p>
<p>Laten we onze opties overlopen. Je zou iets kunnen doneren of vrijwilligerswerk kunnen doen voor een goed doel in een gebied dat je belangrijk vindt, maar je bent niet zeker hoeveel impact dat heeft. Misschien beslis je om meer fairtradeproducten te kopen en je ecologische voetafdruk te verkleinen, maar je maakt je zorgen dat je zo alleen je eigen schuldgevoel afkoopt. Of je overweegt om in de politiek te gaan of activist te worden, maar je bent bang dat je stem zou verdrinken tussen alle luidere stemmen. Je zou voor minder wanhopig worden over je onvermogen om een verschil te maken. Maar wat als ik je zou vertellen dat er een andere manier is om een grote positieve impact te hebben op de wereld, een manier die geen grote opofferingen of veranderingen in je leven vereist, maar die nog veel te weinig mensen kennen? Maak kennis met <a href="https://www.effectivealtruism.org/">effectief altruïsme</a>.</p>
<p>Effectief altruïsme is zowel een idee als een wereldwijde beweging rond dit idee. Als idee gaat effectief altruïsme over het beantwoorden van een simpele vraag: hoe kunnen we de grootst mogelijke positieve impact hebben met een gegeven hoeveelheid middelen? Als een nerd die houdt van efficiëntie en dingen optimalizeren werd ik van deze vraag alleen al nieuwsgierig. Als beweging bestaat Effective Altruism (EA) uit vele mensen en organizaties die deze vraag proberen te beantwoorden voor verschillende gebieden, zoals wereldwijde gezondheidszorg, klimaatverandering, dierenwelzijn, en de langetermijntoekomst van de mensheid. Tegelijk proberen deze organizaties ook mensen te overtuigen om te doneren aan de beste goede doelen die ze hebben gevonden. Een ding wat ze níet doen is je vertellen hoeveel je moet doneren: je kan een effectieve altruïst zijn of je nu 5€ of 50% van je inkomen geeft (wat sommige mensen <a href="(https://80000hours.org/articles/earning-to-give/)">echt doen</a>!)</p>
<p>Een reden waarom je zoveel impact kan hebben is dat je rijker bent dan je waarschijnlijk denkt: op <a href="https://howrichami.givingwhatwecan.org/how-rich-am-i">deze pagina</a> van Giving What We Can kan je berekenen hoe rijk je bent ten opzichte van de rest van de wereld. Volgens deze pagina kan je als typische westerling met een gemiddeld inkomen die 10% van zijn inkomen doneert aan de <a href="https://www.againstmalaria.com/">Against Malaria Foundation</a> (of een even effectief goed doel) over de duur van je loopbaan tientallen mensenlevens redden. Dat is alsof je een superheld bent zonder al de spandex! (Niets tegen mensen die van spandex houden.) In domeinen waar impact moeilijker te meten is, zoals klimaatverandering of de langetermijntoekomst van de mensheid, is je impact mogelijk nog groter. Toen ik voor de eerste keer hoorde dat ik met een klein deel van mijn inkomen mensenlevens kon redden, voelde ik me enorm gemotiveerd, en vandaag voel ik die motivatie nog steeds.</p>
<p>Je zou je nu kunnen afvragen of het wel echt zo belangrijk is om de allerbeste goede doelen te vinden, in plaats van gewoon een goed doel te kiezen dat redelijk effectief is en waar je meer voeling mee hebt. Maar in feite zijn de beste goede doelen vaak 10x (en soms 100x) meer effectief dan het gemiddelde. Om klimaatverandering te bestrijden zou je bijvoorbeeld kunnen beslissen om je eigen CO2-uitstoot te compenseren, wat voor elke euro ongeveer 0.05 tot 0.1 ton CO2-uitstoot voorkomt (zie <a href="https://marketplace.goldstandard.org/collections/projects#market-place">Gold Standard</a>). Of je zou die euro in de plaats daarvan kunnen doneren aan de <a href="https://www.rainforestcoalition.org/">Coalition of Rainforest Nations</a> of de <a href="https://www.catf.us/">Clean Air Task Force</a>, wat volgens het onderzoek van <a href="https://founderspledge.com/stories/climate-change-executive-summary">Founder’s Pledge</a> ruim een hele ton CO2-uitstoot voorkomt (10 à 20x zoveel). Nog een voorbeeld: de minst effectieve procedures om HIV/AIDS te bestrijden hebben minder dan 0.1 percent van het effect van de meest effectieve (bron: <a href="https://www.cgdev.org/sites/default/files/1427016_file_moral_imperative_cost_effectiveness.pdf">The Moral Imperative of Cost Effectiveness</a>). Vergelijk dat maar eens met de tijd die je besteedt om online de beste prijs te vinden voor die nieuwe TV, wat misschien een verschil maakt van 10 of 20%. Het loont dus echt de moeite om het beste goede doel te vinden voor de zaken waar je iets om geeft!</p>
<p>Naast het zoeken naar de beste goede doelen binnen elk gebied, houdt effectief altruisme zich ook bezig met het uitzoeken in wélk gebied onze donaties het meeste effect hebben. Ter illustratie: <a href="https://www.givewell.org/giving101/Your-dollar-goes-further-overseas">je euro is meer waard in het zuiden</a>. In andere woorden, je kan meer impact hebben op mensenlevens door te doneren aan gezondheidsorganizaties in ontwikkelingslanden dan aan armoedebestrijding in je eigen land. Om verschillende probleemgebieden met elkaar te vergelijken wordt er in EA over het algemeen gebruik gemaakt van <a href="https://80000hours.org/articles/problem-framework/">drie criteria</a>:</p>
<ul>
<li><em>De schaal van het probleem</em>. Hoe groot zijn de negatieve effecten van het probleem, en hoeveel mensen lijden eronder?</li>
<li><em>Verwaarloosdheid.</em> Hoeveel extra ruimte is er voor meer mensen en middelen om aan dit probleem te werken?</li>
<li><em>Oplosbaarheid.</em> Hoe groot is het effect van extra middelen in dit gebied?</li>
</ul>
<p>Als een probleem erg groot, erg verwaarloosd, en erg oplosbaar is, dan is het waarschijnlijk ook een goede kandidaat om veel impact te kunnen hebben. Dit eenvoudige principe kan soms leiden tot onintuïtieve resultaten, zoals sommige effectieve altruïsten die beslissen om te werken aan onderzoek naar <a href="https://80000hours.org/articles/cause-selection/">globale prioriteiten in plaats van klimaatverandering</a> ondanks dat ze het tweede een groter probleem vinden, omdat er aan het eerste veel minder aandacht wordt besteed.</p>
<p>Eens we een probleemgebied hebben gekozen komt de moeilijke opdracht om de meest effectieve goede doelen in dit gebied te vinden en te vergelijken. Vaak is er een grote graad van onzekerheid bij het evalueren van impact. Bijvoorbeeld: helpt het echt om een stuk regenwoud te beschermen of betekent dit enkel dat een ander stuk regenwoud elders wordt neergekapt? Verder is het vaak ook lastig om verschillende vormen van impact te vergelijken: hoe vergelijken we bijvoorbeeld het effect van betere gezondheidszorg met verbeteringen in het onderwijs in ontwikkelingslanden? Gelukkig zijn er meerdere zeer hoog aangeschreven organizaties die zich als doel hebben gesteld om deze moeilijke vragen te beantwoorden:</p>
<ul>
<li><a href="https://www.givewell.org/">GiveWell</a> is de oudste en meest gerespecteerde organizatie in EA. Ze focust vooral op het evalueren van goede doelen voor gezondheidszorg en ontwikkelingshulp.</li>
<li><a href="https://founderspledge.com/">Founder’s Pledge</a> moedigt ondernemers aan om te beloven om een deel van hun inkomsten te doneren aan effectieve goede doelen. Ze doen ook uitgebreid onderzoek naar effectieve goede doelen voor ontwikkelingshulp en klimaatverandering.</li>
<li>Het <a href="https://effectivealtruism.org/">Centre for Effective Altruism</a> biedt <a href="https://app.effectivealtruism.org/funds">fondsen</a> aan die donaties inzamelen voor verschillende gebieden, waaronder de langetermijntoekomst van de mensheid en de organizatie van de EA-beweging zelf.</li>
<li><a href="https://animalcharityevaluators.org/">Animal Charity Evaluators</a> focust -zoals de naam al zegt- op het vinden van de beste goede doelen voor dierenwelzijn.</li>
<li><a href="https://www.givinggreen.earth/">Giving Green</a> is een nieuwe organizatie die de principes van effectief altruïsme toepast op klimaatverandering.</li>
</ul>
<p>Als je een serieuze impact wil hebben met je geld maar niet zeker bent waar je best kan doneren, is het zeker geen slecht idee om het advies van een van de bovenstaande organizaties te volgen. Zelf doneer ik dit jaar aan drie van de <a href="https://app.effectivealtruism.org/funds">Effective Altruism Funds</a>: de <a href="https://founderspledge.com/funds/climate-change-fund">Founder’s Pledge Climate Change Fund</a> (80%), de <a href="https://app.effectivealtruism.org/funds/global-development">Global Health and Development Fund</a> (15%), en de <a href="https://app.effectivealtruism.org/funds/ea-community">Effective Altruism Infrastructure Fund</a> (5%) (deze zijn momenteel belastingsaftrekbaar in de VS, VK, en Nederland, en hopelijk binnenkort ook in andere landen). Het geld in deze fondsen gaat uiteindelijk naar organizaties zoals <a href="https://www.catf.us/">Clean Air Task Force</a> voor het promoten van schone technologie, <a href="https://carbon180.org/">Carbon180</a> voor onderzoek naar CO2-opvangst en opslag, <a href="https://www.againstmalaria.com/">Against Malaria Foundation</a> voor de verdeling van anti-malarianetten, <a href="https://www.povertyactionlab.org/innovation-government-initiative">J-PAL</a> voor innovatie in het bestuur van lage-inkomenlanden, en <a href="https://80000hours.org/">80,000 Hours</a> voor de begeleiding van mensen om de impact van hun carrière te vergroten. Het vult me met een warm gevoel om te leren over de verwezelijkingen van deze organizaties en om te weten dat ik meehelp met hun werk in de toekomst!</p>
<p>Een van de fijne dingen van EA is dat er enorm veel goedgeschreven ideeën te vinden zijn om te lezen of te luisteren (wel bijna uitsluitend in het engels). Dus in plaats van hier verder in de diepte te gaan, wil ik graag een paar startpunten aanbevelen om meer over effectief altruïsme te leren:</p>
<ul>
<li>Een artikel van het Centre for Effective Altruism: <a href="https://www.effectivealtruism.org/articles/introduction-to-effective-altruism/">Introduction to Effective Altruism</a></li>
<li>Het boek van William MacAskill: <a href="https://www.effectivealtruism.org/doing-good-better/">Doing Good Better</a></li>
<li>De TED Talk van Dan Pallotta: <a href="https://www.youtube.com/watch?v=bfAzi6D5FpM">The Way We Think About Charity is Dead Wrong</a></li>
<li>Drie artikels van Giving What We Can: <a href="https://www.givingwhatwecan.org/charity-comparisons/">Charity Comparisons</a>, <a href="https://www.givingwhatwecan.org/get-involved/myths-about-aid/">Myths About Aid</a>, en <a href="https://www.givingwhatwecan.org/best-charities-to-donate-to-2020/">Best Charities to Donate To In 2020</a></li>
<li>Als je liever iets in het nederlands leest is er sinds kort ook de websites van <a href="https://doneereffectief.nl/">Doneer Effectief</a> (Nederland) en <a href="https://www.eabelgium.org/vlaanderen">Effectief Altruïsme Vlaanderen</a>.</li>
</ul>
<p>Als je tot hier hebt gelezen en het me is gelukt om je te overtuigen, dan heb ik een uitdaging voor je om in 2021 méér goed te doen. Concreet is de uitdaging om op 99% van je normale inkomen te leven, en te beloven om de resterende 1% te doneren aan effectieve goede doelen. Één percent is weinig genoeg dat je het waarschijnlijk niet eens merkt, maar groot genoeg om echt iets fantastisch te doen (als je direct meer wil doneren mag dat natuurlijk ook!). Je kan deze belofte ook officiëel maken op de websites van <a href="https://www.givingwhatwecan.org/">Giving What We Can</a> (wat ik sinds 2017 doe) of <a href="https://www.1fortheworld.org/">One for the World</a>. Beide organizaties geven ook uitstekend advies over aan welke goede doelen je kan doneren.</p>
<p>Ongeacht of je mijn uitdaging nu opneemt of niet, hoop ik dat deze post je tenminste een beetje geïnteresseerd heeft gemaakt in effectief altruïsme, en dat je gemotiveerd bent om in 2021 zoveel goed te doen als je maar kan. Gelukkig nieuwjaar!</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Thu, 24 Dec 2020 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/uitdaging-voor-2021.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>My challenge for you in 2021: Do the most good you can</title>
    <link>https://jesper.sikanda.be/posts/challenge-for-2021.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - My challenge for you in 2021: Do the most good you can</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>My challenge for you in 2021: Do the most good you can</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on December 24, 2020
    </p>
    <p><em>(Deze post is ook vertaald naar het <a href="uitdaging-voor-2021.html">nederlands</a>.)</em></p>
<p>This post is quite different from the usual stuff I post here. It’s about an idea I believe is really important; not nearly enough people know about it, and I’d like to share with you. It’s also about a challenge I have for you for 2021. If you were hoping for an Agda post, I apologize! Meanwhile I hope you find this post interesting as well.</p>
<p>If you’re a bit like me, you may have this common problem: you read, watch, or listen to the news and learn about all the horrible things that are happening, such as diseases, poverty, climate change, and war. Then you wish there only was something you could do to stop that from happening and prevent all that suffering! Especially in a year like 2020, I feel the urge to help more strongly than ever. But what can we possibly do?</p>
<p>Let’s think through the options. You could decide to make a donation or volunteer for a charity in an area you care a lot about, but you’re unsure if that will have any impact. Maybe you start buying fair trade products and work on reducing your ecological footprint, but worry that you’re mostly buying off your own guilt. Perhaps you consider going into politics or becoming an activist, but you’re afraid that you would never be heard among all the louder voices. I sure have often felt desparate not being able to make a difference. But what if I told you there’s another way you can make a large positive impact on the world, one that does not require large sacrifices in your career or lifestyle, yet way too few people actually know about? Let me introduce you to <a href="https://www.effectivealtruism.org/">effective altruism</a>.</p>
<p>Effective altruism is both an idea and a global movement built around this idea. As an idea, effective altruism is about finding the answer to a simple question: how can we make the largest possible positive impact with a given amount of resources? As a nerd who likes efficiency and optimizing things, this question alone made me curious already. As a movement, Effective Altruism (EA) consists of many people and several organizations that try to answer this question for different areas, such as global health, climate change, animal welfare, and the long-term future of humanity. At the same time, these organizations also try to convince people to donate to the top charities they identified. However, one thing they <em>don’t</em> do is tell you to give any particular amount to effective charities: you can be an effective altruist whether you donate 5€ or 50% of your income (which some people <a href="https://80000hours.org/articles/earning-to-give/">actually do</a>!).</p>
<p>One of the reasons why it is possible to make such a big impact is because you are probably richer than you realize: see this <a href="https://howrichami.givingwhatwecan.org/how-rich-am-i">calculator</a> by Giving What We Can to find out how rich you are compared to the rest of the world. According to this calculator, if you have an average job in a typical Western country and donate 10% of your income to the <a href="https://www.againstmalaria.com/">Against Malaria Foundation</a> (or an equally effective charity), you will save dozens of lives over the course of your career. That is like being a superhero without the spandex! (Nothing against people who like spandex.) In cause areas that are harder to measure than global poverty and health -such as climate change or long-term future of humanity- your impact could very well be even higher. For me, when I first learned that I could save lives with just a small portion of my income, I felt really motivated, and I still do.</p>
<p>Now, you could wonder whether it is really that important to identify the absolute best charities, instead of just picking one that is reasonably effective. But in fact, the very best charities in an area are often 10x (and sometimes up to 100x) more effective than the average. To give a example, to help fighting climate change you could decide to offset your CO2 emissions, which means you prevent around 0.05-0.1 tons of CO2 for every 1€ (see <a href="https://marketplace.goldstandard.org/collections/projects#market-place">Gold Standard</a>). Meanwhile, according to the research by <a href="https://founderspledge.com/stories/climate-change-executive-summary">Founder’s Pledge</a> that same euro can prevent well over a whole ton of CO2 emissions (10-20x as much) by donating it to their recommended charities such as the <a href="https://www.rainforestcoalition.org/">Coalition of Rainforest Nations</a> and the <a href="https://www.catf.us/">Clean Air Task Force</a>. As another example, the least effective HIV/AIDS intervention produces less than 0.1 percent of the value of the most effective (source: <a href="https://www.cgdev.org/sites/default/files/1427016_file_moral_imperative_cost_effectiveness.pdf">The Moral Imperative of Cost Effectiveness</a>). Just compare that to the time you spend shopping around for better prices online when buying a new TV, which perhaps makes a difference of 10-20%. Compared to that, it really pays off to spend some time on finding the very best charity for the causes you care about!</p>
<p>In addition to finding the best organizations within each cause area, effective altruism is also about identifying the cause areas where our donations can make an outsized impact compared to others. For example, <a href="https://www.givewell.org/giving101/Your-dollar-goes-further-overseas">your dollar goes further overseas</a>: we can have a bigger impact on more people’s lifes by working on global health than by trying to solve poverty in Western countries. To help with evaluating different problem areas, there are <a href="https://80000hours.org/articles/problem-framework/">three main criteria</a> that people within the EA movement generally agree upon:</p>
<ul>
<li><em>Problem scale.</em> How big are the negative effects of the problem, and how many people does it affect?</li>
<li><em>Neglectedness.</em> How much room is there for more people and resources to work on this problem?</li>
<li><em>Tractability.</em> How big is the effect of additional resources spent in this area?</li>
</ul>
<p>The idea is that if a problem is very large, very neglected, and very tractable, then it is likely a good candidate for making a large impact. This simple framework can sometimes lead to non-obvious results, such as some effective altruists deciding to <a href="https://80000hours.org/articles/cause-selection/">support global priorities research over work on climate change</a> despite it being a smaller problem overall, because it is much more neglected.</p>
<p>Once a problem area is selected comes the difficult task of finding and comparing the most effective organizations working on that problem. Often there is a lot of uncertainty involved in estimating impact accurately. For example, does protecting a piece of rainforest really work or does it just mean a different piece of forest will be cut down somewhere else? It is also difficult to compare different forms of impact. For example, how do we compare the effects of preventing diseases to the effects of better education in third-world countries? Luckily there are several highly reputed organizations with the sole mission of answering these hard questions:</p>
<ul>
<li><a href="https://www.givewell.org/">GiveWell</a> is the oldest and most well-respected organization within EA. They mainly focus on evaluating charities within the area of global health and development.</li>
<li><a href="https://founderspledge.com/">Founder’s Pledge</a> encourages entrepeneurs to pledge a part of their gains to effective charities. They also do extensive research on effective charities in various areas including climate change and global health and development.</li>
<li>The <a href="https://effectivealtruism.org/">Centre for Effective Altruism</a> offers <a href="https://app.effectivealtruism.org/funds">various funds</a> that collect donations to effective charities in various areas, including a.o. the long-term future of humanity and the infrastructure of the EA movement itself.</li>
<li><a href="https://animalcharityevaluators.org/">Animal Charity Evaluators</a> focuses -as the name suggests- on identifying the most effective organizations in the area of animal wellfare.</li>
<li><a href="https://www.givinggreen.earth/">Giving Green</a> is a new organization that applies EA principles to the area of climate change.</li>
</ul>
<p>If you want to make a real impact with your money but are unsure where to donate, you definitely could go worse than by following the advice of any of the above organizations. Myself, I’m donating this year to three of the <a href="https://app.effectivealtruism.org/funds">Effective Altruism Funds</a>: the <a href="https://founderspledge.com/funds/climate-change-fund">Founder’s Pledge Climate Change Fund</a> (80%), the <a href="https://app.effectivealtruism.org/funds/global-development">Global Health and Development Fund</a> (15%), and the <a href="https://app.effectivealtruism.org/funds/ea-community">Effective Altruism Infrastructure Fund</a> (5%) (these funds are <a href="https://app.effectivealtruism.org/funds/about/faq#are-ea-funds-tax-deductible">tax deductible</a> in the US, UK, and Netherlands, and hopefully soon in other countries too). The money in these funds will end up at organizations such as <a href="https://www.catf.us/">Clean Air Task Force</a> for advocacy for clean tech, <a href="https://carbon180.org/">Carbon180</a> for carbon removal solutions, <a href="https://www.againstmalaria.com/">Against Malaria Foundation</a> for the distribution of insecticide-treated bednets, <a href="https://www.povertyactionlab.org/innovation-government-initiative">J-PAL</a> for innovation in government of low-income countries, and <a href="https://80000hours.org/">80,000 Hours</a> for helping people maximize the impact of their careers. It fills me with a very warm feeling learning about all the things these organizations accomplish and knowing that I’m a part of what enables them to continue their work!</p>
<p>One of the nice things about the EA movement is that there are lots and lots of very well-articulated ideas you can read or listen to. So instead of going into more depth here, I will recommend some entry points to learn more about effective altruism:</p>
<ul>
<li>Article by the Centre for Effective Altruism: <a href="https://www.effectivealtruism.org/articles/introduction-to-effective-altruism/">Introduction to Effective Altruism</a></li>
<li>Book by William MacAskill: <a href="https://www.effectivealtruism.org/doing-good-better/">Doing Good Better</a></li>
<li>TED Talk by Dan Pallotta: <a href="https://www.youtube.com/watch?v=bfAzi6D5FpM">The Way We Think About Charity is Dead Wrong</a></li>
<li>Three articles from Giving What We Can: <a href="https://www.givingwhatwecan.org/charity-comparisons/">Charity Comparisons</a>, <a href="https://www.givingwhatwecan.org/get-involved/myths-about-aid/">Myths About Aid</a>, and <a href="https://www.givingwhatwecan.org/best-charities-to-donate-to-2020/">Best Charities to Donate To In 2020</a></li>
</ul>
<p>If you’ve read this far and I have managed to convince you, I have a challenge for you to increase the amount of good you do in the year 2021. Concretely, the challenge is to live on 99% of the money you would normally, and pledge to give the remaining 1% to highly effective charities. Just one percent is small enough that you will probably not even notice, yet large enough to do something really awesome (of course if you’d like to give more that’s even better!) If you want, you can make an official pledge on <a href="https://www.givingwhatwecan.org/">Giving What We Can</a> (as I have since 2017) or <a href="https://www.1fortheworld.org/">One for the World</a>. Both these organizations also provide some excellent advice on what effective charities to donate to.</p>
<p>Whether or not you decide to take the challenge, I hope this post has made you at least a bit interested in effective altruism, and that it will motivate you to do the most good you can in 2021. A happy new year!</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Thu, 24 Dec 2020 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/challenge-for-2021.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>An introduction to property-based testing with QuickCheck</title>
    <link>https://jesper.sikanda.be/posts/quickcheck-intro.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - An introduction to property-based testing with QuickCheck</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>An introduction to property-based testing with QuickCheck</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on December 17, 2020
    </p>
    <p>In February, I will be teaching a new course on Functional Programming at TU
Delft. The course will mostly cover Haskell using <a href="https://www.cs.nott.ac.uk/~pszgmh/pih.html">Graham Hutton’s excellent
book</a>, though there will be a part
on basic usage of dependent types in Agda towards the end as well. For the
exercises, we will use the Delft-grown <a href="https://weblab.tudelft.nl/">Weblab
platform</a> for letting the students code and run the
automated tests using QuickCheck. Unfortunately for me, the book does not talk
about QuickCheck at all. Fortunately for you, that means I decided to write a
tutorial myself, which you can read here.</p>
<p>Of course there are many excellent QuickCheck tutorials out there already.
However I found all of them either assumed too much Haskell knowledge (since I
want to introduce QuickCheck as early as possible), skipped out on interesting
parts (such as conditional and quantified properties), or were just not
up-to-date with the latest version of QuickCheck (such as the new approach for
generating random functions using <code>Fun</code>). So I hope this post closes a gap in
the current menu of tutorials for at least a few people.</p>
<p>If you spot any errors or opportunities for improvement, please let me know.
The students at TU Delft will be grateful!</p>
<h1 id="introduction">Introduction</h1>
<p>When you were first learning to program, at some point you were probably told
about the importance of writing <em>unit tests</em>: small test cases that each test a
small piece of functionality of your code. And while it is true that writing
unit tests is important, it is also at the same time <em>boring</em> and <em>difficult</em>.
It is boring because you need to write many separate unit tests for each piece
of functionality, which all look more or less the same. And it is difficult
because it is very easy to miss a certain combination of inputs for which the
program crashes. Would it not be nice if we could just write down how the
program should behave and have the test cases be generated automatically? That
is precisely the approach of <strong>property-based testing</strong>.</p>
<p>In short, property-based testing is an approach to testing where you as the
programmer write down properties that you expect to hold of your program. When
running the tests, the test runner will generate a lot of different random
input values, and then check that the property holds for all these
(combinations of) input values. Compared to writing individual unit tests,
property-based testing has several advantages:</p>
<ul>
<li>You spend <strong>less time writing test code</strong>: a single property can often replace
many hand-written test cases.</li>
<li>You get <strong>better coverage</strong>: by randomly generating inputs, QuickCheck will test
lots of combinations you’d never test by hand.</li>
<li>You spend <strong>less time on diagnosis of errors</strong>: if a property fails to hold,
QuickCheck will automatically produce a minimized counterexample.</li>
</ul>
<p><strong>QuickCheck</strong> is a tool for property-based testing of Haskell code. Since its
introduction for Haskell in 1999, QuickCheck has become very popular as a
testing framework and has been ported to many other programming languages such
as C, C++, Java, JavaScript, Python, Scala, and many others (see
<a href="https://en.wikipedia.org/wiki/QuickCheck">https://en.wikipedia.org/wiki/QuickCheck</a>
for a more complete list). However, QuickCheck really benefits from the fact
that Haskell is a pure language, so that is where the approach continues to be
the most powerful.</p>
<p>This introduction will show you the basic usage of QuickCheck for testing
properties of Haskell code, as well as how to use alternative random
generators. All the functions that are used come from the module
<code>Test.QuickCheck</code> from the QuickCheck package. This package can be installed
using the Cabal package manager for Haskell by issuing the following command:</p>
<pre><code>&gt; cabal install QuickCheck</code></pre>
<h1 id="basic-usage-of-quickcheck">Basic usage of QuickCheck</h1>
<p>To write a QuickCheck test case, all you have to do is define a Haskell
function that defines a <strong>property</strong> of your program that you expect to hold. In
the simplest case, a property is just a value of type <code>Bool</code>. For example,
suppose we have written a simple Haskell function to calculate the distance
between two integers:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">distance ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>distance x y <span class="ot">=</span> <span class="fu">abs</span> (y<span class="op">-</span>x)</span></code></pre></div>
<p>We can then express the property that the distance between <code>3</code> and <code>5</code> equals <code>2</code>:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_dist35 ::</span> <span class="dt">Bool</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>prop_dist35 <span class="ot">=</span> distance <span class="dv">3</span> <span class="dv">5</span> <span class="op">==</span> <span class="dv">2</span></span></code></pre></div>
<p>By convention, names of QuickCheck properties always start with
<code>prop_</code>. We can express more general properties by defining a function
that returns a <code>Bool</code>:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- The distance between any number and itself is always 0</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_dist_self ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>prop_dist_self x <span class="ot">=</span> distance x x <span class="op">==</span> <span class="dv">0</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="co">-- The distance between x and y is equal to the distance between y and x</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_dist_symmetric ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>prop_dist_symmetric x y <span class="ot">=</span> distance x y <span class="op">==</span> distance y x</span></code></pre></div>
<p>When testing a property that takes one or more inputs, QuickCheck will randomly generate
several inputs (100 by default) and check that the function returns <code>True</code> for all inputs.</p>
<p>The main function used to call QuickCheck is <code>quickCheck</code>, which is defined in
the module <code>Test.QuickCheck</code>. To import it, you can either add <code>import Test.QuickCheck</code> at the top of your file or import it manually if you are
working from GHCi. Assuming you have installed the QuickCheck package, you
can then load the file and run tests by calling <code>quickCheck</code>:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> ghci</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span>, version <span class="fl">8.10</span><span class="op">.</span><span class="dv">2</span><span class="op">:</span> https<span class="op">://</span>www<span class="op">.</span>haskell<span class="op">.</span>org<span class="op">/</span>ghc<span class="op">/</span>  <span class="op">:?</span> for help</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="dt">Loaded</span> package environment from <span class="op">~/.</span>ghc<span class="op">/</span>x86_64<span class="op">-</span>linux<span class="op">-</span><span class="fl">8.10</span><span class="op">.</span><span class="dv">2</span><span class="op">/</span>environments<span class="op">/</span>default</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> <span class="op">:</span>l QuickCheckExamples.hs</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> quickCheck prop_dist35</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="op">+++</span> <span class="dt">OK</span>, passed <span class="dv">1</span> test<span class="op">.</span></span></code></pre></div>
<p>QuickCheck tells us that everything is as it should be: it ran the test and got
the result <code>True</code>. Since there are no inputs to the test, it is run only once.
Let us try out some more properties!</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> quickCheck prop_dist_self</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="op">+++</span> <span class="dt">OK</span>, passed <span class="dv">100</span> tests<span class="op">.</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> quickCheck prop_dist_symmetric</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="op">+++</span> <span class="dt">OK</span>, passed <span class="dv">100</span> tests<span class="op">.</span></span></code></pre></div>
<p>Huge success! For each of the tests, QuickCheck has generated 100 random inputs
and verified that for each one the property returns <code>True</code>.</p>
<p>To get more information about the test inputs that are generated by QuickCheck,
you can replace the function <code>quickCheck</code> with <code>verboseCheck</code>. This will print
out each individual test case as it is generated. Try it out for yourself!</p>
<h2 id="shrinking-counterexamples">Shrinking counterexamples</h2>
<p>What happens if there’s a mistake in our code? Say we forgot to write <code>abs</code> in
the definition of <code>distance</code>?</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> quickCheck prop_dist_symmetric</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="op">***</span> <span class="dt">Failed</span><span class="op">!</span> <span class="dt">Falsified</span> (after <span class="dv">2</span> tests)<span class="op">:</span>                  </span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="dv">0</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span></span></code></pre></div>
<p>QuickCheck has found a counterexample: if the first input <code>x</code> is 0 and the
second input <code>y</code> is 1, then <code>y-x</code> is not equal to <code>x-y</code>.</p>
<p>When QuickCheck finds a counterexample, it will not always return the first one
it encounters. Instead, QuickCheck will look for the smallest counterexample it
can find. As an example, let us try to run QuickCheck on the (false) property
stating that every list is sorted.</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">sorted ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Bool</span> </span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>sorted (x<span class="op">:</span>y<span class="op">:</span>ys) <span class="ot">=</span> x <span class="op">&lt;=</span> y <span class="op">&amp;&amp;</span> sorted (y<span class="op">:</span>ys)</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>sorted _        <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a><span class="co">-- A (false) property stating that every list is sorted</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_sorted ::</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>prop_sorted xs <span class="ot">=</span> sorted xs</span></code></pre></div>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> verboseCheck prop_sorted</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Passed</span><span class="op">:</span>  </span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>[]</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a><span class="dt">Passed</span><span class="op">:</span> </span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>[]</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a><span class="dt">Passed</span><span class="op">:</span>  </span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>[<span class="dv">0</span>]</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a><span class="dt">Failed</span><span class="op">:</span>  </span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>[<span class="dv">2</span>,<span class="dv">1</span>,<span class="dv">3</span>]</span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a><span class="dt">Passed</span><span class="op">:</span>                                 </span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a>[]</span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a><span class="dt">Passed</span><span class="op">:</span>                                                 </span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>,<span class="dv">3</span>]</span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true" tabindex="-1"></a><span class="dt">Passed</span><span class="op">:</span>                                                 </span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true" tabindex="-1"></a>[<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true" tabindex="-1"></a><span class="dt">Failed</span><span class="op">:</span>                                                 </span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true" tabindex="-1"></a>[<span class="dv">2</span>,<span class="dv">1</span>]</span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true" tabindex="-1"></a><span class="op">...</span></span>
<span id="cb9-27"><a href="#cb9-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-28"><a href="#cb9-28" aria-hidden="true" tabindex="-1"></a><span class="op">***</span> <span class="dt">Failed</span><span class="op">!</span> <span class="dt">Falsified</span> (after <span class="dv">4</span> tests <span class="fu">and</span> <span class="dv">3</span> shrinks)<span class="op">:</span>    </span>
<span id="cb9-29"><a href="#cb9-29" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>,<span class="dv">0</span>]</span></code></pre></div>
<p>The first list that is generated that is not sorted is <code>[2,1,3]</code>. Note that
this will be a different list every time we run QuickCheck since it is randomly
generated. However, QuickCheck does not stop there and instead tries smaller
and smaller lists until it converges to a minimal counterexample: <code>[1,0]</code>. This
process is called <strong>shrinking</strong>.</p>
<p>It is worth noting that despite the inherent randomness of QuickCheck,
shrinking will often converge to one of a small set of minimal counterexamples.
For example, if we run <code>quickCheck</code> many times on <code>prop_sorted</code>, we always end
up with either <code>[1,0]</code> or <code>[0,-1]</code> as a counterexample.</p>
<p>The precise strategy that QuickCheck uses for shrinking counterexamples depends
on the type of the counterexample:</p>
<ul>
<li><p>For numeric types such as <code>Int</code>, QuickCheck will try a random number that is
smaller in absolute value (i.e. closer to 0).</p></li>
<li><p>For booleans of type <code>Bool</code>, QuickCheck will try to replace <code>True</code> with
<code>False</code>.</p></li>
<li><p>For tuple types <code>(a,b)</code>, QuickCheck will try to shrink one of the components.</p></li>
<li><p>For list types, QuickCheck will try to either delete a random element from
the list, or try to shrink one of the values in the list.</p></li>
</ul>
<h2 id="testing-many-properties-at-once">Testing many properties at once</h2>
<p>Instead of running individual tests from GHCi, you can also combine all your
tests in a <code>main</code> function:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  quickCheck prop_dist35</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  quickCheck prop_dist_self</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  quickCheck prop_dist_symmetric</span></code></pre></div>
<p>This code makes use of Haskell <code>do</code> keyword that we will study in the chapter
on monads. Once you have defined this <code>main</code> function, you can invoke it by
calling <code>runghc</code> from the command line:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> runghc QuickcheckExamples.hs</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="op">+++</span> <span class="dt">OK</span>, passed <span class="dv">1</span> test<span class="op">.</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a><span class="op">+++</span> <span class="dt">OK</span>, passed <span class="dv">100</span> tests<span class="op">.</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a><span class="op">+++</span> <span class="dt">OK</span>, passed <span class="dv">100</span> tests<span class="op">.</span></span></code></pre></div>
<p>Note that a file may only contain a single <code>main</code> function. In a realistic
project, we would instead create a separate file that just defines all
QuickCheck properties and puts them together in a <code>main</code> function.</p>
<p><strong>Remark.</strong> When you are writing code in the WebLab instance for this course,
you do not need to write a main function for QuickCheck tests: WebLab will
automatically collect all functions in the <code>Test</code> tab whose name starts with
<code>prop_</code> and run <code>quickCheck</code> on each one.</p>
<h1 id="discovering-properties-to-test">Discovering properties to test</h1>
<p>The biggest challenge in making effective use of QuickCheck lies in coming up
with good properties to test. So let us take a look at some examples of good
properties to test.</p>
<h2 id="roundtrip-properties">Roundtrip properties</h2>
<p>When one function is an inverse to another function, we can create a property
test for that. For example, we can test that reversing a list is its own
inverse:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_reverse_reverse ::</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>prop_reverse_reverse xs <span class="ot">=</span> <span class="fu">reverse</span> (<span class="fu">reverse</span> xs) <span class="op">==</span> xs</span></code></pre></div>
<p>As another example, we can test that inserting an element into a list and then
deleting it again results in the same list:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> [<span class="dt">Int</span>]</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>insert x [] <span class="ot">=</span> [x]</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>insert x (y<span class="op">:</span>ys) <span class="op">|</span> x <span class="op">&lt;=</span> y    <span class="ot">=</span> x<span class="op">:</span>y<span class="op">:</span>ys</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>                <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> y<span class="op">:</span>insert x ys</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a><span class="ot">delete ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> [<span class="dt">Int</span>]</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>delete x [] <span class="ot">=</span> []</span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a>delete x (y<span class="op">:</span>ys) <span class="op">|</span> x <span class="op">==</span> y    <span class="ot">=</span> ys</span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>                <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> y<span class="op">:</span>delete x ys</span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_insert_delete ::</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>prop_insert_delete xs x <span class="ot">=</span> delete x (insert x xs) <span class="op">==</span> xs</span></code></pre></div>
<p>In general, it might take more than two functions to get back to the point
where we started from. Any property of the form <code>f (g (... (h x))) == x</code> is
called a <strong>roundtrip property</strong>.</p>
<h2 id="equivalent-implementations">Equivalent implementations</h2>
<p>When we have two functions that should be functionally equivalent but have a
different implementation, we can test that this is indeed the case. For example,
we can test that a function <code>qsort :: Ord a =&gt; [a] -&gt; [a]</code>, we can define a property
that tests it has the same behaviour as the builtin Haskell function <code>sort</code>:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_qsort_sort ::</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>prop_qsort_sort xs <span class="ot">=</span> qsort xs <span class="op">==</span> <span class="fu">sort</span> xs</span></code></pre></div>
<p>If there is an alternative implementation available, defining a property of
this kind is usually a very good idea since it can catch a broad range of
errors in the implementation.</p>
<p>Another variant of this technique can be applied when you replace the
implementation of a function with a new version (perhaps because it is more
efficient or more general). In that case, you can keep the old code under a
different name and add a property to test that both implementation produce the
same result. This way you can make sure that the behaviour of the program has
not changed by accident!</p>
<p><strong>Warning.</strong> When testing a polymorphic function such as <code>qsort</code>, it seems
attractive to also define a polymorphic test case:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_qsort_sort' ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>prop_qsort_sort' xs <span class="ot">=</span> qsort xs <span class="op">==</span> <span class="fu">sort</span> xs</span></code></pre></div>
<p>However, this does not work as you might expect: by default, <code>quickCheck</code> will
instantiate all type parameters to the empty tuple type <code>()</code>. So the property
that <code>quickCheck</code> will actually test is <code>prop_qsort_sort'' :: [()] -&gt; Bool</code>.
Since a list of empty tuples <code>[(),(),...,()]</code> is always sorted, this test will
always return <code>True</code> even if the function <code>qsort</code> does nothing! So in general
it is a good idea to <strong>always give a concrete type (without type parameters) to
property tests</strong>.</p>
<h2 id="algebraic-laws">Algebraic laws</h2>
<p>When we have a function that implements a certain idea from algebra, we can use
the <strong>algebraic laws</strong> as inspiration for property tests. For example, suppose
we have a function <code>vAdd :: (Int,Int) -&gt; (Int,Int) -&gt; (Int,Int)</code> that defines
addition on two-dimensional vectors, we can test that it is commutative,
associative, and has a neutral element:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_vAdd_commutative ::</span> (<span class="dt">Int</span>,<span class="dt">Int</span>) <span class="ot">-&gt;</span> (<span class="dt">Int</span>,<span class="dt">Int</span>) <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>prop_vAdd_commutative v w <span class="ot">=</span> vAdd v w <span class="op">==</span> vAdd w v</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_vAdd_associative ::</span> (<span class="dt">Int</span>,<span class="dt">Int</span>) <span class="ot">-&gt;</span> (<span class="dt">Int</span>,<span class="dt">Int</span>) <span class="ot">-&gt;</span> (<span class="dt">Int</span>,<span class="dt">Int</span>) <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>prop_vAdd_associative u v w <span class="ot">=</span> vAdd (vAdd u v) w <span class="op">==</span> vAdd u (vAdd v w)</span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_vAdd_neutral_left ::</span> (<span class="dt">Int</span>,<span class="dt">Int</span>) <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>prop_vAdd_neutral_left u <span class="ot">=</span> vAdd (<span class="dv">0</span>,<span class="dv">0</span>) u <span class="op">==</span> u</span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_vAdd_neutral_right ::</span> (<span class="dt">Int</span>,<span class="dt">Int</span>) <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a>prop_vAdd_neutral_right u <span class="ot">=</span> vAdd u (<span class="dv">0</span>,<span class="dv">0</span>) <span class="op">==</span> u</span></code></pre></div>
<p>As another example, some functions such as sorting functions are <em>idempotent</em>:
applying them twice produces the same result as applying them just once.</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_qsort_idempotent ::</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>prop_qsort_idempotent xs <span class="ot">=</span> qsort (qsort xs) <span class="op">==</span> qsort xs</span></code></pre></div>
<h1 id="testing-with-different-distributions">Testing with different distributions</h1>
<p>Often we want to test a certain property but it does not hold for all possible
inputs. For example, let us try to test that each element in the result of
<code>replicate n x</code> is equal to <code>x</code> (the function <code>replicate :: Int -&gt; a -&gt; [a]</code> is
defined in the standard prelude).</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_replicate ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>prop_replicate n x i <span class="ot">=</span> <span class="fu">replicate</span> n x <span class="op">!!</span> i <span class="op">==</span> x</span></code></pre></div>
<p>However, when we try to test this property we get an error:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> quickCheck prop_replicate</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="op">***</span> <span class="dt">Failed</span><span class="op">!</span> <span class="dt">Exception</span><span class="op">:</span> <span class="dt">'Prelude</span><span class="op">.!!:</span> <span class="fu">index</span> too large' (after <span class="dv">1</span> test)<span class="op">:</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a><span class="dv">0</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a><span class="dv">0</span></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a><span class="dv">0</span></span></code></pre></div>
<p>Oh no! QuickCheck generated a list of length 0, which means any index <code>i</code> is
out of bounds. To resolve this problem, we could change the property so it
always evaluates to <code>True</code> in case the index is out of bounds:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_replicate ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>prop_replicate n x i <span class="ot">=</span> i <span class="op">&lt;</span> <span class="dv">0</span> <span class="op">||</span> i <span class="op">&gt;=</span> n <span class="op">||</span> <span class="fu">replicate</span> n x <span class="op">!!</span> i <span class="op">==</span> x</span></code></pre></div>
<p>Now testing the property is successful:</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> quickCheck prop_replicate</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a><span class="op">+++</span> <span class="dt">OK</span>, passed <span class="dv">100</span> tests<span class="op">.</span></span></code></pre></div>
<p>However, this actually gives us a false sense of security: in the vast majority
of the test cases that are generated, the index is out of bounds and thus
nothing about the behaviour of <code>replicate</code> is tested. You can verify this by
running <code>verboseCheck</code> on this property and counting the cases where <code>i</code> is in
between <code>0</code> and <code>n</code>. In effect much fewer than 100 inputs are tested, so there
is a high chance that mistakes go undetected.</p>
<p>We could try to counteract this by running more test cases. However, how many
test cases is enough? Do we need 1000? 10000? What about if we want to test a
property where it is even rarer that we generate a valid input, for example
when a property only holds for sorted lists?</p>
<p>Instead of running more test cases, we can make sure that the test cases we
generate are always valid. We will discuss two methods provided by the
QuickCheck library that allow us to do this: <strong>conditional properties</strong> and
<strong>quantified properties</strong>.</p>
<h2 id="conditional-properties">Conditional properties</h2>
<p>The first way we can restrict the inputs that QuickCheck uses is by using a
conditional property of the form</p>
<pre><code>    &lt;condition&gt; ==&gt; &lt;property&gt;</code></pre>
<p>For example, we can rewrite <code>prop_replicate</code> as follows:</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_replicate ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Property</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>prop_replicate n x i <span class="ot">=</span> </span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>  (i <span class="op">&gt;=</span> <span class="dv">0</span> <span class="op">&amp;&amp;</span> i <span class="op">&lt;</span> n) <span class="op">==&gt;</span> <span class="fu">replicate</span> n (<span class="ot">x ::</span> <span class="dt">Int</span>) <span class="op">!!</span> i <span class="op">==</span> x</span></code></pre></div>
<p>Notice that the return type is no longer <code>Bool</code> but <code>Property</code>, a new type that
is introduced by QuickCheck. Luckily we do not need to know much about this
type in order to use QuickCheck; all we need to know is that we can use
<code>quickCheck</code> to test functions that return a <code>Property</code> just like functions
that return a <code>Bool</code>!</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> quickCheck prop_replicate</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a><span class="op">+++</span> <span class="dt">OK</span>, passed <span class="dv">100</span> tests; <span class="dv">695</span> discarded<span class="op">.</span></span></code></pre></div>
<p>What just happened? QuickCheck tests the property <code>replicate n (x :: Int) !! i == x</code> as before, but now it discards all test cases that do not satisfy the
condition <code>i &gt;= 0 &amp;&amp; i &lt; n</code>. In the output, we can see that it generated a
total of 795 test cases, of which 695 were discarded and the remaining 100
passed successfully.</p>
<p>Conditional properties work well when there is a reasonable chance that a
randomly generated input will satisfy the condition. However, it breaks down
when valid inputs are very rare. For example, let us try to test that inserting
an element into an ordered list again results in an ordered list:</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_insert_sorted ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> <span class="dt">Property</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>prop_insert_sorted x xs <span class="ot">=</span> sorted xs <span class="op">==&gt;</span> sorted (insert x xs)</span></code></pre></div>
<p>If we ask QuickCheck to test this property, it gives up:</p>
<div class="sourceCode" id="cb26"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> quickCheck prop_insert_sorted</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a><span class="op">***</span> <span class="dt">Gave</span> up<span class="op">!</span> <span class="dt">Passed</span> only <span class="dv">80</span> tests; <span class="dv">1000</span> discarded tests<span class="op">.</span></span></code></pre></div>
<p>The lesson here is that we should not use conditional properties when the
condition is very unlikely to be satisfied.</p>
<h2 id="quantified-properties">Quantified properties</h2>
<p>Instead of first generating random values and then filtering out the ones that
are not valid, we can instead use a different random generator that only
generates valid inputs in the first place. For this purpose, QuickCheck allows
us to define <em>quantified properties</em> by using custom random generators of type
<code>Gen a</code>. For example, we can use the generator <code>orderedList</code> to generate a
random ordered list. We can use random generators to define properties by using
the function <code>forAll</code>:</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_insert_sorted ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Property</span></span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>prop_insert_sorted x <span class="ot">=</span> forAll orderedList (\xs <span class="ot">-&gt;</span> sorted (insert x xs))</span></code></pre></div>
<p>The first argument of <code>forAll</code> is the random generator. The second argument is
a <em>function</em> that maps the result of the generator to the property we want to
test (in other words, <code>forAll</code> is a <em>higher-order function</em>). Here we have
given the function as a lambda expression <code>\xs -&gt; sorted (insert x xs)</code>. Note
that the list <code>xs</code> is no longer an input to the overall property
<code>prop_insert_sorted</code>, as it is already an argument to the lambda expression.
Now if we run <code>quickCheck</code> again, we see that the tests now pass:</p>
<div class="sourceCode" id="cb28"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> quickCheck prop_insert_sorted</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a><span class="op">+++</span> <span class="dt">OK</span>, passed <span class="dv">100</span> tests<span class="op">.</span></span></code></pre></div>
<p>You can also use <code>verboseCheck</code> to verify that all the generated lists are
indeed sorted (do it!)</p>
<p>QuickCheck provides a long list of random generators that we can use to test
our properties. Here are a few useful examples:</p>
<ul>
<li><p>The generator <code>choose</code> will choose a random elements between two bounds. For
example, <code>choose (1,6)</code> will generate a random number between 1 and 6 (both
bounds included).</p></li>
<li><p>The generator <code>elements</code> will choose a random element from a given list of
values. For example, <code>elements ['a','e','i','o','u']</code> will generate a random
vowel.</p></li>
<li><p>The generator <code>frequency</code> works like <code>elements</code> but allows you to give a
weight to each option determining how likely it is that it is generated. For
example, <code>frequency [(99,True),(1,False)]</code> will generate <code>True</code> 99% of the time
and <code>False</code> 1% of the time.</p></li>
<li><p>The generator <code>vector</code> generates lists of a given length. For example,
<code>vector 42</code> generates random lists of length 42.</p></li>
<li><p>The generator <code>shuffle</code> generates lists with the same elements as a given
list but in a random order. For example, <code>shuffle [1..10]</code> generates random
lists containing the numbers <code>1</code> to <code>10</code>.</p></li>
</ul>
<p>You can find many other generators by looking at the module <code>Test.QuickCheck</code>.
In addition, it is possible to define your own random generators, but this goes
beyond the scope of this introduction.</p>
<p>If you want to play around with these random generators, you can use the
function <code>sample</code> from GHCi to generate a couple of random values with the
given generator:</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> <span class="kw">import</span> <span class="dt">Test.QuickCheck</span></span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> sample (shuffle [<span class="dv">1</span><span class="op">..</span><span class="dv">10</span>])</span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>[<span class="dv">9</span>,<span class="dv">1</span>,<span class="dv">8</span>,<span class="dv">7</span>,<span class="dv">3</span>,<span class="dv">2</span>,<span class="dv">10</span>,<span class="dv">4</span>,<span class="dv">6</span>,<span class="dv">5</span>]</span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a>[<span class="dv">3</span>,<span class="dv">10</span>,<span class="dv">5</span>,<span class="dv">7</span>,<span class="dv">2</span>,<span class="dv">1</span>,<span class="dv">9</span>,<span class="dv">4</span>,<span class="dv">6</span>,<span class="dv">8</span>]</span>
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a>[<span class="dv">6</span>,<span class="dv">1</span>,<span class="dv">4</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">7</span>,<span class="dv">8</span>,<span class="dv">10</span>,<span class="dv">5</span>,<span class="dv">9</span>]</span>
<span id="cb29-6"><a href="#cb29-6" aria-hidden="true" tabindex="-1"></a>[<span class="dv">6</span>,<span class="dv">8</span>,<span class="dv">9</span>,<span class="dv">10</span>,<span class="dv">3</span>,<span class="dv">5</span>,<span class="dv">4</span>,<span class="dv">7</span>,<span class="dv">2</span>,<span class="dv">1</span>]</span>
<span id="cb29-7"><a href="#cb29-7" aria-hidden="true" tabindex="-1"></a>[<span class="dv">8</span>,<span class="dv">9</span>,<span class="dv">3</span>,<span class="dv">7</span>,<span class="dv">10</span>,<span class="dv">5</span>,<span class="dv">2</span>,<span class="dv">4</span>,<span class="dv">1</span>,<span class="dv">6</span>]</span>
<span id="cb29-8"><a href="#cb29-8" aria-hidden="true" tabindex="-1"></a>[<span class="dv">7</span>,<span class="dv">5</span>,<span class="dv">2</span>,<span class="dv">9</span>,<span class="dv">10</span>,<span class="dv">4</span>,<span class="dv">6</span>,<span class="dv">8</span>,<span class="dv">3</span>,<span class="dv">1</span>]</span>
<span id="cb29-9"><a href="#cb29-9" aria-hidden="true" tabindex="-1"></a>[<span class="dv">9</span>,<span class="dv">5</span>,<span class="dv">4</span>,<span class="dv">6</span>,<span class="dv">1</span>,<span class="dv">7</span>,<span class="dv">3</span>,<span class="dv">10</span>,<span class="dv">2</span>,<span class="dv">8</span>]</span>
<span id="cb29-10"><a href="#cb29-10" aria-hidden="true" tabindex="-1"></a>[<span class="dv">5</span>,<span class="dv">3</span>,<span class="dv">1</span>,<span class="dv">10</span>,<span class="dv">9</span>,<span class="dv">7</span>,<span class="dv">8</span>,<span class="dv">4</span>,<span class="dv">6</span>,<span class="dv">2</span>]</span>
<span id="cb29-11"><a href="#cb29-11" aria-hidden="true" tabindex="-1"></a>[<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">10</span>,<span class="dv">2</span>,<span class="dv">7</span>,<span class="dv">6</span>,<span class="dv">8</span>,<span class="dv">1</span>,<span class="dv">9</span>,<span class="dv">5</span>]</span>
<span id="cb29-12"><a href="#cb29-12" aria-hidden="true" tabindex="-1"></a>[<span class="dv">3</span>,<span class="dv">9</span>,<span class="dv">2</span>,<span class="dv">8</span>,<span class="dv">5</span>,<span class="dv">4</span>,<span class="dv">1</span>,<span class="dv">10</span>,<span class="dv">6</span>,<span class="dv">7</span>]</span>
<span id="cb29-13"><a href="#cb29-13" aria-hidden="true" tabindex="-1"></a>[<span class="dv">6</span>,<span class="dv">5</span>,<span class="dv">4</span>,<span class="dv">9</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">8</span>,<span class="dv">7</span>,<span class="dv">10</span>,<span class="dv">1</span>]</span></code></pre></div>
<h1 id="testing-properties-of-functions">Testing properties of functions</h1>
<p>In addition of being able to generate values of basic types such as integers,
booleans, and lists, QuickCheck can also generate random <em>functions</em> that you
can use to write tests. However, for technical reasons related to shrinking,
QuickCheck cannot directly generate an element of type, say, <code>String -&gt; Bool</code>.
Instead, QuickCheck introduces a new (generic) type <code>Fun a b</code> with two
parameters <code>a</code> and <code>b</code>, as well as a function <code>applyFun :: Fun a b -&gt; a -&gt; b</code>.</p>
<p>For example, we can test that for any function <code>p :: Int -&gt; Bool</code>, we have that
<code>p x == True</code> for all elements of the list <code>[ x | x &lt;- xs , p x ]</code>:</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_filter ::</span> <span class="dt">Fun</span> <span class="dt">Int</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> <span class="dt">Property</span></span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>prop_filter p xs <span class="ot">=</span> </span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>      <span class="co">-- Filter elements not satisfying p.</span></span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> ys <span class="ot">=</span> [ x <span class="op">|</span> x <span class="ot">&lt;-</span> xs , applyFun p x ]</span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a>      <span class="co">-- If any elements are left...  </span></span>
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">in</span>  ys <span class="op">/=</span> [] <span class="op">==&gt;</span>          </span>
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a>        <span class="co">-- ...generate a random index i...               </span></span>
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a>        forAll (choose (<span class="dv">0</span>,<span class="fu">length</span> ys<span class="op">-</span><span class="dv">1</span>))</span>
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a>          <span class="co">-- ...and test if p (ys!!i) holds.    </span></span>
<span id="cb30-10"><a href="#cb30-10" aria-hidden="true" tabindex="-1"></a>          (\i <span class="ot">-&gt;</span> applyFun p (ys<span class="op">!!</span>i))       </span></code></pre></div>
<div class="sourceCode" id="cb31"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> quickCheck prop_filter</span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a><span class="op">+++</span> <span class="dt">OK</span>, passed <span class="dv">100</span> tests; <span class="dv">41</span> discarded<span class="op">.</span></span></code></pre></div>
<p>As another (silly) example, let us try to test the property that each function
of type <code>String -&gt; Int</code> produces the same result on at least two out of three
values of <code>"banana"</code>, <code>"monkey"</code>, and <code>"elephant"</code>:</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_bananas ::</span> <span class="dt">Fun</span> <span class="dt">String</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>prop_bananas f <span class="ot">=</span> </span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>  applyFun f <span class="st">&quot;banana&quot;</span> <span class="op">==</span> applyFun f <span class="st">&quot;monkey&quot;</span> <span class="op">||</span></span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a>  applyFun f <span class="st">&quot;banana&quot;</span> <span class="op">==</span> applyFun f <span class="st">&quot;elephant&quot;</span> <span class="op">||</span></span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a>  applyFun f <span class="st">&quot;monkey&quot;</span> <span class="op">==</span> applyFun f <span class="st">&quot;elephant&quot;</span></span></code></pre></div>
<pre><code>&gt; quickCheck prop_bananas
*** Failed! Falsified (after 2 tests and 163 shrinks):     
{&quot;banana&quot;-&gt;0, &quot;elephant&quot;-&gt;1, _-&gt;2}</code></pre>
<p>The function <code>{"banana"-&gt;0, "elephant"-&gt;1, _-&gt;2}</code> generated by QuickCheck maps
<code>"banana"</code> to <code>0</code>, <code>"elephant"</code> to <code>1</code>, and all other strings to <code>2</code>. As you
can verify, this is indeed a counterexample to the property we defined. It
might come as a surprise that QuickCheck is able to come up with this
counterexample by itself!</p>
<h1 id="bonus-behind-the-scenes">Bonus: “Behind the scenes”</h1>
<p>The content of this section is not required to use QuickCheck, but it might
help you to get a deeper understanding of the types and type classes that make
QuickCheck tick.</p>
<p>Let us start by trying to analyse the type of the function <code>quickCheck</code>:</p>
<div class="sourceCode" id="cb34"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a><span class="ot">quickCheck ::</span> <span class="dt">Testable</span> prop <span class="ot">=&gt;</span> prop <span class="ot">-&gt;</span> <span class="dt">IO</span> () </span></code></pre></div>
<p>It takes an argument of polymorphic type <code>prop</code> – which must satisfy the
<code>Testable</code> typeclass – and produces an output of type <code>IO ()</code>. Values of type
<code>IO ()</code> are interactive programs that we can run in GHCi or compile to an
executable program; we will look into this type in more detail later in the
course. Meanwhile, <code>Testable</code> is a typeclass just like other classes we have
seen before: <code>Eq</code>, <code>Ord</code>, <code>Show</code>, <code>Num</code>, …</p>
<p>The <code>Testable</code> class determines what kind of properties can be tested by
<code>quickCheck</code>, i.e. what types are valid inputs to <code>quickCheck</code>. It has the
following relevant instances:</p>
<ul>
<li><p><code>Bool</code> is an instance of <code>Testable</code>, which is what allows us to run
<code>quickCheck</code> on properties of type <code>Bool</code>.</p></li>
<li><p>Likewise, the type <code>Property</code> is an instance of <code>Testable</code>, so we can also
run <code>quickCheck</code> on properties such as <code>condition ==&gt; prop</code> and <code>forAll gen (\x -&gt; prop)</code>.</p></li>
<li><p>Finally, a function type <code>a -&gt; b</code> is an instance of <code>Testable</code> provided <code>b</code>
is an instance of type <code>Testable</code> <em>and</em> <code>a</code> is an instance of another class
<code>Arbitrary</code>. This is what allows us to run <code>quickCheck</code> on properties that take
one or more inputs that are randomly generated.</p></li>
</ul>
<p>Next we have the <code>Arbitrary</code> typeclass. Types that are an instance of this
typeclass have a ‘default’ random generator <code>arbitrary :: Arbitrary a =&gt; Gen a</code>. For example, <code>Bool</code> is an instance of <code>Arbitrary</code> with <code>arbitrary = elements [True,False]</code>. In addition, there is also a function <code>shrink :: Arbitrary a =&gt; a -&gt; [a]</code> that computes a list of all ‘shrunk’ versions of a
value.</p>
<p>When testing a property, QuickCheck will first generate random inputs using the
<code>arbitrary</code> generator associated to the input type. It will then test the
property by running it on the generated inputs. Finally, if it finds a
counterexample it will try to <code>shrink</code> it step by step as long as the test
keeps failing.</p>
<h1 id="further-reading">Further reading</h1>
<ul>
<li><p>The <a href="https://hackage.haskell.org/package/QuickCheck-2.14.2/docs/Test-QuickCheck.html">QuickCheck package on Hackage</a></p></li>
<li><p><a href="http://www.cse.chalmers.se/~rjmh/QuickCheck/manual.html">Official QuickCheck manual</a> (somewhat outdated)</p></li>
<li><p><a href="https://wiki.haskell.org/Introduction_to_QuickCheck2">Introduction to QuickCheck v2</a></p></li>
<li><p><a href="https://www.schoolofhaskell.com/user/pbv/an-introduction-to-quickcheck-testing">An introduction to QuickCheck testing</a></p></li>
<li><p><a href="https://www.fpcomplete.com/blog/2017/01/quickcheck/">QuickCheck and Magic of Testing</a></p></li>
<li><p><a href="https://www.stackbuilders.com/news/a-quickcheck-tutorial-generators">A QuickCheck Tutorial: Generators</a></p></li>
<li><p><a href="https://www.cs.utexas.edu/~ragerdl/fmcad11/slides/tutorial-a.pdf">Specification Based Testing with QuickCheck</a> (this
contains lots of real-world examples where QuickCheck is used in other
languages)</p></li>
</ul>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Thu, 17 Dec 2020 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/quickcheck-intro.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>NWO Veni Grant on A Trustworthy and Extensible Core Language for Agda</title>
    <link>https://jesper.sikanda.be/posts/veni-announcement.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - NWO Veni Grant on A Trustworthy and Extensible Core Language for Agda</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>NWO Veni Grant on A Trustworthy and Extensible Core Language for Agda</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on November 11, 2020
    </p>
    <p>I’m very glad and humbled to announce that I received an NWO Veni
Grant for my proposal “A Trustworthy and Extensible Core Language for
Agda.” You can read the official announcement on the <a href="https://www.nwo.nl/en/news/161-researchers-awarded-nwo-veni-grant-worth-250000-euros">NWO
website</a>. Thanks
to this grant I will be able to focus on the development of Agda Core
during the coming three years. Below, you can find the abstract of the
proposal:</p>
<p><em>As software takes an increasingly central position in our society,
being able to trust the software we use likewise becomes more and more
important. Programming languages based on dependent types – such as
Coq and Agda – provide a strong answer to this demand: they allow
programmers to state the expected properties of a program, and the
computer checks that these properties are satisfied before the program
is ever executed. Yet the implementations of these languages are
themselves just pieces of software, so can we really trust them? The
problem is exacerbated by the multitude of extensions to these
languages that make them more expressive and easier to use, but at the
same time increase the number of components that must be trusted.</em></p>
<p><em>The goal of this project is to develop a fundamental approach to
ensure the trustworthiness of dependently typed programming languages
by means of a small core language that is deeply embedded into the
full language. Embedding the core language within the full language
erases the gap between its specification and implementation,
minimizing the amount of code we have to trust and enabling us to do a
meta-theoretic study to increase our trust even further. An embedded
core language is also useful in practice: we intend to explore its
potential as the basis for meta-programming and proof exchange with
other languages. Concretely, we will develop Agda Core, a small and
trustworthy core language for Agda embedded within Agda itself. In the
development of Agda Core we will pay special attention to
extensibility, providing a solid foundation for formalizing Agda’s
various extensions. Thus we provide the basis for the next generation
of programming languages that make it easy to develop programs that do
what they are supposed to do, and nothing else.</em></p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Wed, 11 Nov 2020 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/veni-announcement.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>Announcement: I'm moving to Delft!</title>
    <link>https://jesper.sikanda.be/posts/delft-announcement.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Announcement: I'm moving to Delft!</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Announcement: I'm moving to Delft!</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on November 12, 2019
    </p>
    <p>I’m very glad to announce that starting on the 1st of December, I will
join the <a href="https://pl.ewi.tudelft.nl/">programming languages group at TU
Delft</a> as an assistant professor! Some of
my new colleagues are <a href="https://eelcovisser.org/">Eelco Visser</a>,
<a href="https://robbertkrebbers.nl/">Robert Krebbers</a>, <a href="http://casperbp.net/">Casper Bach
Poulsen</a>, <a href="http://aj.rouvoeten.nl/">Arjen
Rouvoet</a>, and <a href="https://hendrik.van-antwerpen.net/">Hendrik van
Antwerpen</a>. I’m looking forward to
work with them, and of course I will continue to work on improving
Agda.</p>
<p>In related news, I will soon be hiring a PhD student. So if you are
interested to work on improving Agda and dependently typed programming
in general, send me an email at
<a href="mailto:jesper@sikanda.be">jesper@sikanda.be</a> (more information about
the formalities will follow later).</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Tue, 12 Nov 2019 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/delft-announcement.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>Rewriting type theory</title>
    <link>https://jesper.sikanda.be/posts/rewriting-type-theory.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Rewriting type theory</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Rewriting type theory</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on October 30, 2019
    </p>
    <p hidden>
MathJax is awesome!
<span class="math display">\[
\definecolor{AgdaComment}{rgb}{0.7,0.13,0.13}
\definecolor{AgdaKeyword}{rgb}{0.8,0.4,0.0}
\definecolor{AgdaNumber}{rgb}{0.63,0.13,0.94}
\definecolor{AgdaCon}{rgb}{0.0,0.55,0.0}
\definecolor{AgdaField}{rgb}{0.93,0.07,0.54}
\definecolor{AgdaDef}{rgb}{0.0,0.0,0.8}
\definecolor{AgdaModule}{rgb}{0.63,0.13,0.94}
%
\newcommand\ty[1]{{{\color{AgdaDef}{\mathtt{Set}}}_{#1}}}
\newcommand\fun[1]{{\color{AgdaDef}{\mathtt{#1}}}}
\newcommand\data[1]{{\color{AgdaDef}{\mathtt{#1}}}}
\newcommand\con[1]{{\color{AgdaCon}{\mathtt{#1}}}}
\newcommand\field[1]{{\color{AgdaField}{\mathtt{#1}}}}
\newcommand\keyw[1]{{\color{AgdaKeyword}{\mathtt{#1}}}}
\newcommand\level{\fun{Level}}
%
\newcommand\emp{\cdot}
\newcommand\rew{\longrightarrow}
\newcommand\red{\longrightarrow}
\newcommand\subst[2]{{#1\, /\, #2}}
\newcommand\match[2]{{#1\, {/\!\!/}\, #2}}
\newcommand\ceq{\stackrel{?}{=}}
%
\newcommand{\ru}[2]{\dfrac{#1}{#2}}
\]</span>
</p>
<p>This is the second in a series of three blog posts on rewrite rules in
Agda. If you haven’t already, you can read the first post
<a href="hack-your-type-theory.html">here</a>. In that post, I gave several
examples of how you can use rewrite rules in Agda to make your life
easier and experiment with new extensions to type theory. This post
goes into the nitty-gritty details of how to rewrite rules work in
general, and how they interact with several other features of Agda.</p>
<p>Instead of starting with a full-fledged language like Agda, I
first describe a small core language with the ability to declare new
rewrite rules. After that, I’ll extend it with other features that
you are used to from Agda, such as datatypes, record types with
eta-equality, irrelevance, parametrized modules, implicit arguments
and metavariables, and universe level polymorphism.</p>
<p>I apologize in advance if this post is a little dry compared to the
previous one. However, I think it’s worth it to specify the algorithms
we use in detail to give a deeper understanding of a feature. And when
there’s ever some weird behaviour in the implementation of rewrite
rules, the spec helps to determine whether it is a bug in the
implementation or actually the intended semantics.</p>
<h1 id="rewriting-type-theory">Rewriting type theory</h1>
<p>Without further ado, let’s define our core rewriting type theory.</p>
<h2 id="syntax">Syntax</h2>
<p>The syntax has five constructors: variables, function symbols,
lambdas, pi types, and universes.</p>
<p><span class="math display">\[
\begin{array}{lcll}
u, v, A, B &amp;::=&amp; x\; \bar{u} &amp; \text{(variable applied to arguments)} \\
           &amp; | &amp; \fun{f}\; \bar{u} &amp; \text{(function symbol applied to arguments)} \\
	   &amp; | &amp; \lambda x.\, u &amp; \text{(lambda abstraction)} \\
	   &amp; | &amp; (x : A) \rightarrow B &amp; \text{(dependent function type)} \\
	   &amp; | &amp; \ty{i} &amp; \text{(\(i\)th universe)} \\
\end{array}
\]</span></p>
<p>As in the internal syntax of Agda, there is no way to represent a
<span class="math inline">\(\beta\)</span>-redex in this syntax. Instead, substitution <span class="math inline">\(u\sigma\)</span> is
defined to eagerly reduce <span class="math inline">\(\beta\)</span>-redexes on the fly.</p>
<p>Contexts are right-growing lists of variables annotated with their
types.</p>
<p><span class="math display">\[
\begin{array}{lcll}
\Gamma, \Delta &amp;::=&amp; \emp &amp; \text{(empty context)} \\
               &amp; | &amp; \Gamma (x : A) &amp; \text{(context extension)} \\
\end{array}
\]</span></p>
<p>Patterns <span class="math inline">\(p,q\)</span> share their syntax with regular terms, but must
satisfy some additional restrictions. To start with, the only allowed
patterns are unapplied variables <span class="math inline">\(x\)</span> and applications of function
symbols to other patterns <span class="math inline">\(\fun{f}\; \bar{p}\)</span>. This allows us for
example to declare rewrite rules like <span class="math inline">\(\fun{plus}\; x\; \con{zero}
\rew x\)</span> and <span class="math inline">\(\fun{plus}\; x\; (\con{suc}\; y) \rew \con{suc}\; (x +
y)\)</span>.</p>
<h2 id="declarations">Declarations</h2>
<p>In this simple core language, there are two kinds of declarations:
function symbols (corresponding to a <code>postulate</code> in Agda) and rewrite
rules (corresponding to a <code>postulate</code> + a <code>{-# REWRITE #-}</code> pragma).</p>
<p><span class="math display">\[
\begin{array}{lcll}
d &amp;::=&amp; \fun{f} : A &amp; \text{(function symbol)} \\
  &amp; | &amp; \forall \Delta. \fun{f}\; \bar{p} : A \rew v &amp; \text{(rewrite rule)} \\
\end{array}
\]</span></p>
<p>Since this is a blog post and not a full paper, I omit the typing and
conversion rules. The only relevant bit are the rules for checking the
validity of a rewrite rule:</p>
<ul>
<li><p>Each variable in <span class="math inline">\(\Delta\)</span> must occur exactly once in the pattern
<span class="math inline">\(\bar{p}\)</span> (we will later relax this to ‘at least once’).</p></li>
<li><p>The left- and right-hand side of the rewrite rule must be
well-typed, i.e. <span class="math inline">\(\Delta \vdash \fun{f}\; \bar{p} : A\)</span> and <span class="math inline">\(\Delta \vdash v : A\)</span>.</p></li>
<li><p>The left-hand side of the rewrite rule should be neutral, i.e. it
should not reduce.</p></li>
</ul>
<p>The first restriction is necessary because otherwise reduction would
introduce variables that are not in scope, breaking well-scopedness of
expressions (if you do not agree this is reasonable, you’re reading
the wrong blog). Without the second restriction, it would be easy
to define rewrite rules that break type preservation (though just
well-typedness of rewrite rules is not sufficient, see the next post
in this series). It is possible to go without the third restriction,
but in practice this would mean that the rewrite rule would never be
applied.</p>
<h2 id="reduction-and-matching">Reduction and matching</h2>
<p>To reduce a term <span class="math inline">\(\fun{f}\; \bar{u}\)</span>, we look all the rewrite rules
of <span class="math inline">\(\fun{f}\)</span> to see if any of them apply (we assume a global
signature <span class="math inline">\(\Sigma\)</span> containing all declarations).</p>
<p><span class="math display">\[
\ru{(\forall \Delta. \fun{f}\; \bar{p} : A \rew v) \in \Sigma \qquad [\match {\bar u} {\bar p}] \Rightarrow \sigma}
   {\fun{f}\; \bar u \red v\sigma}
\]</span></p>
<p>Matching a term <span class="math inline">\(u\)</span> against a pattern <span class="math inline">\(p\)</span> produces (if it
succeeds) a substitution <span class="math inline">\(\sigma\)</span> and is written <span class="math inline">\([\match u p]
\Rightarrow \sigma\)</span>. In contrast to the first-match semantics of
clauses of a regular definition by pattern matching, all rewrite rules
are considered in parallel, so there is no need for separate notion of a
failing match.</p>
<p><span class="math display">\[
\begin{gather*}
\ru{}{[\match u x] \Rightarrow [\subst u x]} \qquad
%
\ru{[\match {\bar u} {\bar p}] \Rightarrow \sigma}{[\match {\fun{f}\; \bar u} {\fun{f}\; \bar p}] \Rightarrow \sigma} \\[2ex]
%
\ru{u \red^* v \qquad [\match v p] \Rightarrow \sigma}{[\match u p] \Rightarrow \sigma} \\[2ex]
%
\ru{}{[\match \emp \emp] \Rightarrow []} \qquad
%
\ru{[\match u p] \Rightarrow \sigma_1 \qquad [\match {\bar u} {\bar p}] \Rightarrow \sigma_2}{[\match {u;\bar u} {p;\bar p}] \Rightarrow \sigma_1 \uplus \sigma_2}
\end{gather*}
\]</span></p>
<p>Matching a term against a pattern variable produces a substitution
that assigns the given value to the variable, while matching an
expression <span class="math inline">\(\fun{f}\; \bar u\)</span> against a pattern <span class="math inline">\(\fun{f}\;
\bar{p}\)</span> recursively matches the arguments <span class="math inline">\(\bar{u}\)</span> against the
patterns <span class="math inline">\(\bar{p}\)</span>, combining the results of each match by taking
the disjoint union <span class="math inline">\(\sigma_1 \uplus \sigma_2\)</span>. Matching can also
reduce the term being matched, which means matching and reduction are
mutually recursive.</p>
<h1 id="higher-order-rewriting">Higher-order rewriting</h1>
<p>With the basic set of rewrite rules introduced in the previous
section, you can already declare a surprisingly large number of
rewrite rules for <em>first-order</em> algebraic structures. From the
examples of <a href="hack-your-type-theory.html">the previous post in this
series</a>, it handles all of example 1,
rules
<a href="https://jesper.sikanda.be/posts/hack-your-type-theory.html#8468"><code>map-fuse</code></a>
and
<a href="https://jesper.sikanda.be/posts/hack-your-type-theory.html#8599"><code>map-++</code></a>
from example 2, all of example 3, rule
<a href="https://jesper.sikanda.be/posts/hack-your-type-theory.html#14055"><code>//-beta</code></a>
from example 4, rules
<a href="https://jesper.sikanda.be/posts/hack-your-type-theory.html#16412"><code>catch-true</code></a>,
<a href="https://jesper.sikanda.be/posts/hack-your-type-theory.html#16504"><code>catch-false</code></a>,
and
<a href="https://jesper.sikanda.be/posts/hack-your-type-theory.html#16597"><code>catch-exc</code></a>
from example 5, and the rules dealing with <code>Bool</code> in example 6.</p>
<p>Most of the examples that don’t work yet are excluded because they use
<code>λ</code> and/or function types in the pattern of a rewrite rule. This
brings us to the issue of <em>higher-order rewriting</em>. See also <a href="https://github.com/agda/agda/issues/1563">issue
#1563</a> on the Agda bug
tracker for more examples where higher-order rewrite rules are
needed. Although the metatheory of higher-order rewrite systems is
notoriously complex, merely implementing it is much easier.</p>
<p>To support higher-order rewriting, we extend the pattern syntax beyond
variables and function symbols. The following patterns are supported:</p>
<ul>
<li><p>A lambda pattern <span class="math inline">\(\lambda x. p\)</span></p></li>
<li><p>A function type pattern <span class="math inline">\((x:p) \rightarrow q\)</span></p></li>
<li><p>A <em>bound variable</em> pattern <span class="math inline">\(x\; \bar p\)</span>, where <span class="math inline">\(x\)</span> is a
variable bound locally in the pattern by a lambda or function type</p></li>
</ul>
<p>During matching it is important to keep the (rigid) bound variables
separate from the (flexible) pattern variables. For this purpose, the
matcher keeps a list <span class="math inline">\(\Phi\)</span> of all rigid variables. This list is not
touched by any of the previous rules, but any variables bound by a
<span class="math inline">\(\lambda\)</span> or a function type are added to it.</p>
<p><span class="math display">\[
\begin{gather*}
\ru{\Phi, x \vdash [\match u p] \Rightarrow \sigma}{\Phi \vdash [\match {\lambda x.\, u} {\lambda x.\, p}] \Rightarrow \sigma} \\[2ex]
%
\ru{\Phi \vdash [\match A p] \Rightarrow \sigma_1 \qquad \Phi, x \vdash [\match B q] \Rightarrow \sigma_2}{\Phi \vdash [\match {(x : A) \rightarrow B} {(x : p) \rightarrow q}] \Rightarrow \sigma_1 \uplus \sigma_2} \\[2ex]
%
\ru{x \in \Phi \qquad \Phi \vdash [\match {\bar u} {\bar p}] \Rightarrow \sigma}{\Phi \vdash [\match {x\; \bar u} {x\; \bar p}] \Rightarrow \sigma} \\[2ex]
\end{gather*}
\]</span></p>
<p>Note the strong similarity between the third rule and the rule for
matching a function symbol <span class="math inline">\(\fun{f}\)</span>. This is not a coincidence:
both function symbols and bound variables act as rigid symbols that
can be matched against.</p>
<p>The rules above extend the pattern syntax to allow for bound variables
in patterns, and allow for rules such as
<a href="https://jesper.sikanda.be/posts/hack-your-type-theory.html#8365"><code>map-id</code></a>
(i.e. <code>map (λ x → x) xs ≡ xs</code>). However, they do not yet constitute
true higher-order rewriting (such as in rules
<a href="https://jesper.sikanda.be/posts/hack-your-type-theory.html#15878"><code>raise-fun</code></a>,
<a href="https://jesper.sikanda.be/posts/hack-your-type-theory.html#19131"><code>cong-Π</code></a>,
and
<a href="https://jesper.sikanda.be/posts/hack-your-type-theory.html#19234"><code>cong-λ</code></a>). For
this we also consider pattern variables applied to arguments.</p>
<p>As is well known, allowing arbitrary patterns as arguments to pattern
variables makes matching undecidable (!), so it is customary to
restrict patterns to Miller’s pattern fragment, where pattern
variables must be applied to <em>distinct</em>, <em>bound</em> variables. Here is
the general rule for matching against a pattern variable in the Miller
fragment:</p>
<p><span class="math display">\[
\ru{FV(v) \cap \Phi \subseteq \bar{y}}
   {\Phi \vdash [\match v {x\; \bar{y}}] \Rightarrow [\subst {(\lambda \bar{y}. v)} x]}
\]</span></p>
<p>Since all the arguments of <span class="math inline">\(x\)</span> are variables, we can construct the
lambda term <span class="math inline">\(\lambda \bar{y}.\, v\)</span>. To avoid having out-of-scope
variables in the resulting substitution, we check that the free
variables in <span class="math inline">\(v\)</span> are included in <span class="math inline">\(\bar{y}\)</span>.</p>
<h1 id="eta-equality-and-record-types">Eta-equality and record types</h1>
<p>If you’ve been paying close attention, you may have noticed a flaw in
the matching for <span class="math inline">\(\lambda\)</span>-patterns: it does not respect
<span class="math inline">\(\eta\)</span>-equality. With <span class="math inline">\(\eta\)</span>-equality for functions, any term <span class="math inline">\(u
: (x : A) \rightarrow B\; x\)</span> can always safely replaced with <span class="math inline">\(\lambda x.\, u\; x\)</span>, so it should also match a pattern <span class="math inline">\(\lambda
x.\, p\)</span>. In this case fixing the problem is not hard since we can
<span class="math inline">\(\eta\)</span>-expand on the fly whenever we match something against a
<span class="math inline">\(\lambda\)</span>-pattern:</p>
<p><span class="math display">\[
\ru{\Phi, x \vdash [\match {u\; x} p] \Rightarrow \sigma}
   {\Phi \vdash [\match u {\lambda x.\, p}] \Rightarrow \sigma}
\]</span></p>
<p>Unfortunately this is not enough to deal with <span class="math inline">\(\eta\)</span>-equality in
general. It’s possible that the <em>pattern</em> is underapplied as well,
e.g. when we match a term of type <span class="math inline">\((x : A) \rightarrow B\; x\)</span>
against a pattern <span class="math inline">\(\fun{f}\; \bar{p}\)</span> or <span class="math inline">\(x\; \bar{p}\)</span>.</p>
<p>To respect eta equality for functions and record types, we need to
make matching <em>type-directed</em>! We also need contexts with the types of
the free and bound variables. Thus we extend the matching judgement to
<span class="math inline">\(\Gamma;\Phi \vdash [\match {u : A} {p}] \Rightarrow \sigma\)</span> where
<span class="math inline">\(A\)</span> is the type of <span class="math inline">\(u\)</span> (note: not necessarily the same as the type
of <span class="math inline">\(p\)</span>!) and <span class="math inline">\(\Gamma\)</span> and <span class="math inline">\(\Phi\)</span> are now contexts of pattern
variables and bound variables respectively.</p>
<p>The type information is used by the matching algorithm to do
on-the-fly <span class="math inline">\(\eta\)</span>-expansion of functions whenever the type is a
function type:</p>
<p><span class="math display">\[
\ru{\Gamma;\Phi(x:A) \vdash [\match {u\; x : B} {p\; x}] \Rightarrow \sigma}
   {\Gamma;\Phi \vdash [\match {u : (x : A) \rightarrow B} p] \Rightarrow \sigma}
\]</span></p>
<p>Here <span class="math inline">\(p\; x\)</span> is only defined if the result is actually a pattern,
otherwise the rule cannot be applied. We may also reduce the type:</p>
<p><span class="math display">\[
\ru{A \red^* A' \qquad \Gamma;\Phi \vdash [\match {u : A'} p] \Rightarrow \sigma}
   {\Gamma;\Phi \vdash [\match {u : A} p] \Rightarrow \sigma}
\]</span></p>
<h2 id="eta-for-records"><span class="math inline">\(\eta\)</span> for records</h2>
<p>Agda has <span class="math inline">\(\eta\)</span>-equality not just for function types, but also for
record types. For example, any term <span class="math inline">\(u : A \times B\)</span> is
definitionally equal to <span class="math inline">\((\field{fst}\; u , \field{snd}\; u)\)</span>. Since
<span class="math inline">\(\eta\)</span>-equality of records is a core rule of Agda, we extend the
matching algorithm to deal with it (see <a href="https://github.com/agda/agda/issues/2979">issue
#2979</a> and <a href="https://github.com/agda/agda/issues/3335">issue #3335</a>). Luckily, since we now have
a type-directed matching algorithm, it is easy to handle this rule.</p>
<p>Let <span class="math inline">\(\fun{R} : \ty{i}\)</span> be a record type with fields <span class="math inline">\(\field{\pi_1} : A_1\)</span>, <span class="math inline">\(\ldots\)</span>, <span class="math inline">\(\field{\pi_n} : A_n\)</span>.
Since records can be dependent, each type <span class="math inline">\(A_i\)</span> may depend on the
previous fields <span class="math inline">\(\field{\pi_1}\)</span>, <span class="math inline">\(\ldots\)</span>,<span class="math inline">\(\field{\pi_{i-1}}\)</span>. We
have the following matching rule:</p>
<p><span class="math display">\[
\ru{\Gamma;\Phi \vdash [\match {\field{\pi_i}\; u : A_i'} {\field{\pi_i}\; p}] \Rightarrow \sigma \quad (i=1\cdots n)}{\Gamma;\Phi \vdash [\match {u : \fun{R}} p] \Rightarrow \sigma}
\]</span></p>
<p>In this rule, the type <span class="math inline">\(A_i'\)</span> is equal to <span class="math inline">\(A_i[\subst
{\field{\pi_1}\; u} {\field{\pi_1}}, \cdots, \subst {\field{\pi_{i-1}}\; u}
{\field{\pi_{i-1}}}]\)</span>.</p>
<p>In the case where <span class="math inline">\(n=0\)</span>, this rule says that a term of the unit
record type <span class="math inline">\(\fun{\top}\)</span> (with no fields) matches <em>any</em> pattern. So
the matching algorithm even handles the notorious <span class="math inline">\(\eta\)</span>-unit
types!</p>
<h1 id="non-linearity-and-non-patterns">Non-linearity and non-patterns</h1>
<p>Sometimes it is useful to define rewrite rules with <em>non-linear</em>
patterns, i.e. where a pattern variable occurs more than once. As an
example, this allows us to postulate an equality proof <code>trustMe : (x y : A) → x ≡ y</code> with a rewrite rule <code>trustMe x x ≡ refl</code>. This can be
used in a similar way to Agda’s built-in
<a href="https://agda.readthedocs.io/en/v2.6.0.1/language/built-ins.html#primtrustme"><code>primTrustMe</code></a>.
Another example where non-linearity is used is the rule
<a href="https://jesper.sikanda.be/posts/hack-your-type-theory.html#12887"><code>transportR-refl</code></a>
from example 4 in my previous post (it also needs irrelevance for
<code>Prop</code>, see <a href="https://github.com/agda/agda/issues/3525">issue #3525</a>
for more details).</p>
<p>Non-linear matching is actually an instance of a more general pattern
I call a <em>non-pattern</em>. A non-pattern is an arbitrary term that
matches another term if the terms are definitionally
equal. Non-patterns allow embedding of arbitrary terms inside a
pattern, but they cannot bind any variables. So even though we allow
non-patterns, each pattern variable used in the rewrite rule still has
to occur <em>at least once</em> in a pattern position.</p>
<p>Non-patterns are similar to inaccessible patterns (aka dot patterns in
Agda) used in dependent pattern matching, with the important
difference that inaccessible patterns are <em>assumed</em> to match whenever
the rest of the pattern does, while non-patterns have to be <em>checked</em>.</p>
<p>For both non-linear patterns and non-patterns, the matching algorithm
needs to decide whether two given terms are definitionally
equal. This means reduction and matching are now mutually recursive
with conversion checking.</p>
<p>Describing the full conversion checking algorithm of Agda would take
us too far for this blog post, so let’s assume we have a
(type-directed!) conversion judgement <span class="math inline">\(\Gamma \vdash u = v : A\)</span>. We
extend the matching algorithm to also output a set of <em>constraints</em>
<span class="math inline">\(\Psi = \{ \Phi_i \vdash u_i \ceq p_i\; |\; i = 1\cdots n \}\)</span>. The
new judgement form of matching is now <span class="math inline">\(\Gamma;\Phi \vdash [\match {v
: A} p] \Rightarrow \sigma ; \Psi\)</span> (somehow I always end up with
these crazy judgements with way too many arguments). We extend the
matching algorithm with the ability to <em>postpone</em> a matching problem:</p>
<p><span class="math display">\[
\ru{}
   {\Gamma;\Phi \vdash [\match {v : A} p] \Rightarrow []; \{ \Phi \vdash v \ceq p : A \}}
\]</span></p>
<p>All other rules just gather the set of constraints, taking the union
whenever matching produces multiple sub-problems. When matching
concludes, we check that all constraints actually hold before applying
the rewrite rule:</p>
<p><span class="math display">\[
\ru{\begin{array}{c}\fun{f} : \Gamma \rightarrow A \in \Sigma \qquad (\forall\Delta. \fun{f}\; \bar{p} : B \rew v) \in \Sigma \\ [\match {\bar u : \Gamma[\bar u]} {\bar p}] \Rightarrow \sigma;\Psi \qquad \forall (\Phi \vdash v \ceq p : A) \in \Psi.\; \Phi \vdash v = p\sigma : A \end{array} }
   {\fun{f}\; \bar u \red v\sigma}
\]</span></p>
<p>When checking a constraint we apply the final substitution <span class="math inline">\(\sigma\)</span>
to the pattern <span class="math inline">\(p\)</span> but not to the term <span class="math inline">\(v\)</span> or the type <span class="math inline">\(A\)</span>. This
makes sense because the term being matched does not contain any
pattern variables in the first place (and neither does its type).</p>
<p>A quick note on the implementation side: to actually change Agda to
make the matching depend on conversion checking took <a href="https://github.com/agda/agda/pull/3589">quite some
effort</a>.
The reason for this difficulty was that reduction and matching are
running in one monad <code>ReduceM</code>, while conversion was running in
another monad <code>TCM</code> (short for ‘type-checking monad’). In the new
version after my refactoring, the conversion checker is now
<em>polymorphic</em> in the monad it runs in. This means the same piece of
code implements at the same time a pure, declarative conversion
checker and a stateful constraint solver. I think this usage of effect
polymorphism is pretty cool, and I don’t know many other
production-ready languages besides Haskell where this would be
possible.</p>
<h1 id="rewriting-datatypes-and-constructors">Rewriting datatypes and constructors</h1>
<p>Another important question is how rewrite rules interact with
datatypes such as <code>Bool</code>, <code>Nat</code>, and <code>_≡_</code>. Can we simply add rewrite
rules to (type and/or term) constructors? It turns out the answer is
actually a bit more complicated.</p>
<p>If we allow rewriting of datatype constructors, you could (for
example) postulate an equality proof of type <code>Nat ≡ Bool</code> and register
it as a rewrite rule. However, this would mean <span class="math inline">\(\con{zero} :
\data{Bool}\)</span>, violating an important internal invariant of Agda that
any time we have <span class="math inline">\(\con{c}\; \bar{u} : \data{D}\)</span> for a constructor
<span class="math inline">\(\con{c}\)</span> and a datatype <span class="math inline">\(\data{D}\)</span>, <span class="math inline">\(\con{c}\)</span> is actually a
constructor of <span class="math inline">\(\data{D}\)</span> (see <a href="https://github.com/agda/agda/issues/3846">issue
#3846</a>). This is very unsafe
even for the low standards of rewrite rules. For this reason, it’s not
allowed to have rewrite rules on datatypes or record types. Sorry!</p>
<p>For <em>constructors</em> of datatypes there is no a priori reason why they
cannot have rewrite rules attached to them. This would actually be
useful to define a ‘definitional quotient type’ where some of the
constructors may compute.</p>
<p>Unfortunately, there is another problem: internally, Agda does not
store the constructor arguments corresponding to the parameters of the
datatype. For example, the constructors <code>[]</code> and <code>_∷_</code> of the <code>List A</code>
type do not store the type <code>A</code> as an argument. This is actually really
important for efficiency! However it means that rewrite rules on
constructors cannot match against arguments in those positions, or
bind pattern variables in them.</p>
<p>Currently, Agda enforces this restriction by requiring that for a
rewrite rule on a constructor, the parameters need to be <em>fully
general</em>, i.e. they must be distinct variables (see <a href="https://github.com/agda/agda/issues/3211">issue
#3211</a>). But this is not
quite satisfactory yet, as shown by <a href="https://github.com/agda/agda/issues/3538">issue
#3538</a>, so if anyone knows a
better criterion it would be welcome!</p>
<h1 id="irrelevance-and-prop">Irrelevance and Prop</h1>
<p>An important feature of Agda that is (in my opinion) underused is
<em>definitional irrelevance</em>, which comes in the two flavours of
<a href="https://agda.readthedocs.io/en/v2.6.0.1/language/irrelevance.html">irrelevant function types <code>.A → B</code></a>
and the <a href="https://agda.readthedocs.io/en/v2.6.0.1/language/prop.html">universe
<code>Prop</code></a> of
definitionally proof-irrelevant propositions.</p>
<p>For rewrite rules with irrelevant parts in their patterns, we do not
want matching to ever fail because this would mean a supposedly
irrelevant term is not actually irrelevant. However, it should still
be allowed to <em>bind</em> a variable in an irrelevant position, since we
might want to use that variable in (irrelevant positions of) the
right-hand side (see <a href="https://github.com/agda/agda/issues/2300">issue
#2300</a>). This means in
irrelevant positions we allow:</p>
<ol type="1">
<li><p>pattern variables <span class="math inline">\(x\; \bar y\)</span> where <span class="math inline">\(\bar y\)</span> are all the bound
variables in scope, and</p></li>
<li><p>non-patterns <span class="math inline">\(u\)</span> that do not bind any variables.</p></li>
</ol>
<p>Because of irrelevance, neither of these will ever produce a mismatch.</p>
<p>Together with the ability to have non-linear patterns, this allows us
to have cool rewrite rules such as <code>transportR-refl : transportR P refl x ≡ x</code> where <code>transportR : (P : A → Set ℓ) → x ≐ y → P x → P y</code>
and <code>x ≐ y</code> is the equality type in <code>Prop</code>. The constructor <code>refl</code>
here is irrelevant, so this rule does not actually match against the
constructor <code>refl</code>! Instead, Agda checks that the two arguments
<code>x</code> and <code>y</code> are definitionally equal, and apply the rewrite rule if
this is the case.</p>
<h1 id="universe-level-polymorphism">Universe level polymorphism</h1>
<p>Universe level polymorphism allows Agda programmers to write
definitions that are polymorphic in the universe level of a type
parameter. Since the type <code>Level</code> of universe levels is a first-class
type in Agda, it interacts natively with rewrite rules: patterns can
bind variables of type <code>Level</code> just as any other type. This allows us
for example to define rewrite rules such as
<a href="https://jesper.sikanda.be/posts/hack-your-type-theory.html#8365"><code>map-id</code></a>
that work on level-polymorphic lists.</p>
<p>The type <code>Level</code> also supports two operations <code>lsuc : Level → Level</code>
and <code>_⊔_ : Level → Level → Level</code>. These operations have a complex
equational structure: <code>_⊔_</code> is associative, commutative, and
idempotent, and <code>lsuc</code> distributes over <code>_⊔_</code>, just to name a few of
the laws (the <a href="https://github.com/agda/agda/blob/master/src/full/Agda/TypeChecking/Substitute.hs#L1475-L1516">actual implementation of the normalization of
levels</a>
is worth a look). This causes trouble for the matching used for
rewrite rules: how would one even determine whether a given level
matches <code>a ⊔ b</code> when <code>_⊔_</code> is commutative? <a href="https://github.com/agda/agda/issues/2090">Issue
#2090</a> and <a href="https://github.com/agda/agda/issues/2299">issue
#2299</a> show some of the
things that would go wrong. For this reason it is not allowed to have
rewrite rules that match against <code>lsuc</code> or <code>_⊔_</code> (i.e. expressions
containing these symbols are treated as non-patterns).</p>
<p>This restriction on patterns of type <code>Levels</code> is seems reasonable
enough, but it causes trouble for certain rewrite rules. In
particular, it is often not satisfied by rewrite rules that match on
function types — like the <code>cong-Π</code> rule we used in the encoding of
observational type theory last time, or like the problem described in
<a href="https://github.com/agda/agda/issues/3971">issue #3971</a>. The problem
is that if <code>A : Set ℓ₁</code> and <code>B : Set ℓ₂</code>, then the function type <code>(x : A) → B</code> has type <code>Set (ℓ₁ ⊔ ℓ₂)</code>, so there is no sensible position to
bind the variables <code>ℓ₁</code> and <code>ℓ₂</code>.</p>
<p>To allow rewrite rules such as <code>cong-Π</code>, we need to think a little out
of the box. It turns out that in the internal syntax of Agda, function
types <code>(x : A) → B</code> are annotated with the sorts of <code>A</code> and <code>B</code>. So
the ‘real’ function type of Agda looks more like <code>(x : A : Set ℓ₁) → (B : Set ℓ₂)</code>. This means that if we allow rewrite rules to bind
pattern variables in these hidden annotations, we are saved! The
matching rule for function types now becomes:</p>
<p><span class="math display">\[
\ru{\begin{array}{c}
      \Gamma;\Phi \vdash [\match {A : \ty{\ell_1}} p] \Rightarrow \sigma_1; \Psi_1 \qquad
      \Gamma;\Phi \vdash [\match {\ell_1 : \level} q] \Rightarrow \sigma_2; \Psi_2 \\
      \Gamma;\Phi(x:A) \vdash [\match {B : \ty{\ell_2}} r] \Rightarrow \sigma_3; \Psi_3 \qquad
      \Gamma;\Phi [\match {\ell_2 : \level} s] \Rightarrow \sigma_4; \Psi_4
    \end{array} }
   {\begin{array}{l}
      \Gamma;\Phi \vdash [\match {(x : A : \ty{\ell_1}) \rightarrow (B : \ty{\ell_2})} {(x : p : \ty{q}) \rightarrow (r : \ty{s})}] \\
      \qquad \Rightarrow (\sigma_1 \uplus \sigma_2 \uplus \sigma_3 \uplus \sigma_4);(\Psi_1 \cup \Psi_2 \cup \Psi_3 \cup \Psi_4)
    \end{array}
  }
\]</span></p>
<p>That’s quite a mouthful, but sometimes that’s the price you have to
pay to talk about real systems rather than toy examples!</p>
<h1 id="metavariables-and-constraint-solving">Metavariables and constraint solving</h1>
<p>To automatically fill in the values of implicit arguments, Agda
inserts <em>metavariables</em> as their placeholders. These metavariables are
then solved during typechecking by the constraint solver. As a rule,
whenever you add a new feature to Agda, eventually it will cause
something to go wrong in the constraint solver. This is certainly the
case for rewrite rules. I’m in no position to give a full account of
Agda’s constraint solver here, but let me discuss the most important
ways it is impacted by rewrite rules.</p>
<h2 id="blocking-tags">Blocking tags</h2>
<p>To do proper constraint solving, we need to know when a reduction is
<em>blocked</em> on a particular metavariable. Usually it is possible to
point out a <em>single</em> metavariable, but this is no longer the case when
rewrite rules are involved:</p>
<ul>
<li><p>With overlapping rewrite rules, it is possible to be blocked on a
<em>set</em> of metavariables. For example, if we try to reduce the
expression <span class="math inline">\(X + Y\)</span> where <span class="math inline">\(X\)</span> and <span class="math inline">\(Y\)</span> are metavariables of type <code>Nat</code> and
<code>_+_</code> is the parallel version of addition as in example 1 of the
previous post, then this expression might reduce further when
<em>either</em> <span class="math inline">\(X\)</span> <em>or</em> <span class="math inline">\(Y\)</span> is instantiated to a constructor.
So a postponed constraint involving this expression has
to be woken up when <span class="math inline">\(X\)</span> or <span class="math inline">\(Y\)</span> is instantiated.</p></li>
<li><p>For higher-order matching, we check whether a particular variable
occurs freely in the body of a lambda or pi. When metavariables are
involved, a variable occurrence may be <em>flexible</em>: whether or not
the variable occurs depends on the instantiation of a particular
metavariable (see <a href="https://github.com/agda/agda/issues/1663">issue
#1663</a>). In this case we
also remember the set of metavariables on which the flexible
occurrence depends.</p></li>
<li><p>Likewise, when a rewrite rule with non-linear patterns or
non-patterns is blocked on the conversion check because of an
unsolved metavariable, we need to know what metavariable is causing
the problem (see <a href="https://github.com/agda/agda/issues/1987">issue
#1987</a> and <a href="https://github.com/agda/agda/issues/2302">issue
#2302</a>).</p></li>
</ul>
<p>Currently, the Agda implementation uses only an approximation of the
set of metavariables it encounters (i.e. only the first metavariable
encountered). This is not too harmful because the current
implementation of Agda is anyway quite generous in how often it
retries to solve sleeping constraints. If in the future Agda would be
changed to be more careful in letting sleeping constraints lie (which
would be a good thing to do!), a more precise tracking of blocking
metavariables would also be desirable.</p>
<h2 id="pruning-and-constructor-like-symbols">Pruning and constructor-like symbols</h2>
<p>When adding new rewrite rules, we also keep track of what symbols are
<em>constructor-like</em>. This is important for the pruning phase of the
constraint solver. For example, let’s say the constraint solver is
trying to solve an equation <span class="math inline">\(X \ceq Y\; (\fun{f}\; x)\)</span>. Since the
metavariable <span class="math inline">\(X\)</span> does not depend on the variable <span class="math inline">\(x\)</span>, the
constraint solver attempts to <em>prune</em> the dependency of <span class="math inline">\(Y\)</span> on
<span class="math inline">\(x\)</span>. If <span class="math inline">\(\fun{f}\)</span> is a regular postulate without any rewrite
rules, there is no way that <span class="math inline">\(Y\)</span> could depend on <span class="math inline">\(\fun{f}\; x\)</span>
without depending on <span class="math inline">\(x\)</span>, so the dependency of <span class="math inline">\(Y\)</span> on its first
argument is pruned away. However, if there is a rewrite rule where
<span class="math inline">\(f\)</span> plays the role of a constructor — say a rule <span class="math inline">\(\fun{g}\;
(\fun{f}\; y) \rew \con{true}\)</span> — then the assignment <span class="math inline">\(X :=
\con{true}\)</span> and <span class="math inline">\(Y := \lambda y.\, \fun{g}\; y\)</span> is a valid solution
to the constraint where <span class="math inline">\(Y\)</span> does depend on its argument, so it
should <strong>not</strong> be pruned away.</p>
<h1 id="parametrized-modules-and-where-blocks">Parametrized modules and <code>where</code> blocks</h1>
<p>In one sense, parametrized modules in Agda can be thought of as
<span class="math inline">\(\lambda\)</span>-lifting all the definitions inside the module: if a module
with parameters <span class="math inline">\(\Gamma\)</span> contains a definition of <span class="math inline">\(\fun{f} : A\)</span>,
then the real type of <span class="math inline">\(\fun{f}\)</span> is <span class="math inline">\(\Gamma \rightarrow A\)</span>. But
this does not quite capture the intuition that definitions inside a
parametrized module should be <em>parametric</em> in the parameters. So in a
different sense module parameters are <em>rigid symbols</em> more alike to
postulates than variables. For this reason, module parameters play a
double role on the left-hand side of a rewrite rule:</p>
<ul>
<li><p>As long as the parameter is in scope, it is treated as a
non-pattern, so it has to match ‘on the nose’ (i.e. it cannot be
instantiated by matching).</p></li>
<li><p>Once the parameter goes out of scope (i.e. at the end of the
module), it is treated as a regular pattern variable that can be
instantiated by matching.</p></li>
</ul>
<p>This intuition of module parameters as rigid symbols also applies to
Agda’s treatment of <code>where</code> blocks, which are nothing more than
modules parametrized over the pattern variables of the clause (you can
even give a name to the <code>where</code> module using the <a href="https://agda.readthedocs.io/en/v2.6.0.1/language/let-and-where.html#where-blocks"><code>module M where</code>
syntax</a>!)
Here a ‘local’ rewrite rule in a where block should only apply for the
specific arguments to the function that are used in the clause, not
those of a recursive call (see <a href="https://github.com/agda/agda/issues/1652">issue
#1652</a> for an example).</p>
<h1 id="conclusion">Conclusion</h1>
<p>This post is my attempt at documenting all the weird interactions that
come up when you try to integrate user-defined rewrite rules into a
general-purpose dependently typed language. I also wanted to document
the solutions that I came up with along the way. Of course, this is by
no means the only way to do things, nor the best one. But at least it
is <em>a</em> way that I found to work, so I thought it would be worth
writing it down. I know at least some people who are using rewrite
rules in exciting ways I didn’t anticipate, which makes me very glad!</p>
<p>This post was about the technology of how to add rewrite rules to Agda
or similar languages. Using these rewrite rules is essentially
building your own type theory, which means you have to do your own
<em>meta</em>-theory to make sure everything is safe (for whatever notion of
<em>safe</em> you like). But there are many use cases of rewrite rules that
feel like they shouldn’t break any of the usual properties we expect
from an Agda program. Can we carve out a usable fragment of rewrite
rules that is <em>guaranteed</em> to do no harm? Stay tuned for the next and
final post in this series!</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Wed, 30 Oct 2019 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/rewriting-type-theory.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>Hack your type theory with rewrite rules</title>
    <link>https://jesper.sikanda.be/posts/hack-your-type-theory.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Hack your type theory with rewrite rules</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Hack your type theory with rewrite rules</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on October 21, 2019
    </p>
    <p>This is the first in a series of three blog posts on rewrite rules in
Agda. In contrast to my <a href="formalize-all-the-things.html">previous
post</a>, this post will decidedly
<em>non-introductory</em>. Instead, we will have some fun by doing unsafe
things and hacking things into the core reduction machinery of Agda.</p>
<p>The main part of this post will consist of several examples of how to
use rewrite rules to go beyond the usual boundaries set by Agda and
define your <em>own</em> computation rules. The next two posts in this series
will go more into how rewrite rules work in general and the metatheory
of type theory extended with rewrite rules.</p>
<h2 id="why-rewrite-rules">Why rewrite rules?</h2>
<p>The way I learned type theory from <a href="https://www.cs.kent.ac.uk/people/staff/sjt/TTFP/ttfp.pdf">Simon Thompson’s
book</a>, each
type former is defined by four sets of rules:</p>
<ul>
<li><p>The <strong>formation rule</strong> (e.g. <code>Bool : Set</code>)</p></li>
<li><p>The <strong>introduction rules</strong> (e.g. <code>true : Bool</code> and <code>false : Bool</code>)</p></li>
<li><p>The <strong>elimination rules</strong> (e.g. if <code>P : Bool → Set</code>, <code>b : Bool</code>, <code>pt : P true</code>,
and <code>pf : P false</code>, then <code>if b then pt else pf : P b</code>)</p></li>
<li><p>The <strong>computation rules</strong> (e.g. <code>if true then pt else pf = pt</code> and
<code>if false then pt else pf = pf</code>)</p></li>
</ul>
<p>Most of the time when we work in Agda, we don’t introduce new types by
directly giving these rules. That would be very unsafe, as there’s no
easy way for Agda to check that the given rules make sense. Instead,
we can introduce new rules through <em>schemes</em> that are well-known to be
safe, such as strictly positive datatypes and terminating functions by
dependent pattern matching.</p>
<p>However, if you’re experimenting with adding new features to
dependently typed languages or if you’re a heavy user of them, you
might find working within these schemes a bit too restrictive. You
might be tempted to use <code>postulate</code> to define new types and terms, or
to turn off the safety checks for termination, positivity, and/or
universe consistency. Yet there is one thing that cannot be simply
added by using these tricks. This is exactly the one thing that breathes
life into the type theory: the computation rules. This is the purpose
of <em>rewrite rules</em> in Agda (as well as in some other languages like
<a href="https://deducteam.github.io/">Dedukti</a>): to allow the user of the
language to extend the language’s notion of definitional equality with
additional computation rules.</p>
<p>Concretely, given a proof (or a postulate) <code>p : ∀ x₁ ... xₙ → f u₁ ... uₙ ≡ v</code>, you can register it as a rewrite rule with a pragma <code>{-# REWRITE p #-}</code>.
From this point on, Agda will automatically reduce
instances of the left-hand side <code>f u₁ ... uₙ</code> (i.e. for specific
values of <code>x₁ ... xₙ</code>) to the corresponding instance of <code>v</code>. To give a
silly example, if <code>f : A → A</code> and <code>p : ∀ x → f x ≡ x</code>, then the
rewrite rule will replace any application <code>f u</code> with <code>u</code>, effectively
turning <code>f</code> into the identity function <code>λ x → x</code>.</p>
<p>There are some restrictions on what kind of equality proofs can be
turned into rewrite rules, which I will go into more detail in the
next post. Until then, I hope the examples in this post give a good
idea of the kind of things that are possible.</p>
<p>One thing that is perhaps obvious but I want to stress nevertheless is
that by design rewrite rules are a <em>very unsafe</em> feature of
Agda. Compared to using <code>postulate</code>, rewrite rules don’t allow you to
break soundness (at least not directly), but they can break core
assumptions of Agda such as confluence of reduction and even type
preservation. So each time you use a rewrite rule, make sure you know
it is justified, or be prepared to suffer the consequences.</p>
<p>With the introduction out of the way, let’s jump into some examples of
cool things you can do with rewrite rules.</p>
<h2 id="preliminaries">Preliminaries</h2>
<p>This whole post is written as a literate Agda file. As always, we some
basic options and imports. For the purpose of this post, the two most
important ones are the <code>--rewriting</code> flag and the import of
<code>Agda.Builtin.Equality.Rewrite</code>, which are both required to make
rewrite rules work.
Meanwhile, the <code>--prop</code> flag enables Agda’s <a href="https://agda.readthedocs.io/en/v2.6.0.1/language/prop.html"><code>Prop</code>
universe</a>
(new in Agda 2.6.0), which we will use in some of the examples.</p>
<pre class="Agda"><a id="4308" class="Symbol">{-#</a> <a id="4312" class="Keyword">OPTIONS</a> <a id="4320" class="Pragma">--rewriting</a> <a id="4332" class="Pragma">--prop</a> <a id="4339" class="Symbol">#-}</a>

<a id="4344" class="Keyword">open</a> <a id="4349" class="Keyword">import</a> <a id="4356" href="Agda.Primitive.html" class="Module">Agda.Primitive</a>
<a id="4371" class="Keyword">open</a> <a id="4376" class="Keyword">import</a> <a id="4383" href="Agda.Builtin.Bool.html" class="Module">Agda.Builtin.Bool</a>
<a id="4401" class="Keyword">open</a> <a id="4406" class="Keyword">import</a> <a id="4413" href="Agda.Builtin.Nat.html" class="Module">Agda.Builtin.Nat</a>
<a id="4430" class="Keyword">open</a> <a id="4435" class="Keyword">import</a> <a id="4442" href="Agda.Builtin.List.html" class="Module">Agda.Builtin.List</a>
<a id="4460" class="Keyword">open</a> <a id="4465" class="Keyword">import</a> <a id="4472" href="Agda.Builtin.Equality.html" class="Module">Agda.Builtin.Equality</a>
<a id="4494" class="Keyword">open</a> <a id="4499" class="Keyword">import</a> <a id="4506" href="Agda.Builtin.Equality.Rewrite.html" class="Module">Agda.Builtin.Equality.Rewrite</a>
</pre>
<p>As in the previous post, I will make heavy use of <a href="https://agda.readthedocs.io/en/v2.6.0.1/language/generalization-of-declared-variables.html">generalizable
variables</a>
to make the code more readable. (Honestly, I’m not sure how I ever
managed to write Agda code without them.)</p>
<pre class="Agda"><a id="4823" class="Keyword">variable</a>
  <a id="4834" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a> <a id="4836" href="hack-your-type-theory.html#4836" class="Generalizable">ℓ₁</a> <a id="4839" href="hack-your-type-theory.html#4839" class="Generalizable">ℓ₂</a> <a id="4842" href="hack-your-type-theory.html#4842" class="Generalizable">ℓ₃</a> <a id="4845" href="hack-your-type-theory.html#4845" class="Generalizable">ℓ₄</a> <a id="4848" class="Symbol">:</a> <a id="4850" href="Agda.Primitive.html#742" class="Postulate">Level</a>
  <a id="4858" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="4860" href="hack-your-type-theory.html#4860" class="Generalizable">B</a> <a id="4862" href="hack-your-type-theory.html#4862" class="Generalizable">C</a>       <a id="4870" class="Symbol">:</a> <a id="4872" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="4876" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a>
  <a id="4880" href="hack-your-type-theory.html#4880" class="Generalizable">P</a> <a id="4882" href="hack-your-type-theory.html#4882" class="Generalizable">Q</a>         <a id="4892" class="Symbol">:</a> <a id="4894" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="4896" class="Symbol">→</a> <a id="4898" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="4902" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a>
  <a id="4906" href="hack-your-type-theory.html#4906" class="Generalizable">x</a> <a id="4908" href="hack-your-type-theory.html#4908" class="Generalizable">y</a> <a id="4910" href="hack-your-type-theory.html#4910" class="Generalizable">z</a>       <a id="4918" class="Symbol">:</a> <a id="4920" href="hack-your-type-theory.html#4858" class="Generalizable">A</a>
  <a id="4924" href="hack-your-type-theory.html#4924" class="Generalizable">f</a> <a id="4926" href="hack-your-type-theory.html#4926" class="Generalizable">g</a> <a id="4928" href="hack-your-type-theory.html#4928" class="Generalizable">h</a>       <a id="4936" class="Symbol">:</a> <a id="4938" class="Symbol">(</a><a id="4939" href="hack-your-type-theory.html#4939" class="Bound">x</a> <a id="4941" class="Symbol">:</a> <a id="4943" href="hack-your-type-theory.html#4858" class="Generalizable">A</a><a id="4944" class="Symbol">)</a> <a id="4946" class="Symbol">→</a> <a id="4948" href="hack-your-type-theory.html#4880" class="Generalizable">P</a> <a id="4950" href="hack-your-type-theory.html#4939" class="Bound">x</a>
  <a id="4954" href="hack-your-type-theory.html#4954" class="Generalizable">b</a> <a id="4956" href="hack-your-type-theory.html#4956" class="Generalizable">b₁</a> <a id="4959" href="hack-your-type-theory.html#4959" class="Generalizable">b₂</a> <a id="4962" href="hack-your-type-theory.html#4962" class="Generalizable">b₃</a>  <a id="4966" class="Symbol">:</a> <a id="4968" href="Agda.Builtin.Bool.html#173" class="Datatype">Bool</a>
  <a id="4975" href="hack-your-type-theory.html#4975" class="Generalizable">k</a> <a id="4977" href="hack-your-type-theory.html#4977" class="Generalizable">l</a> <a id="4979" href="hack-your-type-theory.html#4979" class="Generalizable">m</a> <a id="4981" href="hack-your-type-theory.html#4981" class="Generalizable">n</a>     <a id="4987" class="Symbol">:</a> <a id="4989" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a>
  <a id="4995" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a> <a id="4998" href="hack-your-type-theory.html#4998" class="Generalizable">ys</a> <a id="5001" href="hack-your-type-theory.html#5001" class="Generalizable">zs</a>    <a id="5007" class="Symbol">:</a> <a id="5009" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="5014" href="hack-your-type-theory.html#4858" class="Generalizable">A</a>
</pre>
<p>To avoid reliance on external libraries, we also need these two basic
equality reasoning principles.</p>
<pre class="Agda"><a id="cong"></a><a id="5127" href="hack-your-type-theory.html#5127" class="Function">cong</a> <a id="5132" class="Symbol">:</a> <a id="5134" class="Symbol">(</a><a id="5135" href="hack-your-type-theory.html#5135" class="Bound">f</a> <a id="5137" class="Symbol">:</a> <a id="5139" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="5141" class="Symbol">→</a> <a id="5143" href="hack-your-type-theory.html#4860" class="Generalizable">B</a><a id="5144" class="Symbol">)</a> <a id="5146" class="Symbol">→</a> <a id="5148" href="hack-your-type-theory.html#4906" class="Generalizable">x</a> <a id="5150" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="5152" href="hack-your-type-theory.html#4908" class="Generalizable">y</a> <a id="5154" class="Symbol">→</a> <a id="5156" href="hack-your-type-theory.html#5135" class="Bound">f</a> <a id="5158" href="hack-your-type-theory.html#4906" class="Generalizable">x</a> <a id="5160" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="5162" href="hack-your-type-theory.html#5135" class="Bound">f</a> <a id="5164" href="hack-your-type-theory.html#4908" class="Generalizable">y</a>
<a id="5166" href="hack-your-type-theory.html#5127" class="Function">cong</a> <a id="5171" href="hack-your-type-theory.html#5171" class="Bound">f</a> <a id="5173" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a> <a id="5178" class="Symbol">=</a> <a id="5180" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>

<a id="transport"></a><a id="5186" href="hack-your-type-theory.html#5186" class="Function">transport</a> <a id="5196" class="Symbol">:</a> <a id="5198" class="Symbol">(</a><a id="5199" href="hack-your-type-theory.html#5199" class="Bound">P</a> <a id="5201" class="Symbol">:</a> <a id="5203" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="5205" class="Symbol">→</a> <a id="5207" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="5211" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a><a id="5212" class="Symbol">)</a> <a id="5214" class="Symbol">→</a> <a id="5216" href="hack-your-type-theory.html#4906" class="Generalizable">x</a> <a id="5218" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="5220" href="hack-your-type-theory.html#4908" class="Generalizable">y</a> <a id="5222" class="Symbol">→</a> <a id="5224" href="hack-your-type-theory.html#5199" class="Bound">P</a> <a id="5226" href="hack-your-type-theory.html#4906" class="Generalizable">x</a> <a id="5228" class="Symbol">→</a> <a id="5230" href="hack-your-type-theory.html#5199" class="Bound">P</a> <a id="5232" href="hack-your-type-theory.html#4908" class="Generalizable">y</a>
<a id="5234" href="hack-your-type-theory.html#5186" class="Function">transport</a> <a id="5244" href="hack-your-type-theory.html#5244" class="Bound">P</a> <a id="5246" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a> <a id="5251" href="hack-your-type-theory.html#5251" class="Bound">p</a> <a id="5253" class="Symbol">=</a> <a id="5255" href="hack-your-type-theory.html#5251" class="Bound">p</a>
</pre>
<h2 id="example-1-overlapping-pattern-matching">Example 1: Overlapping pattern matching</h2>
<p>To start, let’s look at an example where rewrite rules can solve a
problem that is encountered by almost every newcomer to Agda. This problem
usually pops up as the question why <code>0 + m</code> computes to <code>m</code>, but <code>m + 0</code>
does not (and similarly, <code>(suc m) + n</code> computes to <code>suc (m + n)</code>
but <code>m + (suc n)</code> does not). This problem manifests for example when
trying to prove commutativity of <code>_+_</code> (the lack of highlighting means
the code does not typecheck):</p>
<pre class="not-checked"><code>+comm : m + n ≡ n + m
+comm {m = zero}  = refl
+comm {m = suc m} = cong suc (+comm {m = m})</code></pre>
<p>Here, Agda complains that <code>n != n + zero of type Nat</code>. The usual way
to solve this problem is by proving the equations <code>m + 0 ≡ m</code> and <code>m + (suc n) ≡ suc (m + n)</code> and using an explicit <code>rewrite</code> statement in
the main proof (N.B.: Agda’s <code>rewrite</code> keyword should not be confused
with rewrite rules, which are added by a <code>REWRITE</code> pragma. Confusing,
I know.)</p>
<p>This problem is something that has both frustrated and fascinated me
from the very beginning I started working on type theory. During my
master thesis, I worked on adding <a href="https://jesper.sikanda.be/files/overlapping-and-order-independent-patterns.pdf"><em>overlapping computation
rules</em></a>
to make this problem go away <em>without</em> adding any explicit <code>rewrite</code>
statements to the proof above.</p>
<p>By using rewrite rules, we can simulate the solution from our
paper. First, we need to prove that the equations we want hold as
<em>propositional equalities</em>:</p>
<pre class="Agda"><a id="zero+"></a><a id="6802" href="hack-your-type-theory.html#6802" class="Function">zero+</a> <a id="6808" class="Symbol">:</a> <a id="6810" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a> <a id="6815" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">+</a> <a id="6817" href="hack-your-type-theory.html#4981" class="Generalizable">n</a> <a id="6819" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="6821" href="hack-your-type-theory.html#4981" class="Generalizable">n</a>
<a id="6823" href="hack-your-type-theory.html#6802" class="Function">zero+</a> <a id="6829" class="Symbol">=</a> <a id="6831" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>

<a id="suc+"></a><a id="6837" href="hack-your-type-theory.html#6837" class="Function">suc+</a> <a id="6842" class="Symbol">:</a> <a id="6844" class="Symbol">(</a><a id="6845" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6849" href="hack-your-type-theory.html#4979" class="Generalizable">m</a><a id="6850" class="Symbol">)</a> <a id="6852" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">+</a> <a id="6854" href="hack-your-type-theory.html#4981" class="Generalizable">n</a> <a id="6856" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="6858" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6862" class="Symbol">(</a><a id="6863" href="hack-your-type-theory.html#4979" class="Generalizable">m</a> <a id="6865" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">+</a> <a id="6867" href="hack-your-type-theory.html#4981" class="Generalizable">n</a><a id="6868" class="Symbol">)</a>
<a id="6870" href="hack-your-type-theory.html#6837" class="Function">suc+</a> <a id="6875" class="Symbol">=</a> <a id="6877" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>

<a id="+zero"></a><a id="6883" href="hack-your-type-theory.html#6883" class="Function">+zero</a> <a id="6889" class="Symbol">:</a> <a id="6891" href="hack-your-type-theory.html#4979" class="Generalizable">m</a> <a id="6893" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">+</a> <a id="6895" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a> <a id="6900" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="6902" href="hack-your-type-theory.html#4979" class="Generalizable">m</a>
<a id="6904" href="hack-your-type-theory.html#6883" class="Function">+zero</a> <a id="6910" class="Symbol">{</a><a id="6911" class="Argument">m</a> <a id="6913" class="Symbol">=</a> <a id="6915" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a><a id="6919" class="Symbol">}</a>  <a id="6922" class="Symbol">=</a> <a id="6924" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
<a id="6929" href="hack-your-type-theory.html#6883" class="Function">+zero</a> <a id="6935" class="Symbol">{</a><a id="6936" class="Argument">m</a> <a id="6938" class="Symbol">=</a> <a id="6940" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6944" href="hack-your-type-theory.html#6944" class="Bound">m</a><a id="6945" class="Symbol">}</a> <a id="6947" class="Symbol">=</a> <a id="6949" href="hack-your-type-theory.html#5127" class="Function">cong</a> <a id="6954" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6958" href="hack-your-type-theory.html#6883" class="Function">+zero</a>

<a id="+suc"></a><a id="6965" href="hack-your-type-theory.html#6965" class="Function">+suc</a> <a id="6970" class="Symbol">:</a> <a id="6972" href="hack-your-type-theory.html#4979" class="Generalizable">m</a> <a id="6974" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">+</a> <a id="6976" class="Symbol">(</a><a id="6977" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6981" href="hack-your-type-theory.html#4981" class="Generalizable">n</a><a id="6982" class="Symbol">)</a> <a id="6984" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="6986" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6990" class="Symbol">(</a><a id="6991" href="hack-your-type-theory.html#4979" class="Generalizable">m</a> <a id="6993" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">+</a> <a id="6995" href="hack-your-type-theory.html#4981" class="Generalizable">n</a><a id="6996" class="Symbol">)</a>
<a id="6998" href="hack-your-type-theory.html#6965" class="Function">+suc</a> <a id="7003" class="Symbol">{</a><a id="7004" class="Argument">m</a> <a id="7006" class="Symbol">=</a> <a id="7008" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a><a id="7012" class="Symbol">}</a>  <a id="7015" class="Symbol">=</a> <a id="7017" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
<a id="7022" href="hack-your-type-theory.html#6965" class="Function">+suc</a> <a id="7027" class="Symbol">{</a><a id="7028" class="Argument">m</a> <a id="7030" class="Symbol">=</a> <a id="7032" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="7036" href="hack-your-type-theory.html#7036" class="Bound">m</a><a id="7037" class="Symbol">}</a> <a id="7039" class="Symbol">=</a> <a id="7041" href="hack-your-type-theory.html#5127" class="Function">cong</a> <a id="7046" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="7050" href="hack-your-type-theory.html#6965" class="Function">+suc</a>
</pre>
<p>We mark the equalities that are not already definitional as
rewrite rules with a <code>REWRITE</code> pragma:</p>
<pre class="Agda"><a id="7164" class="Symbol">{-#</a> <a id="7168" class="Keyword">REWRITE</a> <a id="7176" href="hack-your-type-theory.html#6883" class="Function">+zero</a> <a id="7182" href="hack-your-type-theory.html#6965" class="Function">+suc</a> <a id="7187" class="Symbol">#-}</a>
</pre>
<p>Now the proof of commutativity works exactly as we wrote before:</p>
<pre class="Agda"><a id="+comm"></a><a id="7266" href="hack-your-type-theory.html#7266" class="Function">+comm</a> <a id="7272" class="Symbol">:</a> <a id="7274" href="hack-your-type-theory.html#4979" class="Generalizable">m</a> <a id="7276" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">+</a> <a id="7278" href="hack-your-type-theory.html#4981" class="Generalizable">n</a> <a id="7280" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="7282" href="hack-your-type-theory.html#4981" class="Generalizable">n</a> <a id="7284" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">+</a> <a id="7286" href="hack-your-type-theory.html#4979" class="Generalizable">m</a>
<a id="7288" href="hack-your-type-theory.html#7266" class="Function">+comm</a> <a id="7294" class="Symbol">{</a><a id="7295" class="Argument">m</a> <a id="7297" class="Symbol">=</a> <a id="7299" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a><a id="7303" class="Symbol">}</a>  <a id="7306" class="Symbol">=</a> <a id="7308" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
<a id="7313" href="hack-your-type-theory.html#7266" class="Function">+comm</a> <a id="7319" class="Symbol">{</a><a id="7320" class="Argument">m</a> <a id="7322" class="Symbol">=</a> <a id="7324" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="7328" href="hack-your-type-theory.html#7328" class="Bound">m</a><a id="7329" class="Symbol">}</a> <a id="7331" class="Symbol">=</a> <a id="7333" href="hack-your-type-theory.html#5127" class="Function">cong</a> <a id="7338" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="7342" class="Symbol">(</a><a id="7343" href="hack-your-type-theory.html#7266" class="Function">+comm</a> <a id="7349" class="Symbol">{</a><a id="7350" class="Argument">m</a> <a id="7352" class="Symbol">=</a> <a id="7354" href="hack-your-type-theory.html#7328" class="Bound">m</a><a id="7355" class="Symbol">})</a>
</pre>
<p>Note that there is <strong>no</strong> way to make this proof go through without
rewrite rules: it is essential that <code>_+_</code> computes both on its first
and second arguments, but there’s no way to define <code>_+_</code> in such a way
using Agda’s regular pattern matching.</p>
<h2 id="example-2-new-equations-for-neutral-terms">Example 2: New equations for neutral terms</h2>
<p>The idea of extending existing functions with new computation rules
has been taken much further in a very nice paper by Guillaume Allais,
Conor McBride, and Pierre Boutillier titled <a href="https://arxiv.org/abs/1304.0809">New Equations for Neutral
Terms</a>. In this paper, they add new
computation rules to classic functions on lists such as <code>map</code>, <code>_++_</code>,
and <code>fold</code>. In Agda, we can prove these rules and then add them as
rewrite rules (here I only show a subset of the rules in the paper):</p>
<pre class="Agda"><a id="map"></a><a id="8177" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="8181" class="Symbol">:</a> <a id="8183" class="Symbol">(</a><a id="8184" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="8186" class="Symbol">→</a> <a id="8188" href="hack-your-type-theory.html#4860" class="Generalizable">B</a><a id="8189" class="Symbol">)</a> <a id="8191" class="Symbol">→</a> <a id="8193" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="8198" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="8200" class="Symbol">→</a> <a id="8202" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="8207" href="hack-your-type-theory.html#4860" class="Generalizable">B</a>
<a id="8209" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="8213" href="hack-your-type-theory.html#8213" class="Bound">f</a> <a id="8215" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a>       <a id="8224" class="Symbol">=</a> <a id="8226" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a>
<a id="8229" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="8233" href="hack-your-type-theory.html#8233" class="Bound">f</a> <a id="8235" class="Symbol">(</a><a id="8236" href="hack-your-type-theory.html#8236" class="Bound">x</a> <a id="8238" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="8240" href="hack-your-type-theory.html#8240" class="Bound">xs</a><a id="8242" class="Symbol">)</a> <a id="8244" class="Symbol">=</a> <a id="8246" class="Symbol">(</a><a id="8247" href="hack-your-type-theory.html#8233" class="Bound">f</a> <a id="8249" href="hack-your-type-theory.html#8236" class="Bound">x</a><a id="8250" class="Symbol">)</a> <a id="8252" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="8254" class="Symbol">(</a><a id="8255" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="8259" href="hack-your-type-theory.html#8233" class="Bound">f</a> <a id="8261" href="hack-your-type-theory.html#8240" class="Bound">xs</a><a id="8263" class="Symbol">)</a>

<a id="8266" class="Keyword">infixr</a> <a id="8273" class="Number">5</a> <a id="8275" href="hack-your-type-theory.html#8280" class="Function Operator">_++_</a>
<a id="_++_"></a><a id="8280" href="hack-your-type-theory.html#8280" class="Function Operator">_++_</a> <a id="8285" class="Symbol">:</a> <a id="8287" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="8292" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="8294" class="Symbol">→</a> <a id="8296" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="8301" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="8303" class="Symbol">→</a> <a id="8305" href="Agda.Builtin.List.html#147" class="Datatype">List</a> <a id="8310" href="hack-your-type-theory.html#4858" class="Generalizable">A</a>
<a id="8312" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a>       <a id="8321" href="hack-your-type-theory.html#8280" class="Function Operator">++</a> <a id="8324" href="hack-your-type-theory.html#8324" class="Bound">ys</a> <a id="8327" class="Symbol">=</a> <a id="8329" href="hack-your-type-theory.html#8324" class="Bound">ys</a>
<a id="8332" class="Symbol">(</a><a id="8333" href="hack-your-type-theory.html#8333" class="Bound">x</a> <a id="8335" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="8337" href="hack-your-type-theory.html#8337" class="Bound">xs</a><a id="8339" class="Symbol">)</a> <a id="8341" href="hack-your-type-theory.html#8280" class="Function Operator">++</a> <a id="8344" href="hack-your-type-theory.html#8344" class="Bound">ys</a> <a id="8347" class="Symbol">=</a> <a id="8349" href="hack-your-type-theory.html#8333" class="Bound">x</a> <a id="8351" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="8353" class="Symbol">(</a><a id="8354" href="hack-your-type-theory.html#8337" class="Bound">xs</a> <a id="8357" href="hack-your-type-theory.html#8280" class="Function Operator">++</a> <a id="8360" href="hack-your-type-theory.html#8344" class="Bound">ys</a><a id="8362" class="Symbol">)</a>

<a id="map-id"></a><a id="8365" href="hack-your-type-theory.html#8365" class="Function">map-id</a> <a id="8372" class="Symbol">:</a> <a id="8374" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="8378" class="Symbol">(λ</a> <a id="8381" href="hack-your-type-theory.html#8381" class="Bound">x</a> <a id="8383" class="Symbol">→</a> <a id="8385" href="hack-your-type-theory.html#8381" class="Bound">x</a><a id="8386" class="Symbol">)</a> <a id="8388" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a> <a id="8391" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="8393" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a>
<a id="8396" href="hack-your-type-theory.html#8365" class="Function">map-id</a> <a id="8403" class="Symbol">{</a><a id="8404" class="Argument">xs</a> <a id="8407" class="Symbol">=</a> <a id="8409" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a><a id="8411" class="Symbol">}</a>     <a id="8417" class="Symbol">=</a> <a id="8419" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
<a id="8424" href="hack-your-type-theory.html#8365" class="Function">map-id</a> <a id="8431" class="Symbol">{</a><a id="8432" class="Argument">xs</a> <a id="8435" class="Symbol">=</a> <a id="8437" href="hack-your-type-theory.html#8437" class="Bound">x</a> <a id="8439" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="8441" href="hack-your-type-theory.html#8441" class="Bound">xs</a><a id="8443" class="Symbol">}</a> <a id="8445" class="Symbol">=</a> <a id="8447" href="hack-your-type-theory.html#5127" class="Function">cong</a> <a id="8452" class="Symbol">(</a><a id="8453" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">_∷_</a> <a id="8457" href="hack-your-type-theory.html#8437" class="Bound">x</a><a id="8458" class="Symbol">)</a> <a id="8460" href="hack-your-type-theory.html#8365" class="Function">map-id</a>

<a id="map-fuse"></a><a id="8468" href="hack-your-type-theory.html#8468" class="Function">map-fuse</a> <a id="8477" class="Symbol">:</a> <a id="8479" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="8483" href="hack-your-type-theory.html#4924" class="Generalizable">f</a> <a id="8485" class="Symbol">(</a><a id="8486" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="8490" href="hack-your-type-theory.html#4926" class="Generalizable">g</a> <a id="8492" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a><a id="8494" class="Symbol">)</a> <a id="8496" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="8498" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="8502" class="Symbol">(λ</a> <a id="8505" href="hack-your-type-theory.html#8505" class="Bound">x</a> <a id="8507" class="Symbol">→</a> <a id="8509" href="hack-your-type-theory.html#4924" class="Generalizable">f</a> <a id="8511" class="Symbol">(</a><a id="8512" href="hack-your-type-theory.html#4926" class="Generalizable">g</a> <a id="8514" href="hack-your-type-theory.html#8505" class="Bound">x</a><a id="8515" class="Symbol">))</a> <a id="8518" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a>
<a id="8521" href="hack-your-type-theory.html#8468" class="Function">map-fuse</a> <a id="8530" class="Symbol">{</a><a id="8531" class="Argument">xs</a> <a id="8534" class="Symbol">=</a> <a id="8536" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a><a id="8538" class="Symbol">}</a>     <a id="8544" class="Symbol">=</a> <a id="8546" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
<a id="8551" href="hack-your-type-theory.html#8468" class="Function">map-fuse</a> <a id="8560" class="Symbol">{</a><a id="8561" class="Argument">xs</a> <a id="8564" class="Symbol">=</a> <a id="8566" href="hack-your-type-theory.html#8566" class="Bound">x</a> <a id="8568" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="8570" href="hack-your-type-theory.html#8570" class="Bound">xs</a><a id="8572" class="Symbol">}</a> <a id="8574" class="Symbol">=</a> <a id="8576" href="hack-your-type-theory.html#5127" class="Function">cong</a> <a id="8581" class="Symbol">(</a><a id="8582" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">_∷_</a> <a id="8586" class="Symbol">_)</a> <a id="8589" href="hack-your-type-theory.html#8468" class="Function">map-fuse</a>

<a id="map-++"></a><a id="8599" href="hack-your-type-theory.html#8599" class="Function">map-++</a> <a id="8606" class="Symbol">:</a> <a id="8608" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="8612" href="hack-your-type-theory.html#4924" class="Generalizable">f</a> <a id="8614" class="Symbol">(</a><a id="8615" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a> <a id="8618" href="hack-your-type-theory.html#8280" class="Function Operator">++</a> <a id="8621" href="hack-your-type-theory.html#4998" class="Generalizable">ys</a><a id="8623" class="Symbol">)</a> <a id="8625" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="8627" class="Symbol">(</a><a id="8628" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="8632" href="hack-your-type-theory.html#4924" class="Generalizable">f</a> <a id="8634" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a><a id="8636" class="Symbol">)</a> <a id="8638" href="hack-your-type-theory.html#8280" class="Function Operator">++</a> <a id="8641" class="Symbol">(</a><a id="8642" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="8646" href="hack-your-type-theory.html#4924" class="Generalizable">f</a> <a id="8648" href="hack-your-type-theory.html#4998" class="Generalizable">ys</a><a id="8650" class="Symbol">)</a>
<a id="8652" href="hack-your-type-theory.html#8599" class="Function">map-++</a> <a id="8659" class="Symbol">{</a><a id="8660" class="Argument">xs</a> <a id="8663" class="Symbol">=</a> <a id="8665" href="Agda.Builtin.List.html#184" class="InductiveConstructor">[]</a><a id="8667" class="Symbol">}</a>     <a id="8673" class="Symbol">=</a> <a id="8675" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
<a id="8680" href="hack-your-type-theory.html#8599" class="Function">map-++</a> <a id="8687" class="Symbol">{</a><a id="8688" class="Argument">xs</a> <a id="8691" class="Symbol">=</a> <a id="8693" href="hack-your-type-theory.html#8693" class="Bound">x</a> <a id="8695" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">∷</a> <a id="8697" href="hack-your-type-theory.html#8697" class="Bound">xs</a><a id="8699" class="Symbol">}</a> <a id="8701" class="Symbol">=</a> <a id="8703" href="hack-your-type-theory.html#5127" class="Function">cong</a> <a id="8708" class="Symbol">(</a><a id="8709" href="Agda.Builtin.List.html#199" class="InductiveConstructor Operator">_∷_</a> <a id="8713" class="Symbol">_)</a> <a id="8716" class="Symbol">(</a><a id="8717" href="hack-your-type-theory.html#8599" class="Function">map-++</a> <a id="8724" class="Symbol">{</a><a id="8725" class="Argument">xs</a> <a id="8728" class="Symbol">=</a> <a id="8730" href="hack-your-type-theory.html#8697" class="Bound">xs</a><a id="8732" class="Symbol">})</a>

<a id="8736" class="Symbol">{-#</a> <a id="8740" class="Keyword">REWRITE</a> <a id="8748" href="hack-your-type-theory.html#8365" class="Function">map-id</a> <a id="8755" href="hack-your-type-theory.html#8468" class="Function">map-fuse</a> <a id="8764" href="hack-your-type-theory.html#8599" class="Function">map-++</a> <a id="8771" class="Symbol">#-}</a>
</pre>
<p>These rules look reasonably simple, but when used together they can be
quite powerful. For example, below we show that the expression <code>map swap (map swap xs ++ map swap ys)</code> reduces directly to <code>xs ++ ys</code>,
without doing any induction on the lists!</p>
<pre class="Agda"><a id="9033" class="Keyword">record</a> <a id="_×_"></a><a id="9040" href="hack-your-type-theory.html#9040" class="Record Operator">_×_</a> <a id="9044" class="Symbol">(</a><a id="9045" href="hack-your-type-theory.html#9045" class="Bound">A</a> <a id="9047" href="hack-your-type-theory.html#9047" class="Bound">B</a> <a id="9049" class="Symbol">:</a> <a id="9051" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="9054" class="Symbol">)</a> <a id="9056" class="Symbol">:</a> <a id="9058" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="9062" class="Keyword">where</a>
  <a id="9070" class="Keyword">constructor</a> <a id="_,_"></a><a id="9082" href="hack-your-type-theory.html#9082" class="InductiveConstructor Operator">_,_</a>
  <a id="9088" class="Keyword">field</a>
    <a id="_×_.fst"></a><a id="9098" href="hack-your-type-theory.html#9098" class="Field">fst</a> <a id="9102" class="Symbol">:</a> <a id="9104" href="hack-your-type-theory.html#9045" class="Bound">A</a>
    <a id="_×_.snd"></a><a id="9110" href="hack-your-type-theory.html#9110" class="Field">snd</a> <a id="9114" class="Symbol">:</a> <a id="9116" href="hack-your-type-theory.html#9047" class="Bound">B</a>
<a id="9118" class="Keyword">open</a> <a id="9123" href="hack-your-type-theory.html#9040" class="Module Operator">_×_</a>

<a id="swap"></a><a id="9128" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9133" class="Symbol">:</a> <a id="9135" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="9137" href="hack-your-type-theory.html#9040" class="Record Operator">×</a> <a id="9139" href="hack-your-type-theory.html#4860" class="Generalizable">B</a> <a id="9141" class="Symbol">→</a> <a id="9143" href="hack-your-type-theory.html#4860" class="Generalizable">B</a> <a id="9145" href="hack-your-type-theory.html#9040" class="Record Operator">×</a> <a id="9147" href="hack-your-type-theory.html#4858" class="Generalizable">A</a>
<a id="9149" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9154" class="Symbol">(</a><a id="9155" href="hack-your-type-theory.html#9155" class="Bound">x</a> <a id="9157" href="hack-your-type-theory.html#9082" class="InductiveConstructor Operator">,</a> <a id="9159" href="hack-your-type-theory.html#9159" class="Bound">y</a><a id="9160" class="Symbol">)</a> <a id="9162" class="Symbol">=</a> <a id="9164" href="hack-your-type-theory.html#9159" class="Bound">y</a> <a id="9166" href="hack-your-type-theory.html#9082" class="InductiveConstructor Operator">,</a> <a id="9168" href="hack-your-type-theory.html#9155" class="Bound">x</a>

<a id="test₁"></a><a id="9171" href="hack-your-type-theory.html#9171" class="Function">test₁</a> <a id="9177" class="Symbol">:</a> <a id="9179" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9183" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9188" class="Symbol">(</a><a id="9189" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9193" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9198" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a> <a id="9201" href="hack-your-type-theory.html#8280" class="Function Operator">++</a> <a id="9204" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9208" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9213" href="hack-your-type-theory.html#4998" class="Generalizable">ys</a><a id="9215" class="Symbol">)</a> <a id="9217" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="9219" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a> <a id="9222" href="hack-your-type-theory.html#8280" class="Function Operator">++</a> <a id="9225" href="hack-your-type-theory.html#4998" class="Generalizable">ys</a>
<a id="9228" href="hack-your-type-theory.html#9171" class="Function">test₁</a> <a id="9234" class="Symbol">=</a> <a id="9236" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
</pre>
<p>To compute the left-hand side of the equation to the right-hand side,
Agda makes use of <code>map-++</code> (<code>step₁</code>), <code>map-fuse</code> (<code>step₂</code>), built-in
eta-equality (<code>step₃</code>), the definition of <code>swap</code> (<code>step₄</code>), and
finally the <code>map-id</code> rewrite rule (<code>step₅</code>).</p>
<pre class="Agda"><a id="9499" class="Comment">-- Using map-++:</a>
<a id="step₁"></a><a id="9516" href="hack-your-type-theory.html#9516" class="Function">step₁</a> <a id="9522" class="Symbol">:</a> <a id="9524" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9528" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9533" class="Symbol">(</a><a id="9534" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9538" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9543" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a> <a id="9546" href="hack-your-type-theory.html#8280" class="Function Operator">++</a> <a id="9549" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9553" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9558" href="hack-your-type-theory.html#4998" class="Generalizable">ys</a><a id="9560" class="Symbol">)</a>
      <a id="9568" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="9570" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9574" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9579" class="Symbol">(</a><a id="9580" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9584" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9589" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a><a id="9591" class="Symbol">)</a> <a id="9593" href="hack-your-type-theory.html#8280" class="Function Operator">++</a> <a id="9596" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9600" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9605" class="Symbol">(</a><a id="9606" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9610" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9615" href="hack-your-type-theory.html#4998" class="Generalizable">ys</a><a id="9617" class="Symbol">)</a>
<a id="9619" href="hack-your-type-theory.html#9516" class="Function">step₁</a> <a id="9625" class="Symbol">=</a> <a id="9627" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>

<a id="9633" class="Comment">-- Using map-fuse (likewise for ys)</a>
<a id="step₂"></a><a id="9669" href="hack-your-type-theory.html#9669" class="Function">step₂</a> <a id="9675" class="Symbol">:</a> <a id="9677" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9681" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9686" class="Symbol">(</a><a id="9687" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9691" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9696" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a><a id="9698" class="Symbol">)</a>
      <a id="9706" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="9708" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9712" class="Symbol">(λ</a> <a id="9715" href="hack-your-type-theory.html#9715" class="Bound">x</a> <a id="9717" class="Symbol">→</a> <a id="9719" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9724" class="Symbol">(</a><a id="9725" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9730" href="hack-your-type-theory.html#9715" class="Bound">x</a><a id="9731" class="Symbol">))</a> <a id="9734" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a>
<a id="9737" href="hack-your-type-theory.html#9669" class="Function">step₂</a> <a id="9743" class="Symbol">=</a> <a id="9745" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>

<a id="9751" class="Comment">-- Using eta-expansion</a>
<a id="step₃"></a><a id="9774" href="hack-your-type-theory.html#9774" class="Function">step₃</a> <a id="9780" class="Symbol">:</a> <a id="9782" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9786" class="Symbol">(λ</a> <a id="9789" href="hack-your-type-theory.html#9789" class="Bound">x</a> <a id="9791" class="Symbol">→</a> <a id="9793" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9798" class="Symbol">(</a><a id="9799" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9804" href="hack-your-type-theory.html#9789" class="Bound">x</a><a id="9805" class="Symbol">))</a> <a id="9808" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a>
      <a id="9817" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="9819" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9823" class="Symbol">(λ</a> <a id="9826" href="hack-your-type-theory.html#9826" class="Bound">x</a> <a id="9828" class="Symbol">→</a> <a id="9830" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9835" class="Symbol">(</a><a id="9836" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9841" class="Symbol">(</a><a id="9842" href="hack-your-type-theory.html#9098" class="Field">fst</a> <a id="9846" href="hack-your-type-theory.html#9826" class="Bound">x</a> <a id="9848" href="hack-your-type-theory.html#9082" class="InductiveConstructor Operator">,</a> <a id="9850" href="hack-your-type-theory.html#9110" class="Field">snd</a> <a id="9854" href="hack-your-type-theory.html#9826" class="Bound">x</a><a id="9855" class="Symbol">)))</a> <a id="9859" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a>
<a id="9862" href="hack-your-type-theory.html#9774" class="Function">step₃</a> <a id="9868" class="Symbol">=</a> <a id="9870" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>

<a id="9876" class="Comment">-- Using definition of swap (2x)</a>
<a id="step₄"></a><a id="9909" href="hack-your-type-theory.html#9909" class="Function">step₄</a> <a id="9915" class="Symbol">:</a> <a id="9917" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9921" class="Symbol">(λ</a> <a id="9924" href="hack-your-type-theory.html#9924" class="Bound">x</a> <a id="9926" class="Symbol">→</a> <a id="9928" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9933" class="Symbol">(</a><a id="9934" href="hack-your-type-theory.html#9128" class="Function">swap</a> <a id="9939" class="Symbol">(</a><a id="9940" href="hack-your-type-theory.html#9098" class="Field">fst</a> <a id="9944" href="hack-your-type-theory.html#9924" class="Bound">x</a> <a id="9946" href="hack-your-type-theory.html#9082" class="InductiveConstructor Operator">,</a> <a id="9948" href="hack-your-type-theory.html#9110" class="Field">snd</a> <a id="9952" href="hack-your-type-theory.html#9924" class="Bound">x</a><a id="9953" class="Symbol">)))</a> <a id="9957" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a>
      <a id="9966" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="9968" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="9972" class="Symbol">(λ</a> <a id="9975" href="hack-your-type-theory.html#9975" class="Bound">x</a> <a id="9977" class="Symbol">→</a> <a id="9979" class="Symbol">(</a><a id="9980" href="hack-your-type-theory.html#9098" class="Field">fst</a> <a id="9984" href="hack-your-type-theory.html#9975" class="Bound">x</a> <a id="9986" href="hack-your-type-theory.html#9082" class="InductiveConstructor Operator">,</a> <a id="9988" href="hack-your-type-theory.html#9110" class="Field">snd</a> <a id="9992" href="hack-your-type-theory.html#9975" class="Bound">x</a><a id="9993" class="Symbol">))</a> <a id="9996" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a>
<a id="9999" href="hack-your-type-theory.html#9909" class="Function">step₄</a> <a id="10005" class="Symbol">=</a> <a id="10007" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>

<a id="10013" class="Comment">-- Using map-id (together with eta-contraction)</a>
<a id="step₅"></a><a id="10061" href="hack-your-type-theory.html#10061" class="Function">step₅</a> <a id="10067" class="Symbol">:</a> <a id="10069" href="hack-your-type-theory.html#8177" class="Function">map</a> <a id="10073" class="Symbol">(λ</a> <a id="10076" href="hack-your-type-theory.html#10076" class="Bound">x</a> <a id="10078" class="Symbol">→</a> <a id="10080" class="Symbol">(</a><a id="10081" href="hack-your-type-theory.html#9098" class="Field">fst</a> <a id="10085" href="hack-your-type-theory.html#10076" class="Bound">x</a> <a id="10087" href="hack-your-type-theory.html#9082" class="InductiveConstructor Operator">,</a> <a id="10089" href="hack-your-type-theory.html#9110" class="Field">snd</a> <a id="10093" href="hack-your-type-theory.html#10076" class="Bound">x</a><a id="10094" class="Symbol">))</a> <a id="10097" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a> <a id="10100" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="10102" href="hack-your-type-theory.html#4995" class="Generalizable">xs</a>
<a id="10105" href="hack-your-type-theory.html#10061" class="Function">step₅</a> <a id="10111" class="Symbol">=</a> <a id="10113" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
</pre>
<h2 id="example-3-higher-inductive-types">Example 3: Higher inductive types</h2>
<p>The original motivation for adding rewrite rules to Agda had little to
do with overlapping computation rules as in the previous
examples. Instead, its purpose was to experiment with defining
<a href="https://homotopytypetheory.org/book/"><em>higher inductive types</em></a>. In
particular, it was meant as an alternative for people using <a href="https://homotopytypetheory.org/2011/04/23/running-circles-around-in-your-proof-assistant/">clever
(but horrible)
hacks</a>
to make their higher inductive types compute.</p>
<p>A higher inductive type is like a regular inductive type <code>D</code> with some
additional <em>path constructors</em>, which construct an element of the
identity type <code>a ≡ b</code> where <code>a : D</code> and <code>b : D</code>. A classic example is
the <code>Circle</code> type, which has one regular constructor <code>base</code> and one
path constructor <code>loop</code>:</p>
<pre class="Agda"><a id="10975" class="Keyword">postulate</a>
  <a id="Circle"></a><a id="10987" href="hack-your-type-theory.html#10987" class="Postulate">Circle</a> <a id="10994" class="Symbol">:</a> <a id="10996" href="Agda.Primitive.html#388" class="Primitive">Set</a>
  <a id="base"></a><a id="11002" href="hack-your-type-theory.html#11002" class="Postulate">base</a> <a id="11007" class="Symbol">:</a> <a id="11009" href="hack-your-type-theory.html#10987" class="Postulate">Circle</a>
  <a id="loop"></a><a id="11018" href="hack-your-type-theory.html#11018" class="Postulate">loop</a> <a id="11023" class="Symbol">:</a> <a id="11025" href="hack-your-type-theory.html#11002" class="Postulate">base</a> <a id="11030" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="11032" href="hack-your-type-theory.html#11002" class="Postulate">base</a>

<a id="11038" class="Keyword">postulate</a>
  <a id="Circle-elim"></a><a id="11050" href="hack-your-type-theory.html#11050" class="Postulate">Circle-elim</a> <a id="11062" class="Symbol">:</a> <a id="11064" class="Symbol">(</a><a id="11065" href="hack-your-type-theory.html#11065" class="Bound">P</a> <a id="11067" class="Symbol">:</a> <a id="11069" href="hack-your-type-theory.html#10987" class="Postulate">Circle</a> <a id="11076" class="Symbol">→</a> <a id="11078" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="11082" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a><a id="11083" class="Symbol">)</a>
    <a id="11089" class="Symbol">→</a> <a id="11091" class="Symbol">(</a><a id="11092" href="hack-your-type-theory.html#11092" class="Bound">base*</a> <a id="11098" class="Symbol">:</a> <a id="11100" href="hack-your-type-theory.html#11065" class="Bound">P</a> <a id="11102" href="hack-your-type-theory.html#11002" class="Postulate">base</a><a id="11106" class="Symbol">)</a>
    <a id="11112" class="Symbol">→</a> <a id="11114" class="Symbol">(</a><a id="11115" href="hack-your-type-theory.html#11115" class="Bound">loop*</a> <a id="11121" class="Symbol">:</a> <a id="11123" href="hack-your-type-theory.html#5186" class="Function">transport</a> <a id="11133" href="hack-your-type-theory.html#11065" class="Bound">P</a> <a id="11135" href="hack-your-type-theory.html#11018" class="Postulate">loop</a> <a id="11140" href="hack-your-type-theory.html#11092" class="Bound">base*</a> <a id="11146" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="11148" href="hack-your-type-theory.html#11092" class="Bound">base*</a><a id="11153" class="Symbol">)</a>
    <a id="11159" class="Symbol">→</a> <a id="11161" class="Symbol">(</a><a id="11162" href="hack-your-type-theory.html#11162" class="Bound">x</a> <a id="11164" class="Symbol">:</a> <a id="11166" href="hack-your-type-theory.html#10987" class="Postulate">Circle</a><a id="11172" class="Symbol">)</a> <a id="11174" class="Symbol">→</a> <a id="11176" href="hack-your-type-theory.html#11065" class="Bound">P</a> <a id="11178" href="hack-your-type-theory.html#11162" class="Bound">x</a>
  <a id="elim-base"></a><a id="11182" href="hack-your-type-theory.html#11182" class="Postulate">elim-base</a> <a id="11192" class="Symbol">:</a> <a id="11194" class="Symbol">∀</a> <a id="11196" class="Symbol">(</a><a id="11197" href="hack-your-type-theory.html#11197" class="Bound">P</a> <a id="11199" class="Symbol">:</a> <a id="11201" href="hack-your-type-theory.html#10987" class="Postulate">Circle</a> <a id="11208" class="Symbol">→</a> <a id="11210" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="11214" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a><a id="11215" class="Symbol">)</a> <a id="11217" href="hack-your-type-theory.html#11217" class="Bound">base*</a> <a id="11223" href="hack-your-type-theory.html#11223" class="Bound">loop*</a>
    <a id="11233" class="Symbol">→</a> <a id="11235" href="hack-your-type-theory.html#11050" class="Postulate">Circle-elim</a> <a id="11247" href="hack-your-type-theory.html#11197" class="Bound">P</a> <a id="11249" href="hack-your-type-theory.html#11217" class="Bound">base*</a> <a id="11255" href="hack-your-type-theory.html#11223" class="Bound">loop*</a> <a id="11261" href="hack-your-type-theory.html#11002" class="Postulate">base</a> <a id="11266" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="11268" href="hack-your-type-theory.html#11217" class="Bound">base*</a>
<a id="11274" class="Symbol">{-#</a> <a id="11278" class="Keyword">REWRITE</a> <a id="11286" href="hack-your-type-theory.html#11182" class="Postulate">elim-base</a> <a id="11296" class="Symbol">#-}</a>
</pre>
<p>To specify the computation rule for <code>Circle-elim</code> applied to <code>loop</code>,
we need the dependent version of <code>cong</code>, which is called <code>apd</code> in the
book.</p>
<pre class="Agda"><a id="apd"></a><a id="11456" href="hack-your-type-theory.html#11456" class="Function">apd</a> <a id="11460" class="Symbol">:</a> <a id="11462" class="Symbol">(</a><a id="11463" href="hack-your-type-theory.html#11463" class="Bound">f</a> <a id="11465" class="Symbol">:</a> <a id="11467" class="Symbol">(</a><a id="11468" href="hack-your-type-theory.html#11468" class="Bound">x</a> <a id="11470" class="Symbol">:</a> <a id="11472" href="hack-your-type-theory.html#4858" class="Generalizable">A</a><a id="11473" class="Symbol">)</a> <a id="11475" class="Symbol">→</a> <a id="11477" href="hack-your-type-theory.html#4880" class="Generalizable">P</a> <a id="11479" href="hack-your-type-theory.html#11468" class="Bound">x</a><a id="11480" class="Symbol">)</a> <a id="11482" class="Symbol">(</a><a id="11483" href="hack-your-type-theory.html#11483" class="Bound">p</a> <a id="11485" class="Symbol">:</a> <a id="11487" href="hack-your-type-theory.html#4906" class="Generalizable">x</a> <a id="11489" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="11491" href="hack-your-type-theory.html#4908" class="Generalizable">y</a><a id="11492" class="Symbol">)</a>
    <a id="11498" class="Symbol">→</a> <a id="11500" href="hack-your-type-theory.html#5186" class="Function">transport</a> <a id="11510" href="hack-your-type-theory.html#4880" class="Generalizable">P</a> <a id="11512" href="hack-your-type-theory.html#11483" class="Bound">p</a> <a id="11514" class="Symbol">(</a><a id="11515" href="hack-your-type-theory.html#11463" class="Bound">f</a> <a id="11517" href="hack-your-type-theory.html#4906" class="Generalizable">x</a><a id="11518" class="Symbol">)</a> <a id="11520" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="11522" href="hack-your-type-theory.html#11463" class="Bound">f</a> <a id="11524" href="hack-your-type-theory.html#4908" class="Generalizable">y</a>
<a id="11526" href="hack-your-type-theory.html#11456" class="Function">apd</a> <a id="11530" href="hack-your-type-theory.html#11530" class="Bound">f</a> <a id="11532" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a> <a id="11537" class="Symbol">=</a> <a id="11539" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>

<a id="11545" class="Keyword">postulate</a>
  <a id="elim-loop"></a><a id="11557" href="hack-your-type-theory.html#11557" class="Postulate">elim-loop</a> <a id="11567" class="Symbol">:</a> <a id="11569" class="Symbol">∀</a> <a id="11571" class="Symbol">(</a><a id="11572" href="hack-your-type-theory.html#11572" class="Bound">P</a> <a id="11574" class="Symbol">:</a> <a id="11576" href="hack-your-type-theory.html#10987" class="Postulate">Circle</a> <a id="11583" class="Symbol">→</a> <a id="11585" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="11589" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a><a id="11590" class="Symbol">)</a> <a id="11592" href="hack-your-type-theory.html#11592" class="Bound">base*</a> <a id="11598" href="hack-your-type-theory.html#11598" class="Bound">loop*</a>
    <a id="11608" class="Symbol">→</a> <a id="11610" href="hack-your-type-theory.html#11456" class="Function">apd</a> <a id="11614" class="Symbol">(</a><a id="11615" href="hack-your-type-theory.html#11050" class="Postulate">Circle-elim</a> <a id="11627" href="hack-your-type-theory.html#11572" class="Bound">P</a> <a id="11629" href="hack-your-type-theory.html#11592" class="Bound">base*</a> <a id="11635" href="hack-your-type-theory.html#11598" class="Bound">loop*</a><a id="11640" class="Symbol">)</a> <a id="11642" href="hack-your-type-theory.html#11018" class="Postulate">loop</a> <a id="11647" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="11649" href="hack-your-type-theory.html#11598" class="Bound">loop*</a>
<a id="11655" class="Symbol">{-#</a> <a id="11659" class="Keyword">REWRITE</a> <a id="11667" href="hack-your-type-theory.html#11557" class="Postulate">elim-loop</a> <a id="11677" class="Symbol">#-}</a>
</pre>
<p>Interestingly, the type of <code>elim-loop</code> is not even well-formed unless
we alreay have <code>elim-base</code> as a rewrite rule! So without rewrite
rules, it is even difficult to <em>state</em> the computation rule of
<code>Circle-elim</code> for <code>loop</code>.</p>
<h2 id="example-4-quotient-types">Example 4: Quotient types</h2>
<p>One of the well-known weak spots of intentional type theory is the
poor handling of quotient types. One of the more promising attempts at
adding quotients to Agda is by <a href="https://github.com/guillaumebrunerie/initiality/blob/reflection/quotients.agda">Guillaume Brunerie in the initiality
project</a>,
which uses a combination of rewrite rules and Agda’s new (strict)
<code>Prop</code> universe.</p>
<p>Before I can give the definition of the quotient type, we first need
to define the <code>Prop</code>-valued equality type <code>_≐_</code>. We also define its
corresponding notion of <code>transport</code>, which has to be postulated due to
current limitations in the implementation of <code>Prop</code>. Luckily, we can
actually make <code>transportR</code> compute in the expected way by postulating
the expected computational behaviour and turning it into a rewrite
rule.</p>
<pre class="Agda"><a id="12760" class="Keyword">data</a> <a id="_≐_"></a><a id="12765" href="hack-your-type-theory.html#12765" class="Datatype Operator">_≐_</a> <a id="12769" class="Symbol">{</a><a id="12770" href="hack-your-type-theory.html#12770" class="Bound">A</a> <a id="12772" class="Symbol">:</a> <a id="12774" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="12778" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a><a id="12779" class="Symbol">}</a> <a id="12781" class="Symbol">(</a><a id="12782" href="hack-your-type-theory.html#12782" class="Bound">x</a> <a id="12784" class="Symbol">:</a> <a id="12786" href="hack-your-type-theory.html#12770" class="Bound">A</a><a id="12787" class="Symbol">)</a> <a id="12789" class="Symbol">:</a> <a id="12791" href="hack-your-type-theory.html#12770" class="Bound">A</a> <a id="12793" class="Symbol">→</a> <a id="12795" href="Agda.Primitive.html#347" class="Primitive">Prop</a> <a id="12800" href="hack-your-type-theory.html#12778" class="Bound">ℓ</a> <a id="12802" class="Keyword">where</a>
  <a id="_≐_.refl"></a><a id="12810" href="hack-your-type-theory.html#12810" class="InductiveConstructor">refl</a> <a id="12815" class="Symbol">:</a> <a id="12817" href="hack-your-type-theory.html#12782" class="Bound">x</a> <a id="12819" href="hack-your-type-theory.html#12765" class="Datatype Operator">≐</a> <a id="12821" href="hack-your-type-theory.html#12782" class="Bound">x</a>

<a id="12824" class="Keyword">postulate</a>
  <a id="transportR"></a><a id="12836" href="hack-your-type-theory.html#12836" class="Postulate">transportR</a> <a id="12847" class="Symbol">:</a> <a id="12849" class="Symbol">(</a><a id="12850" href="hack-your-type-theory.html#12850" class="Bound">P</a> <a id="12852" class="Symbol">:</a> <a id="12854" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="12856" class="Symbol">→</a> <a id="12858" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="12862" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a><a id="12863" class="Symbol">)</a> <a id="12865" class="Symbol">→</a> <a id="12867" href="hack-your-type-theory.html#4906" class="Generalizable">x</a> <a id="12869" href="hack-your-type-theory.html#12765" class="Datatype Operator">≐</a> <a id="12871" href="hack-your-type-theory.html#4908" class="Generalizable">y</a> <a id="12873" class="Symbol">→</a> <a id="12875" href="hack-your-type-theory.html#12850" class="Bound">P</a> <a id="12877" href="hack-your-type-theory.html#4906" class="Generalizable">x</a> <a id="12879" class="Symbol">→</a> <a id="12881" href="hack-your-type-theory.html#12850" class="Bound">P</a> <a id="12883" href="hack-your-type-theory.html#4908" class="Generalizable">y</a>
  <a id="transportR-refl"></a><a id="12887" href="hack-your-type-theory.html#12887" class="Postulate">transportR-refl</a> <a id="12903" class="Symbol">:</a> <a id="12905" href="hack-your-type-theory.html#12836" class="Postulate">transportR</a> <a id="12916" href="hack-your-type-theory.html#4880" class="Generalizable">P</a> <a id="12918" href="hack-your-type-theory.html#12810" class="InductiveConstructor">refl</a> <a id="12923" href="hack-your-type-theory.html#4906" class="Generalizable">x</a> <a id="12925" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="12927" href="hack-your-type-theory.html#4906" class="Generalizable">x</a>
<a id="12929" class="Symbol">{-#</a> <a id="12933" class="Keyword">REWRITE</a> <a id="12941" href="hack-your-type-theory.html#12887" class="Postulate">transportR-refl</a> <a id="12957" class="Symbol">#-}</a>
</pre>
<p>Now we can define the quotient type <code>_//_</code>. Specifically, given a type
<code>A</code> and a <code>Prop</code>-valued relation <code>R : A → A → Prop</code>, we construct the
type <code>A // R</code> consisting of elements <code>proj x</code> where <code>x : A</code> and <code>proj x ≡ proj y</code> if and only if <code>R x y</code>.</p>
<pre class="Agda"><a id="13218" class="Keyword">variable</a>
  <a id="13229" href="hack-your-type-theory.html#13229" class="Generalizable">R</a> <a id="13231" class="Symbol">:</a> <a id="13233" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="13235" class="Symbol">→</a> <a id="13237" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="13239" class="Symbol">→</a> <a id="13241" href="Agda.Primitive.html#347" class="Primitive">Prop</a>

<a id="13247" class="Keyword">postulate</a>
  <a id="_//_"></a><a id="13259" href="hack-your-type-theory.html#13259" class="Postulate Operator">_//_</a>    <a id="13267" class="Symbol">:</a> <a id="13269" class="Symbol">(</a><a id="13270" href="hack-your-type-theory.html#13270" class="Bound">A</a> <a id="13272" class="Symbol">:</a> <a id="13274" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="13278" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a><a id="13279" class="Symbol">)</a> <a id="13281" class="Symbol">(</a><a id="13282" href="hack-your-type-theory.html#13282" class="Bound">R</a> <a id="13284" class="Symbol">:</a> <a id="13286" href="hack-your-type-theory.html#13270" class="Bound">A</a> <a id="13288" class="Symbol">→</a> <a id="13290" href="hack-your-type-theory.html#13270" class="Bound">A</a> <a id="13292" class="Symbol">→</a> <a id="13294" href="Agda.Primitive.html#347" class="Primitive">Prop</a><a id="13298" class="Symbol">)</a> <a id="13300" class="Symbol">→</a> <a id="13302" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="13306" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a>
  <a id="proj"></a><a id="13310" href="hack-your-type-theory.html#13310" class="Postulate">proj</a>    <a id="13318" class="Symbol">:</a> <a id="13320" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="13322" class="Symbol">→</a> <a id="13324" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="13326" href="hack-your-type-theory.html#13259" class="Postulate Operator">//</a> <a id="13329" href="hack-your-type-theory.html#13229" class="Generalizable">R</a>
  <a id="quot"></a><a id="13333" href="hack-your-type-theory.html#13333" class="Postulate">quot</a>    <a id="13341" class="Symbol">:</a> <a id="13343" href="hack-your-type-theory.html#13229" class="Generalizable">R</a> <a id="13345" href="hack-your-type-theory.html#4906" class="Generalizable">x</a> <a id="13347" href="hack-your-type-theory.html#4908" class="Generalizable">y</a> <a id="13349" class="Symbol">→</a> <a id="13351" href="hack-your-type-theory.html#13310" class="Postulate">proj</a> <a id="13356" class="Symbol">{</a><a id="13357" class="Argument">R</a> <a id="13359" class="Symbol">=</a> <a id="13361" href="hack-your-type-theory.html#13229" class="Generalizable">R</a><a id="13362" class="Symbol">}</a> <a id="13364" href="hack-your-type-theory.html#4906" class="Generalizable">x</a> <a id="13366" href="hack-your-type-theory.html#12765" class="Datatype Operator">≐</a> <a id="13368" href="hack-your-type-theory.html#13310" class="Postulate">proj</a> <a id="13373" class="Symbol">{</a><a id="13374" class="Argument">R</a> <a id="13376" class="Symbol">=</a> <a id="13378" href="hack-your-type-theory.html#13229" class="Generalizable">R</a><a id="13379" class="Symbol">}</a> <a id="13381" href="hack-your-type-theory.html#4908" class="Generalizable">y</a>
</pre>
<p>The crucial element here is the elimination principle <code>//-elim</code>, which
allows us to define functions that <em>extract</em> an element of <code>A</code> from a
given element of <code>A // R</code>, as long as we have a <em>proof</em> <code>quot*</code> that
the function behaves the same on <code>proj x</code> and <code>proj y</code> whenever <code>R x y</code> holds. The computation rule <code>//-beta</code> turns this definition of
quotients into more than just a static blob of postulates by allowing
<code>//-elim</code> to compute when it is applied to a <code>proj x</code>.</p>
<pre class="Agda">  <a id="//-elim"></a><a id="13865" href="hack-your-type-theory.html#13865" class="Postulate">//-elim</a> <a id="13873" class="Symbol">:</a> <a id="13875" class="Symbol">(</a><a id="13876" href="hack-your-type-theory.html#13876" class="Bound">P</a> <a id="13878" class="Symbol">:</a> <a id="13880" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="13882" href="hack-your-type-theory.html#13259" class="Postulate Operator">//</a> <a id="13885" href="hack-your-type-theory.html#13229" class="Generalizable">R</a> <a id="13887" class="Symbol">→</a> <a id="13889" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="13893" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a><a id="13894" class="Symbol">)</a>
    <a id="13900" class="Symbol">→</a> <a id="13902" class="Symbol">(</a><a id="13903" href="hack-your-type-theory.html#13903" class="Bound">proj*</a> <a id="13909" class="Symbol">:</a> <a id="13911" class="Symbol">(</a><a id="13912" href="hack-your-type-theory.html#13912" class="Bound">x</a> <a id="13914" class="Symbol">:</a> <a id="13916" href="hack-your-type-theory.html#4858" class="Generalizable">A</a><a id="13917" class="Symbol">)</a> <a id="13919" class="Symbol">→</a> <a id="13921" href="hack-your-type-theory.html#13876" class="Bound">P</a> <a id="13923" class="Symbol">(</a><a id="13924" href="hack-your-type-theory.html#13310" class="Postulate">proj</a> <a id="13929" href="hack-your-type-theory.html#13912" class="Bound">x</a><a id="13930" class="Symbol">))</a>
    <a id="13937" class="Symbol">→</a> <a id="13939" class="Symbol">(</a><a id="13940" href="hack-your-type-theory.html#13940" class="Bound">quot*</a> <a id="13946" class="Symbol">:</a> <a id="13948" class="Symbol">{</a><a id="13949" href="hack-your-type-theory.html#13949" class="Bound">x</a> <a id="13951" href="hack-your-type-theory.html#13951" class="Bound">y</a> <a id="13953" class="Symbol">:</a> <a id="13955" href="hack-your-type-theory.html#4858" class="Generalizable">A</a><a id="13956" class="Symbol">}</a> <a id="13958" class="Symbol">(</a><a id="13959" href="hack-your-type-theory.html#13959" class="Bound">r</a> <a id="13961" class="Symbol">:</a> <a id="13963" href="hack-your-type-theory.html#13229" class="Generalizable">R</a> <a id="13965" href="hack-your-type-theory.html#13949" class="Bound">x</a> <a id="13967" href="hack-your-type-theory.html#13951" class="Bound">y</a><a id="13968" class="Symbol">)</a>
             <a id="13983" class="Symbol">→</a> <a id="13985" href="hack-your-type-theory.html#12836" class="Postulate">transportR</a> <a id="13996" href="hack-your-type-theory.html#13876" class="Bound">P</a> <a id="13998" class="Symbol">(</a><a id="13999" href="hack-your-type-theory.html#13333" class="Postulate">quot</a> <a id="14004" href="hack-your-type-theory.html#13959" class="Bound">r</a><a id="14005" class="Symbol">)</a> <a id="14007" class="Symbol">(</a><a id="14008" href="hack-your-type-theory.html#13903" class="Bound">proj*</a> <a id="14014" href="hack-your-type-theory.html#13949" class="Bound">x</a><a id="14015" class="Symbol">)</a> <a id="14017" href="hack-your-type-theory.html#12765" class="Datatype Operator">≐</a> <a id="14019" href="hack-your-type-theory.html#13903" class="Bound">proj*</a> <a id="14025" href="hack-your-type-theory.html#13951" class="Bound">y</a><a id="14026" class="Symbol">)</a>
    <a id="14032" class="Symbol">→</a> <a id="14034" class="Symbol">(</a><a id="14035" href="hack-your-type-theory.html#14035" class="Bound">x</a> <a id="14037" class="Symbol">:</a> <a id="14039" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="14041" href="hack-your-type-theory.html#13259" class="Postulate Operator">//</a> <a id="14044" href="hack-your-type-theory.html#13229" class="Generalizable">R</a><a id="14045" class="Symbol">)</a> <a id="14047" class="Symbol">→</a> <a id="14049" href="hack-your-type-theory.html#13876" class="Bound">P</a> <a id="14051" href="hack-your-type-theory.html#14035" class="Bound">x</a>
  <a id="//-beta"></a><a id="14055" href="hack-your-type-theory.html#14055" class="Postulate">//-beta</a> <a id="14063" class="Symbol">:</a> <a id="14065" class="Symbol">{</a><a id="14066" href="hack-your-type-theory.html#14066" class="Bound">R</a> <a id="14068" class="Symbol">:</a> <a id="14070" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="14072" class="Symbol">→</a> <a id="14074" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="14076" class="Symbol">→</a> <a id="14078" href="Agda.Primitive.html#347" class="Primitive">Prop</a><a id="14082" class="Symbol">}</a> <a id="14084" class="Symbol">(</a><a id="14085" href="hack-your-type-theory.html#14085" class="Bound">P</a> <a id="14087" class="Symbol">:</a> <a id="14089" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="14091" href="hack-your-type-theory.html#13259" class="Postulate Operator">//</a> <a id="14094" href="hack-your-type-theory.html#14066" class="Bound">R</a> <a id="14096" class="Symbol">→</a> <a id="14098" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="14102" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a><a id="14103" class="Symbol">)</a>
    <a id="14109" class="Symbol">→</a> <a id="14111" class="Symbol">(</a><a id="14112" href="hack-your-type-theory.html#14112" class="Bound">proj*</a> <a id="14118" class="Symbol">:</a> <a id="14120" class="Symbol">(</a><a id="14121" href="hack-your-type-theory.html#14121" class="Bound">x</a> <a id="14123" class="Symbol">:</a> <a id="14125" href="hack-your-type-theory.html#4858" class="Generalizable">A</a><a id="14126" class="Symbol">)</a> <a id="14128" class="Symbol">→</a> <a id="14130" href="hack-your-type-theory.html#14085" class="Bound">P</a> <a id="14132" class="Symbol">(</a><a id="14133" href="hack-your-type-theory.html#13310" class="Postulate">proj</a> <a id="14138" href="hack-your-type-theory.html#14121" class="Bound">x</a><a id="14139" class="Symbol">))</a>
    <a id="14146" class="Symbol">→</a> <a id="14148" class="Symbol">(</a><a id="14149" href="hack-your-type-theory.html#14149" class="Bound">quot*</a> <a id="14155" class="Symbol">:</a> <a id="14157" class="Symbol">{</a><a id="14158" href="hack-your-type-theory.html#14158" class="Bound">x</a> <a id="14160" href="hack-your-type-theory.html#14160" class="Bound">y</a> <a id="14162" class="Symbol">:</a> <a id="14164" href="hack-your-type-theory.html#4858" class="Generalizable">A</a><a id="14165" class="Symbol">}</a> <a id="14167" class="Symbol">(</a><a id="14168" href="hack-your-type-theory.html#14168" class="Bound">r</a> <a id="14170" class="Symbol">:</a> <a id="14172" href="hack-your-type-theory.html#14066" class="Bound">R</a> <a id="14174" href="hack-your-type-theory.html#14158" class="Bound">x</a> <a id="14176" href="hack-your-type-theory.html#14160" class="Bound">y</a><a id="14177" class="Symbol">)</a>
             <a id="14192" class="Symbol">→</a> <a id="14194" href="hack-your-type-theory.html#12836" class="Postulate">transportR</a> <a id="14205" href="hack-your-type-theory.html#14085" class="Bound">P</a> <a id="14207" class="Symbol">(</a><a id="14208" href="hack-your-type-theory.html#13333" class="Postulate">quot</a> <a id="14213" href="hack-your-type-theory.html#14168" class="Bound">r</a><a id="14214" class="Symbol">)</a> <a id="14216" class="Symbol">(</a><a id="14217" href="hack-your-type-theory.html#14112" class="Bound">proj*</a> <a id="14223" href="hack-your-type-theory.html#14158" class="Bound">x</a><a id="14224" class="Symbol">)</a> <a id="14226" href="hack-your-type-theory.html#12765" class="Datatype Operator">≐</a> <a id="14228" href="hack-your-type-theory.html#14112" class="Bound">proj*</a> <a id="14234" href="hack-your-type-theory.html#14160" class="Bound">y</a><a id="14235" class="Symbol">)</a>
    <a id="14241" class="Symbol">→</a> <a id="14243" class="Symbol">{</a><a id="14244" href="hack-your-type-theory.html#14244" class="Bound">u</a> <a id="14246" class="Symbol">:</a> <a id="14248" href="hack-your-type-theory.html#4858" class="Generalizable">A</a><a id="14249" class="Symbol">}</a> <a id="14251" class="Symbol">→</a> <a id="14253" href="hack-your-type-theory.html#13865" class="Postulate">//-elim</a> <a id="14261" href="hack-your-type-theory.html#14085" class="Bound">P</a> <a id="14263" href="hack-your-type-theory.html#14112" class="Bound">proj*</a> <a id="14269" href="hack-your-type-theory.html#14149" class="Bound">quot*</a> <a id="14275" class="Symbol">(</a><a id="14276" href="hack-your-type-theory.html#13310" class="Postulate">proj</a> <a id="14281" href="hack-your-type-theory.html#14244" class="Bound">u</a><a id="14282" class="Symbol">)</a> <a id="14284" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="14286" href="hack-your-type-theory.html#14112" class="Bound">proj*</a> <a id="14292" href="hack-your-type-theory.html#14244" class="Bound">u</a>
  <a id="14296" class="Comment">-- Note: The type of //-beta mysteriously does not</a>
  <a id="14349" class="Comment">-- check when I leave out the {R : A → A → Prop},</a>
  <a id="14401" class="Comment">-- I'm not sure what's up with that.</a>
<a id="14438" class="Symbol">{-#</a> <a id="14442" class="Keyword">REWRITE</a> <a id="14450" href="hack-your-type-theory.html#14055" class="Postulate">//-beta</a> <a id="14458" class="Symbol">#-}</a>
</pre>
<p>(As a side note, <a href="https://github.com/coq/coq/issues/10871">here</a> is an
interesting recent discussion on quotient types in Lean, Coq, and
Agda.)</p>
<h2 id="example-5-exceptional-type-theory">Example 5: Exceptional type theory</h2>
<p>I have a secret to share with you: my first programming language was
Java. While I don’t miss most parts of it, sometimes I just long to
use a good unchecked exception in my pristine purely functional
language. Luckily, my friends over at Inria in Nantes have written the
aptly named paper <a href="https://hal.inria.fr/hal-01840643/document">Failure is Not an Option: An Exceptional Type
Theory</a>, which shows how
to add exceptions to Coq. Through the exceptional power of rewrite
rules, we can also encode their system in Agda.</p>
<p>First, we postulate a type <code>Exc</code> with any kinds of exceptions we might
want to use (here we just have <code>runtimeException</code> for simplicity). We
then add the possibility to <code>raise</code> an exception, producing an element
of an arbitrary type <code>A</code>.</p>
<pre class="Agda"><a id="15437" class="Keyword">postulate</a>
  <a id="Exc"></a><a id="15449" href="hack-your-type-theory.html#15449" class="Postulate">Exc</a> <a id="15453" class="Symbol">:</a> <a id="15455" href="Agda.Primitive.html#388" class="Primitive">Set</a>
  <a id="runtimeException"></a><a id="15461" href="hack-your-type-theory.html#15461" class="Postulate">runtimeException</a> <a id="15478" class="Symbol">:</a> <a id="15480" href="hack-your-type-theory.html#15449" class="Postulate">Exc</a>
  <a id="raise"></a><a id="15486" href="hack-your-type-theory.html#15486" class="Postulate">raise</a> <a id="15492" class="Symbol">:</a> <a id="15494" href="hack-your-type-theory.html#15449" class="Postulate">Exc</a> <a id="15498" class="Symbol">→</a> <a id="15500" href="hack-your-type-theory.html#4858" class="Generalizable">A</a>
</pre>
<p>By adding the appropriate rewrite rules for each type former, we can
ensure that exceptions are <em>propagated</em> to the top-level. Below, I
give two examples. For positive types such as <code>Nat</code>, exceptions are
propagated <em>outwards</em>, while for negative types such as function
types, exceptions are propagated <em>inwards</em>.</p>
<pre class="Agda">  <a id="raise-suc"></a><a id="15827" href="hack-your-type-theory.html#15827" class="Postulate">raise-suc</a> <a id="15837" class="Symbol">:</a> <a id="15839" class="Symbol">{</a><a id="15840" href="hack-your-type-theory.html#15840" class="Bound">e</a> <a id="15842" class="Symbol">:</a> <a id="15844" href="hack-your-type-theory.html#15449" class="Postulate">Exc</a><a id="15847" class="Symbol">}</a> <a id="15849" class="Symbol">→</a> <a id="15851" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="15855" class="Symbol">(</a><a id="15856" href="hack-your-type-theory.html#15486" class="Postulate">raise</a> <a id="15862" href="hack-your-type-theory.html#15840" class="Bound">e</a><a id="15863" class="Symbol">)</a> <a id="15865" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="15867" href="hack-your-type-theory.html#15486" class="Postulate">raise</a> <a id="15873" href="hack-your-type-theory.html#15840" class="Bound">e</a>

  <a id="raise-fun"></a><a id="15878" href="hack-your-type-theory.html#15878" class="Postulate">raise-fun</a> <a id="15888" class="Symbol">:</a> <a id="15890" class="Symbol">{</a><a id="15891" href="hack-your-type-theory.html#15891" class="Bound">e</a> <a id="15893" class="Symbol">:</a> <a id="15895" href="hack-your-type-theory.html#15449" class="Postulate">Exc</a><a id="15898" class="Symbol">}</a>
    <a id="15904" class="Symbol">→</a> <a id="15906" href="hack-your-type-theory.html#15486" class="Postulate">raise</a> <a id="15912" class="Symbol">{</a><a id="15913" class="Argument">A</a> <a id="15915" class="Symbol">=</a> <a id="15917" class="Symbol">(</a><a id="15918" href="hack-your-type-theory.html#15918" class="Bound">x</a> <a id="15920" class="Symbol">:</a> <a id="15922" href="hack-your-type-theory.html#4858" class="Generalizable">A</a><a id="15923" class="Symbol">)</a> <a id="15925" class="Symbol">→</a> <a id="15927" href="hack-your-type-theory.html#4880" class="Generalizable">P</a> <a id="15929" href="hack-your-type-theory.html#15918" class="Bound">x</a><a id="15930" class="Symbol">}</a> <a id="15932" href="hack-your-type-theory.html#15891" class="Bound">e</a>
    <a id="15938" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="15940" class="Symbol">λ</a> <a id="15942" href="hack-your-type-theory.html#15942" class="Bound">x</a> <a id="15944" class="Symbol">→</a> <a id="15946" href="hack-your-type-theory.html#15486" class="Postulate">raise</a> <a id="15952" class="Symbol">{</a><a id="15953" class="Argument">A</a> <a id="15955" class="Symbol">=</a> <a id="15957" href="hack-your-type-theory.html#4880" class="Generalizable">P</a> <a id="15959" href="hack-your-type-theory.html#15942" class="Bound">x</a><a id="15960" class="Symbol">}</a> <a id="15962" href="hack-your-type-theory.html#15891" class="Bound">e</a>

<a id="15965" class="Symbol">{-#</a> <a id="15969" class="Keyword">REWRITE</a> <a id="15977" href="hack-your-type-theory.html#15827" class="Postulate">raise-suc</a> <a id="15987" href="hack-your-type-theory.html#15878" class="Postulate">raise-fun</a> <a id="15997" class="Symbol">#-}</a>
</pre>
<p>To complete the system, we can then add the ability to <code>catch</code>
exceptions at specific types. This takes the shape of an eliminator
with one additional method for handling the case where the element
under scrutiny is of the form <code>raise e</code>.</p>
<pre class="Agda"><a id="16250" class="Keyword">postulate</a>
  <a id="catch-Bool"></a><a id="16262" href="hack-your-type-theory.html#16262" class="Postulate">catch-Bool</a> <a id="16273" class="Symbol">:</a> <a id="16275" class="Symbol">(</a><a id="16276" href="hack-your-type-theory.html#16276" class="Bound">P</a> <a id="16278" class="Symbol">:</a> <a id="16280" href="Agda.Builtin.Bool.html#173" class="Datatype">Bool</a> <a id="16285" class="Symbol">→</a> <a id="16287" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="16291" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a><a id="16292" class="Symbol">)</a>
               <a id="16309" class="Symbol">(</a><a id="16310" href="hack-your-type-theory.html#16310" class="Bound">pt</a> <a id="16313" class="Symbol">:</a> <a id="16315" href="hack-your-type-theory.html#16276" class="Bound">P</a> <a id="16317" href="Agda.Builtin.Bool.html#198" class="InductiveConstructor">true</a><a id="16321" class="Symbol">)</a> <a id="16323" class="Symbol">(</a><a id="16324" href="hack-your-type-theory.html#16324" class="Bound">pf</a> <a id="16327" class="Symbol">:</a> <a id="16329" href="hack-your-type-theory.html#16276" class="Bound">P</a> <a id="16331" href="Agda.Builtin.Bool.html#192" class="InductiveConstructor">false</a><a id="16336" class="Symbol">)</a>
               <a id="16353" class="Symbol">(</a><a id="16354" href="hack-your-type-theory.html#16354" class="Bound">h</a> <a id="16356" class="Symbol">:</a> <a id="16358" class="Symbol">∀</a> <a id="16360" href="hack-your-type-theory.html#16360" class="Bound">e</a> <a id="16362" class="Symbol">→</a> <a id="16364" href="hack-your-type-theory.html#16276" class="Bound">P</a> <a id="16366" class="Symbol">(</a><a id="16367" href="hack-your-type-theory.html#15486" class="Postulate">raise</a> <a id="16373" href="hack-your-type-theory.html#16360" class="Bound">e</a><a id="16374" class="Symbol">))</a>
             <a id="16390" class="Symbol">→</a> <a id="16392" class="Symbol">(</a><a id="16393" href="hack-your-type-theory.html#16393" class="Bound">b</a> <a id="16395" class="Symbol">:</a> <a id="16397" href="Agda.Builtin.Bool.html#173" class="Datatype">Bool</a><a id="16401" class="Symbol">)</a> <a id="16403" class="Symbol">→</a> <a id="16405" href="hack-your-type-theory.html#16276" class="Bound">P</a> <a id="16407" href="hack-your-type-theory.html#16393" class="Bound">b</a>

  <a id="catch-true"></a><a id="16412" href="hack-your-type-theory.html#16412" class="Postulate">catch-true</a>  <a id="16424" class="Symbol">:</a> <a id="16426" class="Symbol">∀</a> <a id="16428" class="Symbol">(</a><a id="16429" href="hack-your-type-theory.html#16429" class="Bound">P</a> <a id="16431" class="Symbol">:</a> <a id="16433" href="Agda.Builtin.Bool.html#173" class="Datatype">Bool</a> <a id="16438" class="Symbol">→</a> <a id="16440" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="16444" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a><a id="16445" class="Symbol">)</a> <a id="16447" href="hack-your-type-theory.html#16447" class="Bound">pt</a> <a id="16450" href="hack-your-type-theory.html#16450" class="Bound">pf</a> <a id="16453" href="hack-your-type-theory.html#16453" class="Bound">h</a>
              <a id="16469" class="Symbol">→</a> <a id="16471" href="hack-your-type-theory.html#16262" class="Postulate">catch-Bool</a> <a id="16482" href="hack-your-type-theory.html#16429" class="Bound">P</a> <a id="16484" href="hack-your-type-theory.html#16447" class="Bound">pt</a> <a id="16487" href="hack-your-type-theory.html#16450" class="Bound">pf</a> <a id="16490" href="hack-your-type-theory.html#16453" class="Bound">h</a> <a id="16492" href="Agda.Builtin.Bool.html#198" class="InductiveConstructor">true</a> <a id="16497" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="16499" href="hack-your-type-theory.html#16447" class="Bound">pt</a>
  <a id="catch-false"></a><a id="16504" href="hack-your-type-theory.html#16504" class="Postulate">catch-false</a> <a id="16516" class="Symbol">:</a> <a id="16518" class="Symbol">∀</a> <a id="16520" class="Symbol">(</a><a id="16521" href="hack-your-type-theory.html#16521" class="Bound">P</a> <a id="16523" class="Symbol">:</a> <a id="16525" href="Agda.Builtin.Bool.html#173" class="Datatype">Bool</a> <a id="16530" class="Symbol">→</a> <a id="16532" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="16536" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a><a id="16537" class="Symbol">)</a> <a id="16539" href="hack-your-type-theory.html#16539" class="Bound">pt</a> <a id="16542" href="hack-your-type-theory.html#16542" class="Bound">pf</a> <a id="16545" href="hack-your-type-theory.html#16545" class="Bound">h</a>
              <a id="16561" class="Symbol">→</a> <a id="16563" href="hack-your-type-theory.html#16262" class="Postulate">catch-Bool</a> <a id="16574" href="hack-your-type-theory.html#16521" class="Bound">P</a> <a id="16576" href="hack-your-type-theory.html#16539" class="Bound">pt</a> <a id="16579" href="hack-your-type-theory.html#16542" class="Bound">pf</a> <a id="16582" href="hack-your-type-theory.html#16545" class="Bound">h</a> <a id="16584" href="Agda.Builtin.Bool.html#192" class="InductiveConstructor">false</a> <a id="16590" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="16592" href="hack-your-type-theory.html#16542" class="Bound">pf</a>
  <a id="catch-exc"></a><a id="16597" href="hack-your-type-theory.html#16597" class="Postulate">catch-exc</a>   <a id="16609" class="Symbol">:</a> <a id="16611" class="Symbol">∀</a> <a id="16613" class="Symbol">(</a><a id="16614" href="hack-your-type-theory.html#16614" class="Bound">P</a> <a id="16616" class="Symbol">:</a> <a id="16618" href="Agda.Builtin.Bool.html#173" class="Datatype">Bool</a> <a id="16623" class="Symbol">→</a> <a id="16625" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="16629" href="hack-your-type-theory.html#4834" class="Generalizable">ℓ</a><a id="16630" class="Symbol">)</a> <a id="16632" href="hack-your-type-theory.html#16632" class="Bound">pt</a> <a id="16635" href="hack-your-type-theory.html#16635" class="Bound">pf</a> <a id="16638" href="hack-your-type-theory.html#16638" class="Bound">h</a> <a id="16640" href="hack-your-type-theory.html#16640" class="Bound">e</a>
              <a id="16656" class="Symbol">→</a> <a id="16658" href="hack-your-type-theory.html#16262" class="Postulate">catch-Bool</a> <a id="16669" href="hack-your-type-theory.html#16614" class="Bound">P</a> <a id="16671" href="hack-your-type-theory.html#16632" class="Bound">pt</a> <a id="16674" href="hack-your-type-theory.html#16635" class="Bound">pf</a> <a id="16677" href="hack-your-type-theory.html#16638" class="Bound">h</a> <a id="16679" class="Symbol">(</a><a id="16680" href="hack-your-type-theory.html#15486" class="Postulate">raise</a> <a id="16686" href="hack-your-type-theory.html#16640" class="Bound">e</a><a id="16687" class="Symbol">)</a> <a id="16689" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="16691" href="hack-your-type-theory.html#16638" class="Bound">h</a> <a id="16693" href="hack-your-type-theory.html#16640" class="Bound">e</a>

<a id="16696" class="Symbol">{-#</a> <a id="16700" class="Keyword">REWRITE</a> <a id="16708" href="hack-your-type-theory.html#16412" class="Postulate">catch-true</a> <a id="16719" href="hack-your-type-theory.html#16504" class="Postulate">catch-false</a> <a id="16731" href="hack-your-type-theory.html#16597" class="Postulate">catch-exc</a> <a id="16741" class="Symbol">#-}</a>
</pre>
<p>In their paper, Pierre-Marie and Nicolas show how to build a <em>safe</em>
version of exceptions on top of this system, using <em>parametricity</em> to
enforce that all exceptions are caught locally. Please go read their
paper if you want to know more!</p>
<h2 id="example-6-observational-equality">Example 6: Observational equality</h2>
<p>We can go even further in extending our type theory with new concepts
using rewrite rules. For example, we can define <em>type constructors</em>
that compute according to the type they are applied to. This is the
core concept of <a href="http://strictlypositive.org/ott.pdf"><em>observational type
theory</em></a> (OTT). OTT extends type
theory with an observational equality type (here called <code>_≅_</code>) that
computes acoording to the type of the elements being compared. For
example, an equality proof of type <code>(a , b) ≅ (c , d)</code> <strong>is</strong> a pair
of proofs, one of type <code>a ≅ c</code> and one of type <code>b ≅ d</code>.</p>
<p>OTT had a strong influence on the recent development of cubical type
theory, which extends it with a <em>proof-relevant</em> notion of
equality. Yet there are still some things that are possible in OTT but
not in cubical, so we should not write it off yet. For example, OTT
has <em>definitional proof irrelevance</em>, while it is not clear yet how
this can be integrated into cubical (although
<a href="https://arxiv.org/abs/1904.08562">XTT</a> looks very promising).</p>
<p>Below, I define a small fragment of OTT by using rewrite rules in
Agda. Since OTT has a proof-irrelevant equality type, I use Agda’s
<code>Prop</code> to get the same effect.</p>
<p>First, we need some basic types in <code>Prop</code>:</p>
<pre class="Agda"><a id="18280" class="Keyword">record</a> <a id="⊤"></a><a id="18287" href="hack-your-type-theory.html#18287" class="Record">⊤</a> <a id="18289" class="Symbol">{</a><a id="18290" href="hack-your-type-theory.html#18290" class="Bound">ℓ</a><a id="18291" class="Symbol">}</a> <a id="18293" class="Symbol">:</a> <a id="18295" href="Agda.Primitive.html#347" class="Primitive">Prop</a> <a id="18300" href="hack-your-type-theory.html#18290" class="Bound">ℓ</a> <a id="18302" class="Keyword">where</a> <a id="18308" class="Keyword">constructor</a> <a id="tt"></a><a id="18320" href="hack-your-type-theory.html#18320" class="InductiveConstructor">tt</a>

<a id="18324" class="Keyword">data</a>   <a id="⊥"></a><a id="18331" href="hack-your-type-theory.html#18331" class="Datatype">⊥</a> <a id="18333" class="Symbol">{</a><a id="18334" href="hack-your-type-theory.html#18334" class="Bound">ℓ</a><a id="18335" class="Symbol">}</a> <a id="18337" class="Symbol">:</a> <a id="18339" href="Agda.Primitive.html#347" class="Primitive">Prop</a> <a id="18344" href="hack-your-type-theory.html#18334" class="Bound">ℓ</a> <a id="18346" class="Keyword">where</a>

<a id="18353" class="Keyword">record</a> <a id="_∧_"></a><a id="18360" href="hack-your-type-theory.html#18360" class="Record Operator">_∧_</a> <a id="18364" class="Symbol">(</a><a id="18365" href="hack-your-type-theory.html#18365" class="Bound">X</a> <a id="18367" class="Symbol">:</a> <a id="18369" href="Agda.Primitive.html#347" class="Primitive">Prop</a> <a id="18374" href="hack-your-type-theory.html#4836" class="Generalizable">ℓ₁</a><a id="18376" class="Symbol">)</a> <a id="18378" class="Symbol">(</a><a id="18379" href="hack-your-type-theory.html#18379" class="Bound">Y</a> <a id="18381" class="Symbol">:</a> <a id="18383" href="Agda.Primitive.html#347" class="Primitive">Prop</a> <a id="18388" href="hack-your-type-theory.html#4839" class="Generalizable">ℓ₂</a><a id="18390" class="Symbol">)</a> <a id="18392" class="Symbol">:</a> <a id="18394" href="Agda.Primitive.html#347" class="Primitive">Prop</a> <a id="18399" class="Symbol">(</a><a id="18400" href="hack-your-type-theory.html#18374" class="Bound">ℓ₁</a> <a id="18403" href="Agda.Primitive.html#961" class="Primitive Operator">⊔</a> <a id="18405" href="hack-your-type-theory.html#18388" class="Bound">ℓ₂</a><a id="18407" class="Symbol">)</a> <a id="18409" class="Keyword">where</a>
  <a id="18417" class="Keyword">constructor</a> <a id="_,_"></a><a id="18429" href="hack-your-type-theory.html#18429" class="InductiveConstructor Operator">_,_</a>
  <a id="18435" class="Keyword">field</a>
    <a id="_∧_.fst"></a><a id="18445" href="hack-your-type-theory.html#18445" class="Field">fst</a> <a id="18449" class="Symbol">:</a> <a id="18451" href="hack-your-type-theory.html#18365" class="Bound">X</a>
    <a id="_∧_.snd"></a><a id="18457" href="hack-your-type-theory.html#18457" class="Field">snd</a> <a id="18461" class="Symbol">:</a> <a id="18463" href="hack-your-type-theory.html#18379" class="Bound">Y</a>
<a id="18465" class="Keyword">open</a> <a id="18470" href="hack-your-type-theory.html#18360" class="Module Operator">_∧_</a>
</pre>
<p>The central type is observational equality <code>_≅_</code>, which should compute
according to the types of the elements being compared. Here I give the
computation rules for <code>Bool</code> and for function types:</p>
<pre class="Agda"><a id="18679" class="Keyword">infix</a> <a id="18685" class="Number">6</a> <a id="18687" href="hack-your-type-theory.html#18729" class="Postulate Operator">_≅_</a>
<a id="18691" class="Comment">-- Observational equality</a>
<a id="18717" class="Keyword">postulate</a>
  <a id="_≅_"></a><a id="18729" href="hack-your-type-theory.html#18729" class="Postulate Operator">_≅_</a> <a id="18733" class="Symbol">:</a> <a id="18735" class="Symbol">{</a><a id="18736" href="hack-your-type-theory.html#18736" class="Bound">A</a> <a id="18738" class="Symbol">:</a> <a id="18740" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="18744" href="hack-your-type-theory.html#4836" class="Generalizable">ℓ₁</a><a id="18746" class="Symbol">}</a> <a id="18748" class="Symbol">{</a><a id="18749" href="hack-your-type-theory.html#18749" class="Bound">B</a> <a id="18751" class="Symbol">:</a> <a id="18753" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="18757" href="hack-your-type-theory.html#4839" class="Generalizable">ℓ₂</a><a id="18759" class="Symbol">}</a> <a id="18761" class="Symbol">→</a> <a id="18763" href="hack-your-type-theory.html#18736" class="Bound">A</a> <a id="18765" class="Symbol">→</a> <a id="18767" href="hack-your-type-theory.html#18749" class="Bound">B</a> <a id="18769" class="Symbol">→</a> <a id="18771" href="Agda.Primitive.html#347" class="Primitive">Prop</a> <a id="18776" class="Symbol">(</a><a id="18777" href="hack-your-type-theory.html#4836" class="Generalizable">ℓ₁</a> <a id="18780" href="Agda.Primitive.html#961" class="Primitive Operator">⊔</a> <a id="18782" href="hack-your-type-theory.html#4839" class="Generalizable">ℓ₂</a><a id="18784" class="Symbol">)</a>

<a id="HEq"></a><a id="18787" href="hack-your-type-theory.html#18787" class="Function">HEq</a> <a id="18791" class="Symbol">=</a> <a id="18793" href="hack-your-type-theory.html#18729" class="Postulate Operator">_≅_</a>
<a id="18797" class="Keyword">syntax</a> <a id="18804" href="hack-your-type-theory.html#18787" class="Function">HEq</a> <a id="18808" class="Symbol">{</a><a id="18809" class="Argument">A</a> <a id="18811" class="Symbol">=</a> <a id="18813" class="Bound">A</a><a id="18814" class="Symbol">}</a> <a id="18816" class="Symbol">{</a><a id="18817" class="Argument">B</a> <a id="18819" class="Symbol">=</a> <a id="18821" class="Bound">B</a><a id="18822" class="Symbol">}</a> <a id="18824" class="Bound">x</a> <a id="18826" class="Bound">y</a> <a id="18828" class="Symbol">=</a> <a id="18830" class="Bound">x</a> <a id="18832" class="Function">∈</a> <a id="18834" class="Bound">A</a> <a id="18836" class="Function">≅</a> <a id="18838" class="Bound">y</a> <a id="18840" class="Function">∈</a> <a id="18842" class="Bound">B</a>

<a id="18845" class="Keyword">postulate</a>
  <a id="refl-Bool"></a><a id="18857" href="hack-your-type-theory.html#18857" class="Postulate">refl-Bool</a>   <a id="18869" class="Symbol">:</a> <a id="18871" class="Symbol">(</a><a id="18872" href="Agda.Builtin.Bool.html#173" class="Datatype">Bool</a>  <a id="18878" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="18880" href="Agda.Builtin.Bool.html#173" class="Datatype">Bool</a><a id="18884" class="Symbol">)</a>  <a id="18887" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="18889" href="hack-your-type-theory.html#18287" class="Record">⊤</a>
  <a id="refl-true"></a><a id="18893" href="hack-your-type-theory.html#18893" class="Postulate">refl-true</a>   <a id="18905" class="Symbol">:</a> <a id="18907" class="Symbol">(</a><a id="18908" href="Agda.Builtin.Bool.html#198" class="InductiveConstructor">true</a>  <a id="18914" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="18916" href="Agda.Builtin.Bool.html#198" class="InductiveConstructor">true</a><a id="18920" class="Symbol">)</a>  <a id="18923" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="18925" href="hack-your-type-theory.html#18287" class="Record">⊤</a>
  <a id="refl-false"></a><a id="18929" href="hack-your-type-theory.html#18929" class="Postulate">refl-false</a>  <a id="18941" class="Symbol">:</a> <a id="18943" class="Symbol">(</a><a id="18944" href="Agda.Builtin.Bool.html#192" class="InductiveConstructor">false</a> <a id="18950" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="18952" href="Agda.Builtin.Bool.html#192" class="InductiveConstructor">false</a><a id="18957" class="Symbol">)</a> <a id="18959" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="18961" href="hack-your-type-theory.html#18287" class="Record">⊤</a>
  <a id="conflict-tf"></a><a id="18965" href="hack-your-type-theory.html#18965" class="Postulate">conflict-tf</a> <a id="18977" class="Symbol">:</a> <a id="18979" class="Symbol">(</a><a id="18980" href="Agda.Builtin.Bool.html#198" class="InductiveConstructor">true</a>  <a id="18986" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="18988" href="Agda.Builtin.Bool.html#192" class="InductiveConstructor">false</a><a id="18993" class="Symbol">)</a> <a id="18995" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="18997" href="hack-your-type-theory.html#18331" class="Datatype">⊥</a>
  <a id="conflict-ft"></a><a id="19001" href="hack-your-type-theory.html#19001" class="Postulate">conflict-ft</a> <a id="19013" class="Symbol">:</a> <a id="19015" class="Symbol">(</a><a id="19016" href="Agda.Builtin.Bool.html#192" class="InductiveConstructor">false</a> <a id="19022" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="19024" href="Agda.Builtin.Bool.html#198" class="InductiveConstructor">true</a><a id="19028" class="Symbol">)</a>  <a id="19031" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="19033" href="hack-your-type-theory.html#18331" class="Datatype">⊥</a>
<a id="19035" class="Symbol">{-#</a> <a id="19039" class="Keyword">REWRITE</a> <a id="19047" href="hack-your-type-theory.html#18857" class="Postulate">refl-Bool</a> <a id="19057" href="hack-your-type-theory.html#18893" class="Postulate">refl-true</a> <a id="19067" href="hack-your-type-theory.html#18929" class="Postulate">refl-false</a>
            <a id="19090" href="hack-your-type-theory.html#18965" class="Postulate">conflict-tf</a> <a id="19102" href="hack-your-type-theory.html#19001" class="Postulate">conflict-ft</a> <a id="19114" class="Symbol">#-}</a>

<a id="19119" class="Keyword">postulate</a>
  <a id="cong-Π"></a><a id="19131" href="hack-your-type-theory.html#19131" class="Postulate">cong-Π</a> <a id="19138" class="Symbol">:</a> <a id="19140" class="Symbol">((</a><a id="19142" href="hack-your-type-theory.html#19142" class="Bound">x</a> <a id="19144" class="Symbol">:</a> <a id="19146" href="hack-your-type-theory.html#4858" class="Generalizable">A</a><a id="19147" class="Symbol">)</a> <a id="19149" class="Symbol">→</a> <a id="19151" href="hack-your-type-theory.html#4880" class="Generalizable">P</a> <a id="19153" href="hack-your-type-theory.html#19142" class="Bound">x</a><a id="19154" class="Symbol">)</a> <a id="19156" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="19158" class="Symbol">((</a><a id="19160" href="hack-your-type-theory.html#19160" class="Bound">y</a> <a id="19162" class="Symbol">:</a> <a id="19164" href="hack-your-type-theory.html#4860" class="Generalizable">B</a><a id="19165" class="Symbol">)</a> <a id="19167" class="Symbol">→</a> <a id="19169" href="hack-your-type-theory.html#4882" class="Generalizable">Q</a> <a id="19171" href="hack-your-type-theory.html#19160" class="Bound">y</a><a id="19172" class="Symbol">)</a>
         <a id="19183" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="19185" class="Symbol">(</a><a id="19186" href="hack-your-type-theory.html#4860" class="Generalizable">B</a> <a id="19188" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="19190" href="hack-your-type-theory.html#4858" class="Generalizable">A</a><a id="19191" class="Symbol">)</a> <a id="19193" href="hack-your-type-theory.html#18360" class="Record Operator">∧</a> <a id="19195" class="Symbol">((</a><a id="19197" href="hack-your-type-theory.html#19197" class="Bound">x</a> <a id="19199" class="Symbol">:</a> <a id="19201" href="hack-your-type-theory.html#4858" class="Generalizable">A</a><a id="19202" class="Symbol">)(</a><a id="19204" href="hack-your-type-theory.html#19204" class="Bound">y</a> <a id="19206" class="Symbol">:</a> <a id="19208" href="hack-your-type-theory.html#4860" class="Generalizable">B</a><a id="19209" class="Symbol">)</a> <a id="19211" class="Symbol">→</a> <a id="19213" href="hack-your-type-theory.html#19204" class="Bound">y</a> <a id="19215" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="19217" href="hack-your-type-theory.html#19197" class="Bound">x</a> <a id="19219" class="Symbol">→</a> <a id="19221" href="hack-your-type-theory.html#4880" class="Generalizable">P</a> <a id="19223" href="hack-your-type-theory.html#19197" class="Bound">x</a> <a id="19225" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="19227" href="hack-your-type-theory.html#4882" class="Generalizable">Q</a> <a id="19229" href="hack-your-type-theory.html#19204" class="Bound">y</a><a id="19230" class="Symbol">)</a>
  <a id="cong-λ"></a><a id="19234" href="hack-your-type-theory.html#19234" class="Postulate">cong-λ</a> <a id="19241" class="Symbol">:</a> <a id="19243" class="Symbol">{</a><a id="19244" href="hack-your-type-theory.html#19244" class="Bound">A</a> <a id="19246" class="Symbol">:</a> <a id="19248" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="19252" href="hack-your-type-theory.html#4836" class="Generalizable">ℓ₁</a><a id="19254" class="Symbol">}</a> <a id="19256" class="Symbol">{</a><a id="19257" href="hack-your-type-theory.html#19257" class="Bound">B</a> <a id="19259" class="Symbol">:</a> <a id="19261" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="19265" href="hack-your-type-theory.html#4839" class="Generalizable">ℓ₂</a><a id="19267" class="Symbol">}</a>
    <a id="19273" class="Symbol">→</a> <a id="19275" class="Symbol">{</a><a id="19276" href="hack-your-type-theory.html#19276" class="Bound">P</a> <a id="19278" class="Symbol">:</a> <a id="19280" href="hack-your-type-theory.html#19244" class="Bound">A</a> <a id="19282" class="Symbol">→</a> <a id="19284" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="19288" href="hack-your-type-theory.html#4842" class="Generalizable">ℓ₃</a><a id="19290" class="Symbol">}</a> <a id="19292" class="Symbol">{</a><a id="19293" href="hack-your-type-theory.html#19293" class="Bound">Q</a> <a id="19295" class="Symbol">:</a> <a id="19297" href="hack-your-type-theory.html#19257" class="Bound">B</a> <a id="19299" class="Symbol">→</a> <a id="19301" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="19305" href="hack-your-type-theory.html#4845" class="Generalizable">ℓ₄</a><a id="19307" class="Symbol">}</a>
    <a id="19313" class="Symbol">→</a> <a id="19315" class="Symbol">(</a><a id="19316" href="hack-your-type-theory.html#19316" class="Bound">f</a> <a id="19318" class="Symbol">:</a> <a id="19320" class="Symbol">(</a><a id="19321" href="hack-your-type-theory.html#19321" class="Bound">x</a> <a id="19323" class="Symbol">:</a> <a id="19325" href="hack-your-type-theory.html#19244" class="Bound">A</a><a id="19326" class="Symbol">)</a> <a id="19328" class="Symbol">→</a> <a id="19330" href="hack-your-type-theory.html#19276" class="Bound">P</a> <a id="19332" href="hack-your-type-theory.html#19321" class="Bound">x</a><a id="19333" class="Symbol">)</a> <a id="19335" class="Symbol">(</a><a id="19336" href="hack-your-type-theory.html#19336" class="Bound">g</a> <a id="19338" class="Symbol">:</a> <a id="19340" class="Symbol">(</a><a id="19341" href="hack-your-type-theory.html#19341" class="Bound">y</a> <a id="19343" class="Symbol">:</a> <a id="19345" href="hack-your-type-theory.html#19257" class="Bound">B</a><a id="19346" class="Symbol">)</a> <a id="19348" class="Symbol">→</a> <a id="19350" href="hack-your-type-theory.html#19293" class="Bound">Q</a> <a id="19352" href="hack-your-type-theory.html#19341" class="Bound">y</a><a id="19353" class="Symbol">)</a>
    <a id="19359" class="Symbol">→</a> <a id="19361" class="Symbol">((λ</a> <a id="19365" href="hack-your-type-theory.html#19365" class="Bound">x</a> <a id="19367" class="Symbol">→</a> <a id="19369" href="hack-your-type-theory.html#19316" class="Bound">f</a> <a id="19371" href="hack-your-type-theory.html#19365" class="Bound">x</a><a id="19372" class="Symbol">)</a> <a id="19374" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="19376" class="Symbol">(λ</a> <a id="19379" href="hack-your-type-theory.html#19379" class="Bound">y</a> <a id="19381" class="Symbol">→</a> <a id="19383" href="hack-your-type-theory.html#19336" class="Bound">g</a> <a id="19385" href="hack-your-type-theory.html#19379" class="Bound">y</a><a id="19386" class="Symbol">))</a>
    <a id="19393" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="19395" class="Symbol">((</a><a id="19397" href="hack-your-type-theory.html#19397" class="Bound">x</a> <a id="19399" class="Symbol">:</a> <a id="19401" href="hack-your-type-theory.html#19244" class="Bound">A</a><a id="19402" class="Symbol">)</a> <a id="19404" class="Symbol">(</a><a id="19405" href="hack-your-type-theory.html#19405" class="Bound">y</a> <a id="19407" class="Symbol">:</a> <a id="19409" href="hack-your-type-theory.html#19257" class="Bound">B</a><a id="19410" class="Symbol">)</a> <a id="19412" class="Symbol">(</a><a id="19413" href="hack-your-type-theory.html#19413" class="Bound">x≅y</a> <a id="19417" class="Symbol">:</a> <a id="19419" href="hack-your-type-theory.html#19397" class="Bound">x</a> <a id="19421" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="19423" href="hack-your-type-theory.html#19405" class="Bound">y</a><a id="19424" class="Symbol">)</a> <a id="19426" class="Symbol">→</a> <a id="19428" href="hack-your-type-theory.html#19316" class="Bound">f</a> <a id="19430" href="hack-your-type-theory.html#19397" class="Bound">x</a> <a id="19432" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="19434" href="hack-your-type-theory.html#19336" class="Bound">g</a> <a id="19436" href="hack-your-type-theory.html#19405" class="Bound">y</a><a id="19437" class="Symbol">)</a>
<a id="19439" class="Symbol">{-#</a> <a id="19443" class="Keyword">REWRITE</a> <a id="19451" href="hack-your-type-theory.html#19131" class="Postulate">cong-Π</a> <a id="19458" href="hack-your-type-theory.html#19234" class="Postulate">cong-λ</a> <a id="19465" class="Symbol">#-}</a>
</pre>
<p>To be able to actually reason about equality, OTT also has two more
notions: <strong>coercion</strong> and <strong>cohesion</strong>. Coercion allows us to cast an
element from one type to the other when we know both types are equal,
and cohesion allows us to prove that coercion is computationally a
no-op.</p>
<pre class="Agda"><a id="19761" class="Keyword">infix</a> <a id="19767" class="Number">10</a> <a id="19770" href="hack-your-type-theory.html#19793" class="Postulate Operator">_[_⟩</a> <a id="19775" href="hack-your-type-theory.html#19839" class="Postulate Operator">_||_</a>

<a id="19781" class="Keyword">postulate</a>
  <a id="_[_⟩"></a><a id="19793" href="hack-your-type-theory.html#19793" class="Postulate Operator">_[_⟩</a>    <a id="19801" class="Symbol">:</a> <a id="19803" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="19805" class="Symbol">→</a> <a id="19807" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="19809" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="19811" href="hack-your-type-theory.html#4860" class="Generalizable">B</a> <a id="19813" class="Symbol">→</a> <a id="19815" href="hack-your-type-theory.html#4860" class="Generalizable">B</a>         <a id="19825" class="Comment">-- Coercion</a>
  <a id="_||_"></a><a id="19839" href="hack-your-type-theory.html#19839" class="Postulate Operator">_||_</a>    <a id="19847" class="Symbol">:</a> <a id="19849" class="Symbol">(</a><a id="19850" href="hack-your-type-theory.html#19850" class="Bound">x</a> <a id="19852" class="Symbol">:</a> <a id="19854" href="hack-your-type-theory.html#4858" class="Generalizable">A</a><a id="19855" class="Symbol">)</a> <a id="19857" class="Symbol">(</a><a id="19858" href="hack-your-type-theory.html#19858" class="Bound">Q</a> <a id="19860" class="Symbol">:</a> <a id="19862" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="19864" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="19866" href="hack-your-type-theory.html#4860" class="Generalizable">B</a><a id="19867" class="Symbol">)</a>
          <a id="19879" class="Symbol">→</a> <a id="19881" href="hack-your-type-theory.html#19850" class="Bound">x</a> <a id="19883" href="hack-your-type-theory.html#18787" class="Function">∈</a> <a id="19885" href="hack-your-type-theory.html#4858" class="Generalizable">A</a> <a id="19887" href="hack-your-type-theory.html#18787" class="Function">≅</a> <a id="19889" href="hack-your-type-theory.html#19850" class="Bound">x</a> <a id="19891" href="hack-your-type-theory.html#19793" class="Postulate Operator">[</a> <a id="19893" href="hack-your-type-theory.html#19858" class="Bound">Q</a> <a id="19895" href="hack-your-type-theory.html#19793" class="Postulate Operator">⟩</a> <a id="19897" href="hack-your-type-theory.html#18787" class="Function">∈</a> <a id="19899" href="hack-your-type-theory.html#4860" class="Generalizable">B</a>   <a id="19903" class="Comment">-- Coherence</a>
</pre>
<p>Again, we need more rewrite rules to make sure coercion computes in
the right way when applied to specific type constructors. Note that we
<em>don’t</em> need rewrite rules for coherence, since the result is of type
<code>_ ≅ _</code> which is a <code>Prop</code>, so it anyway has no computational content.</p>
<p>Coercing an element from <code>Bool</code> to <code>Bool</code> is easy.</p>
<pre class="Agda"><a id="20257" class="Keyword">postulate</a>
  <a id="coerce-Bool"></a><a id="20269" href="hack-your-type-theory.html#20269" class="Postulate">coerce-Bool</a> <a id="20281" class="Symbol">:</a> <a id="20283" href="hack-your-type-theory.html#4954" class="Generalizable">b</a> <a id="20285" href="hack-your-type-theory.html#19793" class="Postulate Operator">[</a> <a id="20287" href="hack-your-type-theory.html#18320" class="InductiveConstructor">tt</a> <a id="20290" href="hack-your-type-theory.html#19793" class="Postulate Operator">⟩</a> <a id="20292" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="20294" href="hack-your-type-theory.html#4954" class="Generalizable">b</a>
<a id="20296" class="Symbol">{-#</a> <a id="20300" class="Keyword">REWRITE</a> <a id="20308" href="hack-your-type-theory.html#20269" class="Postulate">coerce-Bool</a> <a id="20320" class="Symbol">#-}</a>
</pre>
<p>(Note that <code>Bool ≅ Bool</code> computes to <code>⊤</code>, so any proof of it will be
equal to <code>tt</code> by eta-equality.)</p>
<p>To coerce a
function from <code>(x : A) → P x</code> to <code>(y : B) → Q y</code> we need to:</p>
<ol type="1">
<li>Coerce the input from <code>y : B</code> to <code>x : A</code></li>
<li>Apply the function to get an element of type <code>P x</code></li>
<li>Coerce the output back to an element of <code>Q y</code></li>
</ol>
<p>In the last step, we need to use coherence to show that <code>x</code> and <code>y</code>
are (heterogeneously) equal.</p>
<pre class="Agda"><a id="20755" class="Keyword">postulate</a>
  <a id="coerce-Π"></a><a id="20767" href="hack-your-type-theory.html#20767" class="Postulate">coerce-Π</a> <a id="20776" class="Symbol">:</a> <a id="20778" class="Symbol">{</a><a id="20779" href="hack-your-type-theory.html#20779" class="Bound">A</a> <a id="20781" class="Symbol">:</a> <a id="20783" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="20787" href="hack-your-type-theory.html#4836" class="Generalizable">ℓ₁</a><a id="20789" class="Symbol">}</a> <a id="20791" class="Symbol">{</a><a id="20792" href="hack-your-type-theory.html#20792" class="Bound">B</a> <a id="20794" class="Symbol">:</a> <a id="20796" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="20800" href="hack-your-type-theory.html#4839" class="Generalizable">ℓ₂</a><a id="20802" class="Symbol">}</a>
    <a id="20808" class="Symbol">→</a> <a id="20810" class="Symbol">{</a><a id="20811" href="hack-your-type-theory.html#20811" class="Bound">P</a> <a id="20813" class="Symbol">:</a> <a id="20815" href="hack-your-type-theory.html#20779" class="Bound">A</a> <a id="20817" class="Symbol">→</a> <a id="20819" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="20823" href="hack-your-type-theory.html#4842" class="Generalizable">ℓ₃</a><a id="20825" class="Symbol">}</a> <a id="20827" class="Symbol">{</a><a id="20828" href="hack-your-type-theory.html#20828" class="Bound">Q</a> <a id="20830" class="Symbol">:</a> <a id="20832" href="hack-your-type-theory.html#20792" class="Bound">B</a> <a id="20834" class="Symbol">→</a> <a id="20836" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="20840" href="hack-your-type-theory.html#4845" class="Generalizable">ℓ₄</a><a id="20842" class="Symbol">}</a>
    <a id="20848" class="Symbol">→</a> <a id="20850" class="Symbol">{</a><a id="20851" href="hack-your-type-theory.html#20851" class="Bound">f</a> <a id="20853" class="Symbol">:</a> <a id="20855" class="Symbol">(</a><a id="20856" href="hack-your-type-theory.html#20856" class="Bound">x</a> <a id="20858" class="Symbol">:</a> <a id="20860" href="hack-your-type-theory.html#20779" class="Bound">A</a><a id="20861" class="Symbol">)</a> <a id="20863" class="Symbol">→</a> <a id="20865" href="hack-your-type-theory.html#20811" class="Bound">P</a> <a id="20867" href="hack-your-type-theory.html#20856" class="Bound">x</a><a id="20868" class="Symbol">}</a>
    <a id="20874" class="Symbol">→</a> <a id="20876" class="Symbol">(</a><a id="20877" href="hack-your-type-theory.html#20877" class="Bound">ΠAP≅ΠBQ</a> <a id="20885" class="Symbol">:</a> <a id="20887" class="Symbol">((</a><a id="20889" href="hack-your-type-theory.html#20889" class="Bound">x</a> <a id="20891" class="Symbol">:</a> <a id="20893" href="hack-your-type-theory.html#20779" class="Bound">A</a><a id="20894" class="Symbol">)</a> <a id="20896" class="Symbol">→</a> <a id="20898" href="hack-your-type-theory.html#20811" class="Bound">P</a> <a id="20900" href="hack-your-type-theory.html#20889" class="Bound">x</a><a id="20901" class="Symbol">)</a> <a id="20903" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="20905" class="Symbol">((</a><a id="20907" href="hack-your-type-theory.html#20907" class="Bound">y</a> <a id="20909" class="Symbol">:</a> <a id="20911" href="hack-your-type-theory.html#20792" class="Bound">B</a><a id="20912" class="Symbol">)</a> <a id="20914" class="Symbol">→</a> <a id="20916" href="hack-your-type-theory.html#20828" class="Bound">Q</a> <a id="20918" href="hack-your-type-theory.html#20907" class="Bound">y</a><a id="20919" class="Symbol">))</a>
    <a id="20926" class="Symbol">→</a> <a id="20928" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">_≡_</a> <a id="20932" class="Symbol">{</a><a id="20933" class="Argument">A</a> <a id="20935" class="Symbol">=</a> <a id="20937" class="Symbol">(</a><a id="20938" href="hack-your-type-theory.html#20938" class="Bound">y</a> <a id="20940" class="Symbol">:</a> <a id="20942" href="hack-your-type-theory.html#20792" class="Bound">B</a><a id="20943" class="Symbol">)</a> <a id="20945" class="Symbol">→</a> <a id="20947" href="hack-your-type-theory.html#20828" class="Bound">Q</a> <a id="20949" href="hack-your-type-theory.html#20938" class="Bound">y</a><a id="20950" class="Symbol">}</a> <a id="20952" class="Symbol">(</a><a id="20953" href="hack-your-type-theory.html#20851" class="Bound">f</a> <a id="20955" href="hack-your-type-theory.html#19793" class="Postulate Operator">[</a> <a id="20957" href="hack-your-type-theory.html#20877" class="Bound">ΠAP≅ΠBQ</a> <a id="20965" href="hack-your-type-theory.html#19793" class="Postulate Operator">⟩</a><a id="20966" class="Symbol">)</a> <a id="20968" class="Symbol">λ</a> <a id="20970" class="Symbol">(</a><a id="20971" href="hack-your-type-theory.html#20971" class="Bound">y</a> <a id="20973" class="Symbol">:</a> <a id="20975" href="hack-your-type-theory.html#20792" class="Bound">B</a><a id="20976" class="Symbol">)</a> <a id="20978" class="Symbol">→</a>
        <a id="20988" class="Keyword">let</a> <a id="20992" href="hack-your-type-theory.html#20992" class="Bound">B≅A</a> <a id="20996" class="Symbol">:</a> <a id="20998" href="hack-your-type-theory.html#20792" class="Bound">B</a> <a id="21000" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="21002" href="hack-your-type-theory.html#20779" class="Bound">A</a>
            <a id="21016" href="hack-your-type-theory.html#20992" class="Bound">B≅A</a> <a id="21020" class="Symbol">=</a> <a id="21022" href="hack-your-type-theory.html#18445" class="Field">fst</a> <a id="21026" href="hack-your-type-theory.html#20877" class="Bound">ΠAP≅ΠBQ</a>
            <a id="21046" href="hack-your-type-theory.html#21046" class="Bound">x</a>   <a id="21050" class="Symbol">:</a> <a id="21052" href="hack-your-type-theory.html#20779" class="Bound">A</a>
            <a id="21066" href="hack-your-type-theory.html#21046" class="Bound">x</a>   <a id="21070" class="Symbol">=</a> <a id="21072" href="hack-your-type-theory.html#20971" class="Bound">y</a> <a id="21074" href="hack-your-type-theory.html#19793" class="Postulate Operator">[</a> <a id="21076" href="hack-your-type-theory.html#20992" class="Bound">B≅A</a> <a id="21080" href="hack-your-type-theory.html#19793" class="Postulate Operator">⟩</a>
            <a id="21094" href="hack-your-type-theory.html#21094" class="Bound">Px≅Qy</a> <a id="21100" class="Symbol">:</a> <a id="21102" href="hack-your-type-theory.html#20811" class="Bound">P</a> <a id="21104" href="hack-your-type-theory.html#21046" class="Bound">x</a> <a id="21106" href="hack-your-type-theory.html#18729" class="Postulate Operator">≅</a> <a id="21108" href="hack-your-type-theory.html#20828" class="Bound">Q</a> <a id="21110" href="hack-your-type-theory.html#20971" class="Bound">y</a>
            <a id="21124" href="hack-your-type-theory.html#21094" class="Bound">Px≅Qy</a> <a id="21130" class="Symbol">=</a> <a id="21132" href="hack-your-type-theory.html#18457" class="Field">snd</a> <a id="21136" href="hack-your-type-theory.html#20877" class="Bound">ΠAP≅ΠBQ</a> <a id="21144" href="hack-your-type-theory.html#21046" class="Bound">x</a> <a id="21146" href="hack-your-type-theory.html#20971" class="Bound">y</a> <a id="21148" class="Symbol">(</a><a id="21149" href="hack-your-type-theory.html#19839" class="Postulate Operator">_||_</a> <a id="21154" class="Symbol">{</a><a id="21155" class="Argument">B</a> <a id="21157" class="Symbol">=</a> <a id="21159" href="hack-your-type-theory.html#20779" class="Bound">A</a><a id="21160" class="Symbol">}</a> <a id="21162" href="hack-your-type-theory.html#20971" class="Bound">y</a> <a id="21164" href="hack-your-type-theory.html#20992" class="Bound">B≅A</a><a id="21167" class="Symbol">)</a>
        <a id="21177" class="Keyword">in</a> <a id="21180" href="hack-your-type-theory.html#20851" class="Bound">f</a> <a id="21182" href="hack-your-type-theory.html#21046" class="Bound">x</a> <a id="21184" href="hack-your-type-theory.html#19793" class="Postulate Operator">[</a> <a id="21186" href="hack-your-type-theory.html#21094" class="Bound">Px≅Qy</a> <a id="21192" href="hack-your-type-theory.html#19793" class="Postulate Operator">⟩</a>
<a id="21194" class="Symbol">{-#</a> <a id="21198" class="Keyword">REWRITE</a> <a id="21206" href="hack-your-type-theory.html#20767" class="Postulate">coerce-Π</a> <a id="21215" class="Symbol">#-}</a>
</pre>
<p>Of course this is just a fragment of the whole system, but
implementing all of OTT would go beyond the scope of this blog
post. Hopefully this at least gives an idea how one could implement
the full system.</p>
<h2 id="conclusion">Conclusion</h2>
<p>With all these examples, I think this blog post has become long
enough. If you read all the way to here, I hope you found at least one
example that gave you the itch to try rewrite rules yourself. Be sure
to let me know if you come up with other cool examples! And if you got
interested in the exact workings of rewrite rules in Agda and how they
are implemented, stay tuned for the next post in this series.</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Mon, 21 Oct 2019 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/hack-your-type-theory.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>Formalize all the things (in Agda)</title>
    <link>https://jesper.sikanda.be/posts/formalize-all-the-things.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Formalize all the things (in Agda)</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Formalize all the things (in Agda)</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on October  4, 2019
    </p>
    <p>I quite often hear from people that they are interested in learning
Agda, and that’s great! However, I often feel there are not enough
examples out there of how to use the different features of Agda to
implement programs, enforce invariants in their types, and prove their
properties. So in this blog post I hope to address exactly that
problem.</p>
<p><img src="../images/formalize-all-the-stuff.jpg" style="max-width:100%;" /></p>
<p>The main goal of this example is to show off the dual purpose of Agda
as a strongly typed programming language and as a proof assistant for
formalizing mathematics. Since both purposes are part of the same
language, each of them reinforces the other: we can prove properties
of our programs, and we can write programs that produce proofs. In
this example, we will see this power in action by (1) defining the
mathematical structure of partial orders, (2) implementing a generic
binary search trees and insertion of new elements into them, and (3)
proving that this function is implemented correctly.</p>
<p>This blog post was based on a talk I gave at the <a href="https://github.com/InitialTypes/Club">Initial Types
Club</a> at Chalmers.</p>
<h2 id="preliminaries">Preliminaries</h2>
<p>For this post we keep the dependencies to a minimum so we
don’t rely on the standard library. Instead, we import some of the
built-in modules of Agda directly.</p>
<pre class="Agda"><a id="1423" class="Keyword">open</a> <a id="1428" class="Keyword">import</a> <a id="1435" href="Agda.Primitive.html" class="Module">Agda.Primitive</a>
<a id="1450" class="Keyword">open</a> <a id="1455" class="Keyword">import</a> <a id="1462" href="Agda.Builtin.Bool.html" class="Module">Agda.Builtin.Bool</a>
<a id="1480" class="Keyword">open</a> <a id="1485" class="Keyword">import</a> <a id="1492" href="Agda.Builtin.Nat.html" class="Module">Agda.Builtin.Nat</a>
<a id="1509" class="Keyword">open</a> <a id="1514" class="Keyword">import</a> <a id="1521" href="Agda.Builtin.Equality.html" class="Module">Agda.Builtin.Equality</a>
</pre>
<p>A <a href="https://agda.readthedocs.io/en/v2.6.0.1/language/generalization-of-declared-variables.html"><code>variable</code> declaration</a>
(since Agda 2.6.0) allows us to use variables without binding
them explicitly. This means they are implicitly universally quantified
in the types where they occur.</p>
<pre class="Agda"><a id="1836" class="Keyword">variable</a>
  <a id="1847" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="1849" href="formalize-all-the-things.html#1849" class="Generalizable">B</a> <a id="1851" href="formalize-all-the-things.html#1851" class="Generalizable">C</a> <a id="1853" class="Symbol">:</a> <a id="1855" href="Agda.Primitive.html#388" class="Primitive">Set</a>
  <a id="1861" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="1863" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="1865" href="formalize-all-the-things.html#1865" class="Generalizable">z</a> <a id="1867" class="Symbol">:</a> <a id="1869" href="formalize-all-the-things.html#1847" class="Generalizable">A</a>
  <a id="1873" href="formalize-all-the-things.html#1873" class="Generalizable">k</a> <a id="1875" href="formalize-all-the-things.html#1875" class="Generalizable">l</a> <a id="1877" href="formalize-all-the-things.html#1877" class="Generalizable">m</a> <a id="1879" href="formalize-all-the-things.html#1879" class="Generalizable">n</a> <a id="1881" class="Symbol">:</a> <a id="1883" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a>
</pre>
<p>In the code that follows, we will use <a href="https://agda.readthedocs.io/en/v2.6.0.1/language/instance-arguments.html">instance
arguments</a>
to automatically construct some proofs. When working with instance
arguments, the <code>it</code> function below is often very useful. All it does
is ask Agda to please fill in the current argument by using a
definition that is marked as an <code>instance</code>. (More about instance
arguments later).</p>
<pre class="Agda"><a id="it"></a><a id="2311" href="formalize-all-the-things.html#2311" class="Function">it</a> <a id="2314" class="Symbol">:</a> <a id="2316" class="Symbol">{{</a><a id="2318" href="formalize-all-the-things.html#2318" class="Bound">x</a> <a id="2320" class="Symbol">:</a> <a id="2322" href="formalize-all-the-things.html#1847" class="Generalizable">A</a><a id="2323" class="Symbol">}}</a> <a id="2326" class="Symbol">→</a> <a id="2328" href="formalize-all-the-things.html#1847" class="Generalizable">A</a>
<a id="2330" href="formalize-all-the-things.html#2311" class="Function">it</a> <a id="2333" class="Symbol">{{</a><a id="2335" href="formalize-all-the-things.html#2335" class="Bound">x</a><a id="2336" class="Symbol">}}</a> <a id="2339" class="Symbol">=</a> <a id="2341" href="formalize-all-the-things.html#2335" class="Bound">x</a>
</pre>
<p>(Unary) natural numbers are defined as the datatype <code>Nat</code> with two
constructors <code>zero : Nat</code> and <code>suc : Nat → Nat</code>. We use the ones
imported from <code>Agda.Builtin.Nat</code> because they allow us to write
literal numerals as well as constructor forms.</p>
<pre class="Agda"><a id="2596" href="formalize-all-the-things.html#2596" class="Function">_</a> <a id="2598" class="Symbol">:</a> <a id="2600" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a>
<a id="2604" class="Symbol">_</a> <a id="2606" class="Symbol">=</a> <a id="2608" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a> <a id="2613" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">+</a> <a id="2615" class="Number">7</a> <a id="2617" href="Agda.Builtin.Nat.html#539" class="Primitive Operator">*</a> <a id="2619" class="Symbol">(</a><a id="2620" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="2624" class="Number">3</a> <a id="2626" href="Agda.Builtin.Nat.html#426" class="Primitive Operator">-</a> <a id="2628" class="Number">1</a><a id="2629" class="Symbol">)</a>
</pre>
<p>(Definitions that are named <code>_</code> are typechecked by Agda but cannot be
used later on. This is often used to define examples or test cases).</p>
<p>We can define <a href="https://agda.readthedocs.io/en/v2.6.0.1/language/data-types.html#parametrized-datatypes">parametrized datatypes</a>
and functions by <a href="https://agda.readthedocs.io/en/v2.6.0.1/language/function-definitions.html">pattern matching</a>
on them. For example, here is the equivalent of Haskell’s <code>Maybe</code> type.</p>
<pre class="Agda"><a id="3093" class="Keyword">data</a> <a id="Maybe"></a><a id="3098" href="formalize-all-the-things.html#3098" class="Datatype">Maybe</a> <a id="3104" class="Symbol">(</a><a id="3105" href="formalize-all-the-things.html#3105" class="Bound">A</a> <a id="3107" class="Symbol">:</a> <a id="3109" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="3112" class="Symbol">)</a> <a id="3114" class="Symbol">:</a> <a id="3116" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="3120" class="Keyword">where</a>
  <a id="Maybe.just"></a><a id="3128" href="formalize-all-the-things.html#3128" class="InductiveConstructor">just</a>    <a id="3136" class="Symbol">:</a> <a id="3138" href="formalize-all-the-things.html#3105" class="Bound">A</a> <a id="3140" class="Symbol">→</a> <a id="3142" href="formalize-all-the-things.html#3098" class="Datatype">Maybe</a> <a id="3148" href="formalize-all-the-things.html#3105" class="Bound">A</a>
  <a id="Maybe.nothing"></a><a id="3152" href="formalize-all-the-things.html#3152" class="InductiveConstructor">nothing</a> <a id="3160" class="Symbol">:</a>     <a id="3166" href="formalize-all-the-things.html#3098" class="Datatype">Maybe</a> <a id="3172" href="formalize-all-the-things.html#3105" class="Bound">A</a>

<a id="mapMaybe"></a><a id="3175" href="formalize-all-the-things.html#3175" class="Function">mapMaybe</a> <a id="3184" class="Symbol">:</a> <a id="3186" class="Symbol">(</a><a id="3187" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="3189" class="Symbol">→</a> <a id="3191" href="formalize-all-the-things.html#1849" class="Generalizable">B</a><a id="3192" class="Symbol">)</a> <a id="3194" class="Symbol">→</a> <a id="3196" class="Symbol">(</a><a id="3197" href="formalize-all-the-things.html#3098" class="Datatype">Maybe</a> <a id="3203" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="3205" class="Symbol">→</a> <a id="3207" href="formalize-all-the-things.html#3098" class="Datatype">Maybe</a> <a id="3213" href="formalize-all-the-things.html#1849" class="Generalizable">B</a><a id="3214" class="Symbol">)</a>
<a id="3216" href="formalize-all-the-things.html#3175" class="Function">mapMaybe</a> <a id="3225" href="formalize-all-the-things.html#3225" class="Bound">f</a> <a id="3227" class="Symbol">(</a><a id="3228" href="formalize-all-the-things.html#3128" class="InductiveConstructor">just</a> <a id="3233" href="formalize-all-the-things.html#3233" class="Bound">x</a><a id="3234" class="Symbol">)</a> <a id="3236" class="Symbol">=</a> <a id="3238" href="formalize-all-the-things.html#3128" class="InductiveConstructor">just</a> <a id="3243" class="Symbol">(</a><a id="3244" href="formalize-all-the-things.html#3225" class="Bound">f</a> <a id="3246" href="formalize-all-the-things.html#3233" class="Bound">x</a><a id="3247" class="Symbol">)</a>
<a id="3249" href="formalize-all-the-things.html#3175" class="Function">mapMaybe</a> <a id="3258" href="formalize-all-the-things.html#3258" class="Bound">f</a> <a id="3260" href="formalize-all-the-things.html#3152" class="InductiveConstructor">nothing</a> <a id="3268" class="Symbol">=</a> <a id="3270" href="formalize-all-the-things.html#3152" class="InductiveConstructor">nothing</a>
</pre>
<p>Note how <code>A</code> and <code>B</code> are implicitly quantified in the type of
<code>mapMaybe</code>!</p>
<h2 id="quick-recap-on-the-curry-howard-correspondence">Quick recap on the Curry-Howard correspondence</h2>
<p>The Curry-Howard correspondence is the core idea that allows us to use
Agda as both a programming language and a proof assistant. Under the
Curry-Howard correspondence, we can interpret logical propositions (A
∧ B, ¬A, A ⇒ B, …) as the types of all their possible proofs.</p>
<p>A proof of ‘A and B’ is a <em>pair</em> (x , y) of a proof <code>x : A</code> and an
proof <code>y : B</code>.</p>
<pre class="Agda"><a id="3801" class="Keyword">record</a> <a id="_×_"></a><a id="3808" href="formalize-all-the-things.html#3808" class="Record Operator">_×_</a> <a id="3812" class="Symbol">(</a><a id="3813" href="formalize-all-the-things.html#3813" class="Bound">A</a> <a id="3815" href="formalize-all-the-things.html#3815" class="Bound">B</a> <a id="3817" class="Symbol">:</a> <a id="3819" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="3822" class="Symbol">)</a> <a id="3824" class="Symbol">:</a> <a id="3826" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="3830" class="Keyword">where</a>
  <a id="3838" class="Keyword">constructor</a> <a id="_,_"></a><a id="3850" href="formalize-all-the-things.html#3850" class="InductiveConstructor Operator">_,_</a>
  <a id="3856" class="Keyword">field</a>
    <a id="_×_.fst"></a><a id="3866" href="formalize-all-the-things.html#3866" class="Field">fst</a> <a id="3870" class="Symbol">:</a> <a id="3872" href="formalize-all-the-things.html#3813" class="Bound">A</a>
    <a id="_×_.snd"></a><a id="3878" href="formalize-all-the-things.html#3878" class="Field">snd</a> <a id="3882" class="Symbol">:</a> <a id="3884" href="formalize-all-the-things.html#3815" class="Bound">B</a>
<a id="3886" class="Keyword">open</a> <a id="3891" href="formalize-all-the-things.html#3808" class="Module Operator">_×_</a>
</pre>
<p>A proof of ‘A or B’ is either <code>inl x</code> for a proof <code>x : A</code> or <code>inr y</code>
for a proof <code>y : B</code>.</p>
<pre class="Agda"><a id="3995" class="Keyword">data</a> <a id="_⊎_"></a><a id="4000" href="formalize-all-the-things.html#4000" class="Datatype Operator">_⊎_</a> <a id="4004" class="Symbol">(</a><a id="4005" href="formalize-all-the-things.html#4005" class="Bound">A</a> <a id="4007" href="formalize-all-the-things.html#4007" class="Bound">B</a> <a id="4009" class="Symbol">:</a> <a id="4011" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="4014" class="Symbol">)</a> <a id="4016" class="Symbol">:</a> <a id="4018" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="4022" class="Keyword">where</a>
  <a id="_⊎_.inl"></a><a id="4030" href="formalize-all-the-things.html#4030" class="InductiveConstructor">inl</a> <a id="4034" class="Symbol">:</a> <a id="4036" href="formalize-all-the-things.html#4005" class="Bound">A</a> <a id="4038" class="Symbol">→</a> <a id="4040" href="formalize-all-the-things.html#4005" class="Bound">A</a> <a id="4042" href="formalize-all-the-things.html#4000" class="Datatype Operator">⊎</a> <a id="4044" href="formalize-all-the-things.html#4007" class="Bound">B</a>
  <a id="_⊎_.inr"></a><a id="4048" href="formalize-all-the-things.html#4048" class="InductiveConstructor">inr</a> <a id="4052" class="Symbol">:</a> <a id="4054" href="formalize-all-the-things.html#4007" class="Bound">B</a> <a id="4056" class="Symbol">→</a> <a id="4058" href="formalize-all-the-things.html#4005" class="Bound">A</a> <a id="4060" href="formalize-all-the-things.html#4000" class="Datatype Operator">⊎</a> <a id="4062" href="formalize-all-the-things.html#4007" class="Bound">B</a>

<a id="mapInl"></a><a id="4065" href="formalize-all-the-things.html#4065" class="Function">mapInl</a> <a id="4072" class="Symbol">:</a> <a id="4074" class="Symbol">(</a><a id="4075" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="4077" class="Symbol">→</a> <a id="4079" href="formalize-all-the-things.html#1849" class="Generalizable">B</a><a id="4080" class="Symbol">)</a> <a id="4082" class="Symbol">→</a> <a id="4084" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="4086" href="formalize-all-the-things.html#4000" class="Datatype Operator">⊎</a> <a id="4088" href="formalize-all-the-things.html#1851" class="Generalizable">C</a> <a id="4090" class="Symbol">→</a> <a id="4092" href="formalize-all-the-things.html#1849" class="Generalizable">B</a> <a id="4094" href="formalize-all-the-things.html#4000" class="Datatype Operator">⊎</a> <a id="4096" href="formalize-all-the-things.html#1851" class="Generalizable">C</a>
<a id="4098" href="formalize-all-the-things.html#4065" class="Function">mapInl</a> <a id="4105" href="formalize-all-the-things.html#4105" class="Bound">f</a> <a id="4107" class="Symbol">(</a><a id="4108" href="formalize-all-the-things.html#4030" class="InductiveConstructor">inl</a> <a id="4112" href="formalize-all-the-things.html#4112" class="Bound">x</a><a id="4113" class="Symbol">)</a> <a id="4115" class="Symbol">=</a> <a id="4117" href="formalize-all-the-things.html#4030" class="InductiveConstructor">inl</a> <a id="4121" class="Symbol">(</a><a id="4122" href="formalize-all-the-things.html#4105" class="Bound">f</a> <a id="4124" href="formalize-all-the-things.html#4112" class="Bound">x</a><a id="4125" class="Symbol">)</a>
<a id="4127" href="formalize-all-the-things.html#4065" class="Function">mapInl</a> <a id="4134" href="formalize-all-the-things.html#4134" class="Bound">f</a> <a id="4136" class="Symbol">(</a><a id="4137" href="formalize-all-the-things.html#4048" class="InductiveConstructor">inr</a> <a id="4141" href="formalize-all-the-things.html#4141" class="Bound">y</a><a id="4142" class="Symbol">)</a> <a id="4144" class="Symbol">=</a> <a id="4146" href="formalize-all-the-things.html#4048" class="InductiveConstructor">inr</a> <a id="4150" href="formalize-all-the-things.html#4141" class="Bound">y</a>

<a id="mapInr"></a><a id="4153" href="formalize-all-the-things.html#4153" class="Function">mapInr</a> <a id="4160" class="Symbol">:</a> <a id="4162" class="Symbol">(</a><a id="4163" href="formalize-all-the-things.html#1849" class="Generalizable">B</a> <a id="4165" class="Symbol">→</a> <a id="4167" href="formalize-all-the-things.html#1851" class="Generalizable">C</a><a id="4168" class="Symbol">)</a> <a id="4170" class="Symbol">→</a> <a id="4172" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="4174" href="formalize-all-the-things.html#4000" class="Datatype Operator">⊎</a> <a id="4176" href="formalize-all-the-things.html#1849" class="Generalizable">B</a> <a id="4178" class="Symbol">→</a> <a id="4180" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="4182" href="formalize-all-the-things.html#4000" class="Datatype Operator">⊎</a> <a id="4184" href="formalize-all-the-things.html#1851" class="Generalizable">C</a>
<a id="4186" href="formalize-all-the-things.html#4153" class="Function">mapInr</a> <a id="4193" href="formalize-all-the-things.html#4193" class="Bound">f</a> <a id="4195" class="Symbol">(</a><a id="4196" href="formalize-all-the-things.html#4030" class="InductiveConstructor">inl</a> <a id="4200" href="formalize-all-the-things.html#4200" class="Bound">x</a><a id="4201" class="Symbol">)</a> <a id="4203" class="Symbol">=</a> <a id="4205" href="formalize-all-the-things.html#4030" class="InductiveConstructor">inl</a> <a id="4209" href="formalize-all-the-things.html#4200" class="Bound">x</a>
<a id="4211" href="formalize-all-the-things.html#4153" class="Function">mapInr</a> <a id="4218" href="formalize-all-the-things.html#4218" class="Bound">f</a> <a id="4220" class="Symbol">(</a><a id="4221" href="formalize-all-the-things.html#4048" class="InductiveConstructor">inr</a> <a id="4225" href="formalize-all-the-things.html#4225" class="Bound">y</a><a id="4226" class="Symbol">)</a> <a id="4228" class="Symbol">=</a> <a id="4230" href="formalize-all-the-things.html#4048" class="InductiveConstructor">inr</a> <a id="4234" class="Symbol">(</a><a id="4235" href="formalize-all-the-things.html#4218" class="Bound">f</a> <a id="4237" href="formalize-all-the-things.html#4225" class="Bound">y</a><a id="4238" class="Symbol">)</a>
</pre>
<p>A proof of ‘A implies B’ is a transformation from proofs <code>x : A</code> to
proofs of <code>B</code>, i.e. a function of type <code>A → B</code>.</p>
<p>‘true’ has exactly one proof <code>tt : ⊤</code>. We could define this as a
datatype with a single constructor <code>tt</code>, but here we define it as a
record type instead. This has the advantage that Agda will use
eta-equality for elements of <code>⊤</code>, i.e. <code>x = y</code> for any two variables
<code>x</code> and <code>y</code> of type <code>⊤</code>.</p>
<pre class="Agda"><a id="4657" class="Keyword">record</a> <a id="⊤"></a><a id="4664" href="formalize-all-the-things.html#4664" class="Record">⊤</a> <a id="4666" class="Symbol">:</a> <a id="4668" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="4672" class="Keyword">where</a>
  <a id="4680" class="Keyword">constructor</a> <a id="tt"></a><a id="4692" href="formalize-all-the-things.html#4692" class="InductiveConstructor">tt</a>     <a id="4699" class="Comment">-- no fields</a>
</pre>
<p>‘false’ has no proofs.</p>
<pre class="Agda"><a id="4745" class="Keyword">data</a> <a id="⊥"></a><a id="4750" href="formalize-all-the-things.html#4750" class="Datatype">⊥</a> <a id="4752" class="Symbol">:</a> <a id="4754" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="4758" class="Keyword">where</a>   <a id="4766" class="Comment">-- no constructor</a>
</pre>
<p>‘not A’ can be defined as ‘A implies false’.</p>
<pre class="Agda"><a id="¬_"></a><a id="4839" href="formalize-all-the-things.html#4839" class="Function Operator">¬_</a> <a id="4842" class="Symbol">:</a> <a id="4844" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="4848" class="Symbol">→</a> <a id="4850" href="Agda.Primitive.html#388" class="Primitive">Set</a>
<a id="4854" href="formalize-all-the-things.html#4839" class="Function Operator">¬</a> <a id="4856" href="formalize-all-the-things.html#4856" class="Bound">A</a> <a id="4858" class="Symbol">=</a> <a id="4860" href="formalize-all-the-things.html#4856" class="Bound">A</a> <a id="4862" class="Symbol">→</a> <a id="4864" href="formalize-all-the-things.html#4750" class="Datatype">⊥</a>
</pre>
<h3 id="examples">Examples</h3>
<pre class="Agda"><a id="4889" class="Comment">-- “If A then B implies A”</a>
<a id="ex₁"></a><a id="4916" href="formalize-all-the-things.html#4916" class="Function">ex₁</a> <a id="4920" class="Symbol">:</a> <a id="4922" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="4924" class="Symbol">→</a> <a id="4926" class="Symbol">(</a><a id="4927" href="formalize-all-the-things.html#1849" class="Generalizable">B</a> <a id="4929" class="Symbol">→</a> <a id="4931" href="formalize-all-the-things.html#1847" class="Generalizable">A</a><a id="4932" class="Symbol">)</a>
<a id="4934" href="formalize-all-the-things.html#4916" class="Function">ex₁</a> <a id="4938" class="Symbol">=</a> <a id="4940" class="Symbol">λ</a> <a id="4942" href="formalize-all-the-things.html#4942" class="Bound">z</a> <a id="4944" href="formalize-all-the-things.html#4944" class="Bound">_</a> <a id="4946" class="Symbol">→</a> <a id="4948" href="formalize-all-the-things.html#4942" class="Bound">z</a>

<a id="4951" class="Comment">-- “If A and true then A or false”</a>
<a id="ex₂"></a><a id="4986" href="formalize-all-the-things.html#4986" class="Function">ex₂</a> <a id="4990" class="Symbol">:</a> <a id="4992" class="Symbol">(</a><a id="4993" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="4995" href="formalize-all-the-things.html#3808" class="Record Operator">×</a> <a id="4997" href="formalize-all-the-things.html#4664" class="Record">⊤</a><a id="4998" class="Symbol">)</a> <a id="5000" class="Symbol">→</a> <a id="5002" class="Symbol">(</a><a id="5003" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="5005" href="formalize-all-the-things.html#4000" class="Datatype Operator">⊎</a> <a id="5007" href="formalize-all-the-things.html#4750" class="Datatype">⊥</a><a id="5008" class="Symbol">)</a>
<a id="5010" href="formalize-all-the-things.html#4986" class="Function">ex₂</a> <a id="5014" class="Symbol">=</a> <a id="5016" class="Symbol">λ</a> <a id="5018" href="formalize-all-the-things.html#5018" class="Bound">z</a> <a id="5020" class="Symbol">→</a> <a id="5022" href="formalize-all-the-things.html#4030" class="InductiveConstructor">inl</a> <a id="5026" class="Symbol">(</a><a id="5027" href="formalize-all-the-things.html#3866" class="Field">fst</a> <a id="5031" href="formalize-all-the-things.html#5018" class="Bound">z</a><a id="5032" class="Symbol">)</a>

<a id="5035" class="Comment">-- “If A implies B and B implies C then A implies C”</a>
<a id="ex₃"></a><a id="5088" href="formalize-all-the-things.html#5088" class="Function">ex₃</a> <a id="5092" class="Symbol">:</a> <a id="5094" class="Symbol">(</a><a id="5095" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="5097" class="Symbol">→</a> <a id="5099" href="formalize-all-the-things.html#1849" class="Generalizable">B</a><a id="5100" class="Symbol">)</a> <a id="5102" class="Symbol">→</a> <a id="5104" class="Symbol">(</a><a id="5105" href="formalize-all-the-things.html#1849" class="Generalizable">B</a> <a id="5107" class="Symbol">→</a> <a id="5109" href="formalize-all-the-things.html#1851" class="Generalizable">C</a><a id="5110" class="Symbol">)</a> <a id="5112" class="Symbol">→</a> <a id="5114" class="Symbol">(</a><a id="5115" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="5117" class="Symbol">→</a> <a id="5119" href="formalize-all-the-things.html#1851" class="Generalizable">C</a><a id="5120" class="Symbol">)</a>
<a id="5122" href="formalize-all-the-things.html#5088" class="Function">ex₃</a> <a id="5126" class="Symbol">=</a> <a id="5128" class="Symbol">λ</a> <a id="5130" href="formalize-all-the-things.html#5130" class="Bound">f</a> <a id="5132" href="formalize-all-the-things.html#5132" class="Bound">g</a> <a id="5134" href="formalize-all-the-things.html#5134" class="Bound">z</a> <a id="5136" class="Symbol">→</a> <a id="5138" href="formalize-all-the-things.html#5132" class="Bound">g</a> <a id="5140" class="Symbol">(</a><a id="5141" href="formalize-all-the-things.html#5130" class="Bound">f</a> <a id="5143" href="formalize-all-the-things.html#5134" class="Bound">z</a><a id="5144" class="Symbol">)</a>

<a id="5147" class="Comment">-- “It is not the case that not (either A or not A)”</a>
<a id="ex₄"></a><a id="5200" href="formalize-all-the-things.html#5200" class="Function">ex₄</a> <a id="5204" class="Symbol">:</a> <a id="5206" href="formalize-all-the-things.html#4839" class="Function Operator">¬</a> <a id="5208" class="Symbol">(</a><a id="5209" href="formalize-all-the-things.html#4839" class="Function Operator">¬</a> <a id="5211" class="Symbol">(</a><a id="5212" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="5214" href="formalize-all-the-things.html#4000" class="Datatype Operator">⊎</a> <a id="5216" class="Symbol">(</a><a id="5217" href="formalize-all-the-things.html#4839" class="Function Operator">¬</a> <a id="5219" href="formalize-all-the-things.html#1847" class="Generalizable">A</a><a id="5220" class="Symbol">)))</a>
<a id="5224" href="formalize-all-the-things.html#5200" class="Function">ex₄</a> <a id="5228" class="Symbol">=</a> <a id="5230" class="Symbol">λ</a> <a id="5232" href="formalize-all-the-things.html#5232" class="Bound">f</a> <a id="5234" class="Symbol">→</a> <a id="5236" href="formalize-all-the-things.html#5232" class="Bound">f</a> <a id="5238" class="Symbol">(</a><a id="5239" href="formalize-all-the-things.html#4048" class="InductiveConstructor">inr</a> <a id="5243" class="Symbol">(λ</a> <a id="5246" href="formalize-all-the-things.html#5246" class="Bound">x</a> <a id="5248" class="Symbol">→</a> <a id="5250" href="formalize-all-the-things.html#5232" class="Bound">f</a> <a id="5252" class="Symbol">(</a><a id="5253" href="formalize-all-the-things.html#4030" class="InductiveConstructor">inl</a> <a id="5257" href="formalize-all-the-things.html#5246" class="Bound">x</a><a id="5258" class="Symbol">)))</a>
</pre>
<p>Since Agda’s logic is constructive, it is not possible to prove the
direct version of <code>ex₄</code> (<code>A ⊎ (¬ A)</code>).</p>
<h2 id="equality">Equality</h2>
<p>To state many properties of our programs, we need the notion of
equality. In Agda, equality is defined as the datatype <code>_≡_</code> with one
constructor <code>refl : x ≡ x</code> (imported from <code>Agda.Builtin.Equality</code>).</p>
<pre class="Agda"><a id="5601" href="formalize-all-the-things.html#5601" class="Function">_</a> <a id="5603" class="Symbol">:</a> <a id="5605" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="5607" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="5609" href="formalize-all-the-things.html#1861" class="Generalizable">x</a>
<a id="5611" class="Symbol">_</a> <a id="5613" class="Symbol">=</a> <a id="5615" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>

<a id="sym"></a><a id="5621" href="formalize-all-the-things.html#5621" class="Function">sym</a> <a id="5625" class="Symbol">:</a> <a id="5627" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="5629" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="5631" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="5633" class="Symbol">→</a> <a id="5635" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="5637" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="5639" href="formalize-all-the-things.html#1861" class="Generalizable">x</a>
<a id="5641" href="formalize-all-the-things.html#5621" class="Function">sym</a> <a id="5645" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a> <a id="5650" class="Symbol">=</a> <a id="5652" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>

<a id="trans"></a><a id="5658" href="formalize-all-the-things.html#5658" class="Function">trans</a> <a id="5664" class="Symbol">:</a> <a id="5666" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="5668" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="5670" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="5672" class="Symbol">→</a> <a id="5674" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="5676" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="5678" href="formalize-all-the-things.html#1865" class="Generalizable">z</a> <a id="5680" class="Symbol">→</a> <a id="5682" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="5684" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="5686" href="formalize-all-the-things.html#1865" class="Generalizable">z</a>
<a id="5688" href="formalize-all-the-things.html#5658" class="Function">trans</a> <a id="5694" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a> <a id="5699" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a> <a id="5704" class="Symbol">=</a> <a id="5706" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>

<a id="cong"></a><a id="5712" href="formalize-all-the-things.html#5712" class="Function">cong</a> <a id="5717" class="Symbol">:</a> <a id="5719" class="Symbol">(</a><a id="5720" href="formalize-all-the-things.html#5720" class="Bound">f</a> <a id="5722" class="Symbol">:</a> <a id="5724" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="5726" class="Symbol">→</a> <a id="5728" href="formalize-all-the-things.html#1849" class="Generalizable">B</a><a id="5729" class="Symbol">)</a> <a id="5731" class="Symbol">→</a> <a id="5733" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="5735" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="5737" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="5739" class="Symbol">→</a> <a id="5741" href="formalize-all-the-things.html#5720" class="Bound">f</a> <a id="5743" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="5745" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="5747" href="formalize-all-the-things.html#5720" class="Bound">f</a> <a id="5749" href="formalize-all-the-things.html#1863" class="Generalizable">y</a>
<a id="5751" href="formalize-all-the-things.html#5712" class="Function">cong</a> <a id="5756" href="formalize-all-the-things.html#5756" class="Bound">f</a> <a id="5758" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a> <a id="5763" class="Symbol">=</a> <a id="5765" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>

<a id="subst"></a><a id="5771" href="formalize-all-the-things.html#5771" class="Function">subst</a> <a id="5777" class="Symbol">:</a> <a id="5779" class="Symbol">(</a><a id="5780" href="formalize-all-the-things.html#5780" class="Bound">P</a> <a id="5782" class="Symbol">:</a> <a id="5784" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="5786" class="Symbol">→</a> <a id="5788" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="5791" class="Symbol">)</a> <a id="5793" class="Symbol">→</a> <a id="5795" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="5797" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="5799" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="5801" class="Symbol">→</a> <a id="5803" href="formalize-all-the-things.html#5780" class="Bound">P</a> <a id="5805" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="5807" class="Symbol">→</a> <a id="5809" href="formalize-all-the-things.html#5780" class="Bound">P</a> <a id="5811" href="formalize-all-the-things.html#1863" class="Generalizable">y</a>
<a id="5813" href="formalize-all-the-things.html#5771" class="Function">subst</a> <a id="5819" href="formalize-all-the-things.html#5819" class="Bound">P</a> <a id="5821" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a> <a id="5826" href="formalize-all-the-things.html#5826" class="Bound">p</a> <a id="5828" class="Symbol">=</a> <a id="5830" href="formalize-all-the-things.html#5826" class="Bound">p</a>
</pre>
<h2 id="ordering-natural-numbers">Ordering natural numbers</h2>
<p>The standard ordering on natural numbers can be defined as an
<a href="https://agda.readthedocs.io/en/v2.6.0.1/language/data-types.html#indexed-datatypes"><em>indexed datatype</em></a>
with two indices of type <code>Nat</code>:</p>
<pre class="Agda"><a id="6093" class="Keyword">module</a> <a id="Nat-≤"></a><a id="6100" href="formalize-all-the-things.html#6100" class="Module">Nat-≤</a> <a id="6106" class="Keyword">where</a>

  <a id="6115" class="Keyword">data</a> <a id="Nat-≤._≤_"></a><a id="6120" href="formalize-all-the-things.html#6120" class="Datatype Operator">_≤_</a> <a id="6124" class="Symbol">:</a> <a id="6126" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a> <a id="6130" class="Symbol">→</a> <a id="6132" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a> <a id="6136" class="Symbol">→</a> <a id="6138" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="6142" class="Keyword">where</a>
    <a id="Nat-≤._≤_.≤-zero"></a><a id="6152" href="formalize-all-the-things.html#6152" class="InductiveConstructor">≤-zero</a> <a id="6159" class="Symbol">:</a>         <a id="6169" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>  <a id="6175" href="formalize-all-the-things.html#6120" class="Datatype Operator">≤</a> <a id="6177" href="formalize-all-the-things.html#1879" class="Generalizable">n</a>
    <a id="Nat-≤._≤_.≤-suc"></a><a id="6183" href="formalize-all-the-things.html#6183" class="InductiveConstructor">≤-suc</a>  <a id="6190" class="Symbol">:</a> <a id="6192" href="formalize-all-the-things.html#1877" class="Generalizable">m</a> <a id="6194" href="formalize-all-the-things.html#6120" class="Datatype Operator">≤</a> <a id="6196" href="formalize-all-the-things.html#1879" class="Generalizable">n</a> <a id="6198" class="Symbol">→</a> <a id="6200" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6204" href="formalize-all-the-things.html#1877" class="Generalizable">m</a> <a id="6206" href="formalize-all-the-things.html#6120" class="Datatype Operator">≤</a> <a id="6208" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6212" href="formalize-all-the-things.html#1879" class="Generalizable">n</a>

  <a id="Nat-≤.≤-refl"></a><a id="6217" href="formalize-all-the-things.html#6217" class="Function">≤-refl</a> <a id="6224" class="Symbol">:</a> <a id="6226" href="formalize-all-the-things.html#1879" class="Generalizable">n</a> <a id="6228" href="formalize-all-the-things.html#6120" class="Datatype Operator">≤</a> <a id="6230" href="formalize-all-the-things.html#1879" class="Generalizable">n</a>
  <a id="6234" href="formalize-all-the-things.html#6217" class="Function">≤-refl</a> <a id="6241" class="Symbol">{</a><a id="6242" class="Argument">n</a> <a id="6244" class="Symbol">=</a> <a id="6246" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a><a id="6250" class="Symbol">}</a>  <a id="6253" class="Symbol">=</a> <a id="6255" href="formalize-all-the-things.html#6152" class="InductiveConstructor">≤-zero</a>
  <a id="6264" href="formalize-all-the-things.html#6217" class="Function">≤-refl</a> <a id="6271" class="Symbol">{</a><a id="6272" class="Argument">n</a> <a id="6274" class="Symbol">=</a> <a id="6276" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6280" href="formalize-all-the-things.html#6280" class="Bound">k</a><a id="6281" class="Symbol">}</a> <a id="6283" class="Symbol">=</a> <a id="6285" href="formalize-all-the-things.html#6183" class="InductiveConstructor">≤-suc</a> <a id="6291" href="formalize-all-the-things.html#6217" class="Function">≤-refl</a>

  <a id="Nat-≤.≤-trans"></a><a id="6301" href="formalize-all-the-things.html#6301" class="Function">≤-trans</a> <a id="6309" class="Symbol">:</a> <a id="6311" href="formalize-all-the-things.html#1873" class="Generalizable">k</a> <a id="6313" href="formalize-all-the-things.html#6120" class="Datatype Operator">≤</a> <a id="6315" href="formalize-all-the-things.html#1875" class="Generalizable">l</a> <a id="6317" class="Symbol">→</a> <a id="6319" href="formalize-all-the-things.html#1875" class="Generalizable">l</a> <a id="6321" href="formalize-all-the-things.html#6120" class="Datatype Operator">≤</a> <a id="6323" href="formalize-all-the-things.html#1877" class="Generalizable">m</a> <a id="6325" class="Symbol">→</a> <a id="6327" href="formalize-all-the-things.html#1873" class="Generalizable">k</a> <a id="6329" href="formalize-all-the-things.html#6120" class="Datatype Operator">≤</a> <a id="6331" href="formalize-all-the-things.html#1877" class="Generalizable">m</a>
  <a id="6335" href="formalize-all-the-things.html#6301" class="Function">≤-trans</a> <a id="6343" href="formalize-all-the-things.html#6152" class="InductiveConstructor">≤-zero</a>      <a id="6355" href="formalize-all-the-things.html#6355" class="Bound">l≤m</a>         <a id="6367" class="Symbol">=</a> <a id="6369" href="formalize-all-the-things.html#6152" class="InductiveConstructor">≤-zero</a>
  <a id="6378" href="formalize-all-the-things.html#6301" class="Function">≤-trans</a> <a id="6386" class="Symbol">(</a><a id="6387" href="formalize-all-the-things.html#6183" class="InductiveConstructor">≤-suc</a> <a id="6393" href="formalize-all-the-things.html#6393" class="Bound">k≤l</a><a id="6396" class="Symbol">)</a> <a id="6398" class="Symbol">(</a><a id="6399" href="formalize-all-the-things.html#6183" class="InductiveConstructor">≤-suc</a> <a id="6405" href="formalize-all-the-things.html#6405" class="Bound">l≤m</a><a id="6408" class="Symbol">)</a> <a id="6410" class="Symbol">=</a>
    <a id="6416" href="formalize-all-the-things.html#6183" class="InductiveConstructor">≤-suc</a> <a id="6422" class="Symbol">(</a><a id="6423" href="formalize-all-the-things.html#6301" class="Function">≤-trans</a> <a id="6431" href="formalize-all-the-things.html#6393" class="Bound">k≤l</a> <a id="6435" href="formalize-all-the-things.html#6405" class="Bound">l≤m</a><a id="6438" class="Symbol">)</a>

  <a id="Nat-≤.≤-antisym"></a><a id="6443" href="formalize-all-the-things.html#6443" class="Function">≤-antisym</a> <a id="6453" class="Symbol">:</a> <a id="6455" href="formalize-all-the-things.html#1877" class="Generalizable">m</a> <a id="6457" href="formalize-all-the-things.html#6120" class="Datatype Operator">≤</a> <a id="6459" href="formalize-all-the-things.html#1879" class="Generalizable">n</a> <a id="6461" class="Symbol">→</a> <a id="6463" href="formalize-all-the-things.html#1879" class="Generalizable">n</a> <a id="6465" href="formalize-all-the-things.html#6120" class="Datatype Operator">≤</a> <a id="6467" href="formalize-all-the-things.html#1877" class="Generalizable">m</a> <a id="6469" class="Symbol">→</a> <a id="6471" href="formalize-all-the-things.html#1877" class="Generalizable">m</a> <a id="6473" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="6475" href="formalize-all-the-things.html#1879" class="Generalizable">n</a>
  <a id="6479" href="formalize-all-the-things.html#6443" class="Function">≤-antisym</a> <a id="6489" href="formalize-all-the-things.html#6152" class="InductiveConstructor">≤-zero</a>      <a id="6501" href="formalize-all-the-things.html#6152" class="InductiveConstructor">≤-zero</a>      <a id="6513" class="Symbol">=</a> <a id="6515" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
  <a id="6522" href="formalize-all-the-things.html#6443" class="Function">≤-antisym</a> <a id="6532" class="Symbol">(</a><a id="6533" href="formalize-all-the-things.html#6183" class="InductiveConstructor">≤-suc</a> <a id="6539" href="formalize-all-the-things.html#6539" class="Bound">m≤n</a><a id="6542" class="Symbol">)</a> <a id="6544" class="Symbol">(</a><a id="6545" href="formalize-all-the-things.html#6183" class="InductiveConstructor">≤-suc</a> <a id="6551" href="formalize-all-the-things.html#6551" class="Bound">n≤m</a><a id="6554" class="Symbol">)</a> <a id="6556" class="Symbol">=</a>
    <a id="6562" href="formalize-all-the-things.html#5712" class="Function">cong</a> <a id="6567" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="6571" class="Symbol">(</a><a id="6572" href="formalize-all-the-things.html#6443" class="Function">≤-antisym</a> <a id="6582" href="formalize-all-the-things.html#6539" class="Bound">m≤n</a> <a id="6586" href="formalize-all-the-things.html#6551" class="Bound">n≤m</a><a id="6589" class="Symbol">)</a>
</pre>
<p>Now we can prove statements like <code>3 ≤ 5</code> as follows:</p>
<pre class="Agda">  <a id="6656" href="formalize-all-the-things.html#6656" class="Function">_</a> <a id="6658" class="Symbol">:</a> <a id="6660" class="Number">3</a> <a id="6662" href="formalize-all-the-things.html#6120" class="Datatype Operator">≤</a> <a id="6664" class="Number">5</a>
  <a id="6668" class="Symbol">_</a> <a id="6670" class="Symbol">=</a> <a id="6672" href="formalize-all-the-things.html#6183" class="InductiveConstructor">≤-suc</a> <a id="6678" class="Symbol">(</a><a id="6679" href="formalize-all-the-things.html#6183" class="InductiveConstructor">≤-suc</a> <a id="6685" class="Symbol">(</a><a id="6686" href="formalize-all-the-things.html#6183" class="InductiveConstructor">≤-suc</a> <a id="6692" href="formalize-all-the-things.html#6152" class="InductiveConstructor">≤-zero</a><a id="6698" class="Symbol">))</a>
</pre>
<p>However, to prove an inequality like <code>9000 ≤ 9001</code> we would have to
write 9000 <code>≤-suc</code> constructors, which would get very
tedious. Instead, we can use Agda’s <a href="https://agda.readthedocs.io/en/v2.6.0.1/language/instance-arguments.html">instance arguments</a>
to automatically construct these kind of proofs.</p>
<p>To do this, we define an ‘instance’ that automatically constructs a
proof of <code>m ≤ n</code> when m and n are natural number literals. A
definition <code>inst : A</code> that is marked as an ‘instance’ will be used to
automatically construct the implicit argument to functions with a type
of the form <code>{{x : A}} → B</code>.</p>
<p>For efficiency reasons, we don’t mark the constructors <code>≤-zero</code> and
<code>≤-suc</code> as instances directly. Instead, we make use of the efficient
boolean comparison <code>_&lt;_</code> (imported from <code>Agda.Builtin.Nat</code>) to
construct the instance when the precondition <code>So (m &lt; suc n)</code> is
satisfied.</p>
<pre class="Agda">  <a id="Nat-≤.So"></a><a id="7592" href="formalize-all-the-things.html#7592" class="Function">So</a> <a id="7595" class="Symbol">:</a> <a id="7597" href="Agda.Builtin.Bool.html#173" class="Datatype">Bool</a> <a id="7602" class="Symbol">→</a> <a id="7604" href="Agda.Primitive.html#388" class="Primitive">Set</a>
  <a id="7610" href="formalize-all-the-things.html#7592" class="Function">So</a> <a id="7613" href="Agda.Builtin.Bool.html#192" class="InductiveConstructor">false</a> <a id="7619" class="Symbol">=</a> <a id="7621" href="formalize-all-the-things.html#4750" class="Datatype">⊥</a>
  <a id="7625" href="formalize-all-the-things.html#7592" class="Function">So</a> <a id="7628" href="Agda.Builtin.Bool.html#198" class="InductiveConstructor">true</a>  <a id="7634" class="Symbol">=</a> <a id="7636" href="formalize-all-the-things.html#4664" class="Record">⊤</a>

  <a id="7641" class="Keyword">instance</a>
    <a id="Nat-≤.≤-dec"></a><a id="7654" href="formalize-all-the-things.html#7654" class="Function">≤-dec</a> <a id="7660" class="Symbol">:</a> <a id="7662" class="Symbol">{</a><a id="7663" href="formalize-all-the-things.html#7663" class="Bound">p</a> <a id="7665" class="Symbol">:</a> <a id="7667" href="formalize-all-the-things.html#7592" class="Function">So</a> <a id="7670" class="Symbol">(</a><a id="7671" href="formalize-all-the-things.html#1877" class="Generalizable">m</a> <a id="7673" href="Agda.Builtin.Nat.html#757" class="Primitive Operator">&lt;</a> <a id="7675" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="7679" href="formalize-all-the-things.html#1879" class="Generalizable">n</a><a id="7680" class="Symbol">)}</a> <a id="7683" class="Symbol">→</a> <a id="7685" href="formalize-all-the-things.html#1877" class="Generalizable">m</a> <a id="7687" href="formalize-all-the-things.html#6120" class="Datatype Operator">≤</a> <a id="7689" href="formalize-all-the-things.html#1879" class="Generalizable">n</a>
    <a id="7695" href="formalize-all-the-things.html#7654" class="Function">≤-dec</a> <a id="7701" class="Symbol">{</a><a id="7702" class="Argument">m</a> <a id="7704" class="Symbol">=</a> <a id="7706" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a><a id="7710" class="Symbol">}</a> <a id="7712" class="Symbol">{</a><a id="7713" class="Argument">n</a> <a id="7715" class="Symbol">=</a> <a id="7717" href="formalize-all-the-things.html#7717" class="Bound">n</a><a id="7718" class="Symbol">}</a> <a id="7720" class="Symbol">=</a> <a id="7722" href="formalize-all-the-things.html#6152" class="InductiveConstructor">≤-zero</a>
    <a id="7733" href="formalize-all-the-things.html#7654" class="Function">≤-dec</a> <a id="7739" class="Symbol">{</a><a id="7740" class="Argument">m</a> <a id="7742" class="Symbol">=</a> <a id="7744" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="7748" href="formalize-all-the-things.html#7748" class="Bound">m</a><a id="7749" class="Symbol">}</a> <a id="7751" class="Symbol">{</a><a id="7752" class="Argument">n</a> <a id="7754" class="Symbol">=</a> <a id="7756" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="7760" href="formalize-all-the-things.html#7760" class="Bound">n</a><a id="7761" class="Symbol">}</a> <a id="7763" class="Symbol">{</a><a id="7764" class="Argument">p</a> <a id="7766" class="Symbol">=</a> <a id="7768" href="formalize-all-the-things.html#7768" class="Bound">p</a><a id="7769" class="Symbol">}</a> <a id="7771" class="Symbol">=</a>
      <a id="7779" href="formalize-all-the-things.html#6183" class="InductiveConstructor">≤-suc</a> <a id="7785" class="Symbol">(</a><a id="7786" href="formalize-all-the-things.html#7654" class="Function">≤-dec</a> <a id="7792" class="Symbol">{</a><a id="7793" class="Argument">p</a> <a id="7795" class="Symbol">=</a> <a id="7797" href="formalize-all-the-things.html#7768" class="Bound">p</a><a id="7798" class="Symbol">})</a>

  <a id="7804" href="formalize-all-the-things.html#7804" class="Function">_</a> <a id="7806" class="Symbol">:</a> <a id="7808" class="Number">9000</a> <a id="7813" href="formalize-all-the-things.html#6120" class="Datatype Operator">≤</a> <a id="7815" class="Number">9001</a>
  <a id="7822" class="Symbol">_</a> <a id="7824" class="Symbol">=</a> <a id="7826" href="formalize-all-the-things.html#2311" class="Function">it</a>
</pre>
<h2 id="partial-orders">Partial orders</h2>
<p>We’d like to talk not just about orderings on concrete types like
<code>Nat</code>, but also about the general concept of a ‘partial order’. For
this purpose, we define a typeclass <code>Ord</code> that contains the type <code>_≤_</code>
and proofs of its properties.</p>
<pre class="Agda"><a id="8106" class="Keyword">record</a> <a id="Ord"></a><a id="8113" href="formalize-all-the-things.html#8113" class="Record">Ord</a> <a id="8117" class="Symbol">(</a><a id="8118" href="formalize-all-the-things.html#8118" class="Bound">A</a> <a id="8120" class="Symbol">:</a> <a id="8122" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="8125" class="Symbol">)</a> <a id="8127" class="Symbol">:</a> <a id="8129" href="Agda.Primitive.html#388" class="Primitive">Set₁</a> <a id="8134" class="Keyword">where</a>
  <a id="8142" class="Keyword">field</a>
    <a id="Ord._≤_"></a><a id="8152" href="formalize-all-the-things.html#8152" class="Field Operator">_≤_</a>       <a id="8162" class="Symbol">:</a> <a id="8164" href="formalize-all-the-things.html#8118" class="Bound">A</a> <a id="8166" class="Symbol">→</a> <a id="8168" href="formalize-all-the-things.html#8118" class="Bound">A</a> <a id="8170" class="Symbol">→</a> <a id="8172" href="Agda.Primitive.html#388" class="Primitive">Set</a>
    <a id="Ord.≤-refl"></a><a id="8180" href="formalize-all-the-things.html#8180" class="Field">≤-refl</a>    <a id="8190" class="Symbol">:</a> <a id="8192" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="8194" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="8196" href="formalize-all-the-things.html#1861" class="Generalizable">x</a>
    <a id="Ord.≤-trans"></a><a id="8202" href="formalize-all-the-things.html#8202" class="Field">≤-trans</a>   <a id="8212" class="Symbol">:</a> <a id="8214" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="8216" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="8218" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="8220" class="Symbol">→</a> <a id="8222" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="8224" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="8226" href="formalize-all-the-things.html#1865" class="Generalizable">z</a> <a id="8228" class="Symbol">→</a> <a id="8230" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="8232" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="8234" href="formalize-all-the-things.html#1865" class="Generalizable">z</a>
    <a id="Ord.≤-antisym"></a><a id="8240" href="formalize-all-the-things.html#8240" class="Field">≤-antisym</a> <a id="8250" class="Symbol">:</a> <a id="8252" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="8254" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="8256" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="8258" class="Symbol">→</a> <a id="8260" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="8262" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="8264" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="8266" class="Symbol">→</a> <a id="8268" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="8270" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="8272" href="formalize-all-the-things.html#1863" class="Generalizable">y</a>

  <a id="Ord._≥_"></a><a id="8277" href="formalize-all-the-things.html#8277" class="Function Operator">_≥_</a> <a id="8281" class="Symbol">:</a> <a id="8283" href="formalize-all-the-things.html#8118" class="Bound">A</a> <a id="8285" class="Symbol">→</a> <a id="8287" href="formalize-all-the-things.html#8118" class="Bound">A</a> <a id="8289" class="Symbol">→</a> <a id="8291" href="Agda.Primitive.html#388" class="Primitive">Set</a>
  <a id="8297" href="formalize-all-the-things.html#8297" class="Bound">x</a> <a id="8299" href="formalize-all-the-things.html#8277" class="Function Operator">≥</a> <a id="8301" href="formalize-all-the-things.html#8301" class="Bound">y</a> <a id="8303" class="Symbol">=</a> <a id="8305" href="formalize-all-the-things.html#8301" class="Bound">y</a> <a id="8307" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="8309" href="formalize-all-the-things.html#8297" class="Bound">x</a>
</pre>
<p>Unlike in Haskell, typeclasses are not a primitive concept in
Agda. Instead, we use the special syntax <code>open Ord {{...}}</code> to bring
the fields of the record in scope as instance functions with a type of
the form <code>{A : Set}{{r : Ord A}} → ...</code>. Instance search will then
kick in to find the right implementation of the typeclass
automatically.</p>
<pre class="Agda"><a id="8663" class="Keyword">open</a> <a id="8668" href="formalize-all-the-things.html#8113" class="Module">Ord</a> <a id="8672" class="Symbol">{{...}}</a>
</pre>
<p>We now define some concrete
instances of the typeclass using <a href="https://agda.readthedocs.io/en/v2.6.0.1/language/copatterns.html">copattern
matching</a></p>
<pre class="Agda">
<a id="8839" class="Keyword">instance</a>
  <a id="Ord-Nat"></a><a id="8850" href="formalize-all-the-things.html#8850" class="Function">Ord-Nat</a> <a id="8858" class="Symbol">:</a> <a id="8860" href="formalize-all-the-things.html#8113" class="Record">Ord</a> <a id="8864" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a>
  <a id="8870" href="formalize-all-the-things.html#8152" class="Field Operator">_≤_</a>       <a id="8880" class="Symbol">{{</a><a id="8882" href="formalize-all-the-things.html#8850" class="Function">Ord-Nat</a><a id="8889" class="Symbol">}}</a> <a id="8892" class="Symbol">=</a> <a id="8894" href="formalize-all-the-things.html#6120" class="Datatype Operator">Nat-≤._≤_</a>
  <a id="8906" href="formalize-all-the-things.html#8180" class="Field">≤-refl</a>    <a id="8916" class="Symbol">{{</a><a id="8918" href="formalize-all-the-things.html#8850" class="Function">Ord-Nat</a><a id="8925" class="Symbol">}}</a> <a id="8928" class="Symbol">=</a> <a id="8930" href="formalize-all-the-things.html#6217" class="Function">Nat-≤.≤-refl</a>
  <a id="8945" href="formalize-all-the-things.html#8202" class="Field">≤-trans</a>   <a id="8955" class="Symbol">{{</a><a id="8957" href="formalize-all-the-things.html#8850" class="Function">Ord-Nat</a><a id="8964" class="Symbol">}}</a> <a id="8967" class="Symbol">=</a> <a id="8969" href="formalize-all-the-things.html#6301" class="Function">Nat-≤.≤-trans</a>
  <a id="8985" href="formalize-all-the-things.html#8240" class="Field">≤-antisym</a> <a id="8995" class="Symbol">{{</a><a id="8997" href="formalize-all-the-things.html#8850" class="Function">Ord-Nat</a><a id="9004" class="Symbol">}}</a> <a id="9007" class="Symbol">=</a> <a id="9009" href="formalize-all-the-things.html#6443" class="Function">Nat-≤.≤-antisym</a>

<a id="9026" class="Keyword">instance</a>
  <a id="Ord-⊤"></a><a id="9037" href="formalize-all-the-things.html#9037" class="Function">Ord-⊤</a> <a id="9043" class="Symbol">:</a> <a id="9045" href="formalize-all-the-things.html#8113" class="Record">Ord</a> <a id="9049" href="formalize-all-the-things.html#4664" class="Record">⊤</a>
  <a id="9053" href="formalize-all-the-things.html#8152" class="Field Operator">_≤_</a>       <a id="9063" class="Symbol">{{</a><a id="9065" href="formalize-all-the-things.html#9037" class="Function">Ord-⊤</a><a id="9070" class="Symbol">}}</a> <a id="9073" class="Symbol">=</a> <a id="9075" class="Symbol">λ</a> <a id="9077" href="formalize-all-the-things.html#9077" class="Bound">_</a> <a id="9079" href="formalize-all-the-things.html#9079" class="Bound">_</a> <a id="9081" class="Symbol">→</a> <a id="9083" href="formalize-all-the-things.html#4664" class="Record">⊤</a>
  <a id="9087" href="formalize-all-the-things.html#8180" class="Field">≤-refl</a>    <a id="9097" class="Symbol">{{</a><a id="9099" href="formalize-all-the-things.html#9037" class="Function">Ord-⊤</a><a id="9104" class="Symbol">}}</a> <a id="9107" class="Symbol">=</a> <a id="9109" href="formalize-all-the-things.html#4692" class="InductiveConstructor">tt</a>
  <a id="9114" href="formalize-all-the-things.html#8202" class="Field">≤-trans</a>   <a id="9124" class="Symbol">{{</a><a id="9126" href="formalize-all-the-things.html#9037" class="Function">Ord-⊤</a><a id="9131" class="Symbol">}}</a> <a id="9134" class="Symbol">=</a> <a id="9136" class="Symbol">λ</a> <a id="9138" href="formalize-all-the-things.html#9138" class="Bound">_</a> <a id="9140" href="formalize-all-the-things.html#9140" class="Bound">_</a> <a id="9142" class="Symbol">→</a> <a id="9144" href="formalize-all-the-things.html#4692" class="InductiveConstructor">tt</a>
  <a id="9149" href="formalize-all-the-things.html#8240" class="Field">≤-antisym</a> <a id="9159" class="Symbol">{{</a><a id="9161" href="formalize-all-the-things.html#9037" class="Function">Ord-⊤</a><a id="9166" class="Symbol">}}</a> <a id="9169" class="Symbol">=</a> <a id="9171" class="Symbol">λ</a> <a id="9173" href="formalize-all-the-things.html#9173" class="Bound">_</a> <a id="9175" href="formalize-all-the-things.html#9175" class="Bound">_</a> <a id="9177" class="Symbol">→</a> <a id="9179" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>

<a id="9185" class="Keyword">module</a> <a id="Example"></a><a id="9192" href="formalize-all-the-things.html#9192" class="Module">Example</a> <a id="9200" class="Symbol">(</a><a id="9201" href="formalize-all-the-things.html#9201" class="Bound">A</a> <a id="9203" class="Symbol">:</a> <a id="9205" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="9208" class="Symbol">)</a> <a id="9210" class="Symbol">{{</a><a id="9212" href="formalize-all-the-things.html#9212" class="Bound">A-≤</a> <a id="9216" class="Symbol">:</a> <a id="9218" href="formalize-all-the-things.html#8113" class="Record">Ord</a> <a id="9222" href="formalize-all-the-things.html#9201" class="Bound">A</a><a id="9223" class="Symbol">}}</a> <a id="9226" class="Keyword">where</a>

  <a id="Example.example"></a><a id="9235" href="formalize-all-the-things.html#9235" class="Function">example</a> <a id="9243" class="Symbol">:</a> <a id="9245" class="Symbol">{</a><a id="9246" href="formalize-all-the-things.html#9246" class="Bound">x</a> <a id="9248" href="formalize-all-the-things.html#9248" class="Bound">y</a> <a id="9250" href="formalize-all-the-things.html#9250" class="Bound">z</a> <a id="9252" class="Symbol">:</a> <a id="9254" href="formalize-all-the-things.html#9201" class="Bound">A</a><a id="9255" class="Symbol">}</a> <a id="9257" class="Symbol">→</a> <a id="9259" href="formalize-all-the-things.html#9246" class="Bound">x</a> <a id="9261" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="9263" href="formalize-all-the-things.html#9248" class="Bound">y</a> <a id="9265" class="Symbol">→</a> <a id="9267" href="formalize-all-the-things.html#9248" class="Bound">y</a> <a id="9269" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="9271" href="formalize-all-the-things.html#9250" class="Bound">z</a> <a id="9273" class="Symbol">→</a> <a id="9275" href="formalize-all-the-things.html#9250" class="Bound">z</a> <a id="9277" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="9279" href="formalize-all-the-things.html#9246" class="Bound">x</a> <a id="9281" class="Symbol">→</a> <a id="9283" href="formalize-all-the-things.html#9246" class="Bound">x</a> <a id="9285" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="9287" href="formalize-all-the-things.html#9248" class="Bound">y</a>
  <a id="9291" href="formalize-all-the-things.html#9235" class="Function">example</a> <a id="9299" href="formalize-all-the-things.html#9299" class="Bound">x≤y</a> <a id="9303" href="formalize-all-the-things.html#9303" class="Bound">y≤z</a> <a id="9307" href="formalize-all-the-things.html#9307" class="Bound">z≤x</a> <a id="9311" class="Symbol">=</a> <a id="9313" href="formalize-all-the-things.html#8240" class="Field">≤-antisym</a> <a id="9323" class="Symbol">{</a><a id="9324" class="Argument">A</a> <a id="9326" class="Symbol">=</a> <a id="9328" href="formalize-all-the-things.html#9201" class="Bound">A</a><a id="9329" class="Symbol">}</a> <a id="9331" href="formalize-all-the-things.html#9299" class="Bound">x≤y</a> <a id="9335" class="Symbol">(</a><a id="9336" href="formalize-all-the-things.html#8202" class="Field">≤-trans</a> <a id="9344" class="Symbol">{</a><a id="9345" class="Argument">A</a> <a id="9347" class="Symbol">=</a> <a id="9349" href="formalize-all-the-things.html#9201" class="Bound">A</a><a id="9350" class="Symbol">}</a> <a id="9352" href="formalize-all-the-things.html#9303" class="Bound">y≤z</a> <a id="9356" href="formalize-all-the-things.html#9307" class="Bound">z≤x</a><a id="9359" class="Symbol">)</a>
</pre>
<p>For working with binary search trees, we need to be able to decide for
any two elements which is the bigger one, i.e. we need a <em>total</em>,
<em>decidable</em> order.</p>
<pre class="Agda"><a id="9527" class="Keyword">data</a> <a id="Tri"></a><a id="9532" href="formalize-all-the-things.html#9532" class="Datatype">Tri</a> <a id="9536" class="Symbol">{{</a><a id="9538" href="formalize-all-the-things.html#9538" class="Bound">_</a> <a id="9540" class="Symbol">:</a> <a id="9542" href="formalize-all-the-things.html#8113" class="Record">Ord</a> <a id="9546" href="formalize-all-the-things.html#1847" class="Generalizable">A</a><a id="9547" class="Symbol">}}</a> <a id="9550" class="Symbol">:</a> <a id="9552" href="formalize-all-the-things.html#9546" class="Bound">A</a> <a id="9554" class="Symbol">→</a> <a id="9556" href="formalize-all-the-things.html#9546" class="Bound">A</a> <a id="9558" class="Symbol">→</a> <a id="9560" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="9564" class="Keyword">where</a>
  <a id="Tri.less"></a><a id="9572" href="formalize-all-the-things.html#9572" class="InductiveConstructor">less</a>    <a id="9580" class="Symbol">:</a> <a id="9582" class="Symbol">{{</a><a id="9584" href="formalize-all-the-things.html#9584" class="Bound">x≤y</a> <a id="9588" class="Symbol">:</a> <a id="9590" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="9592" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="9594" href="formalize-all-the-things.html#1863" class="Generalizable">y</a><a id="9595" class="Symbol">}}</a> <a id="9598" class="Symbol">→</a> <a id="9600" href="formalize-all-the-things.html#9532" class="Datatype">Tri</a> <a id="9604" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="9606" href="formalize-all-the-things.html#1863" class="Generalizable">y</a>
  <a id="Tri.equal"></a><a id="9610" href="formalize-all-the-things.html#9610" class="InductiveConstructor">equal</a>   <a id="9618" class="Symbol">:</a> <a id="9620" class="Symbol">{{</a><a id="9622" href="formalize-all-the-things.html#9622" class="Bound">x≡y</a> <a id="9626" class="Symbol">:</a> <a id="9628" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="9630" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="9632" href="formalize-all-the-things.html#1863" class="Generalizable">y</a><a id="9633" class="Symbol">}}</a> <a id="9636" class="Symbol">→</a> <a id="9638" href="formalize-all-the-things.html#9532" class="Datatype">Tri</a> <a id="9642" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="9644" href="formalize-all-the-things.html#1863" class="Generalizable">y</a>
  <a id="Tri.greater"></a><a id="9648" href="formalize-all-the-things.html#9648" class="InductiveConstructor">greater</a> <a id="9656" class="Symbol">:</a> <a id="9658" class="Symbol">{{</a><a id="9660" href="formalize-all-the-things.html#9660" class="Bound">x≥y</a> <a id="9664" class="Symbol">:</a> <a id="9666" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="9668" href="formalize-all-the-things.html#8277" class="Function Operator">≥</a> <a id="9670" href="formalize-all-the-things.html#1863" class="Generalizable">y</a><a id="9671" class="Symbol">}}</a> <a id="9674" class="Symbol">→</a> <a id="9676" href="formalize-all-the-things.html#9532" class="Datatype">Tri</a> <a id="9680" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="9682" href="formalize-all-the-things.html#1863" class="Generalizable">y</a>

<a id="9685" class="Keyword">record</a> <a id="TDO"></a><a id="9692" href="formalize-all-the-things.html#9692" class="Record">TDO</a> <a id="9696" class="Symbol">(</a><a id="9697" href="formalize-all-the-things.html#9697" class="Bound">A</a> <a id="9699" class="Symbol">:</a> <a id="9701" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="9704" class="Symbol">)</a> <a id="9706" class="Symbol">:</a> <a id="9708" href="Agda.Primitive.html#388" class="Primitive">Set₁</a> <a id="9713" class="Keyword">where</a>
  <a id="9721" class="Keyword">field</a>
    <a id="9731" class="Symbol">{{</a><a id="TDO.Ord-A"></a><a id="9733" href="formalize-all-the-things.html#9733" class="Field">Ord-A</a><a id="9738" class="Symbol">}}</a> <a id="9741" class="Symbol">:</a> <a id="9743" href="formalize-all-the-things.html#8113" class="Record">Ord</a> <a id="9747" href="formalize-all-the-things.html#9697" class="Bound">A</a>               <a id="9763" class="Comment">-- superclass Ord</a>
    <a id="TDO.tri"></a><a id="9785" href="formalize-all-the-things.html#9785" class="Field">tri</a>       <a id="9795" class="Symbol">:</a> <a id="9797" class="Symbol">(</a><a id="9798" href="formalize-all-the-things.html#9798" class="Bound">x</a> <a id="9800" href="formalize-all-the-things.html#9800" class="Bound">y</a> <a id="9802" class="Symbol">:</a> <a id="9804" href="formalize-all-the-things.html#9697" class="Bound">A</a><a id="9805" class="Symbol">)</a> <a id="9807" class="Symbol">→</a> <a id="9809" href="formalize-all-the-things.html#9532" class="Datatype">Tri</a> <a id="9813" href="formalize-all-the-things.html#9798" class="Bound">x</a> <a id="9815" href="formalize-all-the-things.html#9800" class="Bound">y</a>

<a id="9818" class="Keyword">open</a> <a id="9823" href="formalize-all-the-things.html#9692" class="Module">TDO</a> <a id="9827" class="Symbol">{{...}}</a> <a id="9835" class="Keyword">public</a>

<a id="triNat"></a><a id="9843" href="formalize-all-the-things.html#9843" class="Function">triNat</a> <a id="9850" class="Symbol">:</a> <a id="9852" class="Symbol">(</a><a id="9853" href="formalize-all-the-things.html#9853" class="Bound">x</a> <a id="9855" href="formalize-all-the-things.html#9855" class="Bound">y</a> <a id="9857" class="Symbol">:</a> <a id="9859" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a><a id="9862" class="Symbol">)</a> <a id="9864" class="Symbol">→</a> <a id="9866" href="formalize-all-the-things.html#9532" class="Datatype">Tri</a> <a id="9870" href="formalize-all-the-things.html#9853" class="Bound">x</a> <a id="9872" href="formalize-all-the-things.html#9855" class="Bound">y</a>
<a id="9874" href="formalize-all-the-things.html#9843" class="Function">triNat</a> <a id="9881" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a> <a id="9886" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a> <a id="9891" class="Symbol">=</a> <a id="9893" href="formalize-all-the-things.html#9610" class="InductiveConstructor">equal</a>
<a id="9899" href="formalize-all-the-things.html#9843" class="Function">triNat</a> <a id="9906" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a> <a id="9911" class="Symbol">(</a><a id="9912" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="9916" href="formalize-all-the-things.html#9916" class="Bound">y</a><a id="9917" class="Symbol">)</a> <a id="9919" class="Symbol">=</a> <a id="9921" href="formalize-all-the-things.html#9572" class="InductiveConstructor">less</a>
<a id="9926" href="formalize-all-the-things.html#9843" class="Function">triNat</a> <a id="9933" class="Symbol">(</a><a id="9934" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="9938" href="formalize-all-the-things.html#9938" class="Bound">x</a><a id="9939" class="Symbol">)</a> <a id="9941" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a> <a id="9946" class="Symbol">=</a> <a id="9948" href="formalize-all-the-things.html#9648" class="InductiveConstructor">greater</a>
<a id="9956" href="formalize-all-the-things.html#9843" class="Function">triNat</a> <a id="9963" class="Symbol">(</a><a id="9964" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="9968" href="formalize-all-the-things.html#9968" class="Bound">x</a><a id="9969" class="Symbol">)</a> <a id="9971" class="Symbol">(</a><a id="9972" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="9976" href="formalize-all-the-things.html#9976" class="Bound">y</a><a id="9977" class="Symbol">)</a> <a id="9979" class="Keyword">with</a> <a id="9984" href="formalize-all-the-things.html#9843" class="Function">triNat</a> <a id="9991" href="formalize-all-the-things.html#9968" class="Bound">x</a> <a id="9993" href="formalize-all-the-things.html#9976" class="Bound">y</a>
<a id="9995" class="Symbol">...</a> <a id="9999" class="Symbol">|</a> <a id="10001" href="formalize-all-the-things.html#9572" class="InductiveConstructor">less</a>    <a id="10009" class="Symbol">{{</a><a id="10011" href="formalize-all-the-things.html#10011" class="Bound">x≤y</a><a id="10014" class="Symbol">}}</a> <a id="10017" class="Symbol">=</a> <a id="10019" href="formalize-all-the-things.html#9572" class="InductiveConstructor">less</a>    <a id="10027" class="Symbol">{{</a><a id="10029" class="Argument">x≤y</a> <a id="10033" class="Symbol">=</a> <a id="10035" href="formalize-all-the-things.html#6183" class="InductiveConstructor">Nat-≤.≤-suc</a> <a id="10047" href="formalize-all-the-things.html#10011" class="Bound">x≤y</a><a id="10050" class="Symbol">}}</a>
<a id="10053" class="Symbol">...</a> <a id="10057" class="Symbol">|</a> <a id="10059" href="formalize-all-the-things.html#9610" class="InductiveConstructor">equal</a>   <a id="10067" class="Symbol">{{</a><a id="10069" href="formalize-all-the-things.html#10069" class="Bound">x≡y</a><a id="10072" class="Symbol">}}</a> <a id="10075" class="Symbol">=</a> <a id="10077" href="formalize-all-the-things.html#9610" class="InductiveConstructor">equal</a>   <a id="10085" class="Symbol">{{</a><a id="10087" class="Argument">x≡y</a> <a id="10091" class="Symbol">=</a> <a id="10093" href="formalize-all-the-things.html#5712" class="Function">cong</a> <a id="10098" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="10102" href="formalize-all-the-things.html#10069" class="Bound">x≡y</a><a id="10105" class="Symbol">}}</a>
<a id="10108" class="Symbol">...</a> <a id="10112" class="Symbol">|</a> <a id="10114" href="formalize-all-the-things.html#9648" class="InductiveConstructor">greater</a> <a id="10122" class="Symbol">{{</a><a id="10124" href="formalize-all-the-things.html#10124" class="Bound">x≥y</a><a id="10127" class="Symbol">}}</a> <a id="10130" class="Symbol">=</a> <a id="10132" href="formalize-all-the-things.html#9648" class="InductiveConstructor">greater</a> <a id="10140" class="Symbol">{{</a><a id="10142" class="Argument">x≥y</a> <a id="10146" class="Symbol">=</a> <a id="10148" href="formalize-all-the-things.html#6183" class="InductiveConstructor">Nat-≤.≤-suc</a> <a id="10160" href="formalize-all-the-things.html#10124" class="Bound">x≥y</a><a id="10163" class="Symbol">}}</a>

<a id="10167" class="Keyword">instance</a>
  <a id="TDO-Nat"></a><a id="10178" href="formalize-all-the-things.html#10178" class="Function">TDO-Nat</a> <a id="10186" class="Symbol">:</a> <a id="10188" href="formalize-all-the-things.html#9692" class="Record">TDO</a> <a id="10192" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a>
  <a id="10198" href="formalize-all-the-things.html#9733" class="Field">Ord-A</a> <a id="10204" class="Symbol">{{</a><a id="10206" href="formalize-all-the-things.html#10178" class="Function">TDO-Nat</a><a id="10213" class="Symbol">}}</a> <a id="10216" class="Symbol">=</a> <a id="10218" href="formalize-all-the-things.html#8850" class="Function">Ord-Nat</a>
  <a id="10228" href="formalize-all-the-things.html#9785" class="Field">tri</a>   <a id="10234" class="Symbol">{{</a><a id="10236" href="formalize-all-the-things.html#10178" class="Function">TDO-Nat</a><a id="10243" class="Symbol">}}</a> <a id="10246" class="Symbol">=</a> <a id="10248" href="formalize-all-the-things.html#9843" class="Function">triNat</a>
</pre>
<h2 id="binary-search-trees">Binary search trees</h2>
<p>In a dependently typed language, we can encode invariants of our data
structures by using <em>indexed datatypes</em>. In this example, we will
implement binary search trees by a lower and upper bound to the
elements they contain (see <a href="https://personal.cis.strath.ac.uk/conor.mcbride/Pivotal.pdf">How to Keep Your Neighbours in
Order</a> by
Conor McBride).</p>
<p>Since the lower bound may be -∞ and the upper bound may be +∞, we
start by providing a generic way to extend a partially ordered set
with those two elements.</p>
<pre class="Agda"><a id="10811" class="Keyword">data</a> <a id="[_]∞"></a><a id="10816" href="formalize-all-the-things.html#10816" class="Datatype Operator">[_]∞</a> <a id="10821" class="Symbol">(</a><a id="10822" href="formalize-all-the-things.html#10822" class="Bound">A</a> <a id="10824" class="Symbol">:</a> <a id="10826" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="10829" class="Symbol">)</a> <a id="10831" class="Symbol">:</a> <a id="10833" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="10837" class="Keyword">where</a>
  <a id="[_]∞.-∞"></a><a id="10845" href="formalize-all-the-things.html#10845" class="InductiveConstructor">-∞</a>  <a id="10849" class="Symbol">:</a>     <a id="10855" href="formalize-all-the-things.html#10816" class="Datatype Operator">[</a> <a id="10857" href="formalize-all-the-things.html#10822" class="Bound">A</a> <a id="10859" href="formalize-all-the-things.html#10816" class="Datatype Operator">]∞</a>
  <a id="[_]∞.[_]"></a><a id="10864" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[_]</a> <a id="10868" class="Symbol">:</a> <a id="10870" href="formalize-all-the-things.html#10822" class="Bound">A</a> <a id="10872" class="Symbol">→</a> <a id="10874" href="formalize-all-the-things.html#10816" class="Datatype Operator">[</a> <a id="10876" href="formalize-all-the-things.html#10822" class="Bound">A</a> <a id="10878" href="formalize-all-the-things.html#10816" class="Datatype Operator">]∞</a>
  <a id="[_]∞.+∞"></a><a id="10883" href="formalize-all-the-things.html#10883" class="InductiveConstructor">+∞</a>  <a id="10887" class="Symbol">:</a>     <a id="10893" href="formalize-all-the-things.html#10816" class="Datatype Operator">[</a> <a id="10895" href="formalize-all-the-things.html#10822" class="Bound">A</a> <a id="10897" href="formalize-all-the-things.html#10816" class="Datatype Operator">]∞</a>

<a id="10901" class="Keyword">variable</a>
  <a id="10912" href="formalize-all-the-things.html#10912" class="Generalizable">lower</a> <a id="10918" href="formalize-all-the-things.html#10918" class="Generalizable">upper</a> <a id="10924" class="Symbol">:</a> <a id="10926" href="formalize-all-the-things.html#10816" class="Datatype Operator">[</a> <a id="10928" href="formalize-all-the-things.html#1847" class="Generalizable">A</a> <a id="10930" href="formalize-all-the-things.html#10816" class="Datatype Operator">]∞</a>

<a id="10934" class="Keyword">module</a> <a id="Ord-[]∞"></a><a id="10941" href="formalize-all-the-things.html#10941" class="Module">Ord-[]∞</a> <a id="10949" class="Symbol">{</a><a id="10950" href="formalize-all-the-things.html#10950" class="Bound">A</a> <a id="10952" class="Symbol">:</a> <a id="10954" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="10957" class="Symbol">}</a> <a id="10959" class="Symbol">{{</a> <a id="10962" href="formalize-all-the-things.html#10962" class="Bound">A-≤</a> <a id="10966" class="Symbol">:</a> <a id="10968" href="formalize-all-the-things.html#8113" class="Record">Ord</a> <a id="10972" href="formalize-all-the-things.html#10950" class="Bound">A</a><a id="10973" class="Symbol">}}</a> <a id="10976" class="Keyword">where</a>

  <a id="10985" class="Keyword">data</a> <a id="Ord-[]∞._≤∞_"></a><a id="10990" href="formalize-all-the-things.html#10990" class="Datatype Operator">_≤∞_</a> <a id="10995" class="Symbol">:</a> <a id="10997" href="formalize-all-the-things.html#10816" class="Datatype Operator">[</a> <a id="10999" href="formalize-all-the-things.html#10950" class="Bound">A</a> <a id="11001" href="formalize-all-the-things.html#10816" class="Datatype Operator">]∞</a> <a id="11004" class="Symbol">→</a> <a id="11006" href="formalize-all-the-things.html#10816" class="Datatype Operator">[</a> <a id="11008" href="formalize-all-the-things.html#10950" class="Bound">A</a> <a id="11010" href="formalize-all-the-things.html#10816" class="Datatype Operator">]∞</a> <a id="11013" class="Symbol">→</a> <a id="11015" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="11019" class="Keyword">where</a>
    <a id="Ord-[]∞._≤∞_.-∞-≤"></a><a id="11029" href="formalize-all-the-things.html#11029" class="InductiveConstructor">-∞-≤</a> <a id="11034" class="Symbol">:</a>          <a id="11045" href="formalize-all-the-things.html#10845" class="InductiveConstructor">-∞</a>   <a id="11050" href="formalize-all-the-things.html#10990" class="Datatype Operator">≤∞</a>   <a id="11055" href="formalize-all-the-things.html#1863" class="Generalizable">y</a>
    <a id="Ord-[]∞._≤∞_.[]-≤"></a><a id="11061" href="formalize-all-the-things.html#11061" class="InductiveConstructor">[]-≤</a> <a id="11066" class="Symbol">:</a> <a id="11068" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="11070" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="11072" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="11074" class="Symbol">→</a> <a id="11076" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="11078" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="11080" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a> <a id="11082" href="formalize-all-the-things.html#10990" class="Datatype Operator">≤∞</a> <a id="11085" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="11087" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="11089" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a>
    <a id="Ord-[]∞._≤∞_.+∞-≤"></a><a id="11095" href="formalize-all-the-things.html#11095" class="InductiveConstructor">+∞-≤</a> <a id="11100" class="Symbol">:</a>           <a id="11112" href="formalize-all-the-things.html#1861" class="Generalizable">x</a>   <a id="11116" href="formalize-all-the-things.html#10990" class="Datatype Operator">≤∞</a>  <a id="11120" href="formalize-all-the-things.html#10883" class="InductiveConstructor">+∞</a>

  <a id="Ord-[]∞.[]∞-refl"></a><a id="11126" href="formalize-all-the-things.html#11126" class="Function">[]∞-refl</a> <a id="11135" class="Symbol">:</a> <a id="11137" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="11139" href="formalize-all-the-things.html#10990" class="Datatype Operator">≤∞</a> <a id="11142" href="formalize-all-the-things.html#1861" class="Generalizable">x</a>
  <a id="11146" href="formalize-all-the-things.html#11126" class="Function">[]∞-refl</a> <a id="11155" class="Symbol">{</a> <a id="11157" href="formalize-all-the-things.html#10845" class="InductiveConstructor">-∞</a><a id="11159" class="Symbol">}</a>   <a id="11163" class="Symbol">=</a> <a id="11165" href="formalize-all-the-things.html#11029" class="InductiveConstructor">-∞-≤</a>
  <a id="11172" href="formalize-all-the-things.html#11126" class="Function">[]∞-refl</a> <a id="11181" class="Symbol">{</a><a id="11182" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="11184" href="formalize-all-the-things.html#11184" class="Bound">x</a> <a id="11186" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a><a id="11187" class="Symbol">}</a> <a id="11189" class="Symbol">=</a> <a id="11191" href="formalize-all-the-things.html#11061" class="InductiveConstructor">[]-≤</a> <a id="11196" class="Symbol">(</a><a id="11197" href="formalize-all-the-things.html#8180" class="Field">≤-refl</a> <a id="11204" class="Symbol">{</a><a id="11205" class="Argument">A</a> <a id="11207" class="Symbol">=</a> <a id="11209" href="formalize-all-the-things.html#10950" class="Bound">A</a><a id="11210" class="Symbol">})</a>
  <a id="11215" href="formalize-all-the-things.html#11126" class="Function">[]∞-refl</a> <a id="11224" class="Symbol">{</a> <a id="11226" href="formalize-all-the-things.html#10883" class="InductiveConstructor">+∞</a><a id="11228" class="Symbol">}</a>   <a id="11232" class="Symbol">=</a> <a id="11234" href="formalize-all-the-things.html#11095" class="InductiveConstructor">+∞-≤</a>

  <a id="Ord-[]∞.[]∞-trans"></a><a id="11242" href="formalize-all-the-things.html#11242" class="Function">[]∞-trans</a> <a id="11252" class="Symbol">:</a> <a id="11254" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="11256" href="formalize-all-the-things.html#10990" class="Datatype Operator">≤∞</a> <a id="11259" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="11261" class="Symbol">→</a> <a id="11263" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="11265" href="formalize-all-the-things.html#10990" class="Datatype Operator">≤∞</a> <a id="11268" href="formalize-all-the-things.html#1865" class="Generalizable">z</a> <a id="11270" class="Symbol">→</a> <a id="11272" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="11274" href="formalize-all-the-things.html#10990" class="Datatype Operator">≤∞</a> <a id="11277" href="formalize-all-the-things.html#1865" class="Generalizable">z</a>
  <a id="11281" href="formalize-all-the-things.html#11242" class="Function">[]∞-trans</a> <a id="11291" href="formalize-all-the-things.html#11029" class="InductiveConstructor">-∞-≤</a>       <a id="11302" class="Symbol">_</a>          <a id="11313" class="Symbol">=</a> <a id="11315" href="formalize-all-the-things.html#11029" class="InductiveConstructor">-∞-≤</a>
  <a id="11322" href="formalize-all-the-things.html#11242" class="Function">[]∞-trans</a> <a id="11332" class="Symbol">(</a><a id="11333" href="formalize-all-the-things.html#11061" class="InductiveConstructor">[]-≤</a> <a id="11338" href="formalize-all-the-things.html#11338" class="Bound">x≤y</a><a id="11341" class="Symbol">)</a> <a id="11343" class="Symbol">(</a><a id="11344" href="formalize-all-the-things.html#11061" class="InductiveConstructor">[]-≤</a> <a id="11349" href="formalize-all-the-things.html#11349" class="Bound">y≤z</a><a id="11352" class="Symbol">)</a> <a id="11354" class="Symbol">=</a> <a id="11356" href="formalize-all-the-things.html#11061" class="InductiveConstructor">[]-≤</a> <a id="11361" class="Symbol">(</a><a id="11362" href="formalize-all-the-things.html#8202" class="Field">≤-trans</a> <a id="11370" class="Symbol">{</a><a id="11371" class="Argument">A</a> <a id="11373" class="Symbol">=</a> <a id="11375" href="formalize-all-the-things.html#10950" class="Bound">A</a><a id="11376" class="Symbol">}</a> <a id="11378" href="formalize-all-the-things.html#11338" class="Bound">x≤y</a> <a id="11382" href="formalize-all-the-things.html#11349" class="Bound">y≤z</a><a id="11385" class="Symbol">)</a>
  <a id="11389" href="formalize-all-the-things.html#11242" class="CatchallClause Function">[]∞-trans</a><a id="11398" class="CatchallClause"> </a><a id="11399" class="CatchallClause Symbol">_</a><a id="11400" class="CatchallClause">          </a><a id="11410" href="formalize-all-the-things.html#11095" class="CatchallClause InductiveConstructor">+∞-≤</a>       <a id="11421" class="Symbol">=</a> <a id="11423" href="formalize-all-the-things.html#11095" class="InductiveConstructor">+∞-≤</a>

  <a id="Ord-[]∞.[]∞-antisym"></a><a id="11431" href="formalize-all-the-things.html#11431" class="Function">[]∞-antisym</a> <a id="11443" class="Symbol">:</a> <a id="11445" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="11447" href="formalize-all-the-things.html#10990" class="Datatype Operator">≤∞</a> <a id="11450" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="11452" class="Symbol">→</a> <a id="11454" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="11456" href="formalize-all-the-things.html#10990" class="Datatype Operator">≤∞</a> <a id="11459" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="11461" class="Symbol">→</a> <a id="11463" href="formalize-all-the-things.html#1861" class="Generalizable">x</a> <a id="11465" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="11467" href="formalize-all-the-things.html#1863" class="Generalizable">y</a>
  <a id="11471" href="formalize-all-the-things.html#11431" class="Function">[]∞-antisym</a> <a id="11483" href="formalize-all-the-things.html#11029" class="InductiveConstructor">-∞-≤</a>       <a id="11494" href="formalize-all-the-things.html#11029" class="InductiveConstructor">-∞-≤</a>       <a id="11505" class="Symbol">=</a> <a id="11507" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
  <a id="11514" href="formalize-all-the-things.html#11431" class="Function">[]∞-antisym</a> <a id="11526" class="Symbol">(</a><a id="11527" href="formalize-all-the-things.html#11061" class="InductiveConstructor">[]-≤</a> <a id="11532" href="formalize-all-the-things.html#11532" class="Bound">x≤y</a><a id="11535" class="Symbol">)</a> <a id="11537" class="Symbol">(</a><a id="11538" href="formalize-all-the-things.html#11061" class="InductiveConstructor">[]-≤</a> <a id="11543" href="formalize-all-the-things.html#11543" class="Bound">y≤x</a><a id="11546" class="Symbol">)</a> <a id="11548" class="Symbol">=</a> <a id="11550" href="formalize-all-the-things.html#5712" class="Function">cong</a> <a id="11555" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[_]</a> <a id="11559" class="Symbol">(</a><a id="11560" href="formalize-all-the-things.html#8240" class="Field">≤-antisym</a> <a id="11570" href="formalize-all-the-things.html#11532" class="Bound">x≤y</a> <a id="11574" href="formalize-all-the-things.html#11543" class="Bound">y≤x</a><a id="11577" class="Symbol">)</a>
  <a id="11581" href="formalize-all-the-things.html#11431" class="Function">[]∞-antisym</a> <a id="11593" href="formalize-all-the-things.html#11095" class="InductiveConstructor">+∞-≤</a>       <a id="11604" href="formalize-all-the-things.html#11095" class="InductiveConstructor">+∞-≤</a>       <a id="11615" class="Symbol">=</a> <a id="11617" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>

  <a id="11625" class="Keyword">instance</a>
    <a id="Ord-[]∞.Ord-[]∞"></a><a id="11638" href="formalize-all-the-things.html#11638" class="Function">Ord-[]∞</a> <a id="11646" class="Symbol">:</a> <a id="11648" class="Symbol">{{</a><a id="11650" href="formalize-all-the-things.html#11650" class="Bound">_</a> <a id="11652" class="Symbol">:</a> <a id="11654" href="formalize-all-the-things.html#8113" class="Record">Ord</a> <a id="11658" href="formalize-all-the-things.html#10950" class="Bound">A</a><a id="11659" class="Symbol">}}</a> <a id="11662" class="Symbol">→</a> <a id="11664" href="formalize-all-the-things.html#8113" class="Record">Ord</a> <a id="11668" href="formalize-all-the-things.html#10816" class="Datatype Operator">[</a> <a id="11670" href="formalize-all-the-things.html#10950" class="Bound">A</a> <a id="11672" href="formalize-all-the-things.html#10816" class="Datatype Operator">]∞</a>
    <a id="11679" href="formalize-all-the-things.html#8152" class="Field Operator">_≤_</a>       <a id="11689" class="Symbol">{{</a><a id="11691" href="formalize-all-the-things.html#11638" class="Function">Ord-[]∞</a><a id="11698" class="Symbol">}}</a> <a id="11701" class="Symbol">=</a> <a id="11703" href="formalize-all-the-things.html#10990" class="Datatype Operator">_≤∞_</a>
    <a id="11712" href="formalize-all-the-things.html#8180" class="Field">≤-refl</a>    <a id="11722" class="Symbol">{{</a><a id="11724" href="formalize-all-the-things.html#11638" class="Function">Ord-[]∞</a><a id="11731" class="Symbol">}}</a> <a id="11734" class="Symbol">=</a> <a id="11736" href="formalize-all-the-things.html#11126" class="Function">[]∞-refl</a>
    <a id="11749" href="formalize-all-the-things.html#8202" class="Field">≤-trans</a>   <a id="11759" class="Symbol">{{</a><a id="11761" href="formalize-all-the-things.html#11638" class="Function">Ord-[]∞</a><a id="11768" class="Symbol">}}</a> <a id="11771" class="Symbol">=</a> <a id="11773" href="formalize-all-the-things.html#11242" class="Function">[]∞-trans</a>
    <a id="11787" href="formalize-all-the-things.html#8240" class="Field">≤-antisym</a> <a id="11797" class="Symbol">{{</a><a id="11799" href="formalize-all-the-things.html#11638" class="Function">Ord-[]∞</a><a id="11806" class="Symbol">}}</a> <a id="11809" class="Symbol">=</a> <a id="11811" href="formalize-all-the-things.html#11431" class="Function">[]∞-antisym</a>

<a id="11824" class="Keyword">open</a> <a id="11829" href="formalize-all-the-things.html#10941" class="Module">Ord-[]∞</a> <a id="11837" class="Keyword">public</a>
</pre>
<p>We define some instances to automatically construct inequality proofs.</p>
<pre class="Agda"><a id="11925" class="Keyword">module</a> <a id="11932" href="formalize-all-the-things.html#11932" class="Module">_</a> <a id="11934" class="Symbol">{{</a><a id="11936" href="formalize-all-the-things.html#11936" class="Bound">_</a> <a id="11938" class="Symbol">:</a> <a id="11940" href="formalize-all-the-things.html#8113" class="Record">Ord</a> <a id="11944" href="formalize-all-the-things.html#1847" class="Generalizable">A</a><a id="11945" class="Symbol">}}</a> <a id="11948" class="Keyword">where</a>

  <a id="11957" class="Keyword">instance</a>
    <a id="11970" href="formalize-all-the-things.html#11970" class="Function">-∞-≤-I</a> <a id="11977" class="Symbol">:</a> <a id="11979" class="Symbol">{</a><a id="11980" href="formalize-all-the-things.html#11980" class="Bound">y</a> <a id="11982" class="Symbol">:</a> <a id="11984" href="formalize-all-the-things.html#10816" class="Datatype Operator">[</a> <a id="11986" href="formalize-all-the-things.html#11944" class="Bound">A</a> <a id="11988" href="formalize-all-the-things.html#10816" class="Datatype Operator">]∞</a><a id="11990" class="Symbol">}</a> <a id="11992" class="Symbol">→</a> <a id="11994" href="formalize-all-the-things.html#10845" class="InductiveConstructor">-∞</a> <a id="11997" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="11999" href="formalize-all-the-things.html#11980" class="Bound">y</a>
    <a id="12005" href="formalize-all-the-things.html#11970" class="Function">-∞-≤-I</a> <a id="12012" class="Symbol">=</a> <a id="12014" href="formalize-all-the-things.html#11029" class="InductiveConstructor">-∞-≤</a>

    <a id="12024" href="formalize-all-the-things.html#12024" class="Function">+∞-≤-I</a> <a id="12031" class="Symbol">:</a> <a id="12033" class="Symbol">{</a><a id="12034" href="formalize-all-the-things.html#12034" class="Bound">x</a> <a id="12036" class="Symbol">:</a> <a id="12038" href="formalize-all-the-things.html#10816" class="Datatype Operator">[</a> <a id="12040" href="formalize-all-the-things.html#11944" class="Bound">A</a> <a id="12042" href="formalize-all-the-things.html#10816" class="Datatype Operator">]∞</a><a id="12044" class="Symbol">}</a> <a id="12046" class="Symbol">→</a> <a id="12048" href="formalize-all-the-things.html#12034" class="Bound">x</a> <a id="12050" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="12052" href="formalize-all-the-things.html#10883" class="InductiveConstructor">+∞</a>
    <a id="12059" href="formalize-all-the-things.html#12024" class="Function">+∞-≤-I</a> <a id="12066" class="Symbol">=</a> <a id="12068" href="formalize-all-the-things.html#11095" class="InductiveConstructor">+∞-≤</a>

    <a id="12078" href="formalize-all-the-things.html#12078" class="Function">[]-≤-I</a> <a id="12085" class="Symbol">:</a> <a id="12087" class="Symbol">{</a><a id="12088" href="formalize-all-the-things.html#12088" class="Bound">x</a> <a id="12090" href="formalize-all-the-things.html#12090" class="Bound">y</a> <a id="12092" class="Symbol">:</a> <a id="12094" href="formalize-all-the-things.html#11944" class="Bound">A</a><a id="12095" class="Symbol">}</a> <a id="12097" class="Symbol">{{</a><a id="12099" href="formalize-all-the-things.html#12099" class="Bound">x≤y</a> <a id="12103" class="Symbol">:</a> <a id="12105" href="formalize-all-the-things.html#12088" class="Bound">x</a> <a id="12107" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="12109" href="formalize-all-the-things.html#12090" class="Bound">y</a><a id="12110" class="Symbol">}}</a> <a id="12113" class="Symbol">→</a> <a id="12115" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="12117" href="formalize-all-the-things.html#12088" class="Bound">x</a> <a id="12119" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a> <a id="12121" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="12123" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="12125" href="formalize-all-the-things.html#12090" class="Bound">y</a> <a id="12127" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a>
    <a id="12133" href="formalize-all-the-things.html#12078" class="Function">[]-≤-I</a> <a id="12140" class="Symbol">{{</a><a id="12142" class="Argument">x≤y</a> <a id="12146" class="Symbol">=</a> <a id="12148" href="formalize-all-the-things.html#12148" class="Bound">x≤y</a><a id="12151" class="Symbol">}}</a> <a id="12154" class="Symbol">=</a> <a id="12156" href="formalize-all-the-things.html#11061" class="InductiveConstructor">[]-≤</a> <a id="12161" href="formalize-all-the-things.html#12148" class="Bound">x≤y</a>
</pre>
<p>Now we are (finally) ready to define binary search trees.</p>
<pre class="Agda"><a id="12233" class="Keyword">data</a> <a id="BST"></a><a id="12238" href="formalize-all-the-things.html#12238" class="Datatype">BST</a> <a id="12242" class="Symbol">(</a><a id="12243" href="formalize-all-the-things.html#12243" class="Bound">A</a> <a id="12245" class="Symbol">:</a> <a id="12247" href="Agda.Primitive.html#388" class="Primitive">Set</a><a id="12250" class="Symbol">)</a> <a id="12252" class="Symbol">{{</a><a id="12254" href="formalize-all-the-things.html#12254" class="Bound">_</a> <a id="12256" class="Symbol">:</a> <a id="12258" href="formalize-all-the-things.html#8113" class="Record">Ord</a> <a id="12262" href="formalize-all-the-things.html#12243" class="Bound">A</a><a id="12263" class="Symbol">}}</a>
         <a id="12275" class="Symbol">(</a><a id="12276" href="formalize-all-the-things.html#12276" class="Bound">lower</a> <a id="12282" href="formalize-all-the-things.html#12282" class="Bound">upper</a> <a id="12288" class="Symbol">:</a> <a id="12290" href="formalize-all-the-things.html#10816" class="Datatype Operator">[</a> <a id="12292" href="formalize-all-the-things.html#12243" class="Bound">A</a> <a id="12294" href="formalize-all-the-things.html#10816" class="Datatype Operator">]∞</a><a id="12296" class="Symbol">)</a>  <a id="12299" class="Symbol">:</a> <a id="12301" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="12305" class="Keyword">where</a>

  <a id="BST.leaf"></a><a id="12314" href="formalize-all-the-things.html#12314" class="InductiveConstructor">leaf</a> <a id="12319" class="Symbol">:</a> <a id="12321" class="Symbol">{{</a><a id="12323" href="formalize-all-the-things.html#12323" class="Bound">l≤u</a> <a id="12327" class="Symbol">:</a> <a id="12329" href="formalize-all-the-things.html#12276" class="Bound">lower</a> <a id="12335" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="12337" href="formalize-all-the-things.html#12282" class="Bound">upper</a><a id="12342" class="Symbol">}}</a>
       <a id="12352" class="Symbol">→</a> <a id="12354" href="formalize-all-the-things.html#12238" class="Datatype">BST</a> <a id="12358" href="formalize-all-the-things.html#12243" class="Bound">A</a> <a id="12360" href="formalize-all-the-things.html#12276" class="Bound">lower</a> <a id="12366" href="formalize-all-the-things.html#12282" class="Bound">upper</a>

  <a id="BST.node"></a><a id="12375" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="12380" class="Symbol">:</a> <a id="12382" class="Symbol">(</a><a id="12383" href="formalize-all-the-things.html#12383" class="Bound">x</a> <a id="12385" class="Symbol">:</a> <a id="12387" href="formalize-all-the-things.html#12243" class="Bound">A</a><a id="12388" class="Symbol">)</a>
       <a id="12397" class="Symbol">→</a> <a id="12399" href="formalize-all-the-things.html#12238" class="Datatype">BST</a> <a id="12403" href="formalize-all-the-things.html#12243" class="Bound">A</a> <a id="12405" href="formalize-all-the-things.html#12276" class="Bound">lower</a> <a id="12411" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="12413" href="formalize-all-the-things.html#12383" class="Bound">x</a> <a id="12415" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a>
       <a id="12424" class="Symbol">→</a> <a id="12426" href="formalize-all-the-things.html#12238" class="Datatype">BST</a> <a id="12430" href="formalize-all-the-things.html#12243" class="Bound">A</a> <a id="12432" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="12434" href="formalize-all-the-things.html#12383" class="Bound">x</a> <a id="12436" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a> <a id="12438" href="formalize-all-the-things.html#12282" class="Bound">upper</a>
       <a id="12451" class="Symbol">→</a> <a id="12453" href="formalize-all-the-things.html#12238" class="Datatype">BST</a> <a id="12457" href="formalize-all-the-things.html#12243" class="Bound">A</a> <a id="12459" href="formalize-all-the-things.html#12276" class="Bound">lower</a> <a id="12465" href="formalize-all-the-things.html#12282" class="Bound">upper</a>

<a id="12472" href="formalize-all-the-things.html#12472" class="Function">_</a> <a id="12474" class="Symbol">:</a> <a id="12476" href="formalize-all-the-things.html#12238" class="Datatype">BST</a> <a id="12480" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a> <a id="12484" href="formalize-all-the-things.html#10845" class="InductiveConstructor">-∞</a> <a id="12487" href="formalize-all-the-things.html#10883" class="InductiveConstructor">+∞</a>
<a id="12490" class="Symbol">_</a> <a id="12492" class="Symbol">=</a> <a id="12494" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="12499" class="Number">42</a>
      <a id="12508" class="Symbol">(</a><a id="12509" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="12514" class="Number">6</a>    <a id="12519" href="formalize-all-the-things.html#12314" class="InductiveConstructor">leaf</a> <a id="12524" href="formalize-all-the-things.html#12314" class="InductiveConstructor">leaf</a><a id="12528" class="Symbol">)</a>
      <a id="12536" class="Symbol">(</a><a id="12537" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="12542" class="Number">9000</a> <a id="12547" href="formalize-all-the-things.html#12314" class="InductiveConstructor">leaf</a> <a id="12552" href="formalize-all-the-things.html#12314" class="InductiveConstructor">leaf</a><a id="12556" class="Symbol">)</a>
</pre>
<p>Note how instances help by automatically filling in the proofs that
the bounds are satisfied! Somewhat more explicitly, the tree looks as
follows:</p>
<pre class="Agda"><a id="12715" href="formalize-all-the-things.html#12715" class="Function">_</a> <a id="12717" class="Symbol">:</a> <a id="12719" href="formalize-all-the-things.html#12238" class="Datatype">BST</a> <a id="12723" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a> <a id="12727" href="formalize-all-the-things.html#10845" class="InductiveConstructor">-∞</a> <a id="12730" href="formalize-all-the-things.html#10883" class="InductiveConstructor">+∞</a>
<a id="12733" class="Symbol">_</a> <a id="12735" class="Symbol">=</a> <a id="12737" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="12742" class="Number">42</a>
      <a id="12751" class="Symbol">(</a><a id="12752" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="12757" class="Number">6</a>    <a id="12762" class="Symbol">(</a><a id="12763" href="formalize-all-the-things.html#12314" class="InductiveConstructor">leaf</a> <a id="12768" class="Symbol">{{</a><a id="12770" class="Argument">l≤u</a> <a id="12774" class="Symbol">=</a> <a id="12776" href="formalize-all-the-things.html#12891" class="Function">-∞≤6</a><a id="12780" class="Symbol">}})</a>    <a id="12787" class="Symbol">(</a><a id="12788" href="formalize-all-the-things.html#12314" class="InductiveConstructor">leaf</a> <a id="12793" class="Symbol">{{</a><a id="12795" class="Argument">l≤u</a> <a id="12799" class="Symbol">=</a> <a id="12801" href="formalize-all-the-things.html#12928" class="Function">6≤42</a><a id="12805" class="Symbol">}}))</a>
      <a id="12816" class="Symbol">(</a><a id="12817" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="12822" class="Number">9000</a> <a id="12827" class="Symbol">(</a><a id="12828" href="formalize-all-the-things.html#12314" class="InductiveConstructor">leaf</a> <a id="12833" class="Symbol">{{</a><a id="12835" class="Argument">l≤u</a> <a id="12839" class="Symbol">=</a> <a id="12841" href="formalize-all-the-things.html#12969" class="Function">42≤9000</a><a id="12848" class="Symbol">}})</a> <a id="12852" class="Symbol">(</a><a id="12853" href="formalize-all-the-things.html#12314" class="InductiveConstructor">leaf</a> <a id="12858" class="Symbol">{{</a><a id="12860" class="Argument">l≤u</a> <a id="12864" class="Symbol">=</a> <a id="12866" href="formalize-all-the-things.html#13019" class="Function">9000≤+∞</a><a id="12873" class="Symbol">}}))</a>

  <a id="12881" class="Keyword">where</a>
    <a id="12891" href="formalize-all-the-things.html#12891" class="Function">-∞≤6</a> <a id="12896" class="Symbol">:</a> <a id="12898" href="formalize-all-the-things.html#10845" class="InductiveConstructor">-∞</a> <a id="12901" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="12903" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="12905" class="Number">6</a> <a id="12907" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a>
    <a id="12913" href="formalize-all-the-things.html#12891" class="Function">-∞≤6</a> <a id="12918" class="Symbol">=</a> <a id="12920" href="formalize-all-the-things.html#2311" class="Function">it</a>

    <a id="12928" href="formalize-all-the-things.html#12928" class="Function">6≤42</a> <a id="12933" class="Symbol">:</a> <a id="12935" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="12937" class="Number">6</a> <a id="12939" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a> <a id="12941" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="12943" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="12945" class="Number">42</a> <a id="12948" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a>
    <a id="12954" href="formalize-all-the-things.html#12928" class="Function">6≤42</a> <a id="12959" class="Symbol">=</a> <a id="12961" href="formalize-all-the-things.html#2311" class="Function">it</a>

    <a id="12969" href="formalize-all-the-things.html#12969" class="Function">42≤9000</a> <a id="12977" class="Symbol">:</a> <a id="12979" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="12981" class="Number">42</a> <a id="12984" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a> <a id="12986" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="12988" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="12990" class="Number">9000</a> <a id="12995" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a>
    <a id="13001" href="formalize-all-the-things.html#12969" class="Function">42≤9000</a> <a id="13009" class="Symbol">=</a> <a id="13011" href="formalize-all-the-things.html#2311" class="Function">it</a>

    <a id="13019" href="formalize-all-the-things.html#13019" class="Function">9000≤+∞</a> <a id="13027" class="Symbol">:</a> <a id="13029" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="13031" class="Number">9000</a> <a id="13036" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a> <a id="13038" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="13040" href="formalize-all-the-things.html#10883" class="InductiveConstructor">+∞</a>
    <a id="13047" href="formalize-all-the-things.html#13019" class="Function">9000≤+∞</a> <a id="13055" class="Symbol">=</a> <a id="13057" href="formalize-all-the-things.html#2311" class="Function">it</a>
</pre>
<p>Next up: defining a lookup function. The result of this function is
not just a boolean true/false, but a <em>proof</em> that the element is
indeed in the tree. A proof that <code>x</code> is in the tree <code>t</code> is either a
proof that it is <code>here</code>, a proof that it is in the <code>left</code> subtree, or
a proof that it is in the <code>right</code> subtree.</p>
<pre class="Agda"><a id="13384" class="Keyword">module</a> <a id="Lookup"></a><a id="13391" href="formalize-all-the-things.html#13391" class="Module">Lookup</a> <a id="13398" class="Symbol">{{</a><a id="13400" href="formalize-all-the-things.html#13400" class="Bound">_</a> <a id="13402" class="Symbol">:</a> <a id="13404" href="formalize-all-the-things.html#9692" class="Record">TDO</a> <a id="13408" href="formalize-all-the-things.html#1847" class="Generalizable">A</a><a id="13409" class="Symbol">}}</a> <a id="13412" class="Keyword">where</a>

  <a id="13421" class="Keyword">data</a> <a id="Lookup._∈_"></a><a id="13426" href="formalize-all-the-things.html#13426" class="Datatype Operator">_∈_</a> <a id="13430" class="Symbol">{</a><a id="13431" href="formalize-all-the-things.html#13431" class="Bound">lower</a><a id="13436" class="Symbol">}</a> <a id="13438" class="Symbol">{</a><a id="13439" href="formalize-all-the-things.html#13439" class="Bound">upper</a><a id="13444" class="Symbol">}</a> <a id="13446" class="Symbol">(</a><a id="13447" href="formalize-all-the-things.html#13447" class="Bound">x</a> <a id="13449" class="Symbol">:</a> <a id="13451" href="formalize-all-the-things.html#13408" class="Bound">A</a><a id="13452" class="Symbol">)</a> <a id="13454" class="Symbol">:</a>
           <a id="13467" class="Symbol">(</a><a id="13468" href="formalize-all-the-things.html#13468" class="Bound">t</a> <a id="13470" class="Symbol">:</a> <a id="13472" href="formalize-all-the-things.html#12238" class="Datatype">BST</a> <a id="13476" href="formalize-all-the-things.html#13408" class="Bound">A</a> <a id="13478" href="formalize-all-the-things.html#13431" class="Bound">lower</a> <a id="13484" href="formalize-all-the-things.html#13439" class="Bound">upper</a><a id="13489" class="Symbol">)</a> <a id="13491" class="Symbol">→</a> <a id="13493" href="Agda.Primitive.html#388" class="Primitive">Set</a> <a id="13497" class="Keyword">where</a>
    <a id="Lookup._∈_.here"></a><a id="13507" href="formalize-all-the-things.html#13507" class="InductiveConstructor">here</a>  <a id="13513" class="Symbol">:</a> <a id="13515" class="Symbol">∀</a> <a id="13517" class="Symbol">{</a><a id="13518" href="formalize-all-the-things.html#13518" class="Bound">t₁</a> <a id="13521" href="formalize-all-the-things.html#13521" class="Bound">t₂</a><a id="13523" class="Symbol">}</a> <a id="13525" class="Symbol">→</a> <a id="13527" href="formalize-all-the-things.html#13447" class="Bound">x</a> <a id="13529" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="13531" href="formalize-all-the-things.html#1863" class="Generalizable">y</a>  <a id="13534" class="Symbol">→</a> <a id="13536" href="formalize-all-the-things.html#13447" class="Bound">x</a> <a id="13538" href="formalize-all-the-things.html#13426" class="Datatype Operator">∈</a> <a id="13540" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="13545" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="13547" href="formalize-all-the-things.html#13518" class="Bound">t₁</a> <a id="13550" href="formalize-all-the-things.html#13521" class="Bound">t₂</a>
    <a id="Lookup._∈_.left"></a><a id="13557" href="formalize-all-the-things.html#13557" class="InductiveConstructor">left</a>  <a id="13563" class="Symbol">:</a> <a id="13565" class="Symbol">∀</a> <a id="13567" class="Symbol">{</a><a id="13568" href="formalize-all-the-things.html#13568" class="Bound">t₁</a> <a id="13571" href="formalize-all-the-things.html#13571" class="Bound">t₂</a><a id="13573" class="Symbol">}</a> <a id="13575" class="Symbol">→</a> <a id="13577" href="formalize-all-the-things.html#13447" class="Bound">x</a> <a id="13579" href="formalize-all-the-things.html#13426" class="Datatype Operator">∈</a> <a id="13581" href="formalize-all-the-things.html#13568" class="Bound">t₁</a> <a id="13584" class="Symbol">→</a> <a id="13586" href="formalize-all-the-things.html#13447" class="Bound">x</a> <a id="13588" href="formalize-all-the-things.html#13426" class="Datatype Operator">∈</a> <a id="13590" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="13595" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="13597" href="formalize-all-the-things.html#13568" class="Bound">t₁</a> <a id="13600" href="formalize-all-the-things.html#13571" class="Bound">t₂</a>
    <a id="Lookup._∈_.right"></a><a id="13607" href="formalize-all-the-things.html#13607" class="InductiveConstructor">right</a> <a id="13613" class="Symbol">:</a> <a id="13615" class="Symbol">∀</a> <a id="13617" class="Symbol">{</a><a id="13618" href="formalize-all-the-things.html#13618" class="Bound">t₁</a> <a id="13621" href="formalize-all-the-things.html#13621" class="Bound">t₂</a><a id="13623" class="Symbol">}</a> <a id="13625" class="Symbol">→</a> <a id="13627" href="formalize-all-the-things.html#13447" class="Bound">x</a> <a id="13629" href="formalize-all-the-things.html#13426" class="Datatype Operator">∈</a> <a id="13631" href="formalize-all-the-things.html#13621" class="Bound">t₂</a> <a id="13634" class="Symbol">→</a> <a id="13636" href="formalize-all-the-things.html#13447" class="Bound">x</a> <a id="13638" href="formalize-all-the-things.html#13426" class="Datatype Operator">∈</a> <a id="13640" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="13645" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="13647" href="formalize-all-the-things.html#13618" class="Bound">t₁</a> <a id="13650" href="formalize-all-the-things.html#13621" class="Bound">t₂</a>
</pre>
<p>The definition of <code>lookup</code> makes use of
<a href="https://agda.readthedocs.io/en/v2.6.0.1/language/with-abstraction.html"><code>with</code>-abstraction</a>
to inspect the result of the <code>tri</code> function on <code>x</code> and <code>y</code>.</p>
<pre class="Agda">  <a id="Lookup.lookup"></a><a id="13858" href="formalize-all-the-things.html#13858" class="Function">lookup</a> <a id="13865" class="Symbol">:</a> <a id="13867" class="Symbol">∀</a> <a id="13869" class="Symbol">{</a><a id="13870" href="formalize-all-the-things.html#13870" class="Bound">lower</a><a id="13875" class="Symbol">}</a> <a id="13877" class="Symbol">{</a><a id="13878" href="formalize-all-the-things.html#13878" class="Bound">upper</a><a id="13883" class="Symbol">}</a>
         <a id="13894" class="Symbol">→</a> <a id="13896" class="Symbol">(</a><a id="13897" href="formalize-all-the-things.html#13897" class="Bound">x</a> <a id="13899" class="Symbol">:</a> <a id="13901" href="formalize-all-the-things.html#13408" class="Bound">A</a><a id="13902" class="Symbol">)</a> <a id="13904" class="Symbol">(</a><a id="13905" href="formalize-all-the-things.html#13905" class="Bound">t</a> <a id="13907" class="Symbol">:</a> <a id="13909" href="formalize-all-the-things.html#12238" class="Datatype">BST</a> <a id="13913" href="formalize-all-the-things.html#13408" class="Bound">A</a> <a id="13915" href="formalize-all-the-things.html#13870" class="Bound">lower</a> <a id="13921" href="formalize-all-the-things.html#13878" class="Bound">upper</a><a id="13926" class="Symbol">)</a> <a id="13928" class="Symbol">→</a> <a id="13930" href="formalize-all-the-things.html#3098" class="Datatype">Maybe</a> <a id="13936" class="Symbol">(</a><a id="13937" href="formalize-all-the-things.html#13897" class="Bound">x</a> <a id="13939" href="formalize-all-the-things.html#13426" class="Datatype Operator">∈</a> <a id="13941" href="formalize-all-the-things.html#13905" class="Bound">t</a><a id="13942" class="Symbol">)</a>
  <a id="13946" href="formalize-all-the-things.html#13858" class="Function">lookup</a> <a id="13953" href="formalize-all-the-things.html#13953" class="Bound">x</a> <a id="13955" href="formalize-all-the-things.html#12314" class="InductiveConstructor">leaf</a> <a id="13960" class="Symbol">=</a> <a id="13962" href="formalize-all-the-things.html#3152" class="InductiveConstructor">nothing</a>
  <a id="13972" href="formalize-all-the-things.html#13858" class="Function">lookup</a> <a id="13979" href="formalize-all-the-things.html#13979" class="Bound">x</a> <a id="13981" class="Symbol">(</a><a id="13982" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="13987" href="formalize-all-the-things.html#13987" class="Bound">y</a> <a id="13989" href="formalize-all-the-things.html#13989" class="Bound">t₁</a> <a id="13992" href="formalize-all-the-things.html#13992" class="Bound">t₂</a><a id="13994" class="Symbol">)</a> <a id="13996" class="Keyword">with</a> <a id="14001" href="formalize-all-the-things.html#9785" class="Field">tri</a> <a id="14005" href="formalize-all-the-things.html#13979" class="Bound">x</a> <a id="14007" href="formalize-all-the-things.html#13987" class="Bound">y</a>
  <a id="14011" class="Symbol">...</a> <a id="14015" class="Symbol">|</a> <a id="14017" href="formalize-all-the-things.html#9572" class="InductiveConstructor">less</a>    <a id="14025" class="Symbol">=</a> <a id="14027" href="formalize-all-the-things.html#3175" class="Function">mapMaybe</a> <a id="14036" href="formalize-all-the-things.html#13557" class="InductiveConstructor">left</a> <a id="14041" class="Symbol">(</a><a id="14042" href="formalize-all-the-things.html#13858" class="Function">lookup</a> <a id="14049" class="Bound">x</a> <a id="14051" class="Bound">t₁</a><a id="14053" class="Symbol">)</a>
  <a id="14057" class="Symbol">...</a> <a id="14061" class="Symbol">|</a> <a id="14063" href="formalize-all-the-things.html#9610" class="InductiveConstructor">equal</a>   <a id="14071" class="Symbol">=</a> <a id="14073" href="formalize-all-the-things.html#3128" class="InductiveConstructor">just</a> <a id="14078" class="Symbol">(</a><a id="14079" href="formalize-all-the-things.html#13507" class="InductiveConstructor">here</a> <a id="14084" href="formalize-all-the-things.html#2311" class="Function">it</a><a id="14086" class="Symbol">)</a>
  <a id="14090" class="Symbol">...</a> <a id="14094" class="Symbol">|</a> <a id="14096" href="formalize-all-the-things.html#9648" class="InductiveConstructor">greater</a> <a id="14104" class="Symbol">=</a> <a id="14106" href="formalize-all-the-things.html#3175" class="Function">mapMaybe</a> <a id="14115" href="formalize-all-the-things.html#13607" class="InductiveConstructor">right</a> <a id="14121" class="Symbol">(</a><a id="14122" href="formalize-all-the-things.html#13858" class="Function">lookup</a> <a id="14129" class="Bound">x</a> <a id="14131" class="Bound">t₂</a><a id="14133" class="Symbol">)</a>
</pre>
<p>Similarly, we can define an insertion function. Here, we need to
enforce the precondition that the element we want to insert is between
the bounds (alternatively, we could have updated the bounds in the
return type to ensure they include the inserted element).</p>
<pre class="Agda"><a id="14407" class="Keyword">module</a> <a id="Insert"></a><a id="14414" href="formalize-all-the-things.html#14414" class="Module">Insert</a> <a id="14421" class="Symbol">{{</a><a id="14423" href="formalize-all-the-things.html#14423" class="Bound">_</a> <a id="14425" class="Symbol">:</a> <a id="14427" href="formalize-all-the-things.html#9692" class="Record">TDO</a> <a id="14431" href="formalize-all-the-things.html#1847" class="Generalizable">A</a><a id="14432" class="Symbol">}}</a> <a id="14435" class="Keyword">where</a>

  <a id="Insert.insert"></a><a id="14444" href="formalize-all-the-things.html#14444" class="Function">insert</a> <a id="14451" class="Symbol">:</a> <a id="14453" class="Symbol">(</a><a id="14454" href="formalize-all-the-things.html#14454" class="Bound">x</a> <a id="14456" class="Symbol">:</a> <a id="14458" href="formalize-all-the-things.html#14431" class="Bound">A</a><a id="14459" class="Symbol">)</a> <a id="14461" class="Symbol">(</a><a id="14462" href="formalize-all-the-things.html#14462" class="Bound">t</a> <a id="14464" class="Symbol">:</a> <a id="14466" href="formalize-all-the-things.html#12238" class="Datatype">BST</a> <a id="14470" href="formalize-all-the-things.html#14431" class="Bound">A</a> <a id="14472" href="formalize-all-the-things.html#10912" class="Generalizable">lower</a> <a id="14478" href="formalize-all-the-things.html#10918" class="Generalizable">upper</a><a id="14483" class="Symbol">)</a>
         <a id="14494" class="Symbol">→</a> <a id="14496" class="Symbol">{{</a><a id="14498" href="formalize-all-the-things.html#14498" class="Bound">l≤x</a> <a id="14502" class="Symbol">:</a> <a id="14504" href="formalize-all-the-things.html#10912" class="Generalizable">lower</a> <a id="14510" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="14512" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="14514" href="formalize-all-the-things.html#14454" class="Bound">x</a> <a id="14516" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a><a id="14517" class="Symbol">}}</a> <a id="14520" class="Symbol">{{</a><a id="14522" href="formalize-all-the-things.html#14522" class="Bound">x≤u</a> <a id="14526" class="Symbol">:</a> <a id="14528" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="14530" href="formalize-all-the-things.html#14454" class="Bound">x</a> <a id="14532" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a> <a id="14534" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="14536" href="formalize-all-the-things.html#10918" class="Generalizable">upper</a><a id="14541" class="Symbol">}}</a>
         <a id="14553" class="Symbol">→</a> <a id="14555" href="formalize-all-the-things.html#12238" class="Datatype">BST</a> <a id="14559" href="formalize-all-the-things.html#14431" class="Bound">A</a> <a id="14561" href="formalize-all-the-things.html#10912" class="Generalizable">lower</a> <a id="14567" href="formalize-all-the-things.html#10918" class="Generalizable">upper</a>
  <a id="14575" href="formalize-all-the-things.html#14444" class="Function">insert</a> <a id="14582" href="formalize-all-the-things.html#14582" class="Bound">x</a> <a id="14584" href="formalize-all-the-things.html#12314" class="InductiveConstructor">leaf</a> <a id="14589" class="Symbol">=</a> <a id="14591" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="14596" href="formalize-all-the-things.html#14582" class="Bound">x</a> <a id="14598" href="formalize-all-the-things.html#12314" class="InductiveConstructor">leaf</a> <a id="14603" href="formalize-all-the-things.html#12314" class="InductiveConstructor">leaf</a>
  <a id="14610" href="formalize-all-the-things.html#14444" class="Function">insert</a> <a id="14617" href="formalize-all-the-things.html#14617" class="Bound">x</a> <a id="14619" class="Symbol">(</a><a id="14620" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="14625" href="formalize-all-the-things.html#14625" class="Bound">y</a> <a id="14627" href="formalize-all-the-things.html#14627" class="Bound">t₁</a> <a id="14630" href="formalize-all-the-things.html#14630" class="Bound">t₂</a><a id="14632" class="Symbol">)</a> <a id="14634" class="Keyword">with</a> <a id="14639" href="formalize-all-the-things.html#9785" class="Field">tri</a> <a id="14643" href="formalize-all-the-things.html#14617" class="Bound">x</a> <a id="14645" href="formalize-all-the-things.html#14625" class="Bound">y</a>
  <a id="14649" class="Symbol">...</a> <a id="14653" class="Symbol">|</a> <a id="14655" href="formalize-all-the-things.html#9572" class="InductiveConstructor">less</a>    <a id="14663" class="Symbol">=</a> <a id="14665" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="14670" class="Bound">y</a> <a id="14672" class="Symbol">(</a><a id="14673" href="formalize-all-the-things.html#14444" class="Function">insert</a> <a id="14680" class="Bound">x</a> <a id="14682" class="Bound">t₁</a><a id="14684" class="Symbol">)</a> <a id="14686" class="Bound">t₂</a>
  <a id="14691" class="Symbol">...</a> <a id="14695" class="Symbol">|</a> <a id="14697" href="formalize-all-the-things.html#9610" class="InductiveConstructor">equal</a>   <a id="14705" class="Symbol">=</a> <a id="14707" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="14712" class="Bound">y</a> <a id="14714" class="Bound">t₁</a> <a id="14717" class="Bound">t₂</a>
  <a id="14722" class="Symbol">...</a> <a id="14726" class="Symbol">|</a> <a id="14728" href="formalize-all-the-things.html#9648" class="InductiveConstructor">greater</a> <a id="14736" class="Symbol">=</a> <a id="14738" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="14743" class="Bound">y</a> <a id="14745" class="Bound">t₁</a> <a id="14748" class="Symbol">(</a><a id="14749" href="formalize-all-the-things.html#14444" class="Function">insert</a> <a id="14756" class="Bound">x</a> <a id="14758" class="Bound">t₂</a><a id="14760" class="Symbol">)</a>
</pre>
<p>To prove correctness of insertion, we have to show that <code>y ∈ insert x t</code> is equivalent to <code>x ≡ y ⊎ y ∈ t</code>. The proofs <code>insert-sound₂</code> and
<code>insert-complete</code> are a bit long because there are two elements <code>x</code>
and <code>y</code> that can both independently be <code>here</code>, in the left subtree, or
in the right subtree, so we have to distinguish 9 distinct cases. Let
me know if you manage to find a shorter proof!</p>
<pre class="Agda">  <a id="15168" class="Keyword">open</a> <a id="15173" href="formalize-all-the-things.html#13391" class="Module">Lookup</a>

  <a id="Insert.insert-sound"></a><a id="15183" href="formalize-all-the-things.html#15183" class="Function">insert-sound</a> <a id="15196" class="Symbol">:</a>
    <a id="15202" class="Symbol">(</a><a id="15203" href="formalize-all-the-things.html#15203" class="Bound">x</a> <a id="15205" class="Symbol">:</a> <a id="15207" href="formalize-all-the-things.html#14431" class="Bound">A</a><a id="15208" class="Symbol">)</a> <a id="15210" class="Symbol">(</a><a id="15211" href="formalize-all-the-things.html#15211" class="Bound">t</a> <a id="15213" class="Symbol">:</a> <a id="15215" href="formalize-all-the-things.html#12238" class="Datatype">BST</a> <a id="15219" href="formalize-all-the-things.html#14431" class="Bound">A</a> <a id="15221" href="formalize-all-the-things.html#10912" class="Generalizable">lower</a> <a id="15227" href="formalize-all-the-things.html#10918" class="Generalizable">upper</a><a id="15232" class="Symbol">)</a>
    <a id="15238" class="Symbol">→</a> <a id="15240" class="Symbol">{{</a><a id="15242" href="formalize-all-the-things.html#15242" class="Symbol">_</a> <a id="15244" class="Symbol">:</a> <a id="15246" href="formalize-all-the-things.html#10912" class="Generalizable">lower</a> <a id="15252" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="15254" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="15256" href="formalize-all-the-things.html#15203" class="Bound">x</a> <a id="15258" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a><a id="15259" class="Symbol">}}</a> <a id="15262" class="Symbol">{{</a><a id="15264" href="formalize-all-the-things.html#15264" class="Symbol">_</a> <a id="15266" class="Symbol">:</a> <a id="15268" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="15270" href="formalize-all-the-things.html#15203" class="Bound">x</a> <a id="15272" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a> <a id="15274" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="15276" href="formalize-all-the-things.html#10918" class="Generalizable">upper</a><a id="15281" class="Symbol">}}</a>
    <a id="15288" class="Symbol">→</a> <a id="15290" class="Symbol">(</a><a id="15291" href="formalize-all-the-things.html#15203" class="Bound">x</a> <a id="15293" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="15295" href="formalize-all-the-things.html#1863" class="Generalizable">y</a><a id="15296" class="Symbol">)</a> <a id="15298" href="formalize-all-the-things.html#4000" class="Datatype Operator">⊎</a> <a id="15300" class="Symbol">(</a><a id="15301" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="15303" href="formalize-all-the-things.html#13426" class="Datatype Operator">∈</a> <a id="15305" href="formalize-all-the-things.html#15211" class="Bound">t</a><a id="15306" class="Symbol">)</a> <a id="15308" class="Symbol">→</a> <a id="15310" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="15312" href="formalize-all-the-things.html#13426" class="Datatype Operator">∈</a> <a id="15314" href="formalize-all-the-things.html#14444" class="Function">insert</a> <a id="15321" href="formalize-all-the-things.html#15203" class="Bound">x</a> <a id="15323" href="formalize-all-the-things.html#15211" class="Bound">t</a>
  <a id="15327" href="formalize-all-the-things.html#15183" class="Function">insert-sound</a> <a id="15340" href="formalize-all-the-things.html#15340" class="Bound">x</a> <a id="15342" href="formalize-all-the-things.html#15342" class="Bound">t</a> <a id="15344" class="Symbol">(</a><a id="15345" href="formalize-all-the-things.html#4030" class="InductiveConstructor">inl</a> <a id="15349" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a><a id="15353" class="Symbol">)</a> <a id="15355" class="Symbol">=</a> <a id="15357" href="formalize-all-the-things.html#15393" class="Function">insert-sound₁</a> <a id="15371" href="formalize-all-the-things.html#15340" class="Bound">x</a> <a id="15373" href="formalize-all-the-things.html#15342" class="Bound">t</a>

    <a id="15380" class="Keyword">where</a>

      <a id="15393" href="formalize-all-the-things.html#15393" class="Function">insert-sound₁</a> <a id="15407" class="Symbol">:</a>
        <a id="15417" class="Symbol">(</a><a id="15418" href="formalize-all-the-things.html#15418" class="Bound">x</a> <a id="15420" class="Symbol">:</a> <a id="15422" href="formalize-all-the-things.html#14431" class="Bound">A</a><a id="15423" class="Symbol">)</a> <a id="15425" class="Symbol">(</a><a id="15426" href="formalize-all-the-things.html#15426" class="Bound">t</a> <a id="15428" class="Symbol">:</a> <a id="15430" href="formalize-all-the-things.html#12238" class="Datatype">BST</a> <a id="15434" href="formalize-all-the-things.html#14431" class="Bound">A</a> <a id="15436" href="formalize-all-the-things.html#10912" class="Generalizable">lower</a> <a id="15442" href="formalize-all-the-things.html#10918" class="Generalizable">upper</a><a id="15447" class="Symbol">)</a>
        <a id="15457" class="Symbol">→</a> <a id="15459" class="Symbol">{{</a><a id="15461" href="formalize-all-the-things.html#15461" class="Bound">_</a> <a id="15463" class="Symbol">:</a> <a id="15465" href="formalize-all-the-things.html#10912" class="Generalizable">lower</a> <a id="15471" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="15473" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="15475" href="formalize-all-the-things.html#15418" class="Bound">x</a> <a id="15477" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a><a id="15478" class="Symbol">}}</a> <a id="15481" class="Symbol">{{</a><a id="15483" href="formalize-all-the-things.html#15483" class="Bound">_</a> <a id="15485" class="Symbol">:</a> <a id="15487" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="15489" href="formalize-all-the-things.html#15418" class="Bound">x</a> <a id="15491" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a> <a id="15493" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="15495" href="formalize-all-the-things.html#10918" class="Generalizable">upper</a><a id="15500" class="Symbol">}}</a>
        <a id="15511" class="Symbol">→</a> <a id="15513" href="formalize-all-the-things.html#15418" class="Bound">x</a> <a id="15515" href="formalize-all-the-things.html#13426" class="Datatype Operator">∈</a> <a id="15517" href="formalize-all-the-things.html#14444" class="Function">insert</a> <a id="15524" href="formalize-all-the-things.html#15418" class="Bound">x</a> <a id="15526" href="formalize-all-the-things.html#15426" class="Bound">t</a>
      <a id="15534" href="formalize-all-the-things.html#15393" class="Function">insert-sound₁</a> <a id="15548" href="formalize-all-the-things.html#15548" class="Bound">x</a> <a id="15550" href="formalize-all-the-things.html#12314" class="InductiveConstructor">leaf</a> <a id="15555" class="Symbol">=</a> <a id="15557" href="formalize-all-the-things.html#13507" class="InductiveConstructor">here</a> <a id="15562" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
      <a id="15573" href="formalize-all-the-things.html#15393" class="Function">insert-sound₁</a> <a id="15587" href="formalize-all-the-things.html#15587" class="Bound">x</a> <a id="15589" class="Symbol">(</a><a id="15590" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="15595" href="formalize-all-the-things.html#15595" class="Bound">y</a> <a id="15597" href="formalize-all-the-things.html#15597" class="Bound">t₁</a> <a id="15600" href="formalize-all-the-things.html#15600" class="Bound">t₂</a><a id="15602" class="Symbol">)</a> <a id="15604" class="Keyword">with</a> <a id="15609" href="formalize-all-the-things.html#9785" class="Field">tri</a> <a id="15613" href="formalize-all-the-things.html#15587" class="Bound">x</a> <a id="15615" href="formalize-all-the-things.html#15595" class="Bound">y</a>
      <a id="15623" href="formalize-all-the-things.html#15393" class="Function">insert-sound₁</a> <a id="15637" href="formalize-all-the-things.html#15637" class="Bound">x</a> <a id="15639" class="Symbol">(</a><a id="15640" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="15645" href="formalize-all-the-things.html#15645" class="Bound">y</a> <a id="15647" href="formalize-all-the-things.html#15647" class="Bound">t₁</a> <a id="15650" href="formalize-all-the-things.html#15650" class="Bound">t₂</a><a id="15652" class="Symbol">)</a> <a id="15654" class="Symbol">|</a> <a id="15656" href="formalize-all-the-things.html#9572" class="InductiveConstructor">less</a>    <a id="15664" class="Symbol">=</a> <a id="15666" href="formalize-all-the-things.html#13557" class="InductiveConstructor">left</a> <a id="15671" class="Symbol">(</a><a id="15672" href="formalize-all-the-things.html#15393" class="Function">insert-sound₁</a> <a id="15686" href="formalize-all-the-things.html#15637" class="Bound">x</a> <a id="15688" href="formalize-all-the-things.html#15647" class="Bound">t₁</a><a id="15690" class="Symbol">)</a>
      <a id="15698" href="formalize-all-the-things.html#15393" class="Function">insert-sound₁</a> <a id="15712" href="formalize-all-the-things.html#15712" class="Bound">x</a> <a id="15714" class="Symbol">(</a><a id="15715" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="15720" href="formalize-all-the-things.html#15720" class="Bound">y</a> <a id="15722" href="formalize-all-the-things.html#15722" class="Bound">t₁</a> <a id="15725" href="formalize-all-the-things.html#15725" class="Bound">t₂</a><a id="15727" class="Symbol">)</a> <a id="15729" class="Symbol">|</a> <a id="15731" href="formalize-all-the-things.html#9610" class="InductiveConstructor">equal</a>   <a id="15739" class="Symbol">=</a> <a id="15741" href="formalize-all-the-things.html#13507" class="InductiveConstructor">here</a> <a id="15746" href="formalize-all-the-things.html#2311" class="Function">it</a>
      <a id="15755" href="formalize-all-the-things.html#15393" class="Function">insert-sound₁</a> <a id="15769" href="formalize-all-the-things.html#15769" class="Bound">x</a> <a id="15771" class="Symbol">(</a><a id="15772" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="15777" href="formalize-all-the-things.html#15777" class="Bound">y</a> <a id="15779" href="formalize-all-the-things.html#15779" class="Bound">t₁</a> <a id="15782" href="formalize-all-the-things.html#15782" class="Bound">t₂</a><a id="15784" class="Symbol">)</a> <a id="15786" class="Symbol">|</a> <a id="15788" href="formalize-all-the-things.html#9648" class="InductiveConstructor">greater</a> <a id="15796" class="Symbol">=</a> <a id="15798" href="formalize-all-the-things.html#13607" class="InductiveConstructor">right</a> <a id="15804" class="Symbol">(</a><a id="15805" href="formalize-all-the-things.html#15393" class="Function">insert-sound₁</a> <a id="15819" href="formalize-all-the-things.html#15769" class="Bound">x</a> <a id="15821" href="formalize-all-the-things.html#15782" class="Bound">t₂</a><a id="15823" class="Symbol">)</a>

  <a id="15828" href="formalize-all-the-things.html#15183" class="Function">insert-sound</a> <a id="15841" href="formalize-all-the-things.html#15841" class="Bound">x</a> <a id="15843" href="formalize-all-the-things.html#15843" class="Bound">t</a> <a id="15845" class="Symbol">(</a><a id="15846" href="formalize-all-the-things.html#4048" class="InductiveConstructor">inr</a> <a id="15850" href="formalize-all-the-things.html#15850" class="Bound">y∈t</a><a id="15853" class="Symbol">)</a> <a id="15855" class="Symbol">=</a> <a id="15857" href="formalize-all-the-things.html#15897" class="Function">insert-sound₂</a> <a id="15871" href="formalize-all-the-things.html#15841" class="Bound">x</a> <a id="15873" href="formalize-all-the-things.html#15843" class="Bound">t</a> <a id="15875" href="formalize-all-the-things.html#15850" class="Bound">y∈t</a>

    <a id="15884" class="Keyword">where</a>

      <a id="15897" href="formalize-all-the-things.html#15897" class="Function">insert-sound₂</a> <a id="15911" class="Symbol">:</a>
        <a id="15921" class="Symbol">(</a><a id="15922" href="formalize-all-the-things.html#15922" class="Bound">x</a> <a id="15924" class="Symbol">:</a> <a id="15926" href="formalize-all-the-things.html#14431" class="Bound">A</a><a id="15927" class="Symbol">)</a> <a id="15929" class="Symbol">(</a><a id="15930" href="formalize-all-the-things.html#15930" class="Bound">t</a> <a id="15932" class="Symbol">:</a> <a id="15934" href="formalize-all-the-things.html#12238" class="Datatype">BST</a> <a id="15938" href="formalize-all-the-things.html#14431" class="Bound">A</a> <a id="15940" href="formalize-all-the-things.html#10912" class="Generalizable">lower</a> <a id="15946" href="formalize-all-the-things.html#10918" class="Generalizable">upper</a><a id="15951" class="Symbol">)</a>
        <a id="15961" class="Symbol">→</a> <a id="15963" class="Symbol">{{</a><a id="15965" href="formalize-all-the-things.html#15965" class="Bound">_</a> <a id="15967" class="Symbol">:</a> <a id="15969" href="formalize-all-the-things.html#10912" class="Generalizable">lower</a> <a id="15975" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="15977" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="15979" href="formalize-all-the-things.html#15922" class="Bound">x</a> <a id="15981" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a><a id="15982" class="Symbol">}}</a> <a id="15985" class="Symbol">{{</a><a id="15987" href="formalize-all-the-things.html#15987" class="Bound">_</a> <a id="15989" class="Symbol">:</a> <a id="15991" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="15993" href="formalize-all-the-things.html#15922" class="Bound">x</a> <a id="15995" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a> <a id="15997" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="15999" href="formalize-all-the-things.html#10918" class="Generalizable">upper</a><a id="16004" class="Symbol">}}</a>
        <a id="16015" class="Symbol">→</a> <a id="16017" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="16019" href="formalize-all-the-things.html#13426" class="Datatype Operator">∈</a> <a id="16021" href="formalize-all-the-things.html#15930" class="Bound">t</a> <a id="16023" class="Symbol">→</a> <a id="16025" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="16027" href="formalize-all-the-things.html#13426" class="Datatype Operator">∈</a> <a id="16029" href="formalize-all-the-things.html#14444" class="Function">insert</a> <a id="16036" href="formalize-all-the-things.html#15922" class="Bound">x</a> <a id="16038" href="formalize-all-the-things.html#15930" class="Bound">t</a>
      <a id="16046" href="formalize-all-the-things.html#15897" class="Function">insert-sound₂</a> <a id="16060" href="formalize-all-the-things.html#16060" class="Bound">x</a> <a id="16062" class="Symbol">(</a><a id="16063" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="16068" href="formalize-all-the-things.html#16068" class="Bound">y</a> <a id="16070" href="formalize-all-the-things.html#16070" class="Bound">t₁</a> <a id="16073" href="formalize-all-the-things.html#16073" class="Bound">t₂</a><a id="16075" class="Symbol">)</a> <a id="16077" class="Symbol">(</a><a id="16078" href="formalize-all-the-things.html#13507" class="InductiveConstructor">here</a>  <a id="16084" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a><a id="16088" class="Symbol">)</a> <a id="16090" class="Keyword">with</a> <a id="16095" href="formalize-all-the-things.html#9785" class="Field">tri</a> <a id="16099" href="formalize-all-the-things.html#16060" class="Bound">x</a> <a id="16101" href="formalize-all-the-things.html#16068" class="Bound">y</a>
      <a id="16109" class="Symbol">...</a> <a id="16113" class="Symbol">|</a> <a id="16115" href="formalize-all-the-things.html#9572" class="InductiveConstructor">less</a>    <a id="16123" class="Symbol">=</a> <a id="16125" href="formalize-all-the-things.html#13507" class="InductiveConstructor">here</a> <a id="16130" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
      <a id="16141" class="Symbol">...</a> <a id="16145" class="Symbol">|</a> <a id="16147" href="formalize-all-the-things.html#9610" class="InductiveConstructor">equal</a>   <a id="16155" class="Symbol">=</a> <a id="16157" href="formalize-all-the-things.html#13507" class="InductiveConstructor">here</a> <a id="16162" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
      <a id="16173" class="Symbol">...</a> <a id="16177" class="Symbol">|</a> <a id="16179" href="formalize-all-the-things.html#9648" class="InductiveConstructor">greater</a> <a id="16187" class="Symbol">=</a> <a id="16189" href="formalize-all-the-things.html#13507" class="InductiveConstructor">here</a> <a id="16194" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
      <a id="16205" href="formalize-all-the-things.html#15897" class="Function">insert-sound₂</a> <a id="16219" href="formalize-all-the-things.html#16219" class="Bound">x</a> <a id="16221" class="Symbol">(</a><a id="16222" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="16227" href="formalize-all-the-things.html#16227" class="Bound">y</a> <a id="16229" href="formalize-all-the-things.html#16229" class="Bound">t₁</a> <a id="16232" href="formalize-all-the-things.html#16232" class="Bound">t₂</a><a id="16234" class="Symbol">)</a> <a id="16236" class="Symbol">(</a><a id="16237" href="formalize-all-the-things.html#13557" class="InductiveConstructor">left</a>  <a id="16243" href="formalize-all-the-things.html#16243" class="Bound">y∈t₁</a><a id="16247" class="Symbol">)</a> <a id="16249" class="Keyword">with</a> <a id="16254" href="formalize-all-the-things.html#9785" class="Field">tri</a> <a id="16258" href="formalize-all-the-things.html#16219" class="Bound">x</a> <a id="16260" href="formalize-all-the-things.html#16227" class="Bound">y</a>
      <a id="16268" class="Symbol">...</a> <a id="16272" class="Symbol">|</a> <a id="16274" href="formalize-all-the-things.html#9572" class="InductiveConstructor">less</a>    <a id="16282" class="Symbol">=</a> <a id="16284" href="formalize-all-the-things.html#13557" class="InductiveConstructor">left</a> <a id="16289" class="Symbol">(</a><a id="16290" href="formalize-all-the-things.html#15897" class="Function">insert-sound₂</a> <a id="16304" class="Bound">x</a> <a id="16306" class="Bound">t₁</a> <a id="16309" class="Bound">y∈t₁</a><a id="16313" class="Symbol">)</a>
      <a id="16321" class="Symbol">...</a> <a id="16325" class="Symbol">|</a> <a id="16327" href="formalize-all-the-things.html#9610" class="InductiveConstructor">equal</a>   <a id="16335" class="Symbol">=</a> <a id="16337" href="formalize-all-the-things.html#13557" class="InductiveConstructor">left</a> <a id="16342" class="Bound">y∈t₁</a>
      <a id="16353" class="Symbol">...</a> <a id="16357" class="Symbol">|</a> <a id="16359" href="formalize-all-the-things.html#9648" class="InductiveConstructor">greater</a> <a id="16367" class="Symbol">=</a> <a id="16369" href="formalize-all-the-things.html#13557" class="InductiveConstructor">left</a> <a id="16374" class="Bound">y∈t₁</a>
      <a id="16385" href="formalize-all-the-things.html#15897" class="Function">insert-sound₂</a> <a id="16399" href="formalize-all-the-things.html#16399" class="Bound">x</a> <a id="16401" class="Symbol">(</a><a id="16402" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="16407" href="formalize-all-the-things.html#16407" class="Bound">y</a> <a id="16409" href="formalize-all-the-things.html#16409" class="Bound">t₁</a> <a id="16412" href="formalize-all-the-things.html#16412" class="Bound">t₂</a><a id="16414" class="Symbol">)</a> <a id="16416" class="Symbol">(</a><a id="16417" href="formalize-all-the-things.html#13607" class="InductiveConstructor">right</a> <a id="16423" href="formalize-all-the-things.html#16423" class="Bound">y∈t₂</a><a id="16427" class="Symbol">)</a> <a id="16429" class="Keyword">with</a> <a id="16434" href="formalize-all-the-things.html#9785" class="Field">tri</a> <a id="16438" href="formalize-all-the-things.html#16399" class="Bound">x</a> <a id="16440" href="formalize-all-the-things.html#16407" class="Bound">y</a>
      <a id="16448" class="Symbol">...</a> <a id="16452" class="Symbol">|</a> <a id="16454" href="formalize-all-the-things.html#9572" class="InductiveConstructor">less</a>    <a id="16462" class="Symbol">=</a> <a id="16464" href="formalize-all-the-things.html#13607" class="InductiveConstructor">right</a> <a id="16470" class="Bound">y∈t₂</a>
      <a id="16481" class="Symbol">...</a> <a id="16485" class="Symbol">|</a> <a id="16487" href="formalize-all-the-things.html#9610" class="InductiveConstructor">equal</a>   <a id="16495" class="Symbol">=</a> <a id="16497" href="formalize-all-the-things.html#13607" class="InductiveConstructor">right</a> <a id="16503" class="Bound">y∈t₂</a>
      <a id="16514" class="Symbol">...</a> <a id="16518" class="Symbol">|</a> <a id="16520" href="formalize-all-the-things.html#9648" class="InductiveConstructor">greater</a> <a id="16528" class="Symbol">=</a> <a id="16530" href="formalize-all-the-things.html#13607" class="InductiveConstructor">right</a> <a id="16536" class="Symbol">(</a><a id="16537" href="formalize-all-the-things.html#15897" class="Function">insert-sound₂</a> <a id="16551" class="Bound">x</a> <a id="16553" class="Bound">t₂</a> <a id="16556" class="Bound">y∈t₂</a><a id="16560" class="Symbol">)</a>

  <a id="Insert.insert-complete"></a><a id="16565" href="formalize-all-the-things.html#16565" class="Function">insert-complete</a> <a id="16581" class="Symbol">:</a>
    <a id="16587" class="Symbol">(</a><a id="16588" href="formalize-all-the-things.html#16588" class="Bound">x</a> <a id="16590" class="Symbol">:</a> <a id="16592" href="formalize-all-the-things.html#14431" class="Bound">A</a><a id="16593" class="Symbol">)</a> <a id="16595" class="Symbol">(</a><a id="16596" href="formalize-all-the-things.html#16596" class="Bound">t</a> <a id="16598" class="Symbol">:</a> <a id="16600" href="formalize-all-the-things.html#12238" class="Datatype">BST</a> <a id="16604" href="formalize-all-the-things.html#14431" class="Bound">A</a> <a id="16606" href="formalize-all-the-things.html#10912" class="Generalizable">lower</a> <a id="16612" href="formalize-all-the-things.html#10918" class="Generalizable">upper</a><a id="16617" class="Symbol">)</a>
    <a id="16623" class="Symbol">→</a> <a id="16625" class="Symbol">{{</a><a id="16627" href="formalize-all-the-things.html#16627" class="Symbol">_</a> <a id="16629" class="Symbol">:</a> <a id="16631" href="formalize-all-the-things.html#10912" class="Generalizable">lower</a> <a id="16637" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="16639" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="16641" href="formalize-all-the-things.html#16588" class="Bound">x</a> <a id="16643" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a><a id="16644" class="Symbol">}}</a> <a id="16647" class="Symbol">{{</a><a id="16649" href="formalize-all-the-things.html#16649" class="Symbol">_</a> <a id="16651" class="Symbol">:</a> <a id="16653" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">[</a> <a id="16655" href="formalize-all-the-things.html#16588" class="Bound">x</a> <a id="16657" href="formalize-all-the-things.html#10864" class="InductiveConstructor Operator">]</a> <a id="16659" href="formalize-all-the-things.html#8152" class="Field Operator">≤</a> <a id="16661" href="formalize-all-the-things.html#10918" class="Generalizable">upper</a><a id="16666" class="Symbol">}}</a>
    <a id="16673" class="Symbol">→</a> <a id="16675" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="16677" href="formalize-all-the-things.html#13426" class="Datatype Operator">∈</a> <a id="16679" href="formalize-all-the-things.html#14444" class="Function">insert</a> <a id="16686" href="formalize-all-the-things.html#16588" class="Bound">x</a> <a id="16688" href="formalize-all-the-things.html#16596" class="Bound">t</a> <a id="16690" class="Symbol">→</a> <a id="16692" class="Symbol">(</a><a id="16693" href="formalize-all-the-things.html#16588" class="Bound">x</a> <a id="16695" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="16697" href="formalize-all-the-things.html#1863" class="Generalizable">y</a><a id="16698" class="Symbol">)</a> <a id="16700" href="formalize-all-the-things.html#4000" class="Datatype Operator">⊎</a> <a id="16702" class="Symbol">(</a><a id="16703" href="formalize-all-the-things.html#1863" class="Generalizable">y</a> <a id="16705" href="formalize-all-the-things.html#13426" class="Datatype Operator">∈</a> <a id="16707" href="formalize-all-the-things.html#16596" class="Bound">t</a><a id="16708" class="Symbol">)</a>
  <a id="16712" href="formalize-all-the-things.html#16565" class="Function">insert-complete</a> <a id="16728" href="formalize-all-the-things.html#16728" class="Bound">x</a> <a id="16730" href="formalize-all-the-things.html#12314" class="InductiveConstructor">leaf</a>           <a id="16745" class="Symbol">(</a><a id="16746" href="formalize-all-the-things.html#13507" class="InductiveConstructor">here</a> <a id="16751" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a><a id="16755" class="Symbol">)</a> <a id="16757" class="Symbol">=</a> <a id="16759" href="formalize-all-the-things.html#4030" class="InductiveConstructor">inl</a> <a id="16763" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
  <a id="16770" href="formalize-all-the-things.html#16565" class="Function">insert-complete</a> <a id="16786" href="formalize-all-the-things.html#16786" class="Bound">x</a> <a id="16788" class="Symbol">(</a><a id="16789" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="16794" href="formalize-all-the-things.html#16794" class="Bound">y</a> <a id="16796" href="formalize-all-the-things.html#16796" class="Bound">t₁</a> <a id="16799" href="formalize-all-the-things.html#16799" class="Bound">t₂</a><a id="16801" class="Symbol">)</a> <a id="16803" href="formalize-all-the-things.html#16803" class="Bound">y∈t'</a>       <a id="16814" class="Keyword">with</a> <a id="16819" href="formalize-all-the-things.html#9785" class="Field">tri</a> <a id="16823" href="formalize-all-the-things.html#16786" class="Bound">x</a> <a id="16825" href="formalize-all-the-things.html#16794" class="Bound">y</a>
  <a id="16829" href="formalize-all-the-things.html#16565" class="Function">insert-complete</a> <a id="16845" href="formalize-all-the-things.html#16845" class="Bound">x</a> <a id="16847" class="Symbol">(</a><a id="16848" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="16853" href="formalize-all-the-things.html#16853" class="Bound">y</a> <a id="16855" href="formalize-all-the-things.html#16855" class="Bound">t₁</a> <a id="16858" href="formalize-all-the-things.html#16858" class="Bound">t₂</a><a id="16860" class="Symbol">)</a> <a id="16862" class="Symbol">(</a><a id="16863" href="formalize-all-the-things.html#13507" class="InductiveConstructor">here</a> <a id="16868" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a><a id="16872" class="Symbol">)</a>   <a id="16876" class="Symbol">|</a> <a id="16878" href="formalize-all-the-things.html#9572" class="InductiveConstructor">less</a>    <a id="16886" class="Symbol">=</a> <a id="16888" href="formalize-all-the-things.html#4048" class="InductiveConstructor">inr</a> <a id="16892" class="Symbol">(</a><a id="16893" href="formalize-all-the-things.html#13507" class="InductiveConstructor">here</a> <a id="16898" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a><a id="16902" class="Symbol">)</a>
  <a id="16906" href="formalize-all-the-things.html#16565" class="Function">insert-complete</a> <a id="16922" href="formalize-all-the-things.html#16922" class="Bound">x</a> <a id="16924" class="Symbol">(</a><a id="16925" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="16930" href="formalize-all-the-things.html#16930" class="Bound">y</a> <a id="16932" href="formalize-all-the-things.html#16932" class="Bound">t₁</a> <a id="16935" href="formalize-all-the-things.html#16935" class="Bound">t₂</a><a id="16937" class="Symbol">)</a> <a id="16939" class="Symbol">(</a><a id="16940" href="formalize-all-the-things.html#13507" class="InductiveConstructor">here</a> <a id="16945" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a><a id="16949" class="Symbol">)</a>   <a id="16953" class="Symbol">|</a> <a id="16955" href="formalize-all-the-things.html#9610" class="InductiveConstructor">equal</a>   <a id="16963" class="Symbol">=</a> <a id="16965" href="formalize-all-the-things.html#4030" class="InductiveConstructor">inl</a> <a id="16969" href="formalize-all-the-things.html#2311" class="Function">it</a>
  <a id="16974" href="formalize-all-the-things.html#16565" class="Function">insert-complete</a> <a id="16990" href="formalize-all-the-things.html#16990" class="Bound">x</a> <a id="16992" class="Symbol">(</a><a id="16993" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="16998" href="formalize-all-the-things.html#16998" class="Bound">y</a> <a id="17000" href="formalize-all-the-things.html#17000" class="Bound">t₁</a> <a id="17003" href="formalize-all-the-things.html#17003" class="Bound">t₂</a><a id="17005" class="Symbol">)</a> <a id="17007" class="Symbol">(</a><a id="17008" href="formalize-all-the-things.html#13507" class="InductiveConstructor">here</a> <a id="17013" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a><a id="17017" class="Symbol">)</a>   <a id="17021" class="Symbol">|</a> <a id="17023" href="formalize-all-the-things.html#9648" class="InductiveConstructor">greater</a> <a id="17031" class="Symbol">=</a> <a id="17033" href="formalize-all-the-things.html#4048" class="InductiveConstructor">inr</a> <a id="17037" class="Symbol">(</a><a id="17038" href="formalize-all-the-things.html#13507" class="InductiveConstructor">here</a> <a id="17043" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a><a id="17047" class="Symbol">)</a>
  <a id="17051" href="formalize-all-the-things.html#16565" class="Function">insert-complete</a> <a id="17067" href="formalize-all-the-things.html#17067" class="Bound">x</a> <a id="17069" class="Symbol">(</a><a id="17070" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="17075" href="formalize-all-the-things.html#17075" class="Bound">y</a> <a id="17077" href="formalize-all-the-things.html#17077" class="Bound">t₁</a> <a id="17080" href="formalize-all-the-things.html#17080" class="Bound">t₂</a><a id="17082" class="Symbol">)</a> <a id="17084" class="Symbol">(</a><a id="17085" href="formalize-all-the-things.html#13557" class="InductiveConstructor">left</a> <a id="17090" href="formalize-all-the-things.html#17090" class="Bound">y∈t₁'</a><a id="17095" class="Symbol">)</a>  <a id="17098" class="Symbol">|</a> <a id="17100" href="formalize-all-the-things.html#9572" class="InductiveConstructor">less</a>    <a id="17108" class="Symbol">=</a> <a id="17110" href="formalize-all-the-things.html#4153" class="Function">mapInr</a> <a id="17117" href="formalize-all-the-things.html#13557" class="InductiveConstructor">left</a> <a id="17122" class="Symbol">(</a><a id="17123" href="formalize-all-the-things.html#16565" class="Function">insert-complete</a> <a id="17139" href="formalize-all-the-things.html#17067" class="Bound">x</a> <a id="17141" href="formalize-all-the-things.html#17077" class="Bound">t₁</a> <a id="17144" href="formalize-all-the-things.html#17090" class="Bound">y∈t₁'</a><a id="17149" class="Symbol">)</a>
  <a id="17153" href="formalize-all-the-things.html#16565" class="Function">insert-complete</a> <a id="17169" href="formalize-all-the-things.html#17169" class="Bound">x</a> <a id="17171" class="Symbol">(</a><a id="17172" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="17177" href="formalize-all-the-things.html#17177" class="Bound">y</a> <a id="17179" href="formalize-all-the-things.html#17179" class="Bound">t₁</a> <a id="17182" href="formalize-all-the-things.html#17182" class="Bound">t₂</a><a id="17184" class="Symbol">)</a> <a id="17186" class="Symbol">(</a><a id="17187" href="formalize-all-the-things.html#13557" class="InductiveConstructor">left</a>  <a id="17193" href="formalize-all-the-things.html#17193" class="Bound">y∈t₁</a><a id="17197" class="Symbol">)</a>  <a id="17200" class="Symbol">|</a> <a id="17202" href="formalize-all-the-things.html#9610" class="InductiveConstructor">equal</a>   <a id="17210" class="Symbol">=</a> <a id="17212" href="formalize-all-the-things.html#4048" class="InductiveConstructor">inr</a> <a id="17216" class="Symbol">(</a><a id="17217" href="formalize-all-the-things.html#13557" class="InductiveConstructor">left</a> <a id="17222" href="formalize-all-the-things.html#17193" class="Bound">y∈t₁</a><a id="17226" class="Symbol">)</a>
  <a id="17230" href="formalize-all-the-things.html#16565" class="Function">insert-complete</a> <a id="17246" href="formalize-all-the-things.html#17246" class="Bound">x</a> <a id="17248" class="Symbol">(</a><a id="17249" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="17254" href="formalize-all-the-things.html#17254" class="Bound">y</a> <a id="17256" href="formalize-all-the-things.html#17256" class="Bound">t₁</a> <a id="17259" href="formalize-all-the-things.html#17259" class="Bound">t₂</a><a id="17261" class="Symbol">)</a> <a id="17263" class="Symbol">(</a><a id="17264" href="formalize-all-the-things.html#13557" class="InductiveConstructor">left</a>  <a id="17270" href="formalize-all-the-things.html#17270" class="Bound">y∈t₁</a><a id="17274" class="Symbol">)</a>  <a id="17277" class="Symbol">|</a> <a id="17279" href="formalize-all-the-things.html#9648" class="InductiveConstructor">greater</a> <a id="17287" class="Symbol">=</a> <a id="17289" href="formalize-all-the-things.html#4048" class="InductiveConstructor">inr</a> <a id="17293" class="Symbol">(</a><a id="17294" href="formalize-all-the-things.html#13557" class="InductiveConstructor">left</a> <a id="17299" href="formalize-all-the-things.html#17270" class="Bound">y∈t₁</a><a id="17303" class="Symbol">)</a>
  <a id="17307" href="formalize-all-the-things.html#16565" class="Function">insert-complete</a> <a id="17323" href="formalize-all-the-things.html#17323" class="Bound">x</a> <a id="17325" class="Symbol">(</a><a id="17326" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="17331" href="formalize-all-the-things.html#17331" class="Bound">y</a> <a id="17333" href="formalize-all-the-things.html#17333" class="Bound">t₁</a> <a id="17336" href="formalize-all-the-things.html#17336" class="Bound">t₂</a><a id="17338" class="Symbol">)</a> <a id="17340" class="Symbol">(</a><a id="17341" href="formalize-all-the-things.html#13607" class="InductiveConstructor">right</a> <a id="17347" href="formalize-all-the-things.html#17347" class="Bound">y∈t₂</a><a id="17351" class="Symbol">)</a>  <a id="17354" class="Symbol">|</a> <a id="17356" href="formalize-all-the-things.html#9572" class="InductiveConstructor">less</a>    <a id="17364" class="Symbol">=</a> <a id="17366" href="formalize-all-the-things.html#4048" class="InductiveConstructor">inr</a> <a id="17370" class="Symbol">(</a><a id="17371" href="formalize-all-the-things.html#13607" class="InductiveConstructor">right</a> <a id="17377" href="formalize-all-the-things.html#17347" class="Bound">y∈t₂</a><a id="17381" class="Symbol">)</a>
  <a id="17385" href="formalize-all-the-things.html#16565" class="Function">insert-complete</a> <a id="17401" href="formalize-all-the-things.html#17401" class="Bound">x</a> <a id="17403" class="Symbol">(</a><a id="17404" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="17409" href="formalize-all-the-things.html#17409" class="Bound">y</a> <a id="17411" href="formalize-all-the-things.html#17411" class="Bound">t₁</a> <a id="17414" href="formalize-all-the-things.html#17414" class="Bound">t₂</a><a id="17416" class="Symbol">)</a> <a id="17418" class="Symbol">(</a><a id="17419" href="formalize-all-the-things.html#13607" class="InductiveConstructor">right</a> <a id="17425" href="formalize-all-the-things.html#17425" class="Bound">y∈t₂</a><a id="17429" class="Symbol">)</a>  <a id="17432" class="Symbol">|</a> <a id="17434" href="formalize-all-the-things.html#9610" class="InductiveConstructor">equal</a>   <a id="17442" class="Symbol">=</a> <a id="17444" href="formalize-all-the-things.html#4048" class="InductiveConstructor">inr</a> <a id="17448" class="Symbol">(</a><a id="17449" href="formalize-all-the-things.html#13607" class="InductiveConstructor">right</a> <a id="17455" href="formalize-all-the-things.html#17425" class="Bound">y∈t₂</a><a id="17459" class="Symbol">)</a>
  <a id="17463" href="formalize-all-the-things.html#16565" class="Function">insert-complete</a> <a id="17479" href="formalize-all-the-things.html#17479" class="Bound">x</a> <a id="17481" class="Symbol">(</a><a id="17482" href="formalize-all-the-things.html#12375" class="InductiveConstructor">node</a> <a id="17487" href="formalize-all-the-things.html#17487" class="Bound">y</a> <a id="17489" href="formalize-all-the-things.html#17489" class="Bound">t₁</a> <a id="17492" href="formalize-all-the-things.html#17492" class="Bound">t₂</a><a id="17494" class="Symbol">)</a> <a id="17496" class="Symbol">(</a><a id="17497" href="formalize-all-the-things.html#13607" class="InductiveConstructor">right</a> <a id="17503" href="formalize-all-the-things.html#17503" class="Bound">y∈t₂'</a><a id="17508" class="Symbol">)</a> <a id="17510" class="Symbol">|</a> <a id="17512" href="formalize-all-the-things.html#9648" class="InductiveConstructor">greater</a> <a id="17520" class="Symbol">=</a> <a id="17522" href="formalize-all-the-things.html#4153" class="Function">mapInr</a> <a id="17529" href="formalize-all-the-things.html#13607" class="InductiveConstructor">right</a> <a id="17535" class="Symbol">(</a><a id="17536" href="formalize-all-the-things.html#16565" class="Function">insert-complete</a> <a id="17552" href="formalize-all-the-things.html#17479" class="Bound">x</a> <a id="17554" href="formalize-all-the-things.html#17492" class="Bound">t₂</a> <a id="17557" href="formalize-all-the-things.html#17503" class="Bound">y∈t₂'</a><a id="17562" class="Symbol">)</a>
</pre>
<p>Of course, there are many more functions on search trees we could want
to implement and prove correct: deletion, merging, flattening
… Likewise, there are other invariants we might want to enforce in
the type, such as being well-balanced. I strongly recommend to read
<a href="https://personal.cis.strath.ac.uk/conor.mcbride/Pivotal.pdf">Conor McBride’s
paper</a> on
the topic, or try it yourself!</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Fri, 04 Oct 2019 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/formalize-all-the-things.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>EUTYPES '19 Summer School in Ohrid</title>
    <link>https://jesper.sikanda.be/posts/ohrid19.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - EUTYPES '19 Summer School in Ohrid</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>EUTYPES '19 Summer School in Ohrid</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on September 13, 2019
    </p>
    <p>I gave a course about Correct-by-Construction Programming in Agda at
the EUTYPES summer school in Ohrid. The course materials are available
<a href="https://jespercockx.github.io/ohrid19-agda/">here</a>.</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Fri, 13 Sep 2019 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/ohrid19.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>Writing Agda blog posts in literate markdown</title>
    <link>https://jesper.sikanda.be/posts/literate-agda.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Writing Agda blog posts in literate markdown</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Writing Agda blog posts in literate markdown</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on July  9, 2019
    </p>
    <p>So you got to admit all the cool kids are doing it nowadays: writing
blog posts in literate Agda. Do you want to join the club? Then you’ve
come to the right place! In this blog post I’ll explain how to write a
blog post (or any literate Agda code, really) as a markdown file and
transform it into fancy highlighted and hyperlinked html. Don’t worry,
it’s easy!</p>
<pre class="Agda"><a id="461" class="Keyword">open</a> <a id="466" class="Keyword">import</a> <a id="473" href="Agda.Builtin.Nat.html" class="Module">Agda.Builtin.Nat</a>
<a id="490" class="Keyword">open</a> <a id="495" class="Keyword">import</a> <a id="502" href="Agda.Builtin.Equality.html" class="Module">Agda.Builtin.Equality</a>

<a id="plus1"></a><a id="525" href="literate-agda.html#525" class="Function">plus1</a> <a id="531" class="Symbol">:</a> <a id="533" class="Symbol">(</a><a id="534" href="literate-agda.html#534" class="Bound">x</a> <a id="536" class="Symbol">:</a> <a id="538" href="Agda.Builtin.Nat.html#203" class="Datatype">Nat</a><a id="541" class="Symbol">)</a> <a id="543" class="Symbol">→</a> <a id="545" href="literate-agda.html#534" class="Bound">x</a> <a id="547" href="Agda.Builtin.Nat.html#336" class="Primitive Operator">+</a> <a id="549" class="Number">1</a> <a id="551" href="Agda.Builtin.Equality.html#150" class="Datatype Operator">≡</a> <a id="553" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="557" href="literate-agda.html#534" class="Bound">x</a>
<a id="559" href="literate-agda.html#525" class="Function">plus1</a> <a id="565" href="Agda.Builtin.Nat.html#221" class="InductiveConstructor">zero</a>                    <a id="589" class="Symbol">=</a> <a id="591" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
<a id="596" href="literate-agda.html#525" class="Function">plus1</a> <a id="602" class="Symbol">(</a><a id="603" href="Agda.Builtin.Nat.html#234" class="InductiveConstructor">suc</a> <a id="607" href="literate-agda.html#607" class="Bound">x</a><a id="608" class="Symbol">)</a> <a id="610" class="Keyword">rewrite</a> <a id="618" href="literate-agda.html#525" class="Function">plus1</a> <a id="624" href="literate-agda.html#607" class="Bound">x</a> <a id="626" class="Symbol">=</a> <a id="628" href="Agda.Builtin.Equality.html#207" class="InductiveConstructor">refl</a>
</pre>
<h1 id="writing-the-blog-post">Writing the blog post</h1>
<p>To start, you’ll first need to install Agda 2.6.0 or newer and Pandoc
2.2 or newer. Both can be installed from Cabal with <code>cabal install agda-2.6.0.1 pandoc-2.2.1</code> (these versions work well with GHC 8.0,
YMMV).</p>
<p>Next, create a file called <code>blogpost.lagda.md</code> and open it up in
Emacs. Here, you write your text using standard <a href="https://daringfireball.net/projects/markdown/basics">markdown
syntax</a>. Any Agda
code goes between triple backticks:</p>
<pre><code>```
-- write your Agda code here
```</code></pre>
<p>Bonus trick: to hide an Agda code block, just put it between html
comments (&lt;!‐‐ and ‐‐&gt;).</p>
<p>You’ll notice that the agda2-mode for emacs is not automatically
loaded when editing <code>.lagda.md</code> files. You can either load it manually
(using <code>M-x agda2-mode</code>) or fix the problem once and for all by adding
this line to your <code>.emacs</code> configuration:</p>
<pre class="elisp"><code>(add-to-list 'auto-mode-alist '(&quot;\\.lagda.md\\'&quot; . agda2-mode))</code></pre>
<h1 id="from-markdown-to-html">From markdown to html</h1>
<p>Once you are finished with writing your blog post, first use Agda to
convert the code parts to html:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">agda</span> <span class="at">--html</span> <span class="at">--html-highlight</span><span class="op">=</span>code blogpost.lagda.md</span></code></pre></div>
<p>Here, the <code>--html</code> flag tells Agda to generate html from the file, and
<code>--html-highlight=code</code> tells Agda not to touch the non-code parts of
the file (these will be processed by Pandoc). You should now have a
new directory called <code>html</code> containing the following:</p>
<ul>
<li>A file <code>blogpost.md</code></li>
<li><code>.html</code> files for all the imported modules</li>
<li>A css stylesheet <code>Agda.css</code></li>
</ul>
<p>To complete the process, run Pandoc on the <code>.md</code> file like so:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">pandoc</span> html/blogpost.md <span class="at">-o</span> blogpost.html</span></code></pre></div>
<p>This tells Pandoc to convert the markdown file to html (it won’t touch
the code since that’s already been converted by Agda).</p>
<p>If you want, you can go wild with any <a href="https://pandoc.org/MANUAL.html#pandocs-markdown">Pandoc
extensions</a> you want
to use. Personally, I’m just using <code>tex_math_dollars</code>,
<code>tex_math_double_backslash</code> and <code>latex_macros</code> (for using LaTeX
commands in text).</p>
<h1 id="integrating-with-hakyll">Integrating with Hakyll</h1>
<p>Since I’m building my website with
<a href="https://jaspervdj.be/hakyll/">Hakyll</a>, I tried to integrate Agda into
the Hakyll pipeline. Unfortunately, this did not go quite as smoothly
as I expected: Hakyll is built around the paradigm of mapping one
input file to one output file, but this does not match with how
<code>agda --html</code> generates its output. For more details on the problem I
had, see <a href="https://groups.google.com/forum/#!topic/hakyll/fLakSephFQ0">this
post</a>.</p>
<p>Instead, I currently run <code>agda --html</code> on all Agda blog posts as a
preprocessing step to Hakyll. This does not work quite as seamlessly
as I hoped since Hakyll does not automatically detect changes when
running in <code>watch</code> mode, but it gets the job done. If you are also
running Hakyll and you want to steal my method, feel free to take a
look at it
<a href="https://github.com/jespercockx/website/blob/master/site.hs">here</a>. Also,
if you know of a better method please let me know!</p>
<p>I hope you enjoyed this blogpost about the <em>making of</em> this blog, next
time I will finally talk about the long-awaited topic of rewrite rules
in Agda (I promise!)</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Tue, 09 Jul 2019 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/literate-agda.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>Elaborating Dependent (Co)pattern Matching</title>
    <link>https://jesper.sikanda.be/posts/elaborating-dependent-copattern-matching.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - Elaborating Dependent (Co)pattern Matching</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>Elaborating Dependent (Co)pattern Matching</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on September 22, 2018
    </p>
    <p>It has been a while since my last (and first) post, so here is a
new one about this year’s ICFP paper by Andreas Abel and me, titled
“Elaborating Dependent (Co)pattern Matching”
(<a href="../files/elaborating-dependent-copattern-matching.pdf">pdf</a>). Dependent
pattern matching and copattern matching is one of Agda’s coolest
features. It is also a topic very close to my heart since I spend most
of my PhD years on the topic.</p>
<p>My goal in this blog post is not to go into the theoretical details,
you can find those in the paper. Instead, I want to go a bit more into
the reasons why I think this work is important and some unexpected
discoveries I made while working on the paper.</p>
<p><strong>Prerequisites.</strong> I’ll assume you have used a proof assistant with
dependent pattern matching (such as Agda, Idris, or the Equations
package for Coq) at least a few times, but I won’t assume any
knowledge about the Agda internals.</p>
<h2 id="how-to-trust-your-type-system">How to trust your type system</h2>
<p>When we use a typechecker or a proof assistant, it is fundamentally
because we don’t trust ourselves enough (or we can’t be bothered to)
to check whether all the details of a program or proof make sense.
Their usefulness thus depends directly on our ability to trust them.
But why do we believe we can in fact trust them: is it based on
<strong>science</strong> or on <strong>faith</strong>? I claim that currently, we are somewhere
in between these two. Let me explain why.</p>
<p>A typical dependently typed programming language / proof assistant (be
it Agda, Coq, Idris, or even Haskell) actually consists of two
languages: a high-level <em>surface language</em> and a lower-level <em>core
language</em>. The surface language usually has many convenience features
such as implicit arguments, named variables, pattern matching, a
tactic system, etc. On the other hand, the core language has none of
these and is kept as small as possible on purpose. These core
languages have often been studied in great detail for decades and
(while there are still many new discoveries to be made) they lie
firmly in the camp of <strong>science</strong>.</p>
<p>The process of translating from surface to core language is called
<em>elaboration</em>. It includes many steps such as scope checking, type
checking, higher-order unification for checking constraints and
figuring out implicit arguments, and running tactics. The goals of
elaboration are twofold:</p>
<ol type="1">
<li><p>to <em>check</em> that the user-written code (in the surface language) is
correct, and</p></li>
<li><p>to <em>generate</em> the low-level program (in the core language) which
can then be executed (if you are in the business of running your
programs, that is).</p></li>
</ol>
<p>In Agda, currently only a very small part of the core language can be
typechecked independently, so we need to trust the elaboration
process. This elaboration is a big, ugly mess of semi-imperative
Haskell code with lots of unsafe features and no real
specification. This is clearly not based on any rational science, only
<strong>faith</strong> enables us to use Agda while keeping our sanity.</p>
<p>In other languages—such as Coq—the generated core can be checked
independently, and in fact it <em>is</em> checked at every <code>qed</code> and
<code>defined</code>. So should Agda follow Coq and get a proper core language?
While I think this is a good idea (our paper actually takes a step in
that direction), I don’t think that’s <em>enough</em>.</p>
<p>Suppose in extremis that the elaborator would translate every type to
the unit type <code>⊤</code>, and every term to the trivial proof <code>tt</code>. Then all
the generated code is certainly type-correct, but it is as certainly
not what we want! Of course, in reality mistakes in the elaboration
process are never this blatant, but they still happen and may result
in type-correct yet meaningless code being generated. The message is
thus:</p>
<p><em>Even with a trusted core language and double-checking of all
generated code, the elaborator is still part of the trusted kernel!</em></p>
<p>(If you’re using Coq or Agda just as a theorem prover and you don’t
care about the actual proof term, you still have to trust the
elaborator to preserve the meaning of the <em>theorem statement</em>, which
can be a complex expression itself).</p>
<p>So if we must rely on the correctness of elaboration, what can we do
to increase our trust in it? Well, eat our own dogfood and formally
verify it of course. Unfortunately, the current state of Agda is
pretty far from the point where it would be feasible to verify
anything about it (remember it doesn’t even have a proper core
language?). So the first step will be more modest: take a small part
of the elaboration process, specify what properties it ought to have,
and prove that they are indeed satisfied by this small part.</p>
<h2 id="elaborating-pattern-matching">Elaborating pattern matching</h2>
<p>Let’s get to the actual topic of the paper: dependent pattern
matching. Dependent pattern matching provides a very convenient syntax
for defining new functions (and, through the Curry-Howard
correspondence, proofs) by case analysis and recursion. A big part of
the power of dependent pattern matching comes from the unification
algorithm it employs for specializing types to each specific case and
to rule out impossible cases. This unification algorithm was the main
topic of my PhD thesis, but here I want to talk about a different aspect.</p>
<p>Pattern matching is one of these features that are present in the
surface language but are translated away by elaboration. In
particular, the elaboration of a function by dependent pattern
matching proceeds in two steps: first, the clauses written by the user
are translated to a <em>case tree</em>, and then this case tree can be
further translated to the <em>primitive eliminators</em> provided by the core
language (for example CIC for Coq). Agda skips the second step and
uses case trees directly in its internal language instead.</p>
<p>The second step of this translation has been studied extensively in
the past: by Conor McBride, Healfdene Goguen and James McKinna for a
type theory with UIP (uniqueness of identity proofs) and by me and
Dominique Devriese in the general case. On the other hand, no-one ever
really formalized or proved anything about the first step. You guessed
it: that’s exactly what we do in our new paper.</p>
<p>In order to prove anything about the elaboration process, we need to
formalize it in much greater detail than is usually done. Finding the
right judgement forms was actually the main challenge when writing the
paper; once we got them right most of the proofs followed naturally!
At the same time, having a very precise description of the elaboration
process helps a lot when actually implementing the algorithm for
Agda. So formalizing elaboration is a big win from both the
theoretical and the practical side of things!</p>
<p>For example, to prove that the case trees produced by elaboration are
well-typed, it is necessary to have typing rules for case trees in the
first place. However, this is not the case for the case trees
currently used internally by Agda! In fact, they do not contain
sufficient information to check them independently, which is one of
the major obstacles preventing us from having a proper core language
for Agda. In the future, I would like to refactor the representation
of case trees in Agda to be closer to the well-typed case trees in our
paper.</p>
<h2 id="first-match-semantics-and-the-shortcut-rule">First-match semantics and the shortcut rule</h2>
<p>An important goal in our paper is to prove that elaborating a
definition by pattern matching preserves the <em>meaning</em> of the
definition. In particular, if the arguments to the function match a
certain clause, and they didn’t match any of the previous clauses,
then this clause should fire – this is the so-called <em>first-match
semantics</em> of pattern matching. In our paper, prove that our
elaboration process preserves the first-match semantics of the clauses
written by the user.</p>
<p>In a dependently typed language, we expect stronger properties from
our programs than usual, in particular w.r.t. evaluation of open terms
(i.e. terms with free variables). This poses interesting new questions
when proving properties that involve evaluation. For example, consider
Berry’s infamous <code>majority</code> function:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>majority <span class="ot">:</span> Bool <span class="ot">→</span> Bool <span class="ot">→</span> Bool <span class="ot">→</span> Bool</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>majority true  true  true  <span class="ot">=</span> true</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>majority x     true  false <span class="ot">=</span> x</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>majority false y     true  <span class="ot">=</span> y</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>majority true  false z     <span class="ot">=</span> z</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>majority false false false <span class="ot">=</span> false</span></code></pre></div>
<p>When evaluating <code>majority x true false</code>, can we safely skip the first
clause and apply the second clause to conclude <code>majority x true false = x</code>? This so-called <em>shortcut rule</em> allows matching to proceed to the
next clause when there’s a mismatch for one argument (in this case the
third) even when matching for another argument (here the first) is
still inconclusive.</p>
<p>However, it turns out this rule is not allowed if we want to preserve
the first-match semantics in the translation to a case tree! For
example, the obvious case tree for <code>majority</code> matches first on the
first argument, which means <code>majority x true false</code> is a stuck term
that does not evaluate to anything.</p>
<p>A more restricted version of the shortcut rule is <em>left-to-right
matching</em>, where the arguments are matched (you’d never guess) from
left to right, and a mismatch means going to the next clause
immediately. This semantics adequately describes the behaviour of the
case tree for <code>majority</code> and is the one that was (until recently)
the one implemented in Agda.</p>
<p>But this restricted shortcut rule is <em>also</em> not preserved by the
elaboration to a case tree. Here is an example for which the <em>only</em>
valid case tree does not satisfy the first-match semantics with
left-to-right matching:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode agda"><code class="sourceCode agda"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>f <span class="ot">:</span> <span class="ot">(</span>A <span class="ot">:</span> <span class="dt">Set</span><span class="ot">)</span> <span class="ot">→</span> A <span class="ot">→</span> <span class="ot">(</span>A ≡ Bool<span class="ot">)</span> <span class="ot">→</span> Bool</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>f <span class="ot">.</span>Bool true refl <span class="ot">=</span> true</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>f <span class="ot">_</span>     <span class="ot">_</span>    <span class="ot">_</span>    <span class="ot">=</span> false</span></code></pre></div>
<p>The function matches on both its second and third argument, but in a
well-typed case tree the match on the third argument has to come
before the second. Hence <code>f Bool false p</code> for a variable <code>p</code> does not
evaluate to <code>false</code> but is stuck.</p>
<p>This actually caused a bug in Agda which allowed us to break subject
reduction (see <a href="https://github.com/agda/agda/issues/2964">#2964</a>). I
only discovered this bug because I was writing the proof of
preservation of first-match semantics and failed to make it work!
Once we found the error, the problem was easy to fix by removing the
shortcut rule in all forms.</p>
<p>In effect, our theorem says that the first-match semantics (without
the shortcut rule) give a <em>lower bound</em> to the computational behaviour
of any case tree produced by elaboration: the case has at least this
computational behaviour, and possibly some more depending on the order
of case splits. On the other hand, we could also give an <em>upper bound</em>
to the computational behaviour of any case tree, in the form of some
<em>any-match</em> semantics. The definition of any-match semantics and the
proof that it is an upper bound is left as an exercise to the reader
;)</p>
<h2 id="conclusion">Conclusion</h2>
<p>This post is getting pretty long so I’m going to stop here. If you
cannot get enough, you’re in luck since there’s a whole
<a href="../files/elaborating-dependent-copattern-matching.pdf">paper</a> for you!
One thing that’s in the paper but I didn’t talk about here at all is
<em>copattern matching</em>, as indicated by the `(co)’ in the paper
title. Copatterns are very cool so maybe I’ll write something about
them here later.</p>
<p>As always, if you have any questions or comments about this post, let
me know on the Agda mailing list. See you next time, where I’ll
hopefully talk about one of Agda’s most unsafe features: user-defined
rewrite rules!</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Sat, 22 Sep 2018 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/elaborating-dependent-copattern-matching.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>
<item>
    <title>The Agda's New Sorts</title>
    <link>https://jesper.sikanda.be/posts/agdas-new-sorts.html</link>
    <description><![CDATA[<!doctype html>
<script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>

<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Jesper Cockx - The Agda's New Sorts</title>
        <link rel="stylesheet" href="../css/default.css" />
        <link rel="stylesheet" href="Agda.css" />
        <link rel="alternate" type="application/rss+xml" title="RSS" href="https://jesper.sikanda.be/rss.xml">
        <link rel="alternate" type="application/atom+xml" title="Atom" href="https://jesper.sikanda.be/atom.xml">
    </head>
    <body>
        <header>
            <div class="logo">
                <a href="../">Jesper Cockx</a>
            </div>
            <nav>
                <a href="../">Home</a>
                <a href="../blog.html">Blog</a>
                <a href="../publications.html">Papers</a>
                <a href="../talks.html">Talks</a>
                <a href="../teaching.html">Teaching</a>
                <a href="../links.html">Links</a>
            </nav>
        </header>

        <main role="main">
            <h1>The Agda's New Sorts</h1>
            <article>
    <p class="date">
      Posted
      
            by Jesper
       on May  3, 2018
    </p>
    <p>In the last few weeks, Sandro Stucki has given a couple of excellent presentations on pure type systems (pts’s) at the <a href="https://github.com/InitialTypes/Club">initial types club</a> at Chalmers. Since I’ve been working on the implementation of Agda’s sorts system, and the new implementation is closely based on the theory of pure type systems, I thought it would be interesting to talk a bit about the implementation of these concepts used by Agda.</p>
<p><strong>Prerequisites</strong>: a bit of experience with using Agda, basic knowledge of pure type systems (see section 5.2 of <a href="https://www.dropbox.com/s/pwg069e0lomhzie/Barendregt92_-_Lambda_Calculi_with_Types.pdf?dl=0">Barendregt’s classic</a>).</p>
<p>Note: this post started as my personal notes to prepare for a talk at the initial types club, but then I realized it could make a nice blog post. Since this is kind of an experiment, please let me know if there’s something I can improve or if you’re just eager to have more posts about the development of Agda!</p>
<h2 id="agdas-universe-hierarchy">Agda’s universe hierarchy</h2>
<p>Sorts (aka universes) are types whose members themselves are again types. They are a central element of Martin-Löf’s type theory and languages based on that theory, such as Agda. The prototypical example of a sort in Agda is <code>Set</code>, the universe of small types. Why do we need any sort other than <code>Set</code>, you ask? Well, to avoid inconsistency and undecidable typechecking we cannot have <code>Set : Set</code> (known as the <strong>type-in-type</strong> rule): Martin-Löf’s original type theory had a rule like this, but Girard showed that this is inconsistent (this is called Girard’s paradox). While Girard’s original paradox is quite complex, it’s easier to get a contradiction in Agda by (ab)using datatypes and structural recursion (example taken from a <a href="https://lists.chalmers.se/pipermail/agda/2017/009337.html">post by Andreas Abel</a> on the Agda mailing list):</p>
<pre><code>{-# OPTIONS --type-in-type #-}

data ⊥ : Set where

data D : Set where
  c : (f : (A : Set) → A → A) → D

empty : D → ⊥
empty (c f) = empty (f D (c f))

absurd : ⊥
absurd = empty (c λ A x → x)</code></pre>
<p>See also <a href="http://liamoc.net/posts/2015-09-10-girards-paradox.html">this post by Liam O’Connor</a> for a direct encoding of a similar inconsistency with type-in-type, Russell’s paradox (aka the Barber’s paradox).</p>
<p>To avoid these inconsistencies, Agda has an infinite hierarchy of sorts <code>Set0</code> (= <code>Set</code>), <code>Set1</code>, <code>Set2</code>, … such that <code>Set0 : Set1</code>, <code>Set1 : Set2</code>, … Thus if we restrict Agda’s type system to just the sorts <code>SetN</code> and dependent function types <code>(x : A) → B</code>, we can think of it as a pure type system with the sorts given by natural numbers, axioms <code>(n, n+1)</code> and rules <code>(m, n, m ⊔ n)</code> (where <code>⊔</code> indicates the maximum). Unlike Coq, Agda has <em>no</em> cumulativity, so we have <code>Set0 : Set1</code> and <code>Set1 : Set2</code> but not <code>Set0 : Set2</code>. I’ll come back to the point of cumulativity at the end of this post.</p>
<h2 id="universe-polymorphism">Universe polymorphism</h2>
<p>In practice, of course, things aren’t that simple. It turns out that defining the same functions and datatypes at different universe levels gets really old really quickly. To fix this, Agda has a feature called <em>universe polymorphism</em>. This feature exposes a new type <code>Level : Set</code> to the user, as well as primitive functions on levels <code>lzero : Level</code>, <code>lsuc  : Level → Level</code>, and <code>_⊔_ : Level → Level → Level</code>. For each <code>l : Level</code> we get a new universe <code>Set l</code>, with the obvious rules (<code>Set lzero = Set0</code>, <code>Set (lsuc lzero) = Set1</code>, …) This allows us to define functions and datatypes for all universe levels at once, e.g. the polymorphic identity function:</p>
<pre><code>id : (l : Level)(A : Set l)(x : A) → A
id l A x = x</code></pre>
<p>This seems like a useful yet unexciting feature and indeed, if you’ve ever seen some non-trivial Agda code you have probably encountered it already. However, it has some big implications for Agda as a pure type system: it means that the <em>sort</em> of the codomain of a function type can now also depend on the <em>value</em> of the argument. This definitely does not fit into the framework of pure type systems anymore, so we’re entering uncharted lands. It also raises a number of practical questions about Agda’s sort system, such as:</p>
<ul>
<li>Levels are now no longer just natural numbers but they can be arbitrary <em>terms</em>, in particular a level can be neutral (i.e. contain free variables). So how do we determine when two levels are equal?</li>
<li>The type of <code>id</code> is <code>(l : Level) (A : Set l) (x : A) → A</code>, but what is the sort of this type?</li>
</ul>
<p>To answer the former question, Agda has a special-purpose solver to solve equalities and inequalities between arbitrary expressions of type <code>Level</code>, but I won’t say more about it here. The second question is what interests us here: since the sort of this type cannot be <code>Set l</code> for any level <code>l</code>, Agda introduces a new sort <code>Setω</code> which is different from any <code>Set l</code>, and it tells us that <code>(l : Level) (A : Set l) (x : A) → A : Setω</code>. So <code>Setω</code> can be thought of as a sort that’s bigger than <code>Set l</code> for any level <code>l</code>.</p>
<p>To extend the theory of pure type systems to universe polymorphism, we now need to consider ‘dependent pts rules’ of the form <code>(x : _ : s1, s2, s3)</code> where <code>s2</code> can depend on the variable <code>x</code>. We do not care about the type of <code>x</code>, but only about the fact that this type should be in <code>s1</code>. Concretely, the new dependent pts rule for <code>Setω</code> is <code>(x : _ : s , s' , Setω)</code> whenever <code>s'</code> is dependent on <code>x</code>. On the other hand, when <code>s'</code> is not dependent on <code>x</code> we fall back to the regular ‘non-dependent’ pts rules.</p>
<h2 id="beyond-the-universe-hierarchy">Beyond the universe hierarchy</h2>
<p>By introducing universe polymorphism, we also have a first example of a sort which is not in the universe hierarchy of <code>Set l</code>: <code>Setω</code>. It turns out that considering sorts different from any <code>Set l</code> can actually be very useful: we can encode some additional properties of a type in its sort, or we can restrict what the user is allowed to do with types of a certain sort by restricting the pts rules. Here are a few examples which I think would be very nice to have in Agda:</p>
<ul>
<li>We could add a <code>Prop</code> sort to Agda which consists of <em>definitionally proof-irrelevant</em> types (in contrast to <code>Prop</code> in Coq, which is at best propositionally proof-irrelevant). See <a href="https://gist.githubusercontent.com/jespercockx/d7e0885f2078e0c0a54de99117226ac4/raw/da623c143c8922a8459ba136075e6be506b6ba28/PropRezz.agda">PropRezz.agda</a> for a quick demo of the possibilities.</li>
<li>Sized types make use of a type <code>Size</code> to prove termination in a modular way, but there are some operations that are not permitted on function types ending in <code>Size</code>. These properties can be enforced by giving <code>Size</code> its own universe <code>SizeUniv</code>.</li>
<li>We could have a new option <code>--omega-in-omega</code> which makes Agda inconsistent by adding the axiom <code>Setω : Setω</code>, similar to <code>--type-in-type</code> but without collapsing the whole universe hierarchy. This should make it easier to do some ‘unsafe’ things which require <code>--type-in-type</code> without destroying compatibility with standard universe-polymorphic Agda code.</li>
<li>Similarly to <code>Prop</code>, we could also add a universe <code>SSet</code> of <em>strict sets</em>, i.e. types for which the identity type is a <code>Prop</code>. In particular, these types should satisfy the definitional <code>K</code> rule stating that any proof of <code>x ≡ x</code> is <em>definitionally</em> equal to <code>refl</code>.</li>
<li>Finally (and most ambitiously) it would be very interesting to add a sort of <em>non-fibrant types</em> to make Agda into a two-level type theory like Voevodsky’s Homotopy Type System (HTS). The basic idea is that the non-fibrant types serve as an internalization of the metatheory of the fibrant types, which allows us to do all kinds of crazy meta-level things in the language itself. In particular, the first level may satisfy univalence and the second level may satisfy UIP; by separating the sorts we can make sure that this doesn’t lead to inconsistencies. You can read more about two-level type systems in <a href="https://hott-uf.github.io/2017/abstracts/twoleveltt.pdf">Formalisations Using Two-Level Type Theory</a> by Danil Annenkov, Paolo Capriotti, and Nicolai Kraus.</li>
</ul>
<p>Making room in Agda’s architecture for all of these new sorts was the main motivation for me to start working on a new implementation of Agda’s sort system.</p>
<h2 id="meta-levels-and-meta-sorts">Meta levels and meta sorts</h2>
<p>When typechecking an Agda program, we frequently have to check that some expression is a valid type without knowing what sort it has. Up until recently, Agda always assumed that any unknown sort was of the form <code>Set _l</code> for some metavariable <code>_l : Level</code>. You may have noticed that <code>Setω</code> is already not of this form, so there used to be some hacks to make this assumption work anyway (specifically, the metavariable <code>_l</code> was instantiated with the ill-typed solution <code>Setω</code> and there was a computation rule <code>Set Setω ---&gt; Setω</code>. It was horrible.)</p>
<p>To get rid of this assumption that any sort is of the form <code>Set _</code>, I added a new constructor to Agda’s internal representation of sorts for a sort metavariable or <strong>sort meta</strong> for short, representing an as of yet unknown sort. These sort metas can then be solved by the constraint solver just like regular (term) metas. Nice and tidy.</p>
<p>However, there’s a complication: we often have to determine the sort of a function type with domain in sort <code>s1</code> and codomain in sort <code>s2</code>, when <code>s1</code> and/or <code>s2</code> are still unknown. For example, what’s the sort of <code>(l : Level) → Set (_1 l)</code> where <code>_1</code> is a metavariable of type <code>Level → Level</code>? It could be e.g. <code>Setω</code> if <code>_1</code> is the identity function, or <code>Set</code> if <code>_1</code> is the constant function <code>lzero</code>. Similarly, we may want to get the sort ‘one level up’ from a given sort <code>s</code>, but <code>s</code> is still unknown. Introducing more new sort metas in those cases is not ideal, as we actually use those operations <strong>a lot</strong>, so we would get insane numbers of metavariables. Also, it would be quite tricky to keep track of all the dependencies between the different sort metas.</p>
<p>Instead, I opted to introduce two extra constructors <code>PiSort s1 s2</code> and <code>UnivSort s</code> for the sort of a function type and the sort of another sort respectively (for the connoisseurs: <code>PiSort</code> is similar to the old <code>DLub</code> sort). These constructors do not represent new sorts but instead they <em>compute</em> to the right sort once their arguments are known. For example, <code>PiSort Level (\l. Set l)</code> evaluates to <code>Setω</code>, <code>PiSort (Set l) (\_. Set l')</code> evaluates to <code>Set (l ⊔ l')</code> and <code>UnivSort (Set l)</code> evaluates to <code>Set (lsuc l)</code>. Not every <code>PiSort</code> or <code>UnivSort</code> is well-defined, for example <code>Setω</code> does not have a <code>UnivSort</code> since there is no bigger sort than <code>Setω</code>. So the <code>PiSort</code> and <code>UnivSort</code> constructors are accompanied by two new <em>constraints</em> <code>HasBiggerSort s</code> and <code>HasPTSRule s1 s2</code>. Constraints are Agda’s way of handling postponement of certain problems, such as the <code>ValueCmp</code> constraint which enforces two terms are equal. These two new constraints in particular ensure that no occurrence of <code>PiSort</code> or <code>UnivSort</code> will be stuck forever but each will compute to a proper sort eventually (or else Agda will report ‘unsolved constraints’).</p>
<p>So that’s it: the design of Agda’s new sort system. It has already been merged into the main Agda repository, so if you are still hungry for more details you can take a look there. Specifically:</p>
<ul>
<li><a href="https://github.com/agda/agda/blob/master/src/full/Agda/Syntax/Internal.hs#L212">Agda.Syntax.Internal</a>: the Sort datatype used for the internal representation of sorts</li>
<li><a href="https://github.com/agda/agda/blob/dbcee417486f52bd6e17315e15cbb26b17e485e4/src/full/Agda/TypeChecking/Substitute.hs#L1212">Agda.TypeChecking.Substitute</a>: basic functions defining the axioms and rules of Agda’s pts</li>
<li><a href="https://github.com/agda/agda/blob/master/src/full/Agda/TypeChecking/Conversion.hs#L1095">Agda.TypeChecking.Conversion</a>: solving equalities and inequalities between sorts</li>
<li><a href="https://github.com/agda/agda/blob/dbcee417486f52bd6e17315e15cbb26b17e485e4/src/full/Agda/TypeChecking/Monad/Base.hs#L793">Agda.TypeChecking.Monad.Base</a>: two new constraints <code>HasBiggerSort</code> and <code>HasPTSRule</code> were added to the <code>Constraint</code> datatype</li>
<li><a href="https://github.com/agda/agda/blob/master/src/full/Agda/TypeChecking/Sort.hs">Agda.TypeChecking.Sort</a>: functions for solving these constraints</li>
</ul>
<p>At the moment I’m working on implementing <code>Prop</code> for Agda and hopefully more new sorts will follow after that, so stay tuned!</p>
<h2 id="towards-cumulativity-for-agda">Towards cumulativity for Agda?</h2>
<p>One of the most requested features for Agda is cumulativity, i.e. the subtyping rule <code>Set i &lt;: Set j</code> for <code>i &lt; j</code>, so it would be amiss to talk about sorts in Agda without mentioning it. And indeed, there are many cases where cumulativity would make writing Agda code a lot easier and less frustrating! However, as far as I can tell no-one has really figured out how to combine Agda-style universe polymorphism with cumulativity, so it is still an open problem.</p>
<p>The closest working example is Coq, which sports both a cumulative hierarchy of universes and universe polymorphism (see <a href="https://www.irif.fr/~sozeau/research/publications/Universe_Polymorphism_in_Coq.pdf">this paper by Matthieu Sozeau and Nicolas Tabareau</a>). But there are some limitations compared to what we would want to have in Agda:</p>
<ul>
<li>Coq only allows top-level definitions to be quantified over levels, and thus it doesn’t require a sort like <code>Setω</code>. But in Agda we can quantify over universe-polymorphic types which are in <code>Setω</code>! See <a href="http://www.cse.chalmers.se/~nad/listings/equality/Equality.html#3238">this code by Nils Anders Danielsson</a> for an example where this is actually used.</li>
<li>Coq doesn’t guarantee the uniqueness of metavariable solutions, but this uniqueness is a core design principle of Agda. So we expect that simply adding cumulativity to Agda will result in lots and lots of unsolved metavariables, unless we have some way to mitigate this.</li>
</ul>
<p>While my refactoring of the sort system certainly does not enable cumulativity directly, it allows for some new possibilities to experiment with. I’m planning to do some of this experimentation during the next <a href="http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Main.AIMXXVII">Agda meeting in Göteborg</a> 4 – 9 June 2018. So if you’re interested to work on this (or on any other part of Agda) you are very welcome to come and join us!</p>
</article>

        </main>

        <footer>
            Site proudly generated by
            <a href="http://jaspervdj.be/hakyll">Hakyll</a>
        </footer>
    </body>
</html>
]]></description>
    <pubDate>Thu, 03 May 2018 00:00:00 UT</pubDate>
    <guid>https://jesper.sikanda.be/posts/agdas-new-sorts.html</guid>
    <dc:creator>Jesper Cockx</dc:creator>
</item>

    </channel>
</rss>
