<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"><channel><title>Bob Atkey's blog</title><link>https://bentnib.org</link><description>Bob Atkey's blog</description><item><title>More Data Types with Negation at Fun in the REPL</title><link>https://bentnib.org/posts/2023-11-02-more-data-types-with-negation.html</link><description>&lt;p&gt;Yesterday I had a lovely day at &lt;a href=&quot;https://plrg-bristol.github.io/fir/&quot;&gt;Fun in the REPL&lt;/a&gt; in Bristol.&lt;/p&gt;&lt;p&gt;Alex Kavvos invited me to give a talk, so I decided to give an updated and extended version of the &lt;a href=&quot;https://bentnib.org2023-01-15-datatypes-with-negation.html&quot;&gt;Data types with Negation&lt;/a&gt; talk I gave a few times last year.&lt;/p&gt;&lt;p&gt;I've got a bit further in working out how to analyse the semantics of a data type with negation, but seeing an analogy with the solutions of mixed-variance domain equations.&lt;/p&gt;&lt;p&gt;Here are the slides I used:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/docs/data-types-with-negation-20231101.pdf&quot;&gt;&lt;img alt=&quot;Thumbnail of slides for “Data Types with Negation” talk given at Fun in the REPL on 1st November 2023&quot; src=&quot;https://bentnib.org/thumbnails/slides-data-types-with-negation-20231101.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2023-11-02-more-data-types-with-negation.html</guid><pubDate>Thu, 02 Nov 2023 00:00:00 +0000</pubDate></item><item><title>Compiling higher-order specifications to SMT solvers</title><link>https://bentnib.org/posts/2023-01-17-higher-order-specs-to-smt.html</link><description>&lt;p&gt;I just gave a talk at &lt;a href=&quot;https://popl23.sigplan.org/home/CPP-2023&quot;&gt;Certified Programs and Proofs&lt;/a&gt; on our paper &lt;a href=&quot;https://bentnib.org/hospec-smt.html&quot;&gt;Compiling higher-order specifications to SMT solvers&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Slides:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/docs/hospec-smt-20230117.pdf&quot;&gt;&lt;img alt=&quot;Thumbnail of slides for “Compiling higher-order specifications to SMT solvers” talk&quot; src=&quot;https://bentnib.org/thumbnails/slides-hospec-smt-20230117.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;It is a description of the type based analysis approach that we use in the &lt;a href=&quot;https://github.com/vehicle-lang/vehicle&quot;&gt;Vehicle&lt;/a&gt; specification language to discover when the queries that a user writes are actually translatable to an SMT solver. Based on this type based analysis we either give the user a nice error message, or we use a Normalisation by Evaluation (NbE) procedure to normalise the query to one suitable for the solver. The NbE procedure is itself non-trivial to support lifting of uninterpreted functions and if-then-elses. The NbE procedure has been &lt;a href=&quot;https://github.com/vehicle-lang/vehicle-formalisation&quot;&gt;formalised in Agda&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Unfortunately the talk wasn't under the best of circumstances. I am in Boston for the conference, but tested positive for COVID yesterday morning. I had to give the talk from my hotel room 10 floors above the conference, which I think is possibly the worst way to give a talk.&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2023-01-17-higher-order-specs-to-smt.html</guid><pubDate>Tue, 17 Jan 2023 00:00:00 +0000</pubDate></item><item><title>Simple semantics for defaults in Catala</title><link>https://bentnib.org/posts/2023-01-16-catala.html</link><description>&lt;p&gt;&lt;a href=&quot;https://catala-lang.org&quot;&gt;Catala&lt;/a&gt; is a programming language for the law.&lt;/p&gt;&lt;p&gt;As &lt;a href=&quot;https://dl.acm.org/doi/10.1145/3473582&quot;&gt;described in an ICFP 2021 paper by Merigoux et al.&lt;/a&gt;, Catala has multiple features designed for making it easy to write code that implements legal texts.&lt;/p&gt;&lt;p&gt;The feature I want to talk about here is Catala's support for default reasoning.&lt;/p&gt;&lt;p&gt;Default reasoning involves rules like “X is the case, except when Y, Z, ...”. Apparently, such patterns are common in the law.&lt;/p&gt;&lt;p&gt;The ICFP paper points out that default reasoning is analogous to exceptions in normal programming languages. The paper describes how to translate default reasoning into exceptions.&lt;/p&gt;&lt;p&gt;I think that a good way to see how it works is in terms of a simple “exceptions monad”.&lt;/p&gt;&lt;h4&gt;Default Calculus&lt;/h4&gt;&lt;p&gt;The authors define the “default calculus”, which is the λ-calculus extended with constants for undefinedness and conflict and a default operator.&lt;/p&gt;&lt;p&gt;The default operator looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;〈e1, ..., en | j :- c〉
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where the intended meaning is “if &lt;code&gt;j&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt; then evaluate to &lt;code&gt;c&lt;/code&gt; and if &lt;code&gt;j&lt;/code&gt; is undefined or &lt;code&gt;false&lt;/code&gt; then evaluate to undefined, &lt;em&gt;unless&lt;/em&gt; any of &lt;code&gt;e1&lt;/code&gt; to &lt;code&gt;en&lt;/code&gt; are defined, in which case if exactly one &lt;code&gt;ei&lt;/code&gt; is defined then evaluate to &lt;code&gt;ei&lt;/code&gt;, if more than one is defined then evaluate to conflict”.&lt;/p&gt;&lt;p&gt;The Catala ICFP paper defines an operational semantics for the default operator. The authors give a translation into a λ-calculus with exceptions. They have proved the translation correct using &lt;a href=&quot;http://fstar-lang.org/&quot;&gt;F star&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt;Catala values&lt;/h4&gt;&lt;p&gt;I think a more perspicious way of looking at how the default operator works is to think of it in terms of a simple monad.&lt;/p&gt;&lt;p&gt;I'll use &lt;a href=&quot;https://ocaml.org&quot;&gt;OCaml&lt;/a&gt; syntax.&lt;/p&gt;&lt;p&gt;A “Catala value” is either &lt;code&gt;Conflict&lt;/code&gt;, &lt;code&gt;Undefined&lt;/code&gt; or an actual &lt;code&gt;Value&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; 'a catala &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
  &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Conflict
  &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Undefined
  &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Value &lt;span class=&quot;ocamlkeyword&quot;&gt;of&lt;/span&gt; 'a
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This definition is basically the &lt;code&gt;Maybe&lt;/code&gt;/&lt;code&gt;option&lt;/code&gt;/exceptions monad with two exception values.&lt;/p&gt;&lt;p&gt;There is an “information” ordering on Catala values, with &lt;code&gt;Undefined&lt;/code&gt; at the bottom, &lt;code&gt;Conflict&lt;/code&gt; at the top, and the &lt;code&gt;Value&lt;/code&gt;s in between.&lt;/p&gt;&lt;p&gt;I'll not use the monad structure much, but we can decompose Catala's default operator into three simpler operators on Catala values.&lt;/p&gt;&lt;p&gt;The first is a conflict-adverse combination operator, which can be used to combine two Catala values into one:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;&amp;lt;&lt;/span&gt;+&lt;span class=&quot;ocamlsymbol&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; x y &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;match&lt;/span&gt; x&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; y &lt;span class=&quot;ocamlkeyword&quot;&gt;with&lt;/span&gt;
  &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Undefined&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; x &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; x&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; Undefined &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; x
  &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Conflict&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; Conflict &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; Conflict
  &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Value &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; Value &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; Conflict
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;Undefined&lt;/code&gt; always loses, &lt;code&gt;Conflict&lt;/code&gt; always wins, and two attempts at a value (even if they are equal) results in conflict.&lt;/p&gt;&lt;p&gt;This is a commutative monoid with &lt;code&gt;Undefined&lt;/code&gt; as the unit, and it is monotone in both arguments.&lt;/p&gt;&lt;p&gt;It'll be useful to be able to combine a list of Catala values using &lt;code&gt;&amp;lt;+&gt;&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; combine_list xs &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
  List&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;fold_left &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;&amp;lt;&lt;/span&gt;+&lt;span class=&quot;ocamlsymbol&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; Undefined xs
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;guard&lt;/code&gt; operator is a sort of gate that evaluates to its second argument if the first is &lt;code&gt;true&lt;/code&gt;, and undefined otherwise (unless there was a conflict).&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; guard x y &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;match&lt;/span&gt; x &lt;span class=&quot;ocamlkeyword&quot;&gt;with&lt;/span&gt;
  &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Conflict &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; Conflict
  &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Value true &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; y
  &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Value false
  &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Undefined &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; Undefined
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is also monotone in both arguments.&lt;/p&gt;&lt;p&gt;Finally, the &lt;code&gt;unless&lt;/code&gt; operator acts like a backwards try-catch. &lt;code&gt;unless x y&lt;/code&gt; defaults to &lt;code&gt;x&lt;/code&gt; unless &lt;code&gt;y&lt;/code&gt; is defined or is in conflict. Operationally, it tries &lt;code&gt;y&lt;/code&gt; first, and if it throws the &lt;code&gt;Undefined&lt;/code&gt; exception &lt;code&gt;x&lt;/code&gt; is used instead.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; unless x y &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;match&lt;/span&gt; y &lt;span class=&quot;ocamlkeyword&quot;&gt;with&lt;/span&gt;
  &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Conflict &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; Conflict
  &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Undefined &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; x
  &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Value y &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; Value y
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is &lt;em&gt;not&lt;/em&gt; monotone in its second argument.&lt;/p&gt;&lt;p&gt;With these operators, we can recover Catala's default operator. It defaults to a guarded value, unless an exception is defined. In the event of multiple potential definitions, conflict is signaled.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; default value ~justification ~exceptions &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
  unless &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;guard justification value&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;combine_list exceptions&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I think this gives a simpler account of Catala's default operator than the ICFP paper.&lt;/p&gt;&lt;p&gt;We can see that the non-monotone behaviour of the default operator arises from the &lt;code&gt;unless&lt;/code&gt; operator, which you might expect from a try-catch like operator that rescues definition from undefinedness.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;unless&lt;/code&gt; operator is a kind of “try this if that didn't work” operator, like exception handling and ordered choice in PEGs. I reckon that a &lt;a href=&quot;https://bentnib.org2023-01-15-datatypes-with-negation.html&quot;&gt;semantics of data types with negation&lt;/a&gt; would be helpful in understanding such operators by recording “that didn't work” as a negation.&lt;/p&gt;&lt;p&gt;Some questions.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Why is it a &lt;code&gt;Conflict&lt;/code&gt; to combine two values that are equal? I think that Catala thinks of &lt;code&gt;Conflict&lt;/code&gt; as a mistake in the code or in the drafting of the law. But if there is a conflict that has no effect, then is that bad? What if a Catala value was a set of possible outcomes?&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;This formulation must be easier to reason about in a theorem prover than the ICFP paper's operational semantics or exception-based implementation.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;What is the connection to &lt;a href=&quot;https://en.wikipedia.org/wiki/Default_logic&quot;&gt;Default Logic&lt;/a&gt;? The Catala paper states that the default operator is based on &lt;a href=&quot;https://link.springer.com/chapter/10.1007/978-94-015-9383-0_3&quot;&gt;prioritised default logic&lt;/a&gt;, but doesn't elaborate on the formal relationship. Catala is focused on &lt;em&gt;definitions&lt;/em&gt;, and rules are treated as a boolean-valued definitions. But default logic only deals in rules?&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The Catala implementation &lt;a href=&quot;https://github.com/CatalaLang/catala/blob/master/compiler/lcalc/compile_without_exceptions.ml&quot;&gt;seems to have a “without exceptions” translation&lt;/a&gt; but it seems more complicated than what I've written above. What is the connection?&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2023-01-16-catala.html</guid><pubDate>Mon, 16 Jan 2023 00:00:00 +0000</pubDate></item><item><title>Data types with Negation</title><link>https://bentnib.org/posts/2023-01-15-datatypes-with-negation.html</link><description>&lt;p&gt;Back in April and June last year, at MSFP and at TYPES, I gave talks about some work I've done on trying to understand what it would mean to allow negation in data type definitions.&lt;/p&gt;&lt;p&gt;The gist of the talk is: what if we could define a predicate for even numbers like this in Agda (or Coq or Idris or Lean):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;data Even : Nat → Set where
  zero : Even 0
  suc  : ∀ {n} → not (Even n) → Even (suc n)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So &lt;code&gt;0&lt;/code&gt; is even, and &lt;code&gt;suc n&lt;/code&gt; is even if &lt;code&gt;n&lt;/code&gt; isn't.&lt;/p&gt;&lt;p&gt;But if we get this to work, then what would this declaration mean?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;data Liar : Set where
  liar : not Liar → Liar
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I think that data types with negation will be useful for describing the sequences of decisions taken by back tracking algorithms. For example, a PEG parser's ordered choice &lt;code&gt;A / B&lt;/code&gt; means “try &lt;code&gt;A&lt;/code&gt;, and &lt;em&gt;if that doesn't work&lt;/em&gt; try &lt;code&gt;B&lt;/code&gt;”. We need some kind of negation to capture the meaning of “&lt;em&gt;if that doesn't work&lt;/em&gt;”.&lt;/p&gt;&lt;p&gt;The solution I have at the moment is a proof relevant version of the well founded semantics of logic programs with negation, which is related to the stable model semantics used in Answer Set Programming. The key step is to replace the 3-valued logic used in the well founded semantics with Chu spaces.&lt;/p&gt;&lt;p&gt;I'm still working out the best way to present the theory, and what reasoning principles these data types have, but these slides are the best presentation I have so far.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/docs/datatypes-with-negation-20220623.pdf&quot;&gt;&lt;img alt=&quot;Thumbnail of slides for “Data types with Negation” talk&quot; src=&quot;https://bentnib.org/thumbnails/slides-datatypes-with-negation-20220623.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2023-01-15-datatypes-with-negation.html</guid><pubDate>Sun, 15 Jan 2023 00:00:00 +0000</pubDate></item><item><title>Slides and Video for “Resource Constrained Programming with Full Dependent Types”</title><link>https://bentnib.org/posts/2020-11-23-resource-constrained.html</link><description>&lt;p&gt;Last Friday, I gave a talk (virtually) at the &lt;a href=&quot;https://the-au-forml-lab.github.io/colloquium.html&quot;&gt;CCS Colloquim&lt;/a&gt; at Augusta University, hosted by &lt;a href=&quot;https://metatheorem.org/&quot;&gt;Harley Eades III&lt;/a&gt;. The title was “Resource Constrained Programming with Full Dependent Types” and the abstract was:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;I will talk about a system that combines Dependent Types and Linear Types. As an application of this system, I will show how to transport Martin Hofmann’s LFPL and Amortised Resource analysis systems for linear and polynomial time computation to full dependent types. This results in a system where unconstrained computations are permitted at the type level, but only polynominal time computations are permitted at the term level. The combined system now allows one to explore the world of propositions whose proofs are not only constructive, but also of restricted complexity.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;The talk was recorded, and the video is &lt;a href=&quot;https://www.youtube.com/watch?v=MhYbLS6XiZo&quot;&gt;on YouTube&lt;/a&gt;. The slides:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/docs/qtt-forml-20201120.pdf&quot;&gt;&lt;img alt=&quot;Thumbnail of slides for “Resource Constrained Programming with Full Dependent Types” talk&quot; src=&quot;https://bentnib.org/thumbnails/slides-qtt-forml-20201120.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2020-11-23-resource-constrained.html</guid><pubDate>Mon, 23 Nov 2020 00:00:00 +0000</pubDate></item><item><title>Quantitative Typing with Non-idempotent Intersection Types</title><link>https://bentnib.org/posts/2020-08-13-non-idempotent-intersection-types.html</link><description>&lt;p&gt;This post contains a development of an Agda proof that, for the Call-by-Name (CBN) λ-calculus, the number of steps needed to reduce a term to weak head normal form (WHNF) in the Krivine Abstract Machine (KAM) is equal to the size of the term's typing derivation in a non-idempotent intersection type system.&lt;/p&gt;&lt;p&gt;The inverse also holds: if a term reduces to WHNF in the KAM, then it has a typing derivation, the size of which is equal to the number of steps it takes to reduce the term. Therefore, typability characterises termination, quantitatively.&lt;/p&gt;&lt;p&gt;The main result manifests as a “quantitative” subject reduction lemma: not only is typing preserved by each reduction step, but the size of the typing derivation goes down by exactly one in each step.&lt;/p&gt;&lt;p&gt;Non-idempotent intersection types can also be seen as a syntactic presentation of a denotational semantics of untyped λ-calculus in the category Rel of sets and relations for a particular reflexive object. The fact that subject reduction (and expansion) have a quantitative aspectyields a proof of adequacy for this semantics that doesn't rely on logical relations (I've haven't proved this in this file though).&lt;/p&gt;&lt;p&gt;The quantitative nature of non-idempotent intersection types was originally observed for head normalisation by Daniel de Carvalho in &lt;a href=&quot;https://arxiv.org/abs/0905.4251&quot;&gt;Execution Time of lambda-Terms via Denotational Semantics and Intersection Types&lt;/a&gt;.&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;1561&quot; class=&quot;Keyword&quot;&gt;module&lt;/a&gt; &lt;a id=&quot;1568&quot; href=&quot;non-idempotent-intersection-types.html&quot; class=&quot;Module&quot;&gt;non-idempotent-intersection-types&lt;/a&gt; &lt;a id=&quot;1602&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
&lt;/pre&gt;
&lt;h3&gt;Imports&lt;/h3&gt;&lt;p&gt;First we need some things from the Agda standard library:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;1692&quot; class=&quot;Keyword&quot;&gt;open&lt;/a&gt; &lt;a id=&quot;1697&quot; class=&quot;Keyword&quot;&gt;import&lt;/a&gt; &lt;a id=&quot;1704&quot; href=&quot;Data.Nat.html&quot; class=&quot;Module&quot;&gt;Data.Nat&lt;/a&gt; &lt;a id=&quot;1713&quot; class=&quot;Keyword&quot;&gt;using&lt;/a&gt; &lt;a id=&quot;1719&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;1720&quot; href=&quot;Agda.Builtin.Nat.html#192&quot; class=&quot;Datatype&quot;&gt;ℕ&lt;/a&gt;&lt;a id=&quot;1721&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1723&quot; href=&quot;Agda.Builtin.Nat.html#210&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;1727&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1729&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt;&lt;a id=&quot;1732&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1734&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;_+_&lt;/a&gt;&lt;a id=&quot;1737&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;1739&quot; class=&quot;Keyword&quot;&gt;open&lt;/a&gt; &lt;a id=&quot;1744&quot; class=&quot;Keyword&quot;&gt;import&lt;/a&gt; &lt;a id=&quot;1751&quot; href=&quot;Data.Nat.Properties.html&quot; class=&quot;Module&quot;&gt;Data.Nat.Properties&lt;/a&gt; &lt;a id=&quot;1771&quot; class=&quot;Keyword&quot;&gt;using&lt;/a&gt; &lt;a id=&quot;1777&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;1778&quot; href=&quot;Data.Nat.Properties.html#12490&quot; class=&quot;Function&quot;&gt;+-assoc&lt;/a&gt;&lt;a id=&quot;1785&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1787&quot; href=&quot;Data.Nat.Properties.html#12823&quot; class=&quot;Function&quot;&gt;+-comm&lt;/a&gt;&lt;a id=&quot;1793&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1795&quot; href=&quot;Data.Nat.Properties.html#12646&quot; class=&quot;Function&quot;&gt;+-identityʳ&lt;/a&gt;&lt;a id=&quot;1806&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1808&quot; href=&quot;Data.Nat.Properties.html#1607&quot; class=&quot;Function&quot;&gt;suc-injective&lt;/a&gt;&lt;a id=&quot;1821&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;1823&quot; class=&quot;Keyword&quot;&gt;open&lt;/a&gt; &lt;a id=&quot;1828&quot; class=&quot;Keyword&quot;&gt;import&lt;/a&gt; &lt;a id=&quot;1835&quot; href=&quot;Data.Fin.html&quot; class=&quot;Module&quot;&gt;Data.Fin&lt;/a&gt; &lt;a id=&quot;1844&quot; class=&quot;Keyword&quot;&gt;using&lt;/a&gt; &lt;a id=&quot;1850&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;1851&quot; href=&quot;Data.Fin.Base.html#1066&quot; class=&quot;Datatype&quot;&gt;Fin&lt;/a&gt;&lt;a id=&quot;1854&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1856&quot; href=&quot;Data.Fin.Base.html#1088&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;1860&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1862&quot; href=&quot;Data.Fin.Base.html#1119&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt;&lt;a id=&quot;1865&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1867&quot; href=&quot;Data.Fin.Properties.html#2258&quot; class=&quot;Function Operator&quot;&gt;_≟_&lt;/a&gt;&lt;a id=&quot;1870&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;1872&quot; class=&quot;Keyword&quot;&gt;open&lt;/a&gt; &lt;a id=&quot;1877&quot; class=&quot;Keyword&quot;&gt;import&lt;/a&gt; &lt;a id=&quot;1884&quot; href=&quot;Data.Product.html&quot; class=&quot;Module&quot;&gt;Data.Product&lt;/a&gt; &lt;a id=&quot;1897&quot; class=&quot;Keyword&quot;&gt;using&lt;/a&gt; &lt;a id=&quot;1903&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;1904&quot; href=&quot;Data.Product.html#916&quot; class=&quot;Function&quot;&gt;Σ-syntax&lt;/a&gt;&lt;a id=&quot;1912&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1914&quot; href=&quot;Data.Product.html#1167&quot; class=&quot;Function Operator&quot;&gt;_×_&lt;/a&gt;&lt;a id=&quot;1917&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1919&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;_,_&lt;/a&gt;&lt;a id=&quot;1922&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1924&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;1929&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1931&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;1936&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;1938&quot; class=&quot;Keyword&quot;&gt;open&lt;/a&gt; &lt;a id=&quot;1943&quot; class=&quot;Keyword&quot;&gt;import&lt;/a&gt; &lt;a id=&quot;1950&quot; href=&quot;Data.List.html&quot; class=&quot;Module&quot;&gt;Data.List&lt;/a&gt; &lt;a id=&quot;1960&quot; class=&quot;Keyword&quot;&gt;using&lt;/a&gt; &lt;a id=&quot;1966&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;1967&quot; href=&quot;Agda.Builtin.List.html#148&quot; class=&quot;Datatype&quot;&gt;List&lt;/a&gt;&lt;a id=&quot;1971&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1973&quot; href=&quot;Data.List.Base.html#9701&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt;&lt;a id=&quot;1975&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1977&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;_∷_&lt;/a&gt;&lt;a id=&quot;1980&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1982&quot; href=&quot;Data.List.Base.html#1763&quot; class=&quot;Function Operator&quot;&gt;_++_&lt;/a&gt;&lt;a id=&quot;1986&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;1988&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;[_]&lt;/a&gt;&lt;a id=&quot;1991&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;1993&quot; class=&quot;Keyword&quot;&gt;import&lt;/a&gt; &lt;a id=&quot;2000&quot; href=&quot;Relation.Binary.PropositionalEquality.html&quot; class=&quot;Module&quot;&gt;Relation.Binary.PropositionalEquality&lt;/a&gt; &lt;a id=&quot;2038&quot; class=&quot;Symbol&quot;&gt;as&lt;/a&gt; &lt;a id=&quot;2041&quot; class=&quot;Module&quot;&gt;Eq&lt;/a&gt;
&lt;a id=&quot;2044&quot; class=&quot;Keyword&quot;&gt;open&lt;/a&gt; &lt;a id=&quot;2049&quot; href=&quot;Relation.Binary.PropositionalEquality.html&quot; class=&quot;Module&quot;&gt;Eq&lt;/a&gt; &lt;a id=&quot;2052&quot; class=&quot;Keyword&quot;&gt;using&lt;/a&gt; &lt;a id=&quot;2058&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;2059&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;_≡_&lt;/a&gt;&lt;a id=&quot;2062&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;2064&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt;&lt;a id=&quot;2068&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;2070&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1025&quot; class=&quot;Function&quot;&gt;trans&lt;/a&gt;&lt;a id=&quot;2075&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;2077&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt;&lt;a id=&quot;2081&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;2083&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1076&quot; class=&quot;Function&quot;&gt;subst&lt;/a&gt;&lt;a id=&quot;2088&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;2090&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#980&quot; class=&quot;Function&quot;&gt;sym&lt;/a&gt;&lt;a id=&quot;2093&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;2095&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#840&quot; class=&quot;Function Operator&quot;&gt;_≢_&lt;/a&gt;&lt;a id=&quot;2098&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;2100&quot; href=&quot;Relation.Binary.PropositionalEquality.html#1524&quot; class=&quot;Function&quot;&gt;cong₂&lt;/a&gt;&lt;a id=&quot;2105&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;2107&quot; class=&quot;Keyword&quot;&gt;open&lt;/a&gt; &lt;a id=&quot;2112&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2419&quot; class=&quot;Module&quot;&gt;Eq.≡-Reasoning&lt;/a&gt; &lt;a id=&quot;2127&quot; class=&quot;Keyword&quot;&gt;using&lt;/a&gt; &lt;a id=&quot;2133&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;2134&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2517&quot; class=&quot;Function Operator&quot;&gt;begin_&lt;/a&gt;&lt;a id=&quot;2140&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;2142&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2575&quot; class=&quot;Function Operator&quot;&gt;_≡⟨⟩_&lt;/a&gt;&lt;a id=&quot;2147&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;2149&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;step-≡&lt;/a&gt;&lt;a id=&quot;2155&quot; class=&quot;Symbol&quot;&gt;;&lt;/a&gt; &lt;a id=&quot;2157&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2816&quot; class=&quot;Function Operator&quot;&gt;_∎&lt;/a&gt;&lt;a id=&quot;2159&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;/pre&gt;
&lt;h3&gt;Untyped λ-calculus&lt;/h3&gt;&lt;p&gt;The syntax of the programming language we will look at is the same as the usual untyped λ-calculus. I've opted for an intrinsically well-scoped de Bruijn representation:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;2368&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;term&quot;&gt;&lt;/a&gt;&lt;a id=&quot;2373&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;2378&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;2380&quot; href=&quot;Agda.Builtin.Nat.html#192&quot; class=&quot;Datatype&quot;&gt;ℕ&lt;/a&gt; &lt;a id=&quot;2382&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;2384&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;2388&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
  &lt;a id=&quot;term.`_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;2396&quot; href=&quot;non-idempotent-intersection-types.html#2396&quot; class=&quot;InductiveConstructor Operator&quot;&gt;`_&lt;/a&gt;  &lt;a id=&quot;2400&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;2402&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;2404&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;2405&quot; href=&quot;non-idempotent-intersection-types.html#2405&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;2406&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;2408&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;2410&quot; href=&quot;Data.Fin.Base.html#1066&quot; class=&quot;Datatype&quot;&gt;Fin&lt;/a&gt; &lt;a id=&quot;2414&quot; href=&quot;non-idempotent-intersection-types.html#2405&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;2416&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;2418&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;2423&quot; href=&quot;non-idempotent-intersection-types.html#2405&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;
  &lt;a id=&quot;term.ƛ&quot;&gt;&lt;/a&gt;&lt;a id=&quot;2427&quot; href=&quot;non-idempotent-intersection-types.html#2427&quot; class=&quot;InductiveConstructor&quot;&gt;ƛ&lt;/a&gt;   &lt;a id=&quot;2431&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;2433&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;2435&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;2436&quot; href=&quot;non-idempotent-intersection-types.html#2436&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;2437&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;2439&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;2441&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;2446&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;2447&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;2451&quot; href=&quot;non-idempotent-intersection-types.html#2436&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;2452&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;2454&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;2456&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;2461&quot; href=&quot;non-idempotent-intersection-types.html#2436&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;
  &lt;a id=&quot;term._·_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;2465&quot; href=&quot;non-idempotent-intersection-types.html#2465&quot; class=&quot;InductiveConstructor Operator&quot;&gt;_·_&lt;/a&gt; &lt;a id=&quot;2469&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;2471&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;2473&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;2474&quot; href=&quot;non-idempotent-intersection-types.html#2474&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;2475&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;2477&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;2479&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;2484&quot; href=&quot;non-idempotent-intersection-types.html#2474&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;2486&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;2488&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;2493&quot; href=&quot;non-idempotent-intersection-types.html#2474&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;2495&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;2497&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;2502&quot; href=&quot;non-idempotent-intersection-types.html#2474&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;

&lt;a id=&quot;2505&quot; class=&quot;Keyword&quot;&gt;infixl&lt;/a&gt; &lt;a id=&quot;2512&quot; class=&quot;Number&quot;&gt;20&lt;/a&gt; &lt;a id=&quot;2515&quot; href=&quot;non-idempotent-intersection-types.html#2465&quot; class=&quot;InductiveConstructor Operator&quot;&gt;_·_&lt;/a&gt;
&lt;a id=&quot;2519&quot; class=&quot;Keyword&quot;&gt;infix&lt;/a&gt; &lt;a id=&quot;2525&quot; class=&quot;Number&quot;&gt;40&lt;/a&gt; &lt;a id=&quot;2528&quot; href=&quot;non-idempotent-intersection-types.html#2396&quot; class=&quot;InductiveConstructor Operator&quot;&gt;`_&lt;/a&gt;
&lt;/pre&gt;
&lt;h3&gt;Krivine Abstract Machine&lt;/h3&gt;&lt;p&gt;The standard way to give an operational semantics to the untyped λ-calculus is to give a small step reduction relation where the main rule is β-reduction:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  (ƛ t) · t' ---&gt; t [ t' ]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However, our goal here is to measure the complexity of programs via typing and counting the number of β reductions is not a very convincing way of doing this. Substitution does a non-constant amount of work, depending on how big &lt;code&gt;t&lt;/code&gt; is and how often the &lt;code&gt;0&lt;/code&gt;th variable is used in it.&lt;/p&gt;&lt;p&gt;Instead, we want to use a semantics that performs a constant amount of work at each step. One way to do this is to use an abstract machine to interpret programs. Abstract machines break the complex process of β-reduction down into smaller steps, so they are more convincing ways to measure complexity.&lt;/p&gt;&lt;p&gt;The abstract machine we shall use here is the Krivine Abstract Machine (KAM), which implements reduction of λ terms to weak head normal form.&lt;/p&gt;&lt;p&gt;Rather than using substitution, the KAM uses &lt;em&gt;closures&lt;/em&gt;: pairs of a term and an &lt;em&gt;environment&lt;/em&gt; that assigns a closure to each variable in the term. As this description suggests, closures and environments are mutually defined:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;3729&quot; class=&quot;Keyword&quot;&gt;mutual&lt;/a&gt;
  &lt;a id=&quot;3738&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;env&quot;&gt;&lt;/a&gt;&lt;a id=&quot;3743&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;3747&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;3749&quot; href=&quot;Agda.Builtin.Nat.html#192&quot; class=&quot;Datatype&quot;&gt;ℕ&lt;/a&gt; &lt;a id=&quot;3751&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;3753&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;3757&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
    &lt;a id=&quot;env.nil&quot;&gt;&lt;/a&gt;&lt;a id=&quot;3767&quot; href=&quot;non-idempotent-intersection-types.html#3767&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;  &lt;a id=&quot;3772&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;3774&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;3778&quot; href=&quot;Agda.Builtin.Nat.html#210&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;
    &lt;a id=&quot;env._,-_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;3787&quot; href=&quot;non-idempotent-intersection-types.html#3787&quot; class=&quot;InductiveConstructor Operator&quot;&gt;_,-_&lt;/a&gt; &lt;a id=&quot;3792&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;3794&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;3796&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;3797&quot; href=&quot;non-idempotent-intersection-types.html#3797&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;3798&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;3800&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;3802&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;3806&quot; href=&quot;non-idempotent-intersection-types.html#3797&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;3808&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;3810&quot; href=&quot;non-idempotent-intersection-types.html#3831&quot; class=&quot;Function&quot;&gt;clo&lt;/a&gt; &lt;a id=&quot;3814&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;3816&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;3820&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;3821&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;3825&quot; href=&quot;non-idempotent-intersection-types.html#3797&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;3826&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;

  &lt;a id=&quot;clo&quot;&gt;&lt;/a&gt;&lt;a id=&quot;3831&quot; href=&quot;non-idempotent-intersection-types.html#3831&quot; class=&quot;Function&quot;&gt;clo&lt;/a&gt; &lt;a id=&quot;3835&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;3837&quot; href=&quot;Data.Product.html#916&quot; class=&quot;Function&quot;&gt;Σ[&lt;/a&gt; &lt;a id=&quot;3840&quot; href=&quot;non-idempotent-intersection-types.html#3840&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;3842&quot; href=&quot;Data.Product.html#916&quot; class=&quot;Function&quot;&gt;∈&lt;/a&gt; &lt;a id=&quot;3844&quot; href=&quot;Agda.Builtin.Nat.html#192&quot; class=&quot;Datatype&quot;&gt;ℕ&lt;/a&gt; &lt;a id=&quot;3846&quot; href=&quot;Data.Product.html#916&quot; class=&quot;Function&quot;&gt;]&lt;/a&gt; &lt;a id=&quot;3848&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;3852&quot; href=&quot;non-idempotent-intersection-types.html#3840&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;3854&quot; href=&quot;Data.Product.html#1167&quot; class=&quot;Function Operator&quot;&gt;×&lt;/a&gt; &lt;a id=&quot;3856&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;3861&quot; href=&quot;non-idempotent-intersection-types.html#3840&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;Note that environments are built by extending to the right.&lt;/p&gt;&lt;p&gt;The second ingredient for the KAM are stacks of closures. Stacks are used to remember the context within a program we are currently executing. Compare to the congruence rule used in the definition of CBN small step operational semantics:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;       M  --&gt;  M'
 ---------------------
  M · N  --&gt;  M' · N
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the rule, the context is the &lt;code&gt;N&lt;/code&gt; term, and in general we might have to go under several &lt;code&gt;N&lt;/code&gt;s to get to the part we are currently executing. The KAM uses a stack of closures to represent this:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;4450&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;stk&quot;&gt;&lt;/a&gt;&lt;a id=&quot;4455&quot; href=&quot;non-idempotent-intersection-types.html#4455&quot; class=&quot;Datatype&quot;&gt;stk&lt;/a&gt; &lt;a id=&quot;4459&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;4461&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;4465&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
  &lt;a id=&quot;stk.emp&quot;&gt;&lt;/a&gt;&lt;a id=&quot;4473&quot; href=&quot;non-idempotent-intersection-types.html#4473&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt;  &lt;a id=&quot;4478&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;4480&quot; href=&quot;non-idempotent-intersection-types.html#4455&quot; class=&quot;Datatype&quot;&gt;stk&lt;/a&gt;
  &lt;a id=&quot;stk._-,_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;4486&quot; href=&quot;non-idempotent-intersection-types.html#4486&quot; class=&quot;InductiveConstructor Operator&quot;&gt;_-,_&lt;/a&gt; &lt;a id=&quot;4491&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;4493&quot; href=&quot;non-idempotent-intersection-types.html#3831&quot; class=&quot;Function&quot;&gt;clo&lt;/a&gt; &lt;a id=&quot;4497&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;4499&quot; href=&quot;non-idempotent-intersection-types.html#4455&quot; class=&quot;Datatype&quot;&gt;stk&lt;/a&gt; &lt;a id=&quot;4503&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;4505&quot; href=&quot;non-idempotent-intersection-types.html#4455&quot; class=&quot;Datatype&quot;&gt;stk&lt;/a&gt;

&lt;a id=&quot;4510&quot; class=&quot;Keyword&quot;&gt;infixr&lt;/a&gt; &lt;a id=&quot;4517&quot; class=&quot;Number&quot;&gt;10&lt;/a&gt; &lt;a id=&quot;4520&quot; href=&quot;non-idempotent-intersection-types.html#21127&quot; class=&quot;InductiveConstructor Operator&quot;&gt;_-,_&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;Stacks are built by extending to the left.&lt;/p&gt;&lt;p&gt;A &lt;em&gt;configuration&lt;/em&gt; of the KAM is a pair of a closure, the current focus of the computation, and a stack representing the evaluation context. We use the special notation &lt;code&gt;⟨_⋆_⟩&lt;/code&gt; for configurations.&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;4779&quot; class=&quot;Keyword&quot;&gt;record&lt;/a&gt; &lt;a id=&quot;configuration&quot;&gt;&lt;/a&gt;&lt;a id=&quot;4786&quot; href=&quot;non-idempotent-intersection-types.html#4786&quot; class=&quot;Record&quot;&gt;configuration&lt;/a&gt; &lt;a id=&quot;4800&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;4802&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;4806&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
  &lt;a id=&quot;4814&quot; class=&quot;Keyword&quot;&gt;constructor&lt;/a&gt; &lt;a id=&quot;⟨_⋆_⟩&quot;&gt;&lt;/a&gt;&lt;a id=&quot;4826&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨_⋆_⟩&lt;/a&gt;
  &lt;a id=&quot;4834&quot; class=&quot;Keyword&quot;&gt;field&lt;/a&gt;
    &lt;a id=&quot;configuration.closure&quot;&gt;&lt;/a&gt;&lt;a id=&quot;4844&quot; href=&quot;non-idempotent-intersection-types.html#4844&quot; class=&quot;Field&quot;&gt;closure&lt;/a&gt; &lt;a id=&quot;4852&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;4854&quot; href=&quot;non-idempotent-intersection-types.html#3831&quot; class=&quot;Function&quot;&gt;clo&lt;/a&gt;
    &lt;a id=&quot;configuration.stack&quot;&gt;&lt;/a&gt;&lt;a id=&quot;4862&quot; href=&quot;non-idempotent-intersection-types.html#4862&quot; class=&quot;Field&quot;&gt;stack&lt;/a&gt;   &lt;a id=&quot;4870&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;4872&quot; href=&quot;non-idempotent-intersection-types.html#4455&quot; class=&quot;Datatype&quot;&gt;stk&lt;/a&gt;

&lt;a id=&quot;4877&quot; class=&quot;Keyword&quot;&gt;infix&lt;/a&gt;  &lt;a id=&quot;4884&quot; class=&quot;Number&quot;&gt;20&lt;/a&gt; &lt;a id=&quot;4887&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨_⋆_⟩&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;The reduction semantics of the KAM is given by the following four rules, which are driven by the shape of the term in the first component of the configuration:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;5067&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;_⇒_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;5072&quot; href=&quot;non-idempotent-intersection-types.html#5072&quot; class=&quot;Datatype Operator&quot;&gt;_⇒_&lt;/a&gt; &lt;a id=&quot;5076&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;5078&quot; href=&quot;non-idempotent-intersection-types.html#4786&quot; class=&quot;Record&quot;&gt;configuration&lt;/a&gt; &lt;a id=&quot;5092&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;5094&quot; href=&quot;non-idempotent-intersection-types.html#4786&quot; class=&quot;Record&quot;&gt;configuration&lt;/a&gt; &lt;a id=&quot;5108&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;5110&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;5114&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
  &lt;a id=&quot;_⇒_.grab&quot;&gt;&lt;/a&gt;&lt;a id=&quot;5122&quot; href=&quot;non-idempotent-intersection-types.html#5122&quot; class=&quot;InductiveConstructor&quot;&gt;grab&lt;/a&gt; &lt;a id=&quot;5127&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;5129&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;5131&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;5132&quot; href=&quot;non-idempotent-intersection-types.html#5132&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;5134&quot; href=&quot;non-idempotent-intersection-types.html#5134&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;5136&quot; href=&quot;non-idempotent-intersection-types.html#5136&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;5138&quot; href=&quot;non-idempotent-intersection-types.html#5138&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt;&lt;a id=&quot;5139&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;   &lt;a id=&quot;5143&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;5145&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt; &lt;a id=&quot;5147&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;5151&quot; href=&quot;non-idempotent-intersection-types.html#5132&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;5153&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;5155&quot; href=&quot;non-idempotent-intersection-types.html#5134&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;5157&quot; href=&quot;non-idempotent-intersection-types.html#3787&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;5160&quot; href=&quot;non-idempotent-intersection-types.html#5136&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;5162&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;5164&quot; href=&quot;non-idempotent-intersection-types.html#2396&quot; class=&quot;InductiveConstructor Operator&quot;&gt;`&lt;/a&gt; &lt;a id=&quot;5166&quot; href=&quot;Data.Fin.Base.html#1088&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;    &lt;a id=&quot;5174&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;5176&quot; href=&quot;non-idempotent-intersection-types.html#5138&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;5178&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt;      &lt;a id=&quot;5185&quot; href=&quot;non-idempotent-intersection-types.html#5072&quot; class=&quot;Datatype Operator&quot;&gt;⇒&lt;/a&gt; &lt;a id=&quot;5187&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt; &lt;a id=&quot;5189&quot; href=&quot;non-idempotent-intersection-types.html#5136&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;                      &lt;a id=&quot;5212&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;5214&quot; href=&quot;non-idempotent-intersection-types.html#5138&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;5216&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt;
  &lt;a id=&quot;_⇒_.skip&quot;&gt;&lt;/a&gt;&lt;a id=&quot;5220&quot; href=&quot;non-idempotent-intersection-types.html#5220&quot; class=&quot;InductiveConstructor&quot;&gt;skip&lt;/a&gt; &lt;a id=&quot;5225&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;5227&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;5229&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;5230&quot; href=&quot;non-idempotent-intersection-types.html#5230&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;5232&quot; href=&quot;non-idempotent-intersection-types.html#5232&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;5234&quot; href=&quot;non-idempotent-intersection-types.html#5234&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;5236&quot; href=&quot;non-idempotent-intersection-types.html#5236&quot; class=&quot;Bound&quot;&gt;i&lt;/a&gt; &lt;a id=&quot;5238&quot; href=&quot;non-idempotent-intersection-types.html#5238&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt;&lt;a id=&quot;5239&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;5241&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;5243&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt; &lt;a id=&quot;5245&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;5249&quot; href=&quot;non-idempotent-intersection-types.html#5230&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;5251&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;5253&quot; href=&quot;non-idempotent-intersection-types.html#5232&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;5255&quot; href=&quot;non-idempotent-intersection-types.html#3787&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;5258&quot; href=&quot;non-idempotent-intersection-types.html#5234&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;5260&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;5262&quot; href=&quot;non-idempotent-intersection-types.html#2396&quot; class=&quot;InductiveConstructor Operator&quot;&gt;`&lt;/a&gt; &lt;a id=&quot;5264&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;5265&quot; href=&quot;Data.Fin.Base.html#1119&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;5269&quot; href=&quot;non-idempotent-intersection-types.html#5236&quot; class=&quot;Bound&quot;&gt;i&lt;/a&gt;&lt;a id=&quot;5270&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;5272&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;5274&quot; href=&quot;non-idempotent-intersection-types.html#5238&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;5276&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt;      &lt;a id=&quot;5283&quot; href=&quot;non-idempotent-intersection-types.html#5072&quot; class=&quot;Datatype Operator&quot;&gt;⇒&lt;/a&gt; &lt;a id=&quot;5285&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt; &lt;a id=&quot;5287&quot; href=&quot;non-idempotent-intersection-types.html#5230&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;5289&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt;     &lt;a id=&quot;5295&quot; href=&quot;non-idempotent-intersection-types.html#5232&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt;        &lt;a id=&quot;5304&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;5306&quot; href=&quot;non-idempotent-intersection-types.html#2396&quot; class=&quot;InductiveConstructor Operator&quot;&gt;`&lt;/a&gt; &lt;a id=&quot;5308&quot; href=&quot;non-idempotent-intersection-types.html#5236&quot; class=&quot;Bound&quot;&gt;i&lt;/a&gt; &lt;a id=&quot;5310&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;5312&quot; href=&quot;non-idempotent-intersection-types.html#5238&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;5314&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt;
  &lt;a id=&quot;_⇒_.push&quot;&gt;&lt;/a&gt;&lt;a id=&quot;5318&quot; href=&quot;non-idempotent-intersection-types.html#5318&quot; class=&quot;InductiveConstructor&quot;&gt;push&lt;/a&gt; &lt;a id=&quot;5323&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;5325&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;5327&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;5328&quot; href=&quot;non-idempotent-intersection-types.html#5328&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;5330&quot; href=&quot;non-idempotent-intersection-types.html#5330&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;5332&quot; href=&quot;non-idempotent-intersection-types.html#5332&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;5334&quot; href=&quot;non-idempotent-intersection-types.html#5334&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;5336&quot; href=&quot;non-idempotent-intersection-types.html#5336&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt;&lt;a id=&quot;5337&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;5339&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;5341&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt;     &lt;a id=&quot;5347&quot; href=&quot;non-idempotent-intersection-types.html#5328&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;5349&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;5351&quot; href=&quot;non-idempotent-intersection-types.html#5330&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt;      &lt;a id=&quot;5358&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;5360&quot; href=&quot;non-idempotent-intersection-types.html#5332&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;5362&quot; href=&quot;non-idempotent-intersection-types.html#2465&quot; class=&quot;InductiveConstructor Operator&quot;&gt;·&lt;/a&gt; &lt;a id=&quot;5364&quot; href=&quot;non-idempotent-intersection-types.html#5334&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt;     &lt;a id=&quot;5370&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;5372&quot; href=&quot;non-idempotent-intersection-types.html#5336&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;5374&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt;      &lt;a id=&quot;5381&quot; href=&quot;non-idempotent-intersection-types.html#5072&quot; class=&quot;Datatype Operator&quot;&gt;⇒&lt;/a&gt; &lt;a id=&quot;5383&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt; &lt;a id=&quot;5385&quot; href=&quot;non-idempotent-intersection-types.html#5328&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;5387&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt;     &lt;a id=&quot;5393&quot; href=&quot;non-idempotent-intersection-types.html#5330&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt;        &lt;a id=&quot;5402&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;5404&quot; href=&quot;non-idempotent-intersection-types.html#5332&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;   &lt;a id=&quot;5408&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;5410&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;5411&quot; href=&quot;non-idempotent-intersection-types.html#5328&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;5413&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;5415&quot; href=&quot;non-idempotent-intersection-types.html#5330&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;5417&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;5419&quot; href=&quot;non-idempotent-intersection-types.html#5334&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt;&lt;a id=&quot;5420&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;5422&quot; href=&quot;non-idempotent-intersection-types.html#4486&quot; class=&quot;InductiveConstructor Operator&quot;&gt;-,&lt;/a&gt; &lt;a id=&quot;5425&quot; href=&quot;non-idempotent-intersection-types.html#5336&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;5427&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt;
  &lt;a id=&quot;_⇒_.pop&quot;&gt;&lt;/a&gt;&lt;a id=&quot;5431&quot; href=&quot;non-idempotent-intersection-types.html#5431&quot; class=&quot;InductiveConstructor&quot;&gt;pop&lt;/a&gt;  &lt;a id=&quot;5436&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;5438&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;5440&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;5441&quot; href=&quot;non-idempotent-intersection-types.html#5441&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;5443&quot; href=&quot;non-idempotent-intersection-types.html#5443&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;5445&quot; href=&quot;non-idempotent-intersection-types.html#5445&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;5447&quot; href=&quot;non-idempotent-intersection-types.html#5447&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;5449&quot; href=&quot;non-idempotent-intersection-types.html#5449&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt;&lt;a id=&quot;5450&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;5452&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;5454&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt;     &lt;a id=&quot;5460&quot; href=&quot;non-idempotent-intersection-types.html#5441&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;5462&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;5464&quot; href=&quot;non-idempotent-intersection-types.html#5443&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt;      &lt;a id=&quot;5471&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;5473&quot; href=&quot;non-idempotent-intersection-types.html#2427&quot; class=&quot;InductiveConstructor&quot;&gt;ƛ&lt;/a&gt; &lt;a id=&quot;5475&quot; href=&quot;non-idempotent-intersection-types.html#5445&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;       &lt;a id=&quot;5483&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;5485&quot; href=&quot;non-idempotent-intersection-types.html#5447&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;5487&quot; href=&quot;non-idempotent-intersection-types.html#4486&quot; class=&quot;InductiveConstructor Operator&quot;&gt;-,&lt;/a&gt; &lt;a id=&quot;5490&quot; href=&quot;non-idempotent-intersection-types.html#5449&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;5492&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt; &lt;a id=&quot;5494&quot; href=&quot;non-idempotent-intersection-types.html#5072&quot; class=&quot;Datatype Operator&quot;&gt;⇒&lt;/a&gt; &lt;a id=&quot;5496&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt; &lt;a id=&quot;5498&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;5502&quot; href=&quot;non-idempotent-intersection-types.html#5441&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;5504&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;5506&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;5507&quot; href=&quot;non-idempotent-intersection-types.html#5443&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;5509&quot; href=&quot;non-idempotent-intersection-types.html#3787&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;5512&quot; href=&quot;non-idempotent-intersection-types.html#5447&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;5513&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;5515&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;5517&quot; href=&quot;non-idempotent-intersection-types.html#5445&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;   &lt;a id=&quot;5521&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;5523&quot; href=&quot;non-idempotent-intersection-types.html#5449&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;5525&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt;

&lt;a id=&quot;5528&quot; class=&quot;Keyword&quot;&gt;infixr&lt;/a&gt; &lt;a id=&quot;5535&quot; class=&quot;Number&quot;&gt;10&lt;/a&gt; &lt;a id=&quot;5538&quot; href=&quot;non-idempotent-intersection-types.html#5072&quot; class=&quot;Datatype Operator&quot;&gt;_⇒_&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;The rules &lt;code&gt;grab&lt;/code&gt; and &lt;code&gt;skip&lt;/code&gt; handle the execution of variables by incrementally looking them up in the current environment. One could also define a KAM that has a single rule for variable lookup (looking arbitrarily deep into the environment in a single step), but we chose to break it down into individual steps here.&lt;/p&gt;&lt;p&gt;The rule &lt;code&gt;push&lt;/code&gt; executes an application &lt;code&gt;t · s&lt;/code&gt; by pushing the argument &lt;code&gt;s&lt;/code&gt; on to the stack (accompanied by its environment). Execution will then carry on in the function position (compare to the congruence rule given above for a small step operational semantics).&lt;/p&gt;&lt;p&gt;Finally, the rule &lt;code&gt;pop&lt;/code&gt; executes a λ abstraction &lt;code&gt;ƛ t&lt;/code&gt; by popping the current argument from the stack and adding it to the current environment. Combined with the first two rules, this performs a delayed β-reduction.&lt;/p&gt;&lt;p&gt;To start the KAM, we need to take programs that we want to execute and turn them into configurations:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;init&quot;&gt;&lt;/a&gt;&lt;a id=&quot;6460&quot; href=&quot;non-idempotent-intersection-types.html#6460&quot; class=&quot;Function&quot;&gt;init&lt;/a&gt; &lt;a id=&quot;6465&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;6467&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;6472&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt; &lt;a id=&quot;6474&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;6476&quot; href=&quot;non-idempotent-intersection-types.html#4786&quot; class=&quot;Record&quot;&gt;configuration&lt;/a&gt;
&lt;a id=&quot;6490&quot; href=&quot;non-idempotent-intersection-types.html#6460&quot; class=&quot;Function&quot;&gt;init&lt;/a&gt; &lt;a id=&quot;6495&quot; href=&quot;non-idempotent-intersection-types.html#6495&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;6497&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;6499&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt; &lt;a id=&quot;6501&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt; &lt;a id=&quot;6503&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;6505&quot; href=&quot;non-idempotent-intersection-types.html#3767&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;6509&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;6511&quot; href=&quot;non-idempotent-intersection-types.html#6495&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;6513&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;6515&quot; href=&quot;non-idempotent-intersection-types.html#4473&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt; &lt;a id=&quot;6519&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;Due to the fact that we have defined our KAM using intrinsically scoped syntax, it is not possible for the KAM to get stuck by not having a variable in scope. The only way the machine can get stuck is by ending up with a λ-abstraction paired with an empty stack. In this case we can say that the original term has been reduced to its weak head normal form (WHNF). It also possible that a term never reduces to a final configuration at all -- not all terms finish reducing under the Call-by-Name semantics. To identify which terms reduce, we make an inductive definition that also records how many steps it takes for a term to reduce:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;7169&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;reduces&quot;&gt;&lt;/a&gt;&lt;a id=&quot;7174&quot; href=&quot;non-idempotent-intersection-types.html#7174&quot; class=&quot;Datatype&quot;&gt;reduces&lt;/a&gt; &lt;a id=&quot;7182&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;7184&quot; href=&quot;Agda.Builtin.Nat.html#192&quot; class=&quot;Datatype&quot;&gt;ℕ&lt;/a&gt; &lt;a id=&quot;7186&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;7188&quot; href=&quot;non-idempotent-intersection-types.html#4786&quot; class=&quot;Record&quot;&gt;configuration&lt;/a&gt; &lt;a id=&quot;7202&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;7204&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;7208&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
  &lt;a id=&quot;reduces.stop&quot;&gt;&lt;/a&gt;&lt;a id=&quot;7216&quot; href=&quot;non-idempotent-intersection-types.html#7216&quot; class=&quot;InductiveConstructor&quot;&gt;stop&lt;/a&gt; &lt;a id=&quot;7221&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;7223&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;7225&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;7226&quot; href=&quot;non-idempotent-intersection-types.html#7226&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;7227&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;7229&quot; href=&quot;non-idempotent-intersection-types.html#7229&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;7231&quot; href=&quot;non-idempotent-intersection-types.html#7231&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;7233&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;7235&quot; href=&quot;non-idempotent-intersection-types.html#7174&quot; class=&quot;Datatype&quot;&gt;reduces&lt;/a&gt; &lt;a id=&quot;7243&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt; &lt;a id=&quot;7245&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt; &lt;a id=&quot;7247&quot; href=&quot;non-idempotent-intersection-types.html#7226&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;7249&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;7251&quot; href=&quot;non-idempotent-intersection-types.html#7229&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;7253&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;7255&quot; href=&quot;non-idempotent-intersection-types.html#2427&quot; class=&quot;InductiveConstructor&quot;&gt;ƛ&lt;/a&gt; &lt;a id=&quot;7257&quot; href=&quot;non-idempotent-intersection-types.html#7231&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;7259&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;7261&quot; href=&quot;non-idempotent-intersection-types.html#4473&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt; &lt;a id=&quot;7265&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt;
  &lt;a id=&quot;reduces.step&quot;&gt;&lt;/a&gt;&lt;a id=&quot;7269&quot; href=&quot;non-idempotent-intersection-types.html#7269&quot; class=&quot;InductiveConstructor&quot;&gt;step&lt;/a&gt; &lt;a id=&quot;7274&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;7276&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;7278&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;7279&quot; href=&quot;non-idempotent-intersection-types.html#7279&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;7281&quot; href=&quot;non-idempotent-intersection-types.html#7281&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;7283&quot; href=&quot;non-idempotent-intersection-types.html#7283&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt;&lt;a id=&quot;7284&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;7286&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;7288&quot; href=&quot;non-idempotent-intersection-types.html#7281&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;7290&quot; href=&quot;non-idempotent-intersection-types.html#5072&quot; class=&quot;Datatype Operator&quot;&gt;⇒&lt;/a&gt; &lt;a id=&quot;7292&quot; href=&quot;non-idempotent-intersection-types.html#7283&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt; &lt;a id=&quot;7294&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;7296&quot; href=&quot;non-idempotent-intersection-types.html#7174&quot; class=&quot;Datatype&quot;&gt;reduces&lt;/a&gt; &lt;a id=&quot;7304&quot; href=&quot;non-idempotent-intersection-types.html#7279&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;7306&quot; href=&quot;non-idempotent-intersection-types.html#7283&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt; &lt;a id=&quot;7308&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;7310&quot; href=&quot;non-idempotent-intersection-types.html#7174&quot; class=&quot;Datatype&quot;&gt;reduces&lt;/a&gt; &lt;a id=&quot;7318&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;7319&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;7323&quot; href=&quot;non-idempotent-intersection-types.html#7279&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;7324&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;7326&quot; href=&quot;non-idempotent-intersection-types.html#7281&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;So if we have a value of type &lt;code&gt;reduces n p&lt;/code&gt;, then we know that a configuration &lt;code&gt;p&lt;/code&gt; reduces to a WHNF in &lt;code&gt;n&lt;/code&gt; steps.&lt;/p&gt;&lt;p&gt;Since the selection of rules the KAM is driven by the shape of the term being executed, execution in the KAM is deterministic:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;deterministic&quot;&gt;&lt;/a&gt;&lt;a id=&quot;7585&quot; href=&quot;non-idempotent-intersection-types.html#7585&quot; class=&quot;Function&quot;&gt;deterministic&lt;/a&gt; &lt;a id=&quot;7599&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;7601&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;7603&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;7604&quot; href=&quot;non-idempotent-intersection-types.html#7604&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;7606&quot; href=&quot;non-idempotent-intersection-types.html#7606&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt; &lt;a id=&quot;7608&quot; href=&quot;non-idempotent-intersection-types.html#7608&quot; class=&quot;Bound&quot;&gt;q&amp;#39;&lt;/a&gt;&lt;a id=&quot;7610&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;7612&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;7614&quot; href=&quot;non-idempotent-intersection-types.html#7604&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;7616&quot; href=&quot;non-idempotent-intersection-types.html#5072&quot; class=&quot;Datatype Operator&quot;&gt;⇒&lt;/a&gt; &lt;a id=&quot;7618&quot; href=&quot;non-idempotent-intersection-types.html#7606&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt; &lt;a id=&quot;7620&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;7622&quot; href=&quot;non-idempotent-intersection-types.html#7604&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;7624&quot; href=&quot;non-idempotent-intersection-types.html#5072&quot; class=&quot;Datatype Operator&quot;&gt;⇒&lt;/a&gt; &lt;a id=&quot;7626&quot; href=&quot;non-idempotent-intersection-types.html#7608&quot; class=&quot;Bound&quot;&gt;q&amp;#39;&lt;/a&gt; &lt;a id=&quot;7629&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;7631&quot; href=&quot;non-idempotent-intersection-types.html#7606&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt; &lt;a id=&quot;7633&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;7635&quot; href=&quot;non-idempotent-intersection-types.html#7608&quot; class=&quot;Bound&quot;&gt;q&amp;#39;&lt;/a&gt;
&lt;a id=&quot;7638&quot; href=&quot;non-idempotent-intersection-types.html#7585&quot; class=&quot;Function&quot;&gt;deterministic&lt;/a&gt; &lt;a id=&quot;7652&quot; href=&quot;non-idempotent-intersection-types.html#5122&quot; class=&quot;InductiveConstructor&quot;&gt;grab&lt;/a&gt; &lt;a id=&quot;7657&quot; href=&quot;non-idempotent-intersection-types.html#5122&quot; class=&quot;InductiveConstructor&quot;&gt;grab&lt;/a&gt; &lt;a id=&quot;7662&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;7664&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt;
&lt;a id=&quot;7669&quot; href=&quot;non-idempotent-intersection-types.html#7585&quot; class=&quot;Function&quot;&gt;deterministic&lt;/a&gt; &lt;a id=&quot;7683&quot; href=&quot;non-idempotent-intersection-types.html#5220&quot; class=&quot;InductiveConstructor&quot;&gt;skip&lt;/a&gt; &lt;a id=&quot;7688&quot; href=&quot;non-idempotent-intersection-types.html#5220&quot; class=&quot;InductiveConstructor&quot;&gt;skip&lt;/a&gt; &lt;a id=&quot;7693&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;7695&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt;
&lt;a id=&quot;7700&quot; href=&quot;non-idempotent-intersection-types.html#7585&quot; class=&quot;Function&quot;&gt;deterministic&lt;/a&gt; &lt;a id=&quot;7714&quot; href=&quot;non-idempotent-intersection-types.html#5318&quot; class=&quot;InductiveConstructor&quot;&gt;push&lt;/a&gt; &lt;a id=&quot;7719&quot; href=&quot;non-idempotent-intersection-types.html#5318&quot; class=&quot;InductiveConstructor&quot;&gt;push&lt;/a&gt; &lt;a id=&quot;7724&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;7726&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt;
&lt;a id=&quot;7731&quot; href=&quot;non-idempotent-intersection-types.html#7585&quot; class=&quot;Function&quot;&gt;deterministic&lt;/a&gt; &lt;a id=&quot;7745&quot; href=&quot;non-idempotent-intersection-types.html#5431&quot; class=&quot;InductiveConstructor&quot;&gt;pop&lt;/a&gt;  &lt;a id=&quot;7750&quot; href=&quot;non-idempotent-intersection-types.html#5431&quot; class=&quot;InductiveConstructor&quot;&gt;pop&lt;/a&gt;  &lt;a id=&quot;7755&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;7757&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;Consequently, any configuration that reduces does so in a unique number of steps:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;reduces-det&quot;&gt;&lt;/a&gt;&lt;a id=&quot;7858&quot; href=&quot;non-idempotent-intersection-types.html#7858&quot; class=&quot;Function&quot;&gt;reduces-det&lt;/a&gt; &lt;a id=&quot;7870&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;7872&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;7874&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;7875&quot; href=&quot;non-idempotent-intersection-types.html#7875&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;7877&quot; href=&quot;non-idempotent-intersection-types.html#7877&quot; class=&quot;Bound&quot;&gt;m&lt;/a&gt; &lt;a id=&quot;7879&quot; href=&quot;non-idempotent-intersection-types.html#7879&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;7880&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;7882&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;7884&quot; href=&quot;non-idempotent-intersection-types.html#7174&quot; class=&quot;Datatype&quot;&gt;reduces&lt;/a&gt; &lt;a id=&quot;7892&quot; href=&quot;non-idempotent-intersection-types.html#7877&quot; class=&quot;Bound&quot;&gt;m&lt;/a&gt; &lt;a id=&quot;7894&quot; href=&quot;non-idempotent-intersection-types.html#7875&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;7896&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;7898&quot; href=&quot;non-idempotent-intersection-types.html#7174&quot; class=&quot;Datatype&quot;&gt;reduces&lt;/a&gt; &lt;a id=&quot;7906&quot; href=&quot;non-idempotent-intersection-types.html#7879&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;7908&quot; href=&quot;non-idempotent-intersection-types.html#7875&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;7910&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;7912&quot; href=&quot;non-idempotent-intersection-types.html#7877&quot; class=&quot;Bound&quot;&gt;m&lt;/a&gt; &lt;a id=&quot;7914&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;7916&quot; href=&quot;non-idempotent-intersection-types.html#7879&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;
&lt;a id=&quot;7918&quot; href=&quot;non-idempotent-intersection-types.html#7858&quot; class=&quot;Function&quot;&gt;reduces-det&lt;/a&gt; &lt;a id=&quot;7930&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;7931&quot; href=&quot;non-idempotent-intersection-types.html#7216&quot; class=&quot;InductiveConstructor&quot;&gt;stop&lt;/a&gt; &lt;a id=&quot;7936&quot; href=&quot;non-idempotent-intersection-types.html#7936&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;7938&quot; href=&quot;non-idempotent-intersection-types.html#7938&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;7939&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;   &lt;a id=&quot;7943&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;7944&quot; href=&quot;non-idempotent-intersection-types.html#7216&quot; class=&quot;InductiveConstructor&quot;&gt;stop&lt;/a&gt; &lt;a id=&quot;7949&quot; class=&quot;DottedPattern Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;7950&quot; href=&quot;non-idempotent-intersection-types.html#7936&quot; class=&quot;DottedPattern Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;7952&quot; class=&quot;DottedPattern Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;7953&quot; href=&quot;non-idempotent-intersection-types.html#7938&quot; class=&quot;DottedPattern Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;7954&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;7956&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;7958&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt;
&lt;a id=&quot;7963&quot; href=&quot;non-idempotent-intersection-types.html#7858&quot; class=&quot;Function&quot;&gt;reduces-det&lt;/a&gt; &lt;a id=&quot;7975&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;7976&quot; href=&quot;non-idempotent-intersection-types.html#7269&quot; class=&quot;InductiveConstructor&quot;&gt;step&lt;/a&gt; &lt;a id=&quot;7981&quot; href=&quot;non-idempotent-intersection-types.html#7981&quot; class=&quot;Bound&quot;&gt;s1&lt;/a&gt; &lt;a id=&quot;7984&quot; href=&quot;non-idempotent-intersection-types.html#7984&quot; class=&quot;Bound&quot;&gt;r1&lt;/a&gt;&lt;a id=&quot;7986&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;7988&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;7989&quot; href=&quot;non-idempotent-intersection-types.html#7269&quot; class=&quot;InductiveConstructor&quot;&gt;step&lt;/a&gt; &lt;a id=&quot;7994&quot; href=&quot;non-idempotent-intersection-types.html#7994&quot; class=&quot;Bound&quot;&gt;s2&lt;/a&gt; &lt;a id=&quot;7997&quot; href=&quot;non-idempotent-intersection-types.html#7997&quot; class=&quot;Bound&quot;&gt;r2&lt;/a&gt;&lt;a id=&quot;7999&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;8001&quot; class=&quot;Keyword&quot;&gt;with&lt;/a&gt; &lt;a id=&quot;8006&quot; href=&quot;non-idempotent-intersection-types.html#7585&quot; class=&quot;Function&quot;&gt;deterministic&lt;/a&gt; &lt;a id=&quot;8020&quot; href=&quot;non-idempotent-intersection-types.html#7981&quot; class=&quot;Bound&quot;&gt;s1&lt;/a&gt; &lt;a id=&quot;8023&quot; href=&quot;non-idempotent-intersection-types.html#7994&quot; class=&quot;Bound&quot;&gt;s2&lt;/a&gt;
&lt;a id=&quot;8026&quot; class=&quot;Symbol&quot;&gt;...&lt;/a&gt; &lt;a id=&quot;8030&quot; class=&quot;Symbol&quot;&gt;|&lt;/a&gt; &lt;a id=&quot;8032&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt; &lt;a id=&quot;8037&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;8039&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;8044&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;8048&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;8049&quot; href=&quot;non-idempotent-intersection-types.html#7858&quot; class=&quot;Function&quot;&gt;reduces-det&lt;/a&gt; &lt;a id=&quot;8061&quot; class=&quot;Bound&quot;&gt;r1&lt;/a&gt; &lt;a id=&quot;8064&quot; class=&quot;Bound&quot;&gt;r2&lt;/a&gt;&lt;a id=&quot;8066&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;/pre&gt;
&lt;h3&gt;The Non-Idempotent Type Assignment System&lt;/h3&gt;&lt;p&gt;Non-idempotent intersection types assign types to terms according to their precise runtime behaviour. Usually type systems assign types that are over approximations of the possible behaviours of a program. Intersection types (whether idempotent or not) assign types that track precisely the behaviour a program will have (in a particular context). Indeed, as we will see below, the system we present here precisely tracks the termination behaviour of programs. This precision does make typechecking undecidable.&lt;/p&gt;&lt;h4&gt;Types, Observations, Behaviours&lt;/h4&gt;&lt;p&gt;The types of our system are defined as:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;8718&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;type&quot;&gt;&lt;/a&gt;&lt;a id=&quot;8723&quot; href=&quot;non-idempotent-intersection-types.html#8723&quot; class=&quot;Datatype&quot;&gt;type&lt;/a&gt; &lt;a id=&quot;8728&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;8730&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;8734&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
  &lt;a id=&quot;type.⋆&quot;&gt;&lt;/a&gt;&lt;a id=&quot;8742&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt;    &lt;a id=&quot;8747&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;8749&quot; href=&quot;non-idempotent-intersection-types.html#8723&quot; class=&quot;Datatype&quot;&gt;type&lt;/a&gt;
  &lt;a id=&quot;type._↦_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;8756&quot; href=&quot;non-idempotent-intersection-types.html#8756&quot; class=&quot;InductiveConstructor Operator&quot;&gt;_↦_&lt;/a&gt; &lt;a id=&quot;8760&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;8762&quot; href=&quot;Agda.Builtin.List.html#148&quot; class=&quot;Datatype&quot;&gt;List&lt;/a&gt; &lt;a id=&quot;8767&quot; href=&quot;non-idempotent-intersection-types.html#8723&quot; class=&quot;Datatype&quot;&gt;type&lt;/a&gt; &lt;a id=&quot;8772&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;8774&quot; href=&quot;non-idempotent-intersection-types.html#8723&quot; class=&quot;Datatype&quot;&gt;type&lt;/a&gt; &lt;a id=&quot;8779&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;8781&quot; href=&quot;non-idempotent-intersection-types.html#8723&quot; class=&quot;Datatype&quot;&gt;type&lt;/a&gt;

&lt;a id=&quot;8787&quot; class=&quot;Keyword&quot;&gt;infixr&lt;/a&gt; &lt;a id=&quot;8794&quot; class=&quot;Number&quot;&gt;30&lt;/a&gt; &lt;a id=&quot;8797&quot; href=&quot;non-idempotent-intersection-types.html#8756&quot; class=&quot;InductiveConstructor Operator&quot;&gt;_↦_&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;We can interpret the types of the system as kinds of “observations” or “behaviour descriptions” that we can make of a program. Per the definition of &lt;code&gt;type&lt;/code&gt;, we have two kinds of observation in our system:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;The observation &lt;code&gt;⋆&lt;/code&gt; means that we can observe that the term will reduce to a value (a λ abstraction), but gives us no further information. To observe that a complete program reduces to WHNF, we will seek typings that type the whole program with the observation &lt;code&gt;⋆&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The observation &lt;code&gt;σ ↦ τ&lt;/code&gt; pairs a list of observations &lt;code&gt;σ&lt;/code&gt; with a single observation &lt;code&gt;τ&lt;/code&gt;. Making this observation means that the term will reduce to a function that when applied to an argument that exhibits all the behaviours in &lt;code&gt;σ&lt;/code&gt;, exhibits the observation &lt;code&gt;τ&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;For example, the observation &lt;code&gt;[⋆] ↦ ⋆&lt;/code&gt; is one that we can assign to the identity function: we can observe that the output is a value, as long as it can make the observation that the input is a value.&lt;/p&gt;&lt;p&gt;The lists of types &lt;code&gt;σ&lt;/code&gt; are the &lt;em&gt;intersection types&lt;/em&gt; of our system. They indicate that a particular term must have all of the behaviours listed, so it must be in the intersection of all the possible behaviours: &lt;code&gt;σ = τ₁ ∧ τ₂ ∧ ... ∧ τₙ&lt;/code&gt;. Idempotent intersection type systems disregard multiple occurrences of the same behaviour (i.e. &lt;code&gt;τ ∧ τ = τ&lt;/code&gt;) in an intersection: they only track whether a behaviour is present or not. Non-idempotent intersection type systems, in contrast, track the number of occurrences of each behaviour. In turn, this tracks the number of times a function uses its arguments. It is this quantitative aspect that will allow us to use non-idempotent intersection types to measure the reduction complexity of programs.&lt;/p&gt;&lt;p&gt;To see how the rejection of idempotency allows tracking of number of uses, consider the following two terms (written using explicit names):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  λf. λx. f x
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  λf. λx. f (f x)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When applied to the identity function &lt;code&gt;λx .x&lt;/code&gt; and any value &lt;code&gt;λz.t&lt;/code&gt;, these terms both reduce to a value. We can see this by the types that the system we define below will assign to them. The first one gets the following type:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  ⊢ λf. λx. f x ⦂ [[⋆] ↦ ⋆] ↦ [⋆] ↦ ⋆
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In words, this says &quot;if the first argument yields values when given values, and the second argument is a value, then the result is a value&quot;. The second term is assigned a similar type, but here we can see the quantitative nature of the system coming in to play:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  ⊢ λf. λx. f (f x) ⦂ [[⋆] ↦ ⋆, [⋆] ↦ ⋆] ↦ [⋆] ↦ ⋆
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Notice that the type now states that the first argument will be used twice, because two behaviours appear in the first intersection. This precisely tracks the structure of the term, which does indeed use &lt;code&gt;f&lt;/code&gt; twice. If we assumed idempotency, then the two types would be equivalent, and we would be tracking the &lt;em&gt;qualitative&lt;/em&gt; behaviour, but not the &lt;em&gt;quantitative&lt;/em&gt; behaviour.&lt;/p&gt;&lt;h4&gt;Typing contexts&lt;/h4&gt;&lt;p&gt;To assign types to open terms, we need typing contexts. Typing contexts assign to each free variable position a list of possible behaviours. Typing contexts grow to the right.&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;11908&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;ctx&quot;&gt;&lt;/a&gt;&lt;a id=&quot;11913&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;11917&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;11919&quot; href=&quot;Agda.Builtin.Nat.html#192&quot; class=&quot;Datatype&quot;&gt;ℕ&lt;/a&gt; &lt;a id=&quot;11921&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;11923&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;11927&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
  &lt;a id=&quot;ctx.nil&quot;&gt;&lt;/a&gt;&lt;a id=&quot;11935&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;11939&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;11941&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;11945&quot; href=&quot;Agda.Builtin.Nat.html#210&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;
  &lt;a id=&quot;ctx._,-_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;11952&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;_,-_&lt;/a&gt; &lt;a id=&quot;11957&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;11959&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;11961&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;11962&quot; href=&quot;non-idempotent-intersection-types.html#11962&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;11963&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;11965&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;11967&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;11971&quot; href=&quot;non-idempotent-intersection-types.html#11962&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;11973&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;11975&quot; href=&quot;Agda.Builtin.List.html#148&quot; class=&quot;Datatype&quot;&gt;List&lt;/a&gt; &lt;a id=&quot;11980&quot; href=&quot;non-idempotent-intersection-types.html#8723&quot; class=&quot;Datatype&quot;&gt;type&lt;/a&gt; &lt;a id=&quot;11985&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;11987&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;11991&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;11992&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;11996&quot; href=&quot;non-idempotent-intersection-types.html#11962&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;11997&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;We need the following two combinators for typing contexts. The first, &lt;code&gt;empty&lt;/code&gt;, is the typing context where every variable is assumed to have no behaviours. This is used to type terms that do not use any of the variables in scope.&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;empty&quot;&gt;&lt;/a&gt;&lt;a id=&quot;12243&quot; href=&quot;non-idempotent-intersection-types.html#12243&quot; class=&quot;Function&quot;&gt;empty&lt;/a&gt; &lt;a id=&quot;12249&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;12251&quot; class=&quot;Symbol&quot;&gt;∀{&lt;/a&gt;&lt;a id=&quot;12253&quot; href=&quot;non-idempotent-intersection-types.html#12253&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;12254&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;12256&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;12258&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;12262&quot; href=&quot;non-idempotent-intersection-types.html#12253&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;
&lt;a id=&quot;12264&quot; href=&quot;non-idempotent-intersection-types.html#12243&quot; class=&quot;Function&quot;&gt;empty&lt;/a&gt; &lt;a id=&quot;12270&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;12271&quot; href=&quot;Agda.Builtin.Nat.html#210&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;12275&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;  &lt;a id=&quot;12278&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;12280&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;
&lt;a id=&quot;12284&quot; href=&quot;non-idempotent-intersection-types.html#12243&quot; class=&quot;Function&quot;&gt;empty&lt;/a&gt; &lt;a id=&quot;12290&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;12291&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;12295&quot; href=&quot;non-idempotent-intersection-types.html#12295&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;12296&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;12298&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;12300&quot; href=&quot;non-idempotent-intersection-types.html#12243&quot; class=&quot;Function&quot;&gt;empty&lt;/a&gt; &lt;a id=&quot;12306&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;12307&quot; href=&quot;non-idempotent-intersection-types.html#12295&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;12308&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;12310&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;12313&quot; href=&quot;Agda.Builtin.List.html#185&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;_+++_&lt;/code&gt; combinator “zips” two typing contexts to combine their possible behaviours. We will use this to create contexts that combine the observations on contexts required by two the two subterms in an application term.&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;_+++_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;12553&quot; href=&quot;non-idempotent-intersection-types.html#12553&quot; class=&quot;Function Operator&quot;&gt;_+++_&lt;/a&gt; &lt;a id=&quot;12559&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;12561&quot; class=&quot;Symbol&quot;&gt;∀{&lt;/a&gt;&lt;a id=&quot;12563&quot; href=&quot;non-idempotent-intersection-types.html#12563&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;12564&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;12566&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;12568&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;12572&quot; href=&quot;non-idempotent-intersection-types.html#12563&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;12574&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;12576&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;12580&quot; href=&quot;non-idempotent-intersection-types.html#12563&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;12582&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;12584&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;12588&quot; href=&quot;non-idempotent-intersection-types.html#12563&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;
&lt;a id=&quot;12590&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;        &lt;a id=&quot;12601&quot; href=&quot;non-idempotent-intersection-types.html#12553&quot; class=&quot;Function Operator&quot;&gt;+++&lt;/a&gt; &lt;a id=&quot;12605&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;       &lt;a id=&quot;12615&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;12617&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;
&lt;a id=&quot;12621&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;12622&quot; href=&quot;non-idempotent-intersection-types.html#12622&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;12625&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;12628&quot; href=&quot;non-idempotent-intersection-types.html#12628&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;12630&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;12632&quot; href=&quot;non-idempotent-intersection-types.html#12553&quot; class=&quot;Function Operator&quot;&gt;+++&lt;/a&gt; &lt;a id=&quot;12636&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;12637&quot; href=&quot;non-idempotent-intersection-types.html#12637&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;12640&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;12643&quot; href=&quot;non-idempotent-intersection-types.html#12643&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;&lt;a id=&quot;12645&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;12647&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;12649&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;12650&quot; href=&quot;non-idempotent-intersection-types.html#12622&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;12653&quot; href=&quot;non-idempotent-intersection-types.html#12553&quot; class=&quot;Function Operator&quot;&gt;+++&lt;/a&gt; &lt;a id=&quot;12657&quot; href=&quot;non-idempotent-intersection-types.html#12637&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt;&lt;a id=&quot;12659&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;12661&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;12664&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;12665&quot; href=&quot;non-idempotent-intersection-types.html#12628&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;12668&quot; href=&quot;Data.List.Base.html#1763&quot; class=&quot;Function Operator&quot;&gt;++&lt;/a&gt; &lt;a id=&quot;12671&quot; href=&quot;non-idempotent-intersection-types.html#12643&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;&lt;a id=&quot;12673&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;Non-idempotent intersection type systems are sensitive to the number of occurrences of each behaviour in an intersection, but not to their order. We will model this by requiring equivalence only up to permutation at various places. We define a permutation between two lists via sequences of swappings:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;12991&quot; class=&quot;Keyword&quot;&gt;module&lt;/a&gt; &lt;a id=&quot;permutations&quot;&gt;&lt;/a&gt;&lt;a id=&quot;12998&quot; href=&quot;non-idempotent-intersection-types.html#12998&quot; class=&quot;Module&quot;&gt;permutations&lt;/a&gt; &lt;a id=&quot;13011&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;13012&quot; href=&quot;non-idempotent-intersection-types.html#13012&quot; class=&quot;Bound&quot;&gt;X&lt;/a&gt; &lt;a id=&quot;13014&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;13016&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt;&lt;a id=&quot;13019&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;13021&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
  &lt;a id=&quot;13029&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;permutations._⋈_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;13034&quot; href=&quot;non-idempotent-intersection-types.html#13034&quot; class=&quot;Datatype Operator&quot;&gt;_⋈_&lt;/a&gt; &lt;a id=&quot;13038&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;13040&quot; href=&quot;Agda.Builtin.List.html#148&quot; class=&quot;Datatype&quot;&gt;List&lt;/a&gt; &lt;a id=&quot;13045&quot; href=&quot;non-idempotent-intersection-types.html#13012&quot; class=&quot;Bound&quot;&gt;X&lt;/a&gt; &lt;a id=&quot;13047&quot; class=&quot;Symbol&quot;&gt;-&amp;gt;&lt;/a&gt; &lt;a id=&quot;13050&quot; href=&quot;Agda.Builtin.List.html#148&quot; class=&quot;Datatype&quot;&gt;List&lt;/a&gt; &lt;a id=&quot;13055&quot; href=&quot;non-idempotent-intersection-types.html#13012&quot; class=&quot;Bound&quot;&gt;X&lt;/a&gt; &lt;a id=&quot;13057&quot; class=&quot;Symbol&quot;&gt;-&amp;gt;&lt;/a&gt; &lt;a id=&quot;13060&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;13064&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
    &lt;a id=&quot;permutations._⋈_.nil&quot;&gt;&lt;/a&gt;&lt;a id=&quot;13074&quot; href=&quot;non-idempotent-intersection-types.html#13074&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;     &lt;a id=&quot;13082&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;13084&quot; href=&quot;Agda.Builtin.List.html#185&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt; &lt;a id=&quot;13087&quot; href=&quot;non-idempotent-intersection-types.html#13034&quot; class=&quot;Datatype Operator&quot;&gt;⋈&lt;/a&gt; &lt;a id=&quot;13089&quot; href=&quot;Agda.Builtin.List.html#185&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt;
    &lt;a id=&quot;permutations._⋈_.skip&quot;&gt;&lt;/a&gt;&lt;a id=&quot;13096&quot; href=&quot;non-idempotent-intersection-types.html#13096&quot; class=&quot;InductiveConstructor&quot;&gt;skip&lt;/a&gt;    &lt;a id=&quot;13104&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;13106&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;13108&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;13109&quot; href=&quot;non-idempotent-intersection-types.html#13109&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;13111&quot; href=&quot;non-idempotent-intersection-types.html#13111&quot; class=&quot;Bound&quot;&gt;l₁&lt;/a&gt; &lt;a id=&quot;13114&quot; href=&quot;non-idempotent-intersection-types.html#13114&quot; class=&quot;Bound&quot;&gt;l₂&lt;/a&gt;&lt;a id=&quot;13116&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;  &lt;a id=&quot;13119&quot; class=&quot;Symbol&quot;&gt;-&amp;gt;&lt;/a&gt; &lt;a id=&quot;13122&quot; href=&quot;non-idempotent-intersection-types.html#13111&quot; class=&quot;Bound&quot;&gt;l₁&lt;/a&gt; &lt;a id=&quot;13125&quot; href=&quot;non-idempotent-intersection-types.html#13034&quot; class=&quot;Datatype Operator&quot;&gt;⋈&lt;/a&gt; &lt;a id=&quot;13127&quot; href=&quot;non-idempotent-intersection-types.html#13114&quot; class=&quot;Bound&quot;&gt;l₂&lt;/a&gt; &lt;a id=&quot;13130&quot; class=&quot;Symbol&quot;&gt;-&amp;gt;&lt;/a&gt; &lt;a id=&quot;13133&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;13134&quot; href=&quot;non-idempotent-intersection-types.html#13109&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;13136&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;13138&quot; href=&quot;non-idempotent-intersection-types.html#13111&quot; class=&quot;Bound&quot;&gt;l₁&lt;/a&gt;&lt;a id=&quot;13140&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;13142&quot; href=&quot;non-idempotent-intersection-types.html#13034&quot; class=&quot;Datatype Operator&quot;&gt;⋈&lt;/a&gt; &lt;a id=&quot;13144&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;13145&quot; href=&quot;non-idempotent-intersection-types.html#13109&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;13147&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;13149&quot; href=&quot;non-idempotent-intersection-types.html#13114&quot; class=&quot;Bound&quot;&gt;l₂&lt;/a&gt;&lt;a id=&quot;13151&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
    &lt;a id=&quot;permutations._⋈_.swap&quot;&gt;&lt;/a&gt;&lt;a id=&quot;13157&quot; href=&quot;non-idempotent-intersection-types.html#13157&quot; class=&quot;InductiveConstructor&quot;&gt;swap&lt;/a&gt;    &lt;a id=&quot;13165&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;13167&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;13169&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;13170&quot; href=&quot;non-idempotent-intersection-types.html#13170&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;13172&quot; href=&quot;non-idempotent-intersection-types.html#13172&quot; class=&quot;Bound&quot;&gt;y&lt;/a&gt; &lt;a id=&quot;13174&quot; href=&quot;non-idempotent-intersection-types.html#13174&quot; class=&quot;Bound&quot;&gt;l&lt;/a&gt;&lt;a id=&quot;13175&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;    &lt;a id=&quot;13180&quot; class=&quot;Symbol&quot;&gt;-&amp;gt;&lt;/a&gt;           &lt;a id=&quot;13193&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;13194&quot; href=&quot;non-idempotent-intersection-types.html#13170&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;13196&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;13198&quot; href=&quot;non-idempotent-intersection-types.html#13172&quot; class=&quot;Bound&quot;&gt;y&lt;/a&gt; &lt;a id=&quot;13200&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;13202&quot; href=&quot;non-idempotent-intersection-types.html#13174&quot; class=&quot;Bound&quot;&gt;l&lt;/a&gt;&lt;a id=&quot;13203&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;13205&quot; href=&quot;non-idempotent-intersection-types.html#13034&quot; class=&quot;Datatype Operator&quot;&gt;⋈&lt;/a&gt; &lt;a id=&quot;13207&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;13208&quot; href=&quot;non-idempotent-intersection-types.html#13172&quot; class=&quot;Bound&quot;&gt;y&lt;/a&gt; &lt;a id=&quot;13210&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;13212&quot; href=&quot;non-idempotent-intersection-types.html#13170&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;13214&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;13216&quot; href=&quot;non-idempotent-intersection-types.html#13174&quot; class=&quot;Bound&quot;&gt;l&lt;/a&gt;&lt;a id=&quot;13217&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
    &lt;a id=&quot;permutations._⋈_.⋈-trans&quot;&gt;&lt;/a&gt;&lt;a id=&quot;13223&quot; href=&quot;non-idempotent-intersection-types.html#13223&quot; class=&quot;InductiveConstructor&quot;&gt;⋈-trans&lt;/a&gt; &lt;a id=&quot;13231&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;13233&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;13235&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;13236&quot; href=&quot;non-idempotent-intersection-types.html#13236&quot; class=&quot;Bound&quot;&gt;l₁&lt;/a&gt; &lt;a id=&quot;13239&quot; href=&quot;non-idempotent-intersection-types.html#13239&quot; class=&quot;Bound&quot;&gt;l₂&lt;/a&gt; &lt;a id=&quot;13242&quot; href=&quot;non-idempotent-intersection-types.html#13242&quot; class=&quot;Bound&quot;&gt;l₃&lt;/a&gt;&lt;a id=&quot;13244&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;13246&quot; class=&quot;Symbol&quot;&gt;-&amp;gt;&lt;/a&gt; &lt;a id=&quot;13249&quot; href=&quot;non-idempotent-intersection-types.html#13236&quot; class=&quot;Bound&quot;&gt;l₁&lt;/a&gt; &lt;a id=&quot;13252&quot; href=&quot;non-idempotent-intersection-types.html#13034&quot; class=&quot;Datatype Operator&quot;&gt;⋈&lt;/a&gt; &lt;a id=&quot;13254&quot; href=&quot;non-idempotent-intersection-types.html#13239&quot; class=&quot;Bound&quot;&gt;l₂&lt;/a&gt; &lt;a id=&quot;13257&quot; class=&quot;Symbol&quot;&gt;-&amp;gt;&lt;/a&gt; &lt;a id=&quot;13260&quot; href=&quot;non-idempotent-intersection-types.html#13239&quot; class=&quot;Bound&quot;&gt;l₂&lt;/a&gt; &lt;a id=&quot;13263&quot; href=&quot;non-idempotent-intersection-types.html#13034&quot; class=&quot;Datatype Operator&quot;&gt;⋈&lt;/a&gt; &lt;a id=&quot;13265&quot; href=&quot;non-idempotent-intersection-types.html#13242&quot; class=&quot;Bound&quot;&gt;l₃&lt;/a&gt; &lt;a id=&quot;13268&quot; class=&quot;Symbol&quot;&gt;-&amp;gt;&lt;/a&gt; &lt;a id=&quot;13271&quot; href=&quot;non-idempotent-intersection-types.html#13236&quot; class=&quot;Bound&quot;&gt;l₁&lt;/a&gt; &lt;a id=&quot;13274&quot; href=&quot;non-idempotent-intersection-types.html#13034&quot; class=&quot;Datatype Operator&quot;&gt;⋈&lt;/a&gt; &lt;a id=&quot;13276&quot; href=&quot;non-idempotent-intersection-types.html#13242&quot; class=&quot;Bound&quot;&gt;l₃&lt;/a&gt;

  &lt;a id=&quot;permutations.⋈-refl&quot;&gt;&lt;/a&gt;&lt;a id=&quot;13282&quot; href=&quot;non-idempotent-intersection-types.html#13282&quot; class=&quot;Function&quot;&gt;⋈-refl&lt;/a&gt; &lt;a id=&quot;13289&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;13291&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;13293&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;13294&quot; href=&quot;non-idempotent-intersection-types.html#13294&quot; class=&quot;Bound&quot;&gt;l&lt;/a&gt;&lt;a id=&quot;13295&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;13297&quot; class=&quot;Symbol&quot;&gt;-&amp;gt;&lt;/a&gt; &lt;a id=&quot;13300&quot; href=&quot;non-idempotent-intersection-types.html#13294&quot; class=&quot;Bound&quot;&gt;l&lt;/a&gt; &lt;a id=&quot;13302&quot; href=&quot;non-idempotent-intersection-types.html#13034&quot; class=&quot;Datatype Operator&quot;&gt;⋈&lt;/a&gt; &lt;a id=&quot;13304&quot; href=&quot;non-idempotent-intersection-types.html#13294&quot; class=&quot;Bound&quot;&gt;l&lt;/a&gt;
  &lt;a id=&quot;13308&quot; href=&quot;non-idempotent-intersection-types.html#13282&quot; class=&quot;Function&quot;&gt;⋈-refl&lt;/a&gt; &lt;a id=&quot;13315&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;13316&quot; href=&quot;Agda.Builtin.List.html#185&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt;&lt;a id=&quot;13318&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;    &lt;a id=&quot;13323&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;13325&quot; href=&quot;non-idempotent-intersection-types.html#13074&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;
  &lt;a id=&quot;13331&quot; href=&quot;non-idempotent-intersection-types.html#13282&quot; class=&quot;Function&quot;&gt;⋈-refl&lt;/a&gt; &lt;a id=&quot;13338&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;13339&quot; href=&quot;non-idempotent-intersection-types.html#13339&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;13341&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;13343&quot; href=&quot;non-idempotent-intersection-types.html#13343&quot; class=&quot;Bound&quot;&gt;l&lt;/a&gt;&lt;a id=&quot;13344&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;13346&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;13348&quot; href=&quot;non-idempotent-intersection-types.html#13096&quot; class=&quot;InductiveConstructor&quot;&gt;skip&lt;/a&gt; &lt;a id=&quot;13353&quot; href=&quot;non-idempotent-intersection-types.html#13282&quot; class=&quot;Function&quot;&gt;⋈-refl&lt;/a&gt;
&lt;a id=&quot;13360&quot; class=&quot;Keyword&quot;&gt;open&lt;/a&gt; &lt;a id=&quot;13365&quot; href=&quot;non-idempotent-intersection-types.html#12998&quot; class=&quot;Module&quot;&gt;permutations&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;We use permutations to define when two typing contexts are pointwise permutations of each other. I.e., when two contexts have the same number of variables, but the observations at each variable are permuted.&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;13600&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;_⋈ctx_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;13605&quot; href=&quot;non-idempotent-intersection-types.html#13605&quot; class=&quot;Datatype Operator&quot;&gt;_⋈ctx_&lt;/a&gt; &lt;a id=&quot;13612&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;13614&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;13616&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;13617&quot; href=&quot;non-idempotent-intersection-types.html#13617&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;13618&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;13620&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;13622&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;13626&quot; href=&quot;non-idempotent-intersection-types.html#13617&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;13628&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;13630&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;13634&quot; href=&quot;non-idempotent-intersection-types.html#13617&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;13636&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;13638&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;13642&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
  &lt;a id=&quot;_⋈ctx_.nil&quot;&gt;&lt;/a&gt;&lt;a id=&quot;13650&quot; href=&quot;non-idempotent-intersection-types.html#13650&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;13654&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;13656&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;13660&quot; href=&quot;non-idempotent-intersection-types.html#13605&quot; class=&quot;Datatype Operator&quot;&gt;⋈ctx&lt;/a&gt; &lt;a id=&quot;13665&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;
  &lt;a id=&quot;_⋈ctx_._,-_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;13671&quot; href=&quot;non-idempotent-intersection-types.html#13671&quot; class=&quot;InductiveConstructor Operator&quot;&gt;_,-_&lt;/a&gt; &lt;a id=&quot;13676&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;13678&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;13680&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;13681&quot; href=&quot;non-idempotent-intersection-types.html#13681&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;13682&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;13684&quot; href=&quot;non-idempotent-intersection-types.html#13684&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;13687&quot; href=&quot;non-idempotent-intersection-types.html#13687&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;13690&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;13692&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;13696&quot; href=&quot;non-idempotent-intersection-types.html#13681&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;13697&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;13699&quot; href=&quot;non-idempotent-intersection-types.html#13699&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;13702&quot; href=&quot;non-idempotent-intersection-types.html#13702&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;&lt;a id=&quot;13704&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;13706&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;13708&quot; href=&quot;non-idempotent-intersection-types.html#13684&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;13711&quot; href=&quot;non-idempotent-intersection-types.html#13605&quot; class=&quot;Datatype Operator&quot;&gt;⋈ctx&lt;/a&gt; &lt;a id=&quot;13716&quot; href=&quot;non-idempotent-intersection-types.html#13687&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;13719&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;13721&quot; href=&quot;non-idempotent-intersection-types.html#13699&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;13724&quot; href=&quot;non-idempotent-intersection-types.html#13034&quot; class=&quot;Datatype Operator&quot;&gt;⋈&lt;/a&gt; &lt;a id=&quot;13726&quot; href=&quot;non-idempotent-intersection-types.html#13702&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt; &lt;a id=&quot;13729&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;13731&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;13732&quot; href=&quot;non-idempotent-intersection-types.html#13684&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;13735&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;13738&quot; href=&quot;non-idempotent-intersection-types.html#13699&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;13740&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;13742&quot; href=&quot;non-idempotent-intersection-types.html#13605&quot; class=&quot;Datatype Operator&quot;&gt;⋈ctx&lt;/a&gt; &lt;a id=&quot;13747&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;13748&quot; href=&quot;non-idempotent-intersection-types.html#13687&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;13751&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;13754&quot; href=&quot;non-idempotent-intersection-types.html#13702&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;&lt;a id=&quot;13756&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;

&lt;a id=&quot;⋈ctx-refl&quot;&gt;&lt;/a&gt;&lt;a id=&quot;13759&quot; href=&quot;non-idempotent-intersection-types.html#13759&quot; class=&quot;Function&quot;&gt;⋈ctx-refl&lt;/a&gt; &lt;a id=&quot;13769&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;13771&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;13773&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;13774&quot; href=&quot;non-idempotent-intersection-types.html#13774&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;13775&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;13777&quot; href=&quot;non-idempotent-intersection-types.html#13777&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;13779&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;13781&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;13785&quot; href=&quot;non-idempotent-intersection-types.html#13774&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;13786&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;13788&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;13790&quot; href=&quot;non-idempotent-intersection-types.html#13777&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;13792&quot; href=&quot;non-idempotent-intersection-types.html#13605&quot; class=&quot;Datatype Operator&quot;&gt;⋈ctx&lt;/a&gt; &lt;a id=&quot;13797&quot; href=&quot;non-idempotent-intersection-types.html#13777&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt;
&lt;a id=&quot;13799&quot; href=&quot;non-idempotent-intersection-types.html#13759&quot; class=&quot;Function&quot;&gt;⋈ctx-refl&lt;/a&gt; &lt;a id=&quot;13809&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;13810&quot; class=&quot;Argument&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;13812&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;13814&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;13817&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;    &lt;a id=&quot;13822&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;13824&quot; href=&quot;non-idempotent-intersection-types.html#13650&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;
&lt;a id=&quot;13828&quot; href=&quot;non-idempotent-intersection-types.html#13759&quot; class=&quot;Function&quot;&gt;⋈ctx-refl&lt;/a&gt; &lt;a id=&quot;13838&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;13839&quot; class=&quot;Argument&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;13841&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;13843&quot; href=&quot;non-idempotent-intersection-types.html#13843&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;13845&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;13848&quot; href=&quot;non-idempotent-intersection-types.html#13848&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;13849&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;13851&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;13853&quot; href=&quot;non-idempotent-intersection-types.html#13759&quot; class=&quot;Function&quot;&gt;⋈ctx-refl&lt;/a&gt; &lt;a id=&quot;13863&quot; href=&quot;non-idempotent-intersection-types.html#13671&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;13866&quot; href=&quot;non-idempotent-intersection-types.html#13282&quot; class=&quot;Function&quot;&gt;⋈-refl&lt;/a&gt;
&lt;/pre&gt;
&lt;h4&gt;Type Assignment&lt;/h4&gt;&lt;p&gt;We can now define the rules of our system. First, we define what it means for a variable (represented as an Agda value of type &lt;code&gt;Fin n&lt;/code&gt;) to be well typed in a context:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;14075&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;_⊢v_⦂_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;14080&quot; href=&quot;non-idempotent-intersection-types.html#14080&quot; class=&quot;Datatype Operator&quot;&gt;_⊢v_⦂_&lt;/a&gt; &lt;a id=&quot;14087&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;14089&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;14091&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;14092&quot; href=&quot;non-idempotent-intersection-types.html#14092&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;14093&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;14095&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;14097&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;14101&quot; href=&quot;non-idempotent-intersection-types.html#14092&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;14103&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;14105&quot; href=&quot;Data.Fin.Base.html#1066&quot; class=&quot;Datatype&quot;&gt;Fin&lt;/a&gt; &lt;a id=&quot;14109&quot; href=&quot;non-idempotent-intersection-types.html#14092&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;14111&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;14113&quot; href=&quot;non-idempotent-intersection-types.html#8723&quot; class=&quot;Datatype&quot;&gt;type&lt;/a&gt; &lt;a id=&quot;14118&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;14120&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;14124&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
  &lt;a id=&quot;_⊢v_⦂_.zero&quot;&gt;&lt;/a&gt;&lt;a id=&quot;14132&quot; href=&quot;non-idempotent-intersection-types.html#14132&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt; &lt;a id=&quot;14137&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;14139&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;14141&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;14142&quot; href=&quot;non-idempotent-intersection-types.html#14142&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;14144&quot; href=&quot;non-idempotent-intersection-types.html#14144&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;14145&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;14147&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;14149&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;14150&quot; href=&quot;non-idempotent-intersection-types.html#12243&quot; class=&quot;Function&quot;&gt;empty&lt;/a&gt; &lt;a id=&quot;14156&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;14157&quot; href=&quot;non-idempotent-intersection-types.html#14142&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;14158&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;14160&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;14163&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;[&lt;/a&gt; &lt;a id=&quot;14165&quot; href=&quot;non-idempotent-intersection-types.html#14144&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;14167&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;]&lt;/a&gt;&lt;a id=&quot;14168&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;14170&quot; href=&quot;non-idempotent-intersection-types.html#14080&quot; class=&quot;Datatype Operator&quot;&gt;⊢v&lt;/a&gt; &lt;a id=&quot;14173&quot; href=&quot;Data.Fin.Base.html#1088&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt; &lt;a id=&quot;14178&quot; href=&quot;non-idempotent-intersection-types.html#14080&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;14180&quot; href=&quot;non-idempotent-intersection-types.html#14144&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;
  &lt;a id=&quot;_⊢v_⦂_.suc&quot;&gt;&lt;/a&gt;&lt;a id=&quot;14184&quot; href=&quot;non-idempotent-intersection-types.html#14184&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt;  &lt;a id=&quot;14189&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;14191&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;14193&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;14194&quot; href=&quot;non-idempotent-intersection-types.html#14194&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;14196&quot; href=&quot;non-idempotent-intersection-types.html#14196&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;14198&quot; href=&quot;non-idempotent-intersection-types.html#14198&quot; class=&quot;Bound&quot;&gt;i&lt;/a&gt;&lt;a id=&quot;14199&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;14201&quot; href=&quot;non-idempotent-intersection-types.html#14201&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;14203&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;14205&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;14209&quot; href=&quot;non-idempotent-intersection-types.html#14194&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;14210&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;14212&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;14214&quot; href=&quot;non-idempotent-intersection-types.html#14201&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;14216&quot; href=&quot;non-idempotent-intersection-types.html#14080&quot; class=&quot;Datatype Operator&quot;&gt;⊢v&lt;/a&gt; &lt;a id=&quot;14219&quot; href=&quot;non-idempotent-intersection-types.html#14198&quot; class=&quot;Bound&quot;&gt;i&lt;/a&gt; &lt;a id=&quot;14221&quot; href=&quot;non-idempotent-intersection-types.html#14080&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;14223&quot; href=&quot;non-idempotent-intersection-types.html#14196&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;14225&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;14227&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;14228&quot; href=&quot;non-idempotent-intersection-types.html#14201&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;14230&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;14233&quot; href=&quot;Agda.Builtin.List.html#185&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt;&lt;a id=&quot;14235&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;14237&quot; href=&quot;non-idempotent-intersection-types.html#14080&quot; class=&quot;Datatype Operator&quot;&gt;⊢v&lt;/a&gt; &lt;a id=&quot;14240&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;14241&quot; href=&quot;Data.Fin.Base.html#1119&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;14245&quot; href=&quot;non-idempotent-intersection-types.html#14198&quot; class=&quot;Bound&quot;&gt;i&lt;/a&gt;&lt;a id=&quot;14246&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;14248&quot; href=&quot;non-idempotent-intersection-types.html#14080&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;14250&quot; href=&quot;non-idempotent-intersection-types.html#14196&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;The key point here is that the context for a variable must require no behaviours for any variable that is not the one being selected, and must require exactly one behaviour for the one being selected. Thus one use a variable corresponds to one observation.&lt;/p&gt;&lt;p&gt;The typing rules for terms are mutually defined with a rule for typing a single term against an intersection type. I will explain the rules after the definition.&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;14686&quot; class=&quot;Keyword&quot;&gt;mutual&lt;/a&gt;
  &lt;a id=&quot;14695&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;_⊢_⦂_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;14700&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;_⊢_⦂_&lt;/a&gt; &lt;a id=&quot;14706&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;14708&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;14710&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;14711&quot; href=&quot;non-idempotent-intersection-types.html#14711&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;14712&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;14714&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;14716&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;14720&quot; href=&quot;non-idempotent-intersection-types.html#14711&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;14722&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;14724&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;14729&quot; href=&quot;non-idempotent-intersection-types.html#14711&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;14731&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;14733&quot; href=&quot;non-idempotent-intersection-types.html#8723&quot; class=&quot;Datatype&quot;&gt;type&lt;/a&gt; &lt;a id=&quot;14738&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;14740&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;14744&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
    &lt;a id=&quot;_⊢_⦂_.var&quot;&gt;&lt;/a&gt;&lt;a id=&quot;14754&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;14758&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;14760&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;14762&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;14763&quot; href=&quot;non-idempotent-intersection-types.html#14763&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;14765&quot; href=&quot;non-idempotent-intersection-types.html#14765&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;14767&quot; href=&quot;non-idempotent-intersection-types.html#14767&quot; class=&quot;Bound&quot;&gt;i&lt;/a&gt;&lt;a id=&quot;14768&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;14770&quot; href=&quot;non-idempotent-intersection-types.html#14770&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;14772&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;14774&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;14778&quot; href=&quot;non-idempotent-intersection-types.html#14763&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;14779&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;14781&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;14793&quot; href=&quot;non-idempotent-intersection-types.html#14770&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;14795&quot; href=&quot;non-idempotent-intersection-types.html#14080&quot; class=&quot;Datatype Operator&quot;&gt;⊢v&lt;/a&gt; &lt;a id=&quot;14798&quot; href=&quot;non-idempotent-intersection-types.html#14767&quot; class=&quot;Bound&quot;&gt;i&lt;/a&gt; &lt;a id=&quot;14800&quot; href=&quot;non-idempotent-intersection-types.html#14080&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;14802&quot; href=&quot;non-idempotent-intersection-types.html#14765&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;14804&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;14816&quot; href=&quot;non-idempotent-intersection-types.html#14770&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;14818&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;14820&quot; href=&quot;non-idempotent-intersection-types.html#2396&quot; class=&quot;InductiveConstructor Operator&quot;&gt;`&lt;/a&gt; &lt;a id=&quot;14822&quot; href=&quot;non-idempotent-intersection-types.html#14767&quot; class=&quot;Bound&quot;&gt;i&lt;/a&gt; &lt;a id=&quot;14824&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;14826&quot; href=&quot;non-idempotent-intersection-types.html#14765&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;
    &lt;a id=&quot;_⊢_⦂_.lam&quot;&gt;&lt;/a&gt;&lt;a id=&quot;14832&quot; href=&quot;non-idempotent-intersection-types.html#14832&quot; class=&quot;InductiveConstructor&quot;&gt;lam&lt;/a&gt; &lt;a id=&quot;14836&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;14838&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;14840&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;14841&quot; href=&quot;non-idempotent-intersection-types.html#14841&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;14843&quot; href=&quot;non-idempotent-intersection-types.html#14843&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;14845&quot; href=&quot;non-idempotent-intersection-types.html#14845&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;14847&quot; href=&quot;non-idempotent-intersection-types.html#14847&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;14848&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;14850&quot; href=&quot;non-idempotent-intersection-types.html#14850&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;14852&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;14854&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;14858&quot; href=&quot;non-idempotent-intersection-types.html#14841&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;14859&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;14861&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;14873&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;14874&quot; href=&quot;non-idempotent-intersection-types.html#14850&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;14876&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;14879&quot; href=&quot;non-idempotent-intersection-types.html#14843&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;14880&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;14882&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;14884&quot; href=&quot;non-idempotent-intersection-types.html#14847&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;14886&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;14888&quot; href=&quot;non-idempotent-intersection-types.html#14845&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;14890&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;14902&quot; href=&quot;non-idempotent-intersection-types.html#14850&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;14904&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;14906&quot; href=&quot;non-idempotent-intersection-types.html#2427&quot; class=&quot;InductiveConstructor&quot;&gt;ƛ&lt;/a&gt; &lt;a id=&quot;14908&quot; href=&quot;non-idempotent-intersection-types.html#14847&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;14910&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;14912&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;14913&quot; href=&quot;non-idempotent-intersection-types.html#14843&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;14915&quot; href=&quot;non-idempotent-intersection-types.html#8756&quot; class=&quot;InductiveConstructor Operator&quot;&gt;↦&lt;/a&gt; &lt;a id=&quot;14917&quot; href=&quot;non-idempotent-intersection-types.html#14845&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;14918&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
    &lt;a id=&quot;_⊢_⦂_.app&quot;&gt;&lt;/a&gt;&lt;a id=&quot;14924&quot; href=&quot;non-idempotent-intersection-types.html#14924&quot; class=&quot;InductiveConstructor&quot;&gt;app&lt;/a&gt; &lt;a id=&quot;14928&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;14930&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;14932&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;14933&quot; href=&quot;non-idempotent-intersection-types.html#14933&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;14935&quot; href=&quot;non-idempotent-intersection-types.html#14935&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;14937&quot; href=&quot;non-idempotent-intersection-types.html#14937&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;14939&quot; href=&quot;non-idempotent-intersection-types.html#14939&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;14941&quot; href=&quot;non-idempotent-intersection-types.html#14941&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;14942&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;14944&quot; href=&quot;non-idempotent-intersection-types.html#14944&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;14946&quot; href=&quot;non-idempotent-intersection-types.html#14946&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;14949&quot; href=&quot;non-idempotent-intersection-types.html#14949&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;14952&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;14954&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;14958&quot; href=&quot;non-idempotent-intersection-types.html#14933&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;14959&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;14961&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;14973&quot; href=&quot;non-idempotent-intersection-types.html#14946&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;14976&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;14978&quot; href=&quot;non-idempotent-intersection-types.html#14939&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;14980&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;14982&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;14983&quot; href=&quot;non-idempotent-intersection-types.html#14935&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;14985&quot; href=&quot;non-idempotent-intersection-types.html#8756&quot; class=&quot;InductiveConstructor Operator&quot;&gt;↦&lt;/a&gt; &lt;a id=&quot;14987&quot; href=&quot;non-idempotent-intersection-types.html#14937&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;14988&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;14990&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;15002&quot; href=&quot;non-idempotent-intersection-types.html#14949&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;15005&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;15007&quot; href=&quot;non-idempotent-intersection-types.html#14941&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;15009&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;15012&quot; href=&quot;non-idempotent-intersection-types.html#14935&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;15014&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;15026&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;15027&quot; href=&quot;non-idempotent-intersection-types.html#14946&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;15030&quot; href=&quot;non-idempotent-intersection-types.html#12553&quot; class=&quot;Function Operator&quot;&gt;+++&lt;/a&gt; &lt;a id=&quot;15034&quot; href=&quot;non-idempotent-intersection-types.html#14949&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt;&lt;a id=&quot;15036&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;15038&quot; href=&quot;non-idempotent-intersection-types.html#13605&quot; class=&quot;Datatype Operator&quot;&gt;⋈ctx&lt;/a&gt; &lt;a id=&quot;15043&quot; href=&quot;non-idempotent-intersection-types.html#14944&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;15045&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;15057&quot; href=&quot;non-idempotent-intersection-types.html#14944&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;15059&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;15061&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;15062&quot; href=&quot;non-idempotent-intersection-types.html#14939&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;15064&quot; href=&quot;non-idempotent-intersection-types.html#2465&quot; class=&quot;InductiveConstructor Operator&quot;&gt;·&lt;/a&gt; &lt;a id=&quot;15066&quot; href=&quot;non-idempotent-intersection-types.html#14941&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;15067&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;15069&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;15071&quot; href=&quot;non-idempotent-intersection-types.html#14937&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;
    &lt;a id=&quot;_⊢_⦂_.lam⋆&quot;&gt;&lt;/a&gt;&lt;a id=&quot;15077&quot; href=&quot;non-idempotent-intersection-types.html#15077&quot; class=&quot;InductiveConstructor&quot;&gt;lam⋆&lt;/a&gt; &lt;a id=&quot;15082&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;15084&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;15086&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;15087&quot; href=&quot;non-idempotent-intersection-types.html#15087&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;15089&quot; href=&quot;non-idempotent-intersection-types.html#15089&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;15090&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;15092&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;15104&quot; href=&quot;non-idempotent-intersection-types.html#12243&quot; class=&quot;Function&quot;&gt;empty&lt;/a&gt; &lt;a id=&quot;15110&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;15111&quot; href=&quot;non-idempotent-intersection-types.html#15087&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;15112&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;15114&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;15116&quot; href=&quot;non-idempotent-intersection-types.html#2427&quot; class=&quot;InductiveConstructor&quot;&gt;ƛ&lt;/a&gt; &lt;a id=&quot;15118&quot; href=&quot;non-idempotent-intersection-types.html#15089&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;15120&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;15122&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt;

  &lt;a id=&quot;15127&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;_⊢_⦂&amp;#39;_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;15132&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;_⊢_⦂&amp;#39;_&lt;/a&gt; &lt;a id=&quot;15139&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;15141&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;15143&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;15144&quot; href=&quot;non-idempotent-intersection-types.html#15144&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;15145&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;15147&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;15149&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;15153&quot; href=&quot;non-idempotent-intersection-types.html#15144&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;15155&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;15157&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;15162&quot; href=&quot;non-idempotent-intersection-types.html#15144&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;15164&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;15166&quot; href=&quot;Agda.Builtin.List.html#148&quot; class=&quot;Datatype&quot;&gt;List&lt;/a&gt; &lt;a id=&quot;15171&quot; href=&quot;non-idempotent-intersection-types.html#8723&quot; class=&quot;Datatype&quot;&gt;type&lt;/a&gt; &lt;a id=&quot;15176&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;15178&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;15182&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
    &lt;a id=&quot;_⊢_⦂&amp;#39;_.nil&quot;&gt;&lt;/a&gt;&lt;a id=&quot;15192&quot; href=&quot;non-idempotent-intersection-types.html#15192&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;15196&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;15198&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;15200&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;15201&quot; href=&quot;non-idempotent-intersection-types.html#15201&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;15202&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;15204&quot; href=&quot;non-idempotent-intersection-types.html#15204&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;15206&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;15208&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;15213&quot; href=&quot;non-idempotent-intersection-types.html#15201&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;15214&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;15216&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;15228&quot; href=&quot;non-idempotent-intersection-types.html#12243&quot; class=&quot;Function&quot;&gt;empty&lt;/a&gt; &lt;a id=&quot;15234&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;15236&quot; href=&quot;non-idempotent-intersection-types.html#15204&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;15238&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;15241&quot; href=&quot;Agda.Builtin.List.html#185&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt;
    &lt;a id=&quot;_⊢_⦂&amp;#39;_._,~_∷_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;15248&quot; href=&quot;non-idempotent-intersection-types.html#15248&quot; class=&quot;InductiveConstructor Operator&quot;&gt;_,~_∷_&lt;/a&gt; &lt;a id=&quot;15255&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;15257&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;15259&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;15260&quot; href=&quot;non-idempotent-intersection-types.html#15260&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;15262&quot; href=&quot;non-idempotent-intersection-types.html#15262&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;15264&quot; href=&quot;non-idempotent-intersection-types.html#15264&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;15266&quot; href=&quot;non-idempotent-intersection-types.html#15266&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;15267&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;15269&quot; href=&quot;non-idempotent-intersection-types.html#15269&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;15272&quot; href=&quot;non-idempotent-intersection-types.html#15272&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;15275&quot; href=&quot;non-idempotent-intersection-types.html#15275&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;15277&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;15279&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;15283&quot; href=&quot;non-idempotent-intersection-types.html#15260&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;15284&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;15286&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;15298&quot; href=&quot;non-idempotent-intersection-types.html#15269&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;15301&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;15303&quot; href=&quot;non-idempotent-intersection-types.html#15262&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;15305&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;15307&quot; href=&quot;non-idempotent-intersection-types.html#15266&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;15309&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;15321&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;15322&quot; href=&quot;non-idempotent-intersection-types.html#15269&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;15325&quot; href=&quot;non-idempotent-intersection-types.html#12553&quot; class=&quot;Function Operator&quot;&gt;+++&lt;/a&gt; &lt;a id=&quot;15329&quot; href=&quot;non-idempotent-intersection-types.html#15272&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt;&lt;a id=&quot;15331&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;15333&quot; href=&quot;non-idempotent-intersection-types.html#13605&quot; class=&quot;Datatype Operator&quot;&gt;⋈ctx&lt;/a&gt; &lt;a id=&quot;15338&quot; href=&quot;non-idempotent-intersection-types.html#15275&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;15340&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;15352&quot; href=&quot;non-idempotent-intersection-types.html#15272&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;15355&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;15357&quot; href=&quot;non-idempotent-intersection-types.html#15262&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;15359&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;15362&quot; href=&quot;non-idempotent-intersection-types.html#15264&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;15364&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;15376&quot; href=&quot;non-idempotent-intersection-types.html#15275&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;15378&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;15380&quot; href=&quot;non-idempotent-intersection-types.html#15262&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;15382&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;15385&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;15386&quot; href=&quot;non-idempotent-intersection-types.html#15266&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;15388&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;15390&quot; href=&quot;non-idempotent-intersection-types.html#15264&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;15391&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;The rule &lt;code&gt;var&lt;/code&gt; uses the variable typing judgement to assign types to terms that are variables. The rule &lt;code&gt;lam&lt;/code&gt; states that a λ abstraction can be assigned the type &lt;code&gt;σ ↦ τ&lt;/code&gt; if the body can be assigned the type &lt;code&gt;τ&lt;/code&gt; under the assumption that the &lt;code&gt;0&lt;/code&gt;th variable has the intersection type &lt;code&gt;σ&lt;/code&gt;. The &lt;code&gt;app&lt;/code&gt; rule states that if the term &lt;code&gt;s&lt;/code&gt; can be observed to act like a function mapping intersections of behaviours &lt;code&gt;σ&lt;/code&gt; to behaviours &lt;code&gt;τ&lt;/code&gt;, and the term &lt;code&gt;t&lt;/code&gt; exhibits &lt;em&gt;all&lt;/em&gt; the behaviours in &lt;code&gt;σ&lt;/code&gt; (using the auxiliary judgement &lt;code&gt;_⊢_⦂'_&lt;/code&gt;), then the whole application term exhibits the behaviour &lt;code&gt;τ&lt;/code&gt;. Note that the two terms are typed in separate contexts that are combined -- so the uses of variables in &lt;code&gt;s&lt;/code&gt; and &lt;code&gt;t&lt;/code&gt; are tracked separately. The rule &lt;code&gt;lam⋆&lt;/code&gt; is used to assign the observation that λ abstractions are values (&lt;code&gt;⋆&lt;/code&gt; means that the term is a value) to any λ abstraction.&lt;/p&gt;&lt;p&gt;The auxiliary judgement &lt;code&gt;Γ ⊢ t ⦂' σ&lt;/code&gt; is used to ensure that a single term &lt;code&gt;t&lt;/code&gt; can exhibit all the possible behaviours in &lt;code&gt;σ&lt;/code&gt;. Note that each individual behaviour in &lt;code&gt;σ&lt;/code&gt; must be observable under a separate typing context. All the typing contexts are summed up (up to permutation), to give the complete requirements on the context.&lt;/p&gt;&lt;p&gt;This completes the definition of the type assignment system. We demonstrate it using the two terms from above. These are defined as follows:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;16745&quot; class=&quot;Comment&quot;&gt;--- λf. λx. f x&lt;/a&gt;
&lt;a id=&quot;example₁&quot;&gt;&lt;/a&gt;&lt;a id=&quot;16761&quot; href=&quot;non-idempotent-intersection-types.html#16761&quot; class=&quot;Function&quot;&gt;example₁&lt;/a&gt; &lt;a id=&quot;16770&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;16772&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;16777&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;
&lt;a id=&quot;16779&quot; href=&quot;non-idempotent-intersection-types.html#16761&quot; class=&quot;Function&quot;&gt;example₁&lt;/a&gt; &lt;a id=&quot;16788&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;16790&quot; href=&quot;non-idempotent-intersection-types.html#2427&quot; class=&quot;InductiveConstructor&quot;&gt;ƛ&lt;/a&gt; &lt;a id=&quot;16792&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;16793&quot; href=&quot;non-idempotent-intersection-types.html#2427&quot; class=&quot;InductiveConstructor&quot;&gt;ƛ&lt;/a&gt; &lt;a id=&quot;16795&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;16796&quot; href=&quot;non-idempotent-intersection-types.html#2396&quot; class=&quot;InductiveConstructor Operator&quot;&gt;`&lt;/a&gt; &lt;a id=&quot;16798&quot; href=&quot;Data.Fin.Base.html#1119&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;16802&quot; href=&quot;Data.Fin.Base.html#1088&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt; &lt;a id=&quot;16807&quot; href=&quot;non-idempotent-intersection-types.html#2465&quot; class=&quot;InductiveConstructor Operator&quot;&gt;·&lt;/a&gt; &lt;a id=&quot;16809&quot; href=&quot;non-idempotent-intersection-types.html#2396&quot; class=&quot;InductiveConstructor Operator&quot;&gt;`&lt;/a&gt; &lt;a id=&quot;16811&quot; href=&quot;Data.Fin.Base.html#1088&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;16815&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt;

&lt;a id=&quot;16819&quot; class=&quot;Comment&quot;&gt;-- λf. λx. f (f x)&lt;/a&gt;
&lt;a id=&quot;example₂&quot;&gt;&lt;/a&gt;&lt;a id=&quot;16838&quot; href=&quot;non-idempotent-intersection-types.html#16838&quot; class=&quot;Function&quot;&gt;example₂&lt;/a&gt; &lt;a id=&quot;16847&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;16849&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;16854&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;
&lt;a id=&quot;16856&quot; href=&quot;non-idempotent-intersection-types.html#16838&quot; class=&quot;Function&quot;&gt;example₂&lt;/a&gt; &lt;a id=&quot;16865&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;16867&quot; href=&quot;non-idempotent-intersection-types.html#2427&quot; class=&quot;InductiveConstructor&quot;&gt;ƛ&lt;/a&gt; &lt;a id=&quot;16869&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;16870&quot; href=&quot;non-idempotent-intersection-types.html#2427&quot; class=&quot;InductiveConstructor&quot;&gt;ƛ&lt;/a&gt; &lt;a id=&quot;16872&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;16873&quot; href=&quot;non-idempotent-intersection-types.html#2396&quot; class=&quot;InductiveConstructor Operator&quot;&gt;`&lt;/a&gt; &lt;a id=&quot;16875&quot; href=&quot;Data.Fin.Base.html#1119&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;16879&quot; href=&quot;Data.Fin.Base.html#1088&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt; &lt;a id=&quot;16884&quot; href=&quot;non-idempotent-intersection-types.html#2465&quot; class=&quot;InductiveConstructor Operator&quot;&gt;·&lt;/a&gt; &lt;a id=&quot;16886&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;16887&quot; href=&quot;non-idempotent-intersection-types.html#2396&quot; class=&quot;InductiveConstructor Operator&quot;&gt;`&lt;/a&gt; &lt;a id=&quot;16889&quot; href=&quot;Data.Fin.Base.html#1119&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;16893&quot; href=&quot;Data.Fin.Base.html#1088&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt; &lt;a id=&quot;16898&quot; href=&quot;non-idempotent-intersection-types.html#2465&quot; class=&quot;InductiveConstructor Operator&quot;&gt;·&lt;/a&gt; &lt;a id=&quot;16900&quot; href=&quot;non-idempotent-intersection-types.html#2396&quot; class=&quot;InductiveConstructor Operator&quot;&gt;`&lt;/a&gt; &lt;a id=&quot;16902&quot; href=&quot;Data.Fin.Base.html#1088&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;16906&quot; class=&quot;Symbol&quot;&gt;)))&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;To give typing derivations for these, we will save a bit of typing by using the following derived rule for application when we apply a function that will only use its argument once:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;app₁&quot;&gt;&lt;/a&gt;&lt;a id=&quot;17106&quot; href=&quot;non-idempotent-intersection-types.html#17106&quot; class=&quot;Function&quot;&gt;app₁&lt;/a&gt; &lt;a id=&quot;17111&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;17113&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;17115&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;17116&quot; href=&quot;non-idempotent-intersection-types.html#17116&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;17118&quot; href=&quot;non-idempotent-intersection-types.html#17118&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;17121&quot; href=&quot;non-idempotent-intersection-types.html#17121&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;17124&quot; href=&quot;non-idempotent-intersection-types.html#17124&quot; class=&quot;Bound&quot;&gt;τ₁&lt;/a&gt; &lt;a id=&quot;17127&quot; href=&quot;non-idempotent-intersection-types.html#17127&quot; class=&quot;Bound&quot;&gt;τ₂&lt;/a&gt;&lt;a id=&quot;17129&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;17131&quot; href=&quot;non-idempotent-intersection-types.html#17131&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;17133&quot; href=&quot;non-idempotent-intersection-types.html#17133&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;17135&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;17137&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;17142&quot; href=&quot;non-idempotent-intersection-types.html#17116&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;17143&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;17145&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
      &lt;a id=&quot;17153&quot; href=&quot;non-idempotent-intersection-types.html#17118&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;17156&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;17158&quot; href=&quot;non-idempotent-intersection-types.html#17131&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;17160&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;17162&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;[&lt;/a&gt; &lt;a id=&quot;17164&quot; href=&quot;non-idempotent-intersection-types.html#17124&quot; class=&quot;Bound&quot;&gt;τ₁&lt;/a&gt; &lt;a id=&quot;17167&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;]&lt;/a&gt; &lt;a id=&quot;17169&quot; href=&quot;non-idempotent-intersection-types.html#8756&quot; class=&quot;InductiveConstructor Operator&quot;&gt;↦&lt;/a&gt; &lt;a id=&quot;17171&quot; href=&quot;non-idempotent-intersection-types.html#17127&quot; class=&quot;Bound&quot;&gt;τ₂&lt;/a&gt; &lt;a id=&quot;17174&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
      &lt;a id=&quot;17182&quot; href=&quot;non-idempotent-intersection-types.html#17121&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;17185&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;17187&quot; href=&quot;non-idempotent-intersection-types.html#17133&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;17189&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;17191&quot; href=&quot;non-idempotent-intersection-types.html#17124&quot; class=&quot;Bound&quot;&gt;τ₁&lt;/a&gt; &lt;a id=&quot;17194&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
      &lt;a id=&quot;17202&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17203&quot; href=&quot;non-idempotent-intersection-types.html#17118&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;17206&quot; href=&quot;non-idempotent-intersection-types.html#12553&quot; class=&quot;Function Operator&quot;&gt;+++&lt;/a&gt; &lt;a id=&quot;17210&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17211&quot; href=&quot;non-idempotent-intersection-types.html#17121&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;17214&quot; href=&quot;non-idempotent-intersection-types.html#12553&quot; class=&quot;Function Operator&quot;&gt;+++&lt;/a&gt; &lt;a id=&quot;17218&quot; href=&quot;non-idempotent-intersection-types.html#12243&quot; class=&quot;Function&quot;&gt;empty&lt;/a&gt;&lt;a id=&quot;17223&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;17226&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;17228&quot; href=&quot;non-idempotent-intersection-types.html#17131&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;17230&quot; href=&quot;non-idempotent-intersection-types.html#2465&quot; class=&quot;InductiveConstructor Operator&quot;&gt;·&lt;/a&gt; &lt;a id=&quot;17232&quot; href=&quot;non-idempotent-intersection-types.html#17133&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;17234&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;17236&quot; href=&quot;non-idempotent-intersection-types.html#17127&quot; class=&quot;Bound&quot;&gt;τ₂&lt;/a&gt;
&lt;a id=&quot;17239&quot; href=&quot;non-idempotent-intersection-types.html#17106&quot; class=&quot;Function&quot;&gt;app₁&lt;/a&gt; &lt;a id=&quot;17244&quot; href=&quot;non-idempotent-intersection-types.html#17244&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt; &lt;a id=&quot;17249&quot; href=&quot;non-idempotent-intersection-types.html#17249&quot; class=&quot;Bound&quot;&gt;t-ok&lt;/a&gt; &lt;a id=&quot;17254&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;17256&quot; href=&quot;non-idempotent-intersection-types.html#14924&quot; class=&quot;InductiveConstructor&quot;&gt;app&lt;/a&gt; &lt;a id=&quot;17260&quot; href=&quot;non-idempotent-intersection-types.html#17244&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt; &lt;a id=&quot;17265&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17266&quot; href=&quot;non-idempotent-intersection-types.html#17249&quot; class=&quot;Bound&quot;&gt;t-ok&lt;/a&gt; &lt;a id=&quot;17271&quot; href=&quot;non-idempotent-intersection-types.html#15248&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,~&lt;/a&gt; &lt;a id=&quot;17274&quot; href=&quot;non-idempotent-intersection-types.html#13759&quot; class=&quot;Function&quot;&gt;⋈ctx-refl&lt;/a&gt; &lt;a id=&quot;17284&quot; href=&quot;non-idempotent-intersection-types.html#15248&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;17286&quot; href=&quot;non-idempotent-intersection-types.html#15192&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;17289&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;17291&quot; href=&quot;non-idempotent-intersection-types.html#13759&quot; class=&quot;Function&quot;&gt;⋈ctx-refl&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;With this derived rule to help us, the first example can be assigned the type we gave above like so:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;typing₁&quot;&gt;&lt;/a&gt;&lt;a id=&quot;17416&quot; href=&quot;non-idempotent-intersection-types.html#17416&quot; class=&quot;Function&quot;&gt;typing₁&lt;/a&gt; &lt;a id=&quot;17424&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;17426&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;17430&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;17432&quot; href=&quot;non-idempotent-intersection-types.html#16761&quot; class=&quot;Function&quot;&gt;example₁&lt;/a&gt; &lt;a id=&quot;17441&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;17443&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;[&lt;/a&gt; &lt;a id=&quot;17445&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;[&lt;/a&gt; &lt;a id=&quot;17447&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;17449&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;]&lt;/a&gt; &lt;a id=&quot;17451&quot; href=&quot;non-idempotent-intersection-types.html#8756&quot; class=&quot;InductiveConstructor Operator&quot;&gt;↦&lt;/a&gt; &lt;a id=&quot;17453&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;17455&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;]&lt;/a&gt; &lt;a id=&quot;17457&quot; href=&quot;non-idempotent-intersection-types.html#8756&quot; class=&quot;InductiveConstructor Operator&quot;&gt;↦&lt;/a&gt; &lt;a id=&quot;17459&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;[&lt;/a&gt; &lt;a id=&quot;17461&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;17463&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;]&lt;/a&gt; &lt;a id=&quot;17465&quot; href=&quot;non-idempotent-intersection-types.html#8756&quot; class=&quot;InductiveConstructor Operator&quot;&gt;↦&lt;/a&gt; &lt;a id=&quot;17467&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt;
&lt;a id=&quot;17469&quot; href=&quot;non-idempotent-intersection-types.html#17416&quot; class=&quot;Function&quot;&gt;typing₁&lt;/a&gt; &lt;a id=&quot;17477&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;17479&quot; href=&quot;non-idempotent-intersection-types.html#14832&quot; class=&quot;InductiveConstructor&quot;&gt;lam&lt;/a&gt; &lt;a id=&quot;17483&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17484&quot; href=&quot;non-idempotent-intersection-types.html#14832&quot; class=&quot;InductiveConstructor&quot;&gt;lam&lt;/a&gt; &lt;a id=&quot;17488&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17489&quot; href=&quot;non-idempotent-intersection-types.html#17106&quot; class=&quot;Function&quot;&gt;app₁&lt;/a&gt; &lt;a id=&quot;17494&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17495&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;17499&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17500&quot; href=&quot;non-idempotent-intersection-types.html#14184&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;17504&quot; href=&quot;non-idempotent-intersection-types.html#14132&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;17508&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;17511&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17512&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;17516&quot; href=&quot;non-idempotent-intersection-types.html#14132&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;17520&quot; class=&quot;Symbol&quot;&gt;)))&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;And the second one like so:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;typing₂&quot;&gt;&lt;/a&gt;&lt;a id=&quot;17566&quot; href=&quot;non-idempotent-intersection-types.html#17566&quot; class=&quot;Function&quot;&gt;typing₂&lt;/a&gt; &lt;a id=&quot;17574&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;17576&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;17580&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;17582&quot; href=&quot;non-idempotent-intersection-types.html#16838&quot; class=&quot;Function&quot;&gt;example₂&lt;/a&gt; &lt;a id=&quot;17591&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;17593&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17594&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;[&lt;/a&gt; &lt;a id=&quot;17596&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;17598&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;]&lt;/a&gt; &lt;a id=&quot;17600&quot; href=&quot;non-idempotent-intersection-types.html#8756&quot; class=&quot;InductiveConstructor Operator&quot;&gt;↦&lt;/a&gt; &lt;a id=&quot;17602&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;17604&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;17606&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;[&lt;/a&gt; &lt;a id=&quot;17608&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;17610&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;]&lt;/a&gt; &lt;a id=&quot;17612&quot; href=&quot;non-idempotent-intersection-types.html#8756&quot; class=&quot;InductiveConstructor Operator&quot;&gt;↦&lt;/a&gt; &lt;a id=&quot;17614&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;17616&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;17618&quot; href=&quot;Agda.Builtin.List.html#185&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt;&lt;a id=&quot;17620&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;17622&quot; href=&quot;non-idempotent-intersection-types.html#8756&quot; class=&quot;InductiveConstructor Operator&quot;&gt;↦&lt;/a&gt; &lt;a id=&quot;17624&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;[&lt;/a&gt; &lt;a id=&quot;17626&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;17628&quot; href=&quot;Data.List.Base.html#4458&quot; class=&quot;Function Operator&quot;&gt;]&lt;/a&gt; &lt;a id=&quot;17630&quot; href=&quot;non-idempotent-intersection-types.html#8756&quot; class=&quot;InductiveConstructor Operator&quot;&gt;↦&lt;/a&gt; &lt;a id=&quot;17632&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt;
&lt;a id=&quot;17634&quot; href=&quot;non-idempotent-intersection-types.html#17566&quot; class=&quot;Function&quot;&gt;typing₂&lt;/a&gt; &lt;a id=&quot;17642&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;17644&quot; href=&quot;non-idempotent-intersection-types.html#14832&quot; class=&quot;InductiveConstructor&quot;&gt;lam&lt;/a&gt; &lt;a id=&quot;17648&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17649&quot; href=&quot;non-idempotent-intersection-types.html#14832&quot; class=&quot;InductiveConstructor&quot;&gt;lam&lt;/a&gt; &lt;a id=&quot;17653&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17654&quot; href=&quot;non-idempotent-intersection-types.html#17106&quot; class=&quot;Function&quot;&gt;app₁&lt;/a&gt; &lt;a id=&quot;17659&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17660&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;17664&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17665&quot; href=&quot;non-idempotent-intersection-types.html#14184&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;17669&quot; href=&quot;non-idempotent-intersection-types.html#14132&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;17673&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;17676&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17677&quot; href=&quot;non-idempotent-intersection-types.html#17106&quot; class=&quot;Function&quot;&gt;app₁&lt;/a&gt; &lt;a id=&quot;17682&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17683&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;17687&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17688&quot; href=&quot;non-idempotent-intersection-types.html#14184&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;17692&quot; href=&quot;non-idempotent-intersection-types.html#14132&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;17696&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;17699&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;17700&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;17704&quot; href=&quot;non-idempotent-intersection-types.html#14132&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;17708&quot; class=&quot;Symbol&quot;&gt;))))&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;In the second one we see how the type reveals that the term uses its first argument twice.&lt;/p&gt;&lt;h4&gt;Measuring the sizes of derivations&lt;/h4&gt;&lt;p&gt;Our main result below is that typing is preserved by execution &lt;em&gt;quantitatively&lt;/em&gt;. Therefore, we need to be able to compute the sizes of typing derivations. This is done by the following three functions:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;v-size&quot;&gt;&lt;/a&gt;&lt;a id=&quot;18061&quot; href=&quot;non-idempotent-intersection-types.html#18061&quot; class=&quot;Function&quot;&gt;v-size&lt;/a&gt; &lt;a id=&quot;18068&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;18070&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;18072&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;18073&quot; href=&quot;non-idempotent-intersection-types.html#18073&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;18074&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;18076&quot; href=&quot;non-idempotent-intersection-types.html#18076&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;18078&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;18080&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;18084&quot; href=&quot;non-idempotent-intersection-types.html#18073&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;18085&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;18087&quot; href=&quot;non-idempotent-intersection-types.html#18087&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;18089&quot; href=&quot;non-idempotent-intersection-types.html#18089&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;18090&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;18092&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;18094&quot; href=&quot;non-idempotent-intersection-types.html#18076&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;18096&quot; href=&quot;non-idempotent-intersection-types.html#14080&quot; class=&quot;Datatype Operator&quot;&gt;⊢v&lt;/a&gt; &lt;a id=&quot;18099&quot; href=&quot;non-idempotent-intersection-types.html#18087&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;18101&quot; href=&quot;non-idempotent-intersection-types.html#14080&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;18103&quot; href=&quot;non-idempotent-intersection-types.html#18089&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;18105&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;18107&quot; href=&quot;Agda.Builtin.Nat.html#192&quot; class=&quot;Datatype&quot;&gt;ℕ&lt;/a&gt;
&lt;a id=&quot;18109&quot; href=&quot;non-idempotent-intersection-types.html#18061&quot; class=&quot;Function&quot;&gt;v-size&lt;/a&gt; &lt;a id=&quot;18116&quot; href=&quot;non-idempotent-intersection-types.html#14132&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;    &lt;a id=&quot;18124&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;18126&quot; class=&quot;Number&quot;&gt;1&lt;/a&gt;
&lt;a id=&quot;18128&quot; href=&quot;non-idempotent-intersection-types.html#18061&quot; class=&quot;Function&quot;&gt;v-size&lt;/a&gt; &lt;a id=&quot;18135&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;18136&quot; href=&quot;non-idempotent-intersection-types.html#14184&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;18140&quot; href=&quot;non-idempotent-intersection-types.html#18140&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;18141&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;18143&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;18145&quot; class=&quot;Number&quot;&gt;1&lt;/a&gt; &lt;a id=&quot;18147&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;18149&quot; href=&quot;non-idempotent-intersection-types.html#18061&quot; class=&quot;Function&quot;&gt;v-size&lt;/a&gt; &lt;a id=&quot;18156&quot; href=&quot;non-idempotent-intersection-types.html#18140&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;

&lt;a id=&quot;18159&quot; class=&quot;Keyword&quot;&gt;mutual&lt;/a&gt;
  &lt;a id=&quot;size&quot;&gt;&lt;/a&gt;&lt;a id=&quot;18168&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;18173&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;18175&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;18177&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;18178&quot; href=&quot;non-idempotent-intersection-types.html#18178&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;18179&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;18181&quot; href=&quot;non-idempotent-intersection-types.html#18181&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;18183&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;18185&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;18189&quot; href=&quot;non-idempotent-intersection-types.html#18178&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;18190&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;18192&quot; href=&quot;non-idempotent-intersection-types.html#18192&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;18194&quot; href=&quot;non-idempotent-intersection-types.html#18194&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;18195&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;18197&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;18199&quot; href=&quot;non-idempotent-intersection-types.html#18181&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;18201&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;18203&quot; href=&quot;non-idempotent-intersection-types.html#18192&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;18205&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;18207&quot; href=&quot;non-idempotent-intersection-types.html#18194&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;18209&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;18211&quot; href=&quot;Agda.Builtin.Nat.html#192&quot; class=&quot;Datatype&quot;&gt;ℕ&lt;/a&gt;
  &lt;a id=&quot;18215&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;18220&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;18221&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;18225&quot; href=&quot;non-idempotent-intersection-types.html#18225&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;18226&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;      &lt;a id=&quot;18233&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;18235&quot; href=&quot;non-idempotent-intersection-types.html#18061&quot; class=&quot;Function&quot;&gt;v-size&lt;/a&gt; &lt;a id=&quot;18242&quot; href=&quot;non-idempotent-intersection-types.html#18225&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;
  &lt;a id=&quot;18246&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;18251&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;18252&quot; href=&quot;non-idempotent-intersection-types.html#14832&quot; class=&quot;InductiveConstructor&quot;&gt;lam&lt;/a&gt; &lt;a id=&quot;18256&quot; href=&quot;non-idempotent-intersection-types.html#18256&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;18257&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;      &lt;a id=&quot;18264&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;18266&quot; class=&quot;Number&quot;&gt;1&lt;/a&gt; &lt;a id=&quot;18268&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;18270&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;18275&quot; href=&quot;non-idempotent-intersection-types.html#18256&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;
  &lt;a id=&quot;18279&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;18284&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;18285&quot; href=&quot;non-idempotent-intersection-types.html#14924&quot; class=&quot;InductiveConstructor&quot;&gt;app&lt;/a&gt; &lt;a id=&quot;18289&quot; href=&quot;non-idempotent-intersection-types.html#18289&quot; class=&quot;Bound&quot;&gt;d₁&lt;/a&gt; &lt;a id=&quot;18292&quot; href=&quot;non-idempotent-intersection-types.html#18292&quot; class=&quot;Bound&quot;&gt;d₂&lt;/a&gt; &lt;a id=&quot;18295&quot; class=&quot;Symbol&quot;&gt;_)&lt;/a&gt; &lt;a id=&quot;18298&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;18300&quot; class=&quot;Number&quot;&gt;1&lt;/a&gt; &lt;a id=&quot;18302&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;18304&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;18309&quot; href=&quot;non-idempotent-intersection-types.html#18289&quot; class=&quot;Bound&quot;&gt;d₁&lt;/a&gt; &lt;a id=&quot;18312&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;18314&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;18320&quot; href=&quot;non-idempotent-intersection-types.html#18292&quot; class=&quot;Bound&quot;&gt;d₂&lt;/a&gt;
  &lt;a id=&quot;18325&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;18330&quot; href=&quot;non-idempotent-intersection-types.html#15077&quot; class=&quot;InductiveConstructor&quot;&gt;lam⋆&lt;/a&gt;         &lt;a id=&quot;18343&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;18345&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;

  &lt;a id=&quot;size&amp;#39;&quot;&gt;&lt;/a&gt;&lt;a id=&quot;18350&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;18356&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;18358&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;18360&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;18361&quot; href=&quot;non-idempotent-intersection-types.html#18361&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;18362&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;18364&quot; href=&quot;non-idempotent-intersection-types.html#18364&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;18366&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;18368&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;18372&quot; href=&quot;non-idempotent-intersection-types.html#18361&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;18373&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;18375&quot; href=&quot;non-idempotent-intersection-types.html#18375&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;18377&quot; href=&quot;non-idempotent-intersection-types.html#18377&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;18378&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;18380&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;18382&quot; href=&quot;non-idempotent-intersection-types.html#18364&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;18384&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;18386&quot; href=&quot;non-idempotent-intersection-types.html#18375&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;18388&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;18391&quot; href=&quot;non-idempotent-intersection-types.html#18377&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;18393&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;18395&quot; href=&quot;Agda.Builtin.Nat.html#192&quot; class=&quot;Datatype&quot;&gt;ℕ&lt;/a&gt;
  &lt;a id=&quot;18399&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;18405&quot; href=&quot;non-idempotent-intersection-types.html#15192&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;           &lt;a id=&quot;18419&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;18421&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;
  &lt;a id=&quot;18425&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;18431&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;18432&quot; href=&quot;non-idempotent-intersection-types.html#18432&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;18434&quot; href=&quot;non-idempotent-intersection-types.html#15248&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,~&lt;/a&gt; &lt;a id=&quot;18437&quot; class=&quot;Symbol&quot;&gt;_&lt;/a&gt; &lt;a id=&quot;18439&quot; href=&quot;non-idempotent-intersection-types.html#15248&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;18441&quot; href=&quot;non-idempotent-intersection-types.html#18441&quot; class=&quot;Bound&quot;&gt;ds&lt;/a&gt;&lt;a id=&quot;18443&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;18445&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;18447&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;18452&quot; href=&quot;non-idempotent-intersection-types.html#18432&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;18454&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;18456&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;18462&quot; href=&quot;non-idempotent-intersection-types.html#18441&quot; class=&quot;Bound&quot;&gt;ds&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;We have been a little selective in what we have counted. We have added &lt;code&gt;1&lt;/code&gt; for every construct that can cause the KAM to make a step: whether a variable lookup (&lt;code&gt;zero&lt;/code&gt; or &lt;code&gt;suc&lt;/code&gt;), an application, or a λ abstraction that we expect to have some interesting behaviour. In particular a use of &lt;code&gt;lam⋆&lt;/code&gt; is counted as &lt;code&gt;0&lt;/code&gt; because it represents values that will not be inspected any further, and so will not cause the KAM to do any work.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;size'&lt;/code&gt; function adds up all the derivations used in checking an intersection type. This means that we accurately account for all the possible ways that a single term will be used.&lt;/p&gt;&lt;h3&gt;Typing KAM configurations.&lt;/h3&gt;&lt;p&gt;We now extend the non-idempotent intersection typing discipline from terms to configurations of the KAM. This is required so that we can state our main lemmas.&lt;/p&gt;&lt;p&gt;Closures are typed by ensuring that the term contained in them is well typed for some context, and the associated environment is contains closures well typed according to that context. Because contexts contain intersection types, we need an auxiliary judgement that checks that a closure is well typed for all types in an intersection. These three judgements (closures, environments, closures with intersection types) need to be mutually defined:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;19733&quot; class=&quot;Keyword&quot;&gt;mutual&lt;/a&gt;
  &lt;a id=&quot;19742&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;⊢c_⦂_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;19747&quot; href=&quot;non-idempotent-intersection-types.html#19747&quot; class=&quot;Datatype Operator&quot;&gt;⊢c_⦂_&lt;/a&gt; &lt;a id=&quot;19753&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;19755&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;19756&quot; href=&quot;non-idempotent-intersection-types.html#19756&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;19758&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;19760&quot; href=&quot;non-idempotent-intersection-types.html#3831&quot; class=&quot;Function&quot;&gt;clo&lt;/a&gt;&lt;a id=&quot;19763&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;19765&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;19766&quot; href=&quot;non-idempotent-intersection-types.html#19766&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;19768&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;19770&quot; href=&quot;non-idempotent-intersection-types.html#8723&quot; class=&quot;Datatype&quot;&gt;type&lt;/a&gt;&lt;a id=&quot;19774&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;19776&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;19778&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;19782&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
    &lt;a id=&quot;⊢c_⦂_.t-clo&quot;&gt;&lt;/a&gt;&lt;a id=&quot;19792&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;19798&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;19800&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;19802&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;19803&quot; href=&quot;non-idempotent-intersection-types.html#19803&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;19805&quot; href=&quot;non-idempotent-intersection-types.html#19805&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;19807&quot; href=&quot;non-idempotent-intersection-types.html#19807&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;19808&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;19810&quot; href=&quot;non-idempotent-intersection-types.html#19810&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;19812&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;19814&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;19818&quot; href=&quot;non-idempotent-intersection-types.html#19803&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;19819&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;19821&quot; href=&quot;non-idempotent-intersection-types.html#19821&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;19823&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;19825&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;19829&quot; href=&quot;non-idempotent-intersection-types.html#19803&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;19830&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;19832&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
       &lt;a id=&quot;19841&quot; href=&quot;non-idempotent-intersection-types.html#19821&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;19843&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;19845&quot; href=&quot;non-idempotent-intersection-types.html#19805&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;19847&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;19849&quot; href=&quot;non-idempotent-intersection-types.html#19807&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;19851&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
       &lt;a id=&quot;19860&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;19863&quot; href=&quot;non-idempotent-intersection-types.html#19810&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;19865&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;19867&quot; href=&quot;non-idempotent-intersection-types.html#19821&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;19869&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
       &lt;a id=&quot;19878&quot; href=&quot;non-idempotent-intersection-types.html#19747&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;19881&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;19882&quot; href=&quot;non-idempotent-intersection-types.html#19803&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;19884&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;19886&quot; href=&quot;non-idempotent-intersection-types.html#19810&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;19888&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;19890&quot; href=&quot;non-idempotent-intersection-types.html#19805&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;19891&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;19893&quot; href=&quot;non-idempotent-intersection-types.html#19747&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;19895&quot; href=&quot;non-idempotent-intersection-types.html#19807&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;

  &lt;a id=&quot;19900&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;⊢e_⦂_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;19905&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e_⦂_&lt;/a&gt; &lt;a id=&quot;19911&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;19913&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;19915&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;19916&quot; href=&quot;non-idempotent-intersection-types.html#19916&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;19917&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;19919&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;19921&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;19925&quot; href=&quot;non-idempotent-intersection-types.html#19916&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;19927&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;19929&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;19933&quot; href=&quot;non-idempotent-intersection-types.html#19916&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;19935&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;19937&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;19941&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
    &lt;a id=&quot;⊢e_⦂_.nil&quot;&gt;&lt;/a&gt;&lt;a id=&quot;19951&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;19955&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;19957&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;19960&quot; href=&quot;non-idempotent-intersection-types.html#3767&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;19964&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;19966&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;
    &lt;a id=&quot;⊢e_⦂_._,-_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;19974&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;_,-_&lt;/a&gt; &lt;a id=&quot;19979&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;19981&quot; class=&quot;Symbol&quot;&gt;∀{&lt;/a&gt;&lt;a id=&quot;19983&quot; href=&quot;non-idempotent-intersection-types.html#19983&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;19984&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;19986&quot; href=&quot;non-idempotent-intersection-types.html#19986&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;19988&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;19990&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;19994&quot; href=&quot;non-idempotent-intersection-types.html#19983&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;19995&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;19997&quot; href=&quot;non-idempotent-intersection-types.html#19997&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;19999&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;20001&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;20005&quot; href=&quot;non-idempotent-intersection-types.html#19983&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;20006&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;20008&quot; href=&quot;non-idempotent-intersection-types.html#20008&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;20009&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;20011&quot; href=&quot;non-idempotent-intersection-types.html#20011&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;20012&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;20014&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
           &lt;a id=&quot;20027&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;20030&quot; href=&quot;non-idempotent-intersection-types.html#19986&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;20032&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;20034&quot; href=&quot;non-idempotent-intersection-types.html#19997&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;20036&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
           &lt;a id=&quot;20049&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;20052&quot; href=&quot;non-idempotent-intersection-types.html#20008&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;20054&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;20057&quot; href=&quot;non-idempotent-intersection-types.html#20011&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;20059&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
           &lt;a id=&quot;20072&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;20075&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;20076&quot; href=&quot;non-idempotent-intersection-types.html#19986&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;20078&quot; href=&quot;non-idempotent-intersection-types.html#3787&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;20081&quot; href=&quot;non-idempotent-intersection-types.html#20008&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;20082&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;20084&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;20086&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;20087&quot; href=&quot;non-idempotent-intersection-types.html#19997&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;20089&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;20092&quot; href=&quot;non-idempotent-intersection-types.html#20011&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;20093&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;

  &lt;a id=&quot;20098&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;⊢c_⦂&amp;#39;_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;20103&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c_⦂&amp;#39;_&lt;/a&gt; &lt;a id=&quot;20110&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;20112&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;20113&quot; href=&quot;non-idempotent-intersection-types.html#20113&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;20115&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;20117&quot; href=&quot;non-idempotent-intersection-types.html#3831&quot; class=&quot;Function&quot;&gt;clo&lt;/a&gt;&lt;a id=&quot;20120&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;20122&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;20123&quot; href=&quot;non-idempotent-intersection-types.html#20123&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;20125&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;20127&quot; href=&quot;Agda.Builtin.List.html#148&quot; class=&quot;Datatype&quot;&gt;List&lt;/a&gt; &lt;a id=&quot;20132&quot; href=&quot;non-idempotent-intersection-types.html#8723&quot; class=&quot;Datatype&quot;&gt;type&lt;/a&gt;&lt;a id=&quot;20136&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;20138&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;20140&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;20144&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
    &lt;a id=&quot;⊢c_⦂&amp;#39;_.nil&quot;&gt;&lt;/a&gt;&lt;a id=&quot;20154&quot; href=&quot;non-idempotent-intersection-types.html#20154&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;20158&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;20160&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;20162&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;20163&quot; href=&quot;non-idempotent-intersection-types.html#20163&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;20164&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;20166&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
           &lt;a id=&quot;20179&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;20182&quot; href=&quot;non-idempotent-intersection-types.html#20163&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;20184&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;20187&quot; href=&quot;Agda.Builtin.List.html#185&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt;
    &lt;a id=&quot;⊢c_⦂&amp;#39;_._∷_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;20194&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;_∷_&lt;/a&gt; &lt;a id=&quot;20198&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;20200&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;20202&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;20203&quot; href=&quot;non-idempotent-intersection-types.html#20203&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;20205&quot; href=&quot;non-idempotent-intersection-types.html#20205&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;20207&quot; href=&quot;non-idempotent-intersection-types.html#20207&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;20208&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;20210&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
           &lt;a id=&quot;20223&quot; href=&quot;non-idempotent-intersection-types.html#19747&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;20226&quot; href=&quot;non-idempotent-intersection-types.html#20203&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;20228&quot; href=&quot;non-idempotent-intersection-types.html#19747&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;20230&quot; href=&quot;non-idempotent-intersection-types.html#20205&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;20232&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
           &lt;a id=&quot;20245&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;20248&quot; href=&quot;non-idempotent-intersection-types.html#20203&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;20250&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;20253&quot; href=&quot;non-idempotent-intersection-types.html#20207&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;20255&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
           &lt;a id=&quot;20268&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;20271&quot; href=&quot;non-idempotent-intersection-types.html#20203&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;20273&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;20276&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;20277&quot; href=&quot;non-idempotent-intersection-types.html#20205&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;20279&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;20281&quot; href=&quot;non-idempotent-intersection-types.html#20207&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;20282&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;We also extend the measurement of sizes of derivations to well typed closures and environments. Notice that these derivations do not contribute themselves to the size: we only sum up the sizes of the contained term typing derivations.&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;20533&quot; class=&quot;Keyword&quot;&gt;mutual&lt;/a&gt;
  &lt;a id=&quot;c-size&quot;&gt;&lt;/a&gt;&lt;a id=&quot;20542&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;20549&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;20551&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;20553&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;20554&quot; href=&quot;non-idempotent-intersection-types.html#20554&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;20556&quot; href=&quot;non-idempotent-intersection-types.html#20556&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;20557&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;20559&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;20561&quot; href=&quot;non-idempotent-intersection-types.html#19747&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;20564&quot; href=&quot;non-idempotent-intersection-types.html#20554&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;20566&quot; href=&quot;non-idempotent-intersection-types.html#19747&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;20568&quot; href=&quot;non-idempotent-intersection-types.html#20556&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;20570&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;20572&quot; href=&quot;Agda.Builtin.Nat.html#192&quot; class=&quot;Datatype&quot;&gt;ℕ&lt;/a&gt;
  &lt;a id=&quot;20576&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;20583&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;20584&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;20590&quot; href=&quot;non-idempotent-intersection-types.html#20590&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;20592&quot; href=&quot;non-idempotent-intersection-types.html#20592&quot; class=&quot;Bound&quot;&gt;e&lt;/a&gt;&lt;a id=&quot;20593&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;20595&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;20597&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;20602&quot; href=&quot;non-idempotent-intersection-types.html#20590&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;20604&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;20606&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;20613&quot; href=&quot;non-idempotent-intersection-types.html#20592&quot; class=&quot;Bound&quot;&gt;e&lt;/a&gt;

  &lt;a id=&quot;e-size&quot;&gt;&lt;/a&gt;&lt;a id=&quot;20618&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;20625&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;20627&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;20629&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;20630&quot; href=&quot;non-idempotent-intersection-types.html#20630&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;20631&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;20633&quot; href=&quot;non-idempotent-intersection-types.html#20633&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;20635&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;20637&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;20641&quot; href=&quot;non-idempotent-intersection-types.html#20630&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;20642&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;20644&quot; href=&quot;non-idempotent-intersection-types.html#20644&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt;&lt;a id=&quot;20645&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;20647&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;20649&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;20652&quot; href=&quot;non-idempotent-intersection-types.html#20633&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;20654&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;20656&quot; href=&quot;non-idempotent-intersection-types.html#20644&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;20658&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;20660&quot; href=&quot;Agda.Builtin.Nat.html#192&quot; class=&quot;Datatype&quot;&gt;ℕ&lt;/a&gt;
  &lt;a id=&quot;20664&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;20671&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;20675&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;20677&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;
  &lt;a id=&quot;20681&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;20688&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;20689&quot; href=&quot;non-idempotent-intersection-types.html#20689&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;20691&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;20694&quot; href=&quot;non-idempotent-intersection-types.html#20694&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;20695&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;20697&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;20699&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;20706&quot; href=&quot;non-idempotent-intersection-types.html#20689&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;20708&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;20710&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;20718&quot; href=&quot;non-idempotent-intersection-types.html#20694&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;

  &lt;a id=&quot;c&amp;#39;-size&quot;&gt;&lt;/a&gt;&lt;a id=&quot;20723&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;20731&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;20733&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;20735&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;20736&quot; href=&quot;non-idempotent-intersection-types.html#20736&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;20738&quot; href=&quot;non-idempotent-intersection-types.html#20738&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;20739&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;20741&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;20743&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;20746&quot; href=&quot;non-idempotent-intersection-types.html#20736&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;20748&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;20751&quot; href=&quot;non-idempotent-intersection-types.html#20738&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;20753&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;20755&quot; href=&quot;Agda.Builtin.Nat.html#192&quot; class=&quot;Datatype&quot;&gt;ℕ&lt;/a&gt;
  &lt;a id=&quot;20759&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;20767&quot; href=&quot;non-idempotent-intersection-types.html#20154&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;20771&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;20773&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;
  &lt;a id=&quot;20777&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;20785&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;20786&quot; href=&quot;non-idempotent-intersection-types.html#20786&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;20788&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;20790&quot; href=&quot;non-idempotent-intersection-types.html#20790&quot; class=&quot;Bound&quot;&gt;c&amp;#39;&lt;/a&gt;&lt;a id=&quot;20792&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;20794&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;20796&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;20803&quot; href=&quot;non-idempotent-intersection-types.html#20786&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;20805&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;20807&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;20815&quot; href=&quot;non-idempotent-intersection-types.html#20790&quot; class=&quot;Bound&quot;&gt;c&amp;#39;&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;Stacks are typed with two types &lt;code&gt;τ₁ ⊸ τ₂&lt;/code&gt;, meaning that if the observation &lt;code&gt;τ₁&lt;/code&gt; can be made of the computation happening under the stack, then the observation &lt;code&gt;τ₂&lt;/code&gt; can be observed at the &quot;top level&quot;:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;21032&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;⊢s_⦂_⊸_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;21037&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⊢s_⦂_⊸_&lt;/a&gt; &lt;a id=&quot;21045&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;21047&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;21048&quot; href=&quot;non-idempotent-intersection-types.html#21048&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;21050&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;21052&quot; href=&quot;non-idempotent-intersection-types.html#4455&quot; class=&quot;Datatype&quot;&gt;stk&lt;/a&gt;&lt;a id=&quot;21055&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;21057&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;21058&quot; href=&quot;non-idempotent-intersection-types.html#21058&quot; class=&quot;Bound&quot;&gt;τ₁&lt;/a&gt; &lt;a id=&quot;21061&quot; href=&quot;non-idempotent-intersection-types.html#21061&quot; class=&quot;Bound&quot;&gt;τ₂&lt;/a&gt; &lt;a id=&quot;21064&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;21066&quot; href=&quot;non-idempotent-intersection-types.html#8723&quot; class=&quot;Datatype&quot;&gt;type&lt;/a&gt;&lt;a id=&quot;21070&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;21072&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;21074&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;21078&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
  &lt;a id=&quot;⊢s_⦂_⊸_.emp&quot;&gt;&lt;/a&gt;&lt;a id=&quot;21086&quot; href=&quot;non-idempotent-intersection-types.html#21086&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt;  &lt;a id=&quot;21091&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;21093&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;21095&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;21096&quot; href=&quot;non-idempotent-intersection-types.html#21096&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;21097&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;21099&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
         &lt;a id=&quot;21110&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⊢s&lt;/a&gt; &lt;a id=&quot;21113&quot; href=&quot;non-idempotent-intersection-types.html#4473&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt; &lt;a id=&quot;21117&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;21119&quot; href=&quot;non-idempotent-intersection-types.html#21096&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;21121&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⊸&lt;/a&gt; &lt;a id=&quot;21123&quot; href=&quot;non-idempotent-intersection-types.html#21096&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;
  &lt;a id=&quot;⊢s_⦂_⊸_._-,_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;21127&quot; href=&quot;non-idempotent-intersection-types.html#21127&quot; class=&quot;InductiveConstructor Operator&quot;&gt;_-,_&lt;/a&gt; &lt;a id=&quot;21132&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;21134&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;21136&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;21137&quot; href=&quot;non-idempotent-intersection-types.html#21137&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;21139&quot; href=&quot;non-idempotent-intersection-types.html#21139&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;21141&quot; href=&quot;non-idempotent-intersection-types.html#21141&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;21143&quot; href=&quot;non-idempotent-intersection-types.html#21143&quot; class=&quot;Bound&quot;&gt;τ₁&lt;/a&gt; &lt;a id=&quot;21146&quot; href=&quot;non-idempotent-intersection-types.html#21146&quot; class=&quot;Bound&quot;&gt;τ₂&lt;/a&gt;&lt;a id=&quot;21148&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;21150&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
         &lt;a id=&quot;21161&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;21164&quot; href=&quot;non-idempotent-intersection-types.html#21137&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;21166&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;21169&quot; href=&quot;non-idempotent-intersection-types.html#21141&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;21171&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
         &lt;a id=&quot;21182&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⊢s&lt;/a&gt; &lt;a id=&quot;21185&quot; href=&quot;non-idempotent-intersection-types.html#21139&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;21187&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;21189&quot; href=&quot;non-idempotent-intersection-types.html#21143&quot; class=&quot;Bound&quot;&gt;τ₁&lt;/a&gt; &lt;a id=&quot;21192&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⊸&lt;/a&gt; &lt;a id=&quot;21194&quot; href=&quot;non-idempotent-intersection-types.html#21146&quot; class=&quot;Bound&quot;&gt;τ₂&lt;/a&gt; &lt;a id=&quot;21197&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
         &lt;a id=&quot;21208&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⊢s&lt;/a&gt; &lt;a id=&quot;21211&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;21212&quot; href=&quot;non-idempotent-intersection-types.html#21137&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;21214&quot; href=&quot;non-idempotent-intersection-types.html#4486&quot; class=&quot;InductiveConstructor Operator&quot;&gt;-,&lt;/a&gt; &lt;a id=&quot;21217&quot; href=&quot;non-idempotent-intersection-types.html#21139&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt;&lt;a id=&quot;21218&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;21220&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;21222&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;21223&quot; href=&quot;non-idempotent-intersection-types.html#21141&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;21225&quot; href=&quot;non-idempotent-intersection-types.html#8756&quot; class=&quot;InductiveConstructor Operator&quot;&gt;↦&lt;/a&gt; &lt;a id=&quot;21227&quot; href=&quot;non-idempotent-intersection-types.html#21143&quot; class=&quot;Bound&quot;&gt;τ₁&lt;/a&gt;&lt;a id=&quot;21229&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;21231&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⊸&lt;/a&gt; &lt;a id=&quot;21233&quot; href=&quot;non-idempotent-intersection-types.html#21146&quot; class=&quot;Bound&quot;&gt;τ₂&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;Again, we measure the size of a stack typing derivation by adding up the sizes of the typing derivations contained within:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;s-size&quot;&gt;&lt;/a&gt;&lt;a id=&quot;21373&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;21380&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;21382&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;21384&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;21385&quot; href=&quot;non-idempotent-intersection-types.html#21385&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;21387&quot; href=&quot;non-idempotent-intersection-types.html#21387&quot; class=&quot;Bound&quot;&gt;τ₁&lt;/a&gt; &lt;a id=&quot;21390&quot; href=&quot;non-idempotent-intersection-types.html#21390&quot; class=&quot;Bound&quot;&gt;τ₂&lt;/a&gt;&lt;a id=&quot;21392&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;21394&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;21396&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⊢s&lt;/a&gt; &lt;a id=&quot;21399&quot; href=&quot;non-idempotent-intersection-types.html#21385&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;21401&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;21403&quot; href=&quot;non-idempotent-intersection-types.html#21387&quot; class=&quot;Bound&quot;&gt;τ₁&lt;/a&gt; &lt;a id=&quot;21406&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⊸&lt;/a&gt; &lt;a id=&quot;21408&quot; href=&quot;non-idempotent-intersection-types.html#21390&quot; class=&quot;Bound&quot;&gt;τ₂&lt;/a&gt; &lt;a id=&quot;21411&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;21413&quot; href=&quot;Agda.Builtin.Nat.html#192&quot; class=&quot;Datatype&quot;&gt;ℕ&lt;/a&gt;
&lt;a id=&quot;21415&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;21422&quot; href=&quot;non-idempotent-intersection-types.html#21086&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt; &lt;a id=&quot;21426&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;21428&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;
&lt;a id=&quot;21430&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;21437&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;21438&quot; href=&quot;non-idempotent-intersection-types.html#21438&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;21440&quot; href=&quot;non-idempotent-intersection-types.html#21127&quot; class=&quot;InductiveConstructor Operator&quot;&gt;-,&lt;/a&gt; &lt;a id=&quot;21443&quot; href=&quot;non-idempotent-intersection-types.html#21443&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt;&lt;a id=&quot;21444&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;21446&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;21448&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;21456&quot; href=&quot;non-idempotent-intersection-types.html#21438&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;21458&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;21460&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;21467&quot; href=&quot;non-idempotent-intersection-types.html#21443&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;Well typed KAM configurations are constructed by pairing closures that can generate a behaviour &lt;code&gt;τ₁&lt;/code&gt; with stacks that can turn that behaviour into a behaviour &lt;code&gt;τ&lt;/code&gt; at the top level. The size of a configuration is measured by summing up the sizes of the typing derivations included in the closure and the stack.&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;21793&quot; class=&quot;Keyword&quot;&gt;data&lt;/a&gt; &lt;a id=&quot;⊢p_⦂_&quot;&gt;&lt;/a&gt;&lt;a id=&quot;21798&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⊢p_⦂_&lt;/a&gt; &lt;a id=&quot;21804&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;21806&quot; href=&quot;non-idempotent-intersection-types.html#4786&quot; class=&quot;Record&quot;&gt;configuration&lt;/a&gt; &lt;a id=&quot;21820&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;21822&quot; href=&quot;non-idempotent-intersection-types.html#8723&quot; class=&quot;Datatype&quot;&gt;type&lt;/a&gt; &lt;a id=&quot;21827&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;21829&quot; class=&quot;PrimitiveType&quot;&gt;Set&lt;/a&gt; &lt;a id=&quot;21833&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
  &lt;a id=&quot;⊢p_⦂_.cfg&quot;&gt;&lt;/a&gt;&lt;a id=&quot;21841&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;21845&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;21847&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;21849&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;21850&quot; href=&quot;non-idempotent-intersection-types.html#21850&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;21852&quot; href=&quot;non-idempotent-intersection-types.html#21852&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;21854&quot; href=&quot;non-idempotent-intersection-types.html#21854&quot; class=&quot;Bound&quot;&gt;τ₁&lt;/a&gt; &lt;a id=&quot;21857&quot; href=&quot;non-idempotent-intersection-types.html#21857&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;21858&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;21860&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
         &lt;a id=&quot;21871&quot; href=&quot;non-idempotent-intersection-types.html#19747&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;21874&quot; href=&quot;non-idempotent-intersection-types.html#21850&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;21876&quot; href=&quot;non-idempotent-intersection-types.html#19747&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;21878&quot; href=&quot;non-idempotent-intersection-types.html#21854&quot; class=&quot;Bound&quot;&gt;τ₁&lt;/a&gt; &lt;a id=&quot;21881&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
         &lt;a id=&quot;21892&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⊢s&lt;/a&gt; &lt;a id=&quot;21895&quot; href=&quot;non-idempotent-intersection-types.html#21852&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;21897&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;21899&quot; href=&quot;non-idempotent-intersection-types.html#21854&quot; class=&quot;Bound&quot;&gt;τ₁&lt;/a&gt; &lt;a id=&quot;21902&quot; href=&quot;non-idempotent-intersection-types.html#21037&quot; class=&quot;Datatype Operator&quot;&gt;⊸&lt;/a&gt; &lt;a id=&quot;21904&quot; href=&quot;non-idempotent-intersection-types.html#21857&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;21906&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
         &lt;a id=&quot;21917&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⊢p&lt;/a&gt; &lt;a id=&quot;21920&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt; &lt;a id=&quot;21922&quot; href=&quot;non-idempotent-intersection-types.html#21850&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;21924&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;21926&quot; href=&quot;non-idempotent-intersection-types.html#21852&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt; &lt;a id=&quot;21928&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt; &lt;a id=&quot;21930&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;21932&quot; href=&quot;non-idempotent-intersection-types.html#21857&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;

&lt;a id=&quot;cfg-size&quot;&gt;&lt;/a&gt;&lt;a id=&quot;21935&quot; href=&quot;non-idempotent-intersection-types.html#21935&quot; class=&quot;Function&quot;&gt;cfg-size&lt;/a&gt; &lt;a id=&quot;21944&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;21946&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;21948&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;21949&quot; href=&quot;non-idempotent-intersection-types.html#21949&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;21951&quot; href=&quot;non-idempotent-intersection-types.html#21951&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;21952&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;21954&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;21956&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⊢p&lt;/a&gt; &lt;a id=&quot;21959&quot; href=&quot;non-idempotent-intersection-types.html#21949&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;21961&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;21963&quot; href=&quot;non-idempotent-intersection-types.html#21951&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;21965&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;21967&quot; href=&quot;Agda.Builtin.Nat.html#192&quot; class=&quot;Datatype&quot;&gt;ℕ&lt;/a&gt;
&lt;a id=&quot;21969&quot; href=&quot;non-idempotent-intersection-types.html#21935&quot; class=&quot;Function&quot;&gt;cfg-size&lt;/a&gt; &lt;a id=&quot;21978&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;21979&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;21983&quot; href=&quot;non-idempotent-intersection-types.html#21983&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;21985&quot; href=&quot;non-idempotent-intersection-types.html#21985&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt;&lt;a id=&quot;21986&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;21988&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;21990&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;21997&quot; href=&quot;non-idempotent-intersection-types.html#21983&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;21999&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;22001&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;22008&quot; href=&quot;non-idempotent-intersection-types.html#21985&quot; class=&quot;Bound&quot;&gt;π&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;We can now prove that the initial configuration of the KAM for a given program is well typed if the program is:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;init-typed&quot;&gt;&lt;/a&gt;&lt;a id=&quot;22136&quot; href=&quot;non-idempotent-intersection-types.html#22136&quot; class=&quot;Function&quot;&gt;init-typed&lt;/a&gt; &lt;a id=&quot;22147&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;22149&quot; class=&quot;Symbol&quot;&gt;∀{&lt;/a&gt;&lt;a id=&quot;22151&quot; href=&quot;non-idempotent-intersection-types.html#22151&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;22153&quot; href=&quot;non-idempotent-intersection-types.html#22153&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;22154&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;22156&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;22158&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;22162&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;22164&quot; href=&quot;non-idempotent-intersection-types.html#22151&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;22166&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;22168&quot; href=&quot;non-idempotent-intersection-types.html#22153&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;22170&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;22172&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⊢p&lt;/a&gt; &lt;a id=&quot;22175&quot; href=&quot;non-idempotent-intersection-types.html#6460&quot; class=&quot;Function&quot;&gt;init&lt;/a&gt; &lt;a id=&quot;22180&quot; href=&quot;non-idempotent-intersection-types.html#22151&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;22182&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;22184&quot; href=&quot;non-idempotent-intersection-types.html#22153&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;
&lt;a id=&quot;22186&quot; href=&quot;non-idempotent-intersection-types.html#22136&quot; class=&quot;Function&quot;&gt;init-typed&lt;/a&gt; &lt;a id=&quot;22197&quot; href=&quot;non-idempotent-intersection-types.html#22197&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;22199&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;22201&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;22205&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;22206&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;22212&quot; href=&quot;non-idempotent-intersection-types.html#22197&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;22214&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;22217&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;22219&quot; href=&quot;non-idempotent-intersection-types.html#21086&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;The size of this initial typing derivation is also equal to the size of the original typing derivation:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;init-typed-size&quot;&gt;&lt;/a&gt;&lt;a id=&quot;22341&quot; href=&quot;non-idempotent-intersection-types.html#22341&quot; class=&quot;Function&quot;&gt;init-typed-size&lt;/a&gt; &lt;a id=&quot;22357&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;22359&quot; class=&quot;Symbol&quot;&gt;∀{&lt;/a&gt;&lt;a id=&quot;22361&quot; href=&quot;non-idempotent-intersection-types.html#22361&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;22363&quot; href=&quot;non-idempotent-intersection-types.html#22363&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;22364&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;22366&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;22368&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;22369&quot; href=&quot;non-idempotent-intersection-types.html#22369&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;22371&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;22373&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;22377&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;22379&quot; href=&quot;non-idempotent-intersection-types.html#22361&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;22381&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;22383&quot; href=&quot;non-idempotent-intersection-types.html#22363&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;22384&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;22386&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;22388&quot; href=&quot;non-idempotent-intersection-types.html#21935&quot; class=&quot;Function&quot;&gt;cfg-size&lt;/a&gt; &lt;a id=&quot;22397&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;22398&quot; href=&quot;non-idempotent-intersection-types.html#22136&quot; class=&quot;Function&quot;&gt;init-typed&lt;/a&gt; &lt;a id=&quot;22409&quot; href=&quot;non-idempotent-intersection-types.html#22369&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;22410&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;22412&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;22414&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;22419&quot; href=&quot;non-idempotent-intersection-types.html#22369&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;
&lt;a id=&quot;22421&quot; href=&quot;non-idempotent-intersection-types.html#22341&quot; class=&quot;Function&quot;&gt;init-typed-size&lt;/a&gt;&lt;a id=&quot;22436&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;22437&quot; class=&quot;Argument&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;22439&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;22441&quot; href=&quot;non-idempotent-intersection-types.html#22441&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;22442&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;22444&quot; href=&quot;non-idempotent-intersection-types.html#22444&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;22446&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt;
  &lt;a id=&quot;22450&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2517&quot; class=&quot;Function Operator&quot;&gt;begin&lt;/a&gt;
     &lt;a id=&quot;22461&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;22466&quot; href=&quot;non-idempotent-intersection-types.html#22444&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;22468&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;22470&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;22477&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;22481&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;22483&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt;&lt;a id=&quot;22489&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;22490&quot; class=&quot;Argument&quot;&gt;τ₁&lt;/a&gt; &lt;a id=&quot;22493&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;22495&quot; href=&quot;non-idempotent-intersection-types.html#22441&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;22496&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;22498&quot; href=&quot;non-idempotent-intersection-types.html#21086&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt;
   &lt;a id=&quot;22505&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2575&quot; class=&quot;Function Operator&quot;&gt;≡⟨⟩&lt;/a&gt;
     &lt;a id=&quot;22514&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;22519&quot; href=&quot;non-idempotent-intersection-types.html#22444&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;22521&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;22523&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt; &lt;a id=&quot;22525&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;22527&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;
   &lt;a id=&quot;22532&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;22535&quot; href=&quot;Data.Nat.Properties.html#12646&quot; class=&quot;Function&quot;&gt;+-identityʳ&lt;/a&gt; &lt;a id=&quot;22547&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;22548&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;22553&quot; href=&quot;non-idempotent-intersection-types.html#22444&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;22555&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;22557&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;&lt;a id=&quot;22558&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;22560&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;22567&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;22572&quot; href=&quot;non-idempotent-intersection-types.html#22444&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;22574&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;22576&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;
   &lt;a id=&quot;22581&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;22584&quot; href=&quot;Data.Nat.Properties.html#12646&quot; class=&quot;Function&quot;&gt;+-identityʳ&lt;/a&gt; &lt;a id=&quot;22596&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;22597&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;22602&quot; href=&quot;non-idempotent-intersection-types.html#22444&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;22603&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;22605&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;22612&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;22617&quot; href=&quot;non-idempotent-intersection-types.html#22444&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;
   &lt;a id=&quot;22622&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2816&quot; class=&quot;Function Operator&quot;&gt;∎&lt;/a&gt;
&lt;/pre&gt;
&lt;h3&gt;Quantitative Subject Reduction&lt;/h3&gt;&lt;p&gt;We now connect the KAM semantics to the non-idempotent intersection type system. This will take the form of three key lemmas:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;em&gt;Subject Reduction&lt;/em&gt; (a.k.a preservation), which says that if a configuration of the KAM is well typed, and steps to another configuration, then that configuration is also well-typed. The twist here is that this lemma is also quantitative: the size of the typing derivation after one step is exactly one smaller than it was before. This will allow us to prove that all typable terms reduce.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;em&gt;Subject Expansion&lt;/em&gt;, the converse of subject reduction. If a configuration is well typed and was the result of a step of the KAM, then the predecessor was also well typed. Subject expansion does not usually hold for type systems, but is characteristic of intersection type systems due to the way they describe what a program &lt;em&gt;must&lt;/em&gt; do, instead of what it &lt;em&gt;may&lt;/em&gt; do. Subject expansion allows us to prove a completeness result: if a program reduces to WHNF, then we can step it backwards to recover a typing derivation for the initial state.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;em&gt;Progress&lt;/em&gt;: if a configuration is well typed, and its derivation has non-zero size, then the KAM can take a step. Thus we can interpret the size of a derivation as the amount of computation that a program has left to perform.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h4&gt;Some lemmas&lt;/h4&gt;&lt;p&gt;Before we can prove subject reduction, we will need some auxiliary lemmas about the type system. These mostly say that typing is preserved under permutation, splitting, or joining of intersection types. We also prove that these preservations are size preserving, anticipating the quantitative subject reduction lemma in the next section.&lt;/p&gt;&lt;p&gt;First, we need that if a closure &lt;code&gt;c&lt;/code&gt; can be well typed for (i.e., exhibits the behaviour of) all the types in &lt;code&gt;σ₁&lt;/code&gt; then it is well typed for any permutation of &lt;code&gt;σ₁&lt;/code&gt;. Also, this does not affect the size of the typing derivation. We prove this by induction on the permutation applied:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;clo-permute&quot;&gt;&lt;/a&gt;&lt;a id=&quot;24654&quot; href=&quot;non-idempotent-intersection-types.html#24654&quot; class=&quot;Function&quot;&gt;clo-permute&lt;/a&gt; &lt;a id=&quot;24666&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;24668&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;24670&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;24671&quot; href=&quot;non-idempotent-intersection-types.html#24671&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;24673&quot; href=&quot;non-idempotent-intersection-types.html#24673&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;24676&quot; href=&quot;non-idempotent-intersection-types.html#24676&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;&lt;a id=&quot;24678&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;24680&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;24682&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;24685&quot; href=&quot;non-idempotent-intersection-types.html#24671&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;24687&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;24690&quot; href=&quot;non-idempotent-intersection-types.html#24673&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;24693&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;24695&quot; href=&quot;non-idempotent-intersection-types.html#24676&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt; &lt;a id=&quot;24698&quot; href=&quot;non-idempotent-intersection-types.html#13034&quot; class=&quot;Datatype Operator&quot;&gt;⋈&lt;/a&gt; &lt;a id=&quot;24700&quot; href=&quot;non-idempotent-intersection-types.html#24673&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;24703&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;24705&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;24708&quot; href=&quot;non-idempotent-intersection-types.html#24671&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;24710&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;24713&quot; href=&quot;non-idempotent-intersection-types.html#24676&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;
&lt;a id=&quot;24716&quot; href=&quot;non-idempotent-intersection-types.html#24654&quot; class=&quot;Function&quot;&gt;clo-permute&lt;/a&gt; &lt;a id=&quot;24728&quot; href=&quot;non-idempotent-intersection-types.html#24728&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;            &lt;a id=&quot;24741&quot; href=&quot;non-idempotent-intersection-types.html#13074&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;            &lt;a id=&quot;24756&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;24758&quot; href=&quot;non-idempotent-intersection-types.html#24728&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;
&lt;a id=&quot;24760&quot; href=&quot;non-idempotent-intersection-types.html#24654&quot; class=&quot;Function&quot;&gt;clo-permute&lt;/a&gt; &lt;a id=&quot;24772&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;24773&quot; href=&quot;non-idempotent-intersection-types.html#24773&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;24775&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;24777&quot; href=&quot;non-idempotent-intersection-types.html#24777&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;24778&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;      &lt;a id=&quot;24785&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;24786&quot; href=&quot;non-idempotent-intersection-types.html#13096&quot; class=&quot;InductiveConstructor&quot;&gt;skip&lt;/a&gt; &lt;a id=&quot;24791&quot; href=&quot;non-idempotent-intersection-types.html#24791&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;24792&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;       &lt;a id=&quot;24800&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;24802&quot; href=&quot;non-idempotent-intersection-types.html#24773&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;24804&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;24806&quot; href=&quot;non-idempotent-intersection-types.html#24654&quot; class=&quot;Function&quot;&gt;clo-permute&lt;/a&gt; &lt;a id=&quot;24818&quot; href=&quot;non-idempotent-intersection-types.html#24777&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;24820&quot; href=&quot;non-idempotent-intersection-types.html#24791&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;
&lt;a id=&quot;24822&quot; href=&quot;non-idempotent-intersection-types.html#24654&quot; class=&quot;Function&quot;&gt;clo-permute&lt;/a&gt; &lt;a id=&quot;24834&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;24835&quot; href=&quot;non-idempotent-intersection-types.html#24835&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;24837&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;24839&quot; href=&quot;non-idempotent-intersection-types.html#24839&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt; &lt;a id=&quot;24842&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;24844&quot; href=&quot;non-idempotent-intersection-types.html#24844&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;24845&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;24847&quot; href=&quot;non-idempotent-intersection-types.html#13157&quot; class=&quot;InductiveConstructor&quot;&gt;swap&lt;/a&gt;           &lt;a id=&quot;24862&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;24864&quot; href=&quot;non-idempotent-intersection-types.html#24839&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt; &lt;a id=&quot;24867&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;24869&quot; href=&quot;non-idempotent-intersection-types.html#24835&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;24871&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;24873&quot; href=&quot;non-idempotent-intersection-types.html#24844&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;
&lt;a id=&quot;24875&quot; href=&quot;non-idempotent-intersection-types.html#24654&quot; class=&quot;Function&quot;&gt;clo-permute&lt;/a&gt; &lt;a id=&quot;24887&quot; href=&quot;non-idempotent-intersection-types.html#24887&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;            &lt;a id=&quot;24900&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;24901&quot; href=&quot;non-idempotent-intersection-types.html#13223&quot; class=&quot;InductiveConstructor&quot;&gt;⋈-trans&lt;/a&gt; &lt;a id=&quot;24909&quot; href=&quot;non-idempotent-intersection-types.html#24909&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;24911&quot; href=&quot;non-idempotent-intersection-types.html#24911&quot; class=&quot;Bound&quot;&gt;p₁&lt;/a&gt;&lt;a id=&quot;24913&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;24915&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;24917&quot; href=&quot;non-idempotent-intersection-types.html#24654&quot; class=&quot;Function&quot;&gt;clo-permute&lt;/a&gt; &lt;a id=&quot;24929&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;24930&quot; href=&quot;non-idempotent-intersection-types.html#24654&quot; class=&quot;Function&quot;&gt;clo-permute&lt;/a&gt; &lt;a id=&quot;24942&quot; href=&quot;non-idempotent-intersection-types.html#24887&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;24944&quot; href=&quot;non-idempotent-intersection-types.html#24911&quot; class=&quot;Bound&quot;&gt;p₁&lt;/a&gt;&lt;a id=&quot;24946&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;24948&quot; href=&quot;non-idempotent-intersection-types.html#24909&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;

&lt;a id=&quot;clo-permute-size&quot;&gt;&lt;/a&gt;&lt;a id=&quot;24951&quot; href=&quot;non-idempotent-intersection-types.html#24951&quot; class=&quot;Function&quot;&gt;clo-permute-size&lt;/a&gt; &lt;a id=&quot;24968&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;24970&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;24972&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;24973&quot; href=&quot;non-idempotent-intersection-types.html#24973&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;24975&quot; href=&quot;non-idempotent-intersection-types.html#24975&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;24978&quot; href=&quot;non-idempotent-intersection-types.html#24978&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;&lt;a id=&quot;24980&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;24982&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;24984&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;24985&quot; href=&quot;non-idempotent-intersection-types.html#24985&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;24987&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;24989&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;24992&quot; href=&quot;non-idempotent-intersection-types.html#24973&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;24994&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;24997&quot; href=&quot;non-idempotent-intersection-types.html#24975&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;24999&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;25001&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;25003&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25004&quot; href=&quot;non-idempotent-intersection-types.html#25004&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;25006&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;25008&quot; href=&quot;non-idempotent-intersection-types.html#24978&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt; &lt;a id=&quot;25011&quot; href=&quot;non-idempotent-intersection-types.html#13034&quot; class=&quot;Datatype Operator&quot;&gt;⋈&lt;/a&gt; &lt;a id=&quot;25013&quot; href=&quot;non-idempotent-intersection-types.html#24975&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;25015&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;25017&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;25019&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;25027&quot; href=&quot;non-idempotent-intersection-types.html#24985&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;25029&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;25031&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;25039&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25040&quot; href=&quot;non-idempotent-intersection-types.html#24654&quot; class=&quot;Function&quot;&gt;clo-permute&lt;/a&gt; &lt;a id=&quot;25052&quot; href=&quot;non-idempotent-intersection-types.html#24985&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;25054&quot; href=&quot;non-idempotent-intersection-types.html#25004&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;25055&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;25057&quot; href=&quot;non-idempotent-intersection-types.html#24951&quot; class=&quot;Function&quot;&gt;clo-permute-size&lt;/a&gt; &lt;a id=&quot;25074&quot; href=&quot;non-idempotent-intersection-types.html#25074&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;              &lt;a id=&quot;25089&quot; href=&quot;non-idempotent-intersection-types.html#13074&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;            &lt;a id=&quot;25104&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;25106&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt;
&lt;a id=&quot;25111&quot; href=&quot;non-idempotent-intersection-types.html#24951&quot; class=&quot;Function&quot;&gt;clo-permute-size&lt;/a&gt; &lt;a id=&quot;25128&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25129&quot; href=&quot;non-idempotent-intersection-types.html#25129&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;25131&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;25133&quot; href=&quot;non-idempotent-intersection-types.html#25133&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;25134&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;        &lt;a id=&quot;25143&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25144&quot; href=&quot;non-idempotent-intersection-types.html#13096&quot; class=&quot;InductiveConstructor&quot;&gt;skip&lt;/a&gt; &lt;a id=&quot;25149&quot; href=&quot;non-idempotent-intersection-types.html#25149&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;25150&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;       &lt;a id=&quot;25158&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;25160&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;25165&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;25168&quot; href=&quot;non-idempotent-intersection-types.html#25168&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;25170&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;25172&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;25179&quot; href=&quot;non-idempotent-intersection-types.html#25129&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;25181&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;25183&quot; href=&quot;non-idempotent-intersection-types.html#25168&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt;&lt;a id=&quot;25184&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;25186&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25187&quot; href=&quot;non-idempotent-intersection-types.html#24951&quot; class=&quot;Function&quot;&gt;clo-permute-size&lt;/a&gt; &lt;a id=&quot;25204&quot; href=&quot;non-idempotent-intersection-types.html#25133&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;25206&quot; href=&quot;non-idempotent-intersection-types.html#25149&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;25207&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;25209&quot; href=&quot;non-idempotent-intersection-types.html#24951&quot; class=&quot;Function&quot;&gt;clo-permute-size&lt;/a&gt; &lt;a id=&quot;25226&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25227&quot; href=&quot;non-idempotent-intersection-types.html#25227&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;25229&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;25231&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25232&quot; href=&quot;non-idempotent-intersection-types.html#25232&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt; &lt;a id=&quot;25235&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;25237&quot; href=&quot;non-idempotent-intersection-types.html#25237&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;25238&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;25241&quot; href=&quot;non-idempotent-intersection-types.html#13157&quot; class=&quot;InductiveConstructor&quot;&gt;swap&lt;/a&gt;           &lt;a id=&quot;25256&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;25258&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1025&quot; class=&quot;Function&quot;&gt;trans&lt;/a&gt; &lt;a id=&quot;25264&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25265&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#980&quot; class=&quot;Function&quot;&gt;sym&lt;/a&gt; &lt;a id=&quot;25269&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25270&quot; href=&quot;Data.Nat.Properties.html#12490&quot; class=&quot;Function&quot;&gt;+-assoc&lt;/a&gt; &lt;a id=&quot;25278&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25279&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;25286&quot; href=&quot;non-idempotent-intersection-types.html#25227&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;25287&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;25289&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25290&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;25297&quot; href=&quot;non-idempotent-intersection-types.html#25232&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt;&lt;a id=&quot;25299&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;25301&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25302&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;25310&quot; href=&quot;non-idempotent-intersection-types.html#25237&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;25311&quot; class=&quot;Symbol&quot;&gt;)))&lt;/a&gt; &lt;a id=&quot;25315&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25316&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1025&quot; class=&quot;Function&quot;&gt;trans&lt;/a&gt; &lt;a id=&quot;25322&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25323&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;25328&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;25331&quot; href=&quot;non-idempotent-intersection-types.html#25331&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;25333&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;25335&quot; href=&quot;non-idempotent-intersection-types.html#25331&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;25337&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;25339&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;25347&quot; href=&quot;non-idempotent-intersection-types.html#25237&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;25348&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;25350&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25351&quot; href=&quot;Data.Nat.Properties.html#12823&quot; class=&quot;Function&quot;&gt;+-comm&lt;/a&gt; &lt;a id=&quot;25358&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25359&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;25366&quot; href=&quot;non-idempotent-intersection-types.html#25227&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;25367&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;25369&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25370&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;25377&quot; href=&quot;non-idempotent-intersection-types.html#25232&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt;&lt;a id=&quot;25379&quot; class=&quot;Symbol&quot;&gt;)))&lt;/a&gt; &lt;a id=&quot;25383&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25384&quot; href=&quot;Data.Nat.Properties.html#12490&quot; class=&quot;Function&quot;&gt;+-assoc&lt;/a&gt; &lt;a id=&quot;25392&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25393&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;25400&quot; href=&quot;non-idempotent-intersection-types.html#25232&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt;&lt;a id=&quot;25402&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;25404&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25405&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;25412&quot; href=&quot;non-idempotent-intersection-types.html#25227&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;25413&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;25415&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25416&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;25424&quot; href=&quot;non-idempotent-intersection-types.html#25237&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;25425&quot; class=&quot;Symbol&quot;&gt;)))&lt;/a&gt;
&lt;a id=&quot;25429&quot; href=&quot;non-idempotent-intersection-types.html#24951&quot; class=&quot;Function&quot;&gt;clo-permute-size&lt;/a&gt; &lt;a id=&quot;25446&quot; href=&quot;non-idempotent-intersection-types.html#25446&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;              &lt;a id=&quot;25461&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25462&quot; href=&quot;non-idempotent-intersection-types.html#13223&quot; class=&quot;InductiveConstructor&quot;&gt;⋈-trans&lt;/a&gt; &lt;a id=&quot;25470&quot; href=&quot;non-idempotent-intersection-types.html#25470&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;25472&quot; href=&quot;non-idempotent-intersection-types.html#25472&quot; class=&quot;Bound&quot;&gt;p₁&lt;/a&gt;&lt;a id=&quot;25474&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;25476&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;25478&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1025&quot; class=&quot;Function&quot;&gt;trans&lt;/a&gt; &lt;a id=&quot;25484&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25485&quot; href=&quot;non-idempotent-intersection-types.html#24951&quot; class=&quot;Function&quot;&gt;clo-permute-size&lt;/a&gt; &lt;a id=&quot;25502&quot; href=&quot;non-idempotent-intersection-types.html#25446&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;25504&quot; href=&quot;non-idempotent-intersection-types.html#25472&quot; class=&quot;Bound&quot;&gt;p₁&lt;/a&gt;&lt;a id=&quot;25506&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;25508&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25509&quot; href=&quot;non-idempotent-intersection-types.html#24951&quot; class=&quot;Function&quot;&gt;clo-permute-size&lt;/a&gt; &lt;a id=&quot;25526&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25527&quot; href=&quot;non-idempotent-intersection-types.html#24654&quot; class=&quot;Function&quot;&gt;clo-permute&lt;/a&gt; &lt;a id=&quot;25539&quot; href=&quot;non-idempotent-intersection-types.html#25446&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;25541&quot; href=&quot;non-idempotent-intersection-types.html#25472&quot; class=&quot;Bound&quot;&gt;p₁&lt;/a&gt;&lt;a id=&quot;25543&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;25545&quot; href=&quot;non-idempotent-intersection-types.html#25470&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;25546&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;Preservation of closure typing under permutation extends to preservation of environment typing under pointwise permutation of typing contexts, and this is also size preserving:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;env-permute&quot;&gt;&lt;/a&gt;&lt;a id=&quot;25739&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;25751&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;25753&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;25755&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;25756&quot; href=&quot;non-idempotent-intersection-types.html#25756&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;25757&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;25759&quot; href=&quot;non-idempotent-intersection-types.html#25759&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;25761&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;25763&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;25767&quot; href=&quot;non-idempotent-intersection-types.html#25756&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;25768&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;25770&quot; href=&quot;non-idempotent-intersection-types.html#25770&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;25773&quot; href=&quot;non-idempotent-intersection-types.html#25773&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;25776&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;25778&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;25782&quot; href=&quot;non-idempotent-intersection-types.html#25756&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;25783&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;25785&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
             &lt;a id=&quot;25800&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;25803&quot; href=&quot;non-idempotent-intersection-types.html#25759&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;25805&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;25807&quot; href=&quot;non-idempotent-intersection-types.html#25770&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;25810&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
             &lt;a id=&quot;25825&quot; href=&quot;non-idempotent-intersection-types.html#25773&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;25828&quot; href=&quot;non-idempotent-intersection-types.html#13605&quot; class=&quot;Datatype Operator&quot;&gt;⋈ctx&lt;/a&gt; &lt;a id=&quot;25833&quot; href=&quot;non-idempotent-intersection-types.html#25770&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;25836&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
             &lt;a id=&quot;25851&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;25854&quot; href=&quot;non-idempotent-intersection-types.html#25759&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;25856&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;25858&quot; href=&quot;non-idempotent-intersection-types.html#25773&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt;
&lt;a id=&quot;25861&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;25873&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;      &lt;a id=&quot;25882&quot; href=&quot;non-idempotent-intersection-types.html#13650&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;       &lt;a id=&quot;25892&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;25894&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;
&lt;a id=&quot;25898&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;25910&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25911&quot; href=&quot;non-idempotent-intersection-types.html#25911&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;25913&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;25916&quot; href=&quot;non-idempotent-intersection-types.html#25916&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;25917&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;25919&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;25920&quot; href=&quot;non-idempotent-intersection-types.html#25920&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;25922&quot; href=&quot;non-idempotent-intersection-types.html#13671&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;25925&quot; href=&quot;non-idempotent-intersection-types.html#25925&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt;&lt;a id=&quot;25927&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;25929&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;25931&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;25943&quot; href=&quot;non-idempotent-intersection-types.html#25911&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;25945&quot; href=&quot;non-idempotent-intersection-types.html#25920&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;25947&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;25950&quot; href=&quot;non-idempotent-intersection-types.html#24654&quot; class=&quot;Function&quot;&gt;clo-permute&lt;/a&gt; &lt;a id=&quot;25962&quot; href=&quot;non-idempotent-intersection-types.html#25916&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;25964&quot; href=&quot;non-idempotent-intersection-types.html#25925&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt;

&lt;a id=&quot;env-permute-size&quot;&gt;&lt;/a&gt;&lt;a id=&quot;25968&quot; href=&quot;non-idempotent-intersection-types.html#25968&quot; class=&quot;Function&quot;&gt;env-permute-size&lt;/a&gt; &lt;a id=&quot;25985&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;25987&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;25989&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;25990&quot; href=&quot;non-idempotent-intersection-types.html#25990&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;25991&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;25993&quot; href=&quot;non-idempotent-intersection-types.html#25993&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;25995&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;25997&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;26001&quot; href=&quot;non-idempotent-intersection-types.html#25990&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;26002&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;26004&quot; href=&quot;non-idempotent-intersection-types.html#26004&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;26007&quot; href=&quot;non-idempotent-intersection-types.html#26007&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;26010&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;26012&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;26016&quot; href=&quot;non-idempotent-intersection-types.html#25990&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;26017&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;26019&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
             &lt;a id=&quot;26034&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26035&quot; href=&quot;non-idempotent-intersection-types.html#26035&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;26037&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;26039&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;26042&quot; href=&quot;non-idempotent-intersection-types.html#25993&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;26044&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;26046&quot; href=&quot;non-idempotent-intersection-types.html#26004&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt;&lt;a id=&quot;26048&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;26050&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;26052&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26053&quot; href=&quot;non-idempotent-intersection-types.html#26053&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;26055&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;26057&quot; href=&quot;non-idempotent-intersection-types.html#26007&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;26060&quot; href=&quot;non-idempotent-intersection-types.html#13605&quot; class=&quot;Datatype Operator&quot;&gt;⋈ctx&lt;/a&gt; &lt;a id=&quot;26065&quot; href=&quot;non-idempotent-intersection-types.html#26004&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt;&lt;a id=&quot;26067&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;26069&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
             &lt;a id=&quot;26084&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;26091&quot; href=&quot;non-idempotent-intersection-types.html#26035&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;26093&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;26095&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;26102&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26103&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;26115&quot; href=&quot;non-idempotent-intersection-types.html#26035&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;26117&quot; href=&quot;non-idempotent-intersection-types.html#26053&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;26118&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;26120&quot; href=&quot;non-idempotent-intersection-types.html#25968&quot; class=&quot;Function&quot;&gt;env-permute-size&lt;/a&gt; &lt;a id=&quot;26137&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;      &lt;a id=&quot;26146&quot; href=&quot;non-idempotent-intersection-types.html#13650&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;       &lt;a id=&quot;26156&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;26158&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt;
&lt;a id=&quot;26163&quot; href=&quot;non-idempotent-intersection-types.html#25968&quot; class=&quot;Function&quot;&gt;env-permute-size&lt;/a&gt; &lt;a id=&quot;26180&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26181&quot; href=&quot;non-idempotent-intersection-types.html#26181&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;26183&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;26186&quot; href=&quot;non-idempotent-intersection-types.html#26186&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;26187&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;26189&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26190&quot; href=&quot;non-idempotent-intersection-types.html#26190&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;26192&quot; href=&quot;non-idempotent-intersection-types.html#13671&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;26195&quot; href=&quot;non-idempotent-intersection-types.html#26195&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt;&lt;a id=&quot;26197&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;26199&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;26201&quot; href=&quot;Relation.Binary.PropositionalEquality.html#1524&quot; class=&quot;Function&quot;&gt;cong₂&lt;/a&gt; &lt;a id=&quot;26207&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;_+_&lt;/a&gt; &lt;a id=&quot;26211&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26212&quot; href=&quot;non-idempotent-intersection-types.html#25968&quot; class=&quot;Function&quot;&gt;env-permute-size&lt;/a&gt; &lt;a id=&quot;26229&quot; href=&quot;non-idempotent-intersection-types.html#26181&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;26231&quot; href=&quot;non-idempotent-intersection-types.html#26190&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;26232&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;26234&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26235&quot; href=&quot;non-idempotent-intersection-types.html#24951&quot; class=&quot;Function&quot;&gt;clo-permute-size&lt;/a&gt; &lt;a id=&quot;26252&quot; href=&quot;non-idempotent-intersection-types.html#26186&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;26254&quot; href=&quot;non-idempotent-intersection-types.html#26195&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt;&lt;a id=&quot;26256&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;If a closure &lt;code&gt;c&lt;/code&gt; exhibits all the behaviours in the big intersection &lt;code&gt;σ₁ ++ σ₂&lt;/code&gt;, then it exhibits them separately. Moreover, the sizes of the two separate typing derivations sums to the original:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;clo-split&quot;&gt;&lt;/a&gt;&lt;a id=&quot;26468&quot; href=&quot;non-idempotent-intersection-types.html#26468&quot; class=&quot;Function&quot;&gt;clo-split&lt;/a&gt; &lt;a id=&quot;26478&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;26480&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;26482&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;26483&quot; href=&quot;non-idempotent-intersection-types.html#26483&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;26485&quot; href=&quot;non-idempotent-intersection-types.html#26485&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;26488&quot; href=&quot;non-idempotent-intersection-types.html#26488&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;&lt;a id=&quot;26490&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;26492&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;26494&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;26497&quot; href=&quot;non-idempotent-intersection-types.html#26483&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;26499&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;26502&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26503&quot; href=&quot;non-idempotent-intersection-types.html#26485&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;26506&quot; href=&quot;Data.List.Base.html#1763&quot; class=&quot;Function Operator&quot;&gt;++&lt;/a&gt; &lt;a id=&quot;26509&quot; href=&quot;non-idempotent-intersection-types.html#26488&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;&lt;a id=&quot;26511&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;26513&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;26515&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;26518&quot; href=&quot;non-idempotent-intersection-types.html#26483&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;26520&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;26523&quot; href=&quot;non-idempotent-intersection-types.html#26485&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;26526&quot; href=&quot;Data.Product.html#1167&quot; class=&quot;Function Operator&quot;&gt;×&lt;/a&gt; &lt;a id=&quot;26528&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;26531&quot; href=&quot;non-idempotent-intersection-types.html#26483&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;26533&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;26536&quot; href=&quot;non-idempotent-intersection-types.html#26488&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;
&lt;a id=&quot;26539&quot; href=&quot;non-idempotent-intersection-types.html#26468&quot; class=&quot;Function&quot;&gt;clo-split&lt;/a&gt; &lt;a id=&quot;26549&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;26550&quot; class=&quot;Argument&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;26553&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;26555&quot; href=&quot;Agda.Builtin.List.html#185&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt;&lt;a id=&quot;26557&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;     &lt;a id=&quot;26563&quot; href=&quot;non-idempotent-intersection-types.html#26563&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;        &lt;a id=&quot;26572&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;26574&quot; href=&quot;non-idempotent-intersection-types.html#20154&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;26578&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;26580&quot; href=&quot;non-idempotent-intersection-types.html#26563&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;
&lt;a id=&quot;26582&quot; href=&quot;non-idempotent-intersection-types.html#26468&quot; class=&quot;Function&quot;&gt;clo-split&lt;/a&gt; &lt;a id=&quot;26592&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;26593&quot; class=&quot;Argument&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;26596&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;26598&quot; href=&quot;non-idempotent-intersection-types.html#26598&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;26600&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;26602&quot; href=&quot;non-idempotent-intersection-types.html#26602&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;26604&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;26606&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26607&quot; href=&quot;non-idempotent-intersection-types.html#26607&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt; &lt;a id=&quot;26610&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;26612&quot; href=&quot;non-idempotent-intersection-types.html#26612&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;26613&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;26615&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;26617&quot; class=&quot;Keyword&quot;&gt;let&lt;/a&gt; &lt;a id=&quot;26621&quot; href=&quot;non-idempotent-intersection-types.html#26621&quot; class=&quot;Bound&quot;&gt;d₁&lt;/a&gt; &lt;a id=&quot;26624&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;26626&quot; href=&quot;non-idempotent-intersection-types.html#26626&quot; class=&quot;Bound&quot;&gt;d₂&lt;/a&gt; &lt;a id=&quot;26629&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;26631&quot; href=&quot;non-idempotent-intersection-types.html#26468&quot; class=&quot;Function&quot;&gt;clo-split&lt;/a&gt; &lt;a id=&quot;26641&quot; href=&quot;non-idempotent-intersection-types.html#26612&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;26643&quot; class=&quot;Keyword&quot;&gt;in&lt;/a&gt; &lt;a id=&quot;26646&quot; href=&quot;non-idempotent-intersection-types.html#26607&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt; &lt;a id=&quot;26649&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;26651&quot; href=&quot;non-idempotent-intersection-types.html#26621&quot; class=&quot;Bound&quot;&gt;d₁&lt;/a&gt; &lt;a id=&quot;26654&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;26656&quot; href=&quot;non-idempotent-intersection-types.html#26626&quot; class=&quot;Bound&quot;&gt;d₂&lt;/a&gt;

&lt;a id=&quot;clo-split-size&quot;&gt;&lt;/a&gt;&lt;a id=&quot;26660&quot; href=&quot;non-idempotent-intersection-types.html#26660&quot; class=&quot;Function&quot;&gt;clo-split-size&lt;/a&gt; &lt;a id=&quot;26675&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;26677&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;26679&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;26680&quot; href=&quot;non-idempotent-intersection-types.html#26680&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;26682&quot; href=&quot;non-idempotent-intersection-types.html#26682&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;26685&quot; href=&quot;non-idempotent-intersection-types.html#26685&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;&lt;a id=&quot;26687&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;26689&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;26691&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26692&quot; href=&quot;non-idempotent-intersection-types.html#26692&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;26694&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;26696&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;26699&quot; href=&quot;non-idempotent-intersection-types.html#26680&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;26701&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;26704&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26705&quot; href=&quot;non-idempotent-intersection-types.html#26682&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;26708&quot; href=&quot;Data.List.Base.html#1763&quot; class=&quot;Function Operator&quot;&gt;++&lt;/a&gt; &lt;a id=&quot;26711&quot; href=&quot;non-idempotent-intersection-types.html#26685&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;&lt;a id=&quot;26713&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;26716&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;26718&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;26726&quot; href=&quot;non-idempotent-intersection-types.html#26692&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;26728&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;26730&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;26738&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26739&quot; href=&quot;non-idempotent-intersection-types.html#26468&quot; class=&quot;Function&quot;&gt;clo-split&lt;/a&gt; &lt;a id=&quot;26749&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;26750&quot; class=&quot;Argument&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;26753&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;26755&quot; href=&quot;non-idempotent-intersection-types.html#26682&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;26757&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;26759&quot; href=&quot;non-idempotent-intersection-types.html#26692&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;26761&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;26762&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;26767&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;26769&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;26771&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;26779&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26780&quot; href=&quot;non-idempotent-intersection-types.html#26468&quot; class=&quot;Function&quot;&gt;clo-split&lt;/a&gt; &lt;a id=&quot;26790&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;26791&quot; class=&quot;Argument&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;26794&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;26796&quot; href=&quot;non-idempotent-intersection-types.html#26682&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;26798&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;26800&quot; href=&quot;non-idempotent-intersection-types.html#26692&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;26802&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;26803&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;26808&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;26810&quot; href=&quot;non-idempotent-intersection-types.html#26660&quot; class=&quot;Function&quot;&gt;clo-split-size&lt;/a&gt; &lt;a id=&quot;26825&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;26826&quot; class=&quot;Argument&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;26829&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;26831&quot; href=&quot;Agda.Builtin.List.html#185&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt;&lt;a id=&quot;26833&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;     &lt;a id=&quot;26839&quot; href=&quot;non-idempotent-intersection-types.html#26839&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;        &lt;a id=&quot;26848&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;26850&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt;
&lt;a id=&quot;26855&quot; href=&quot;non-idempotent-intersection-types.html#26660&quot; class=&quot;Function&quot;&gt;clo-split-size&lt;/a&gt; &lt;a id=&quot;26870&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;26871&quot; class=&quot;Argument&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;26874&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;26876&quot; href=&quot;non-idempotent-intersection-types.html#26876&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;26878&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;26880&quot; href=&quot;non-idempotent-intersection-types.html#26880&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;26882&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;26884&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26885&quot; href=&quot;non-idempotent-intersection-types.html#26885&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt; &lt;a id=&quot;26888&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;26890&quot; href=&quot;non-idempotent-intersection-types.html#26890&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;26891&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;26893&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;26895&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1025&quot; class=&quot;Function&quot;&gt;trans&lt;/a&gt; &lt;a id=&quot;26901&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26902&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;26907&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;26910&quot; href=&quot;non-idempotent-intersection-types.html#26910&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;26912&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;26914&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;26921&quot; href=&quot;non-idempotent-intersection-types.html#26885&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt; &lt;a id=&quot;26924&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;26926&quot; href=&quot;non-idempotent-intersection-types.html#26910&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt;&lt;a id=&quot;26927&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;26929&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26930&quot; href=&quot;non-idempotent-intersection-types.html#26660&quot; class=&quot;Function&quot;&gt;clo-split-size&lt;/a&gt; &lt;a id=&quot;26945&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;26946&quot; class=&quot;Argument&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;26949&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;26951&quot; href=&quot;non-idempotent-intersection-types.html#26880&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;26953&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;26955&quot; href=&quot;non-idempotent-intersection-types.html#26890&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;26956&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;26959&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26960&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#980&quot; class=&quot;Function&quot;&gt;sym&lt;/a&gt; &lt;a id=&quot;26964&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26965&quot; href=&quot;Data.Nat.Properties.html#12490&quot; class=&quot;Function&quot;&gt;+-assoc&lt;/a&gt; &lt;a id=&quot;26973&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;26974&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;26981&quot; href=&quot;non-idempotent-intersection-types.html#26885&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt;&lt;a id=&quot;26983&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;26985&quot; class=&quot;Symbol&quot;&gt;_&lt;/a&gt; &lt;a id=&quot;26987&quot; class=&quot;Symbol&quot;&gt;_))&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;As a consequence of &lt;code&gt;clo-split&lt;/code&gt;, we can prove that if an environment exhibits behaviours in two contexts combined, then it exhibits them separately. We will use this to distribute welltypedness of environments between the two parts of an application term in the &lt;code&gt;push&lt;/code&gt; rule of the KAM.&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;env-split&quot;&gt;&lt;/a&gt;&lt;a id=&quot;27291&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;27301&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;27303&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;27305&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;27306&quot; href=&quot;non-idempotent-intersection-types.html#27306&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;27307&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;27309&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;27310&quot; href=&quot;non-idempotent-intersection-types.html#27310&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;27312&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;27314&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;27318&quot; href=&quot;non-idempotent-intersection-types.html#27306&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;27319&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;27321&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;27322&quot; href=&quot;non-idempotent-intersection-types.html#27322&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;27325&quot; href=&quot;non-idempotent-intersection-types.html#27325&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt;&lt;a id=&quot;27327&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;27329&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;27331&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;27334&quot; href=&quot;non-idempotent-intersection-types.html#27310&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;27336&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;27338&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27339&quot; href=&quot;non-idempotent-intersection-types.html#27322&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;27342&quot; href=&quot;non-idempotent-intersection-types.html#12553&quot; class=&quot;Function Operator&quot;&gt;+++&lt;/a&gt; &lt;a id=&quot;27346&quot; href=&quot;non-idempotent-intersection-types.html#27325&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt;&lt;a id=&quot;27348&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;27350&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;27352&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;27355&quot; href=&quot;non-idempotent-intersection-types.html#27310&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;27357&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;27359&quot; href=&quot;non-idempotent-intersection-types.html#27322&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;27362&quot; href=&quot;Data.Product.html#1167&quot; class=&quot;Function Operator&quot;&gt;×&lt;/a&gt; &lt;a id=&quot;27364&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;27367&quot; href=&quot;non-idempotent-intersection-types.html#27310&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;27369&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;27371&quot; href=&quot;non-idempotent-intersection-types.html#27325&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt;
&lt;a id=&quot;27374&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;27384&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;27385&quot; class=&quot;Argument&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;27387&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;27389&quot; href=&quot;Agda.Builtin.Nat.html#210&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;27393&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;  &lt;a id=&quot;27396&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;27397&quot; href=&quot;non-idempotent-intersection-types.html#3767&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;27400&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;    &lt;a id=&quot;27405&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;27406&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;27409&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;      &lt;a id=&quot;27416&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;27417&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;27420&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;     &lt;a id=&quot;27426&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;       &lt;a id=&quot;27436&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;27438&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;27442&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;27444&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;
&lt;a id=&quot;27448&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;27458&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;27459&quot; class=&quot;Argument&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;27461&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;27463&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;27467&quot; href=&quot;non-idempotent-intersection-types.html#27467&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;27468&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;27470&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;27471&quot; href=&quot;non-idempotent-intersection-types.html#27471&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;27473&quot; href=&quot;non-idempotent-intersection-types.html#3787&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;27476&quot; href=&quot;non-idempotent-intersection-types.html#27476&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;27477&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;27479&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;27480&quot; href=&quot;non-idempotent-intersection-types.html#27480&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;27483&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;27486&quot; href=&quot;non-idempotent-intersection-types.html#27486&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt;&lt;a id=&quot;27488&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;27490&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;27491&quot; href=&quot;non-idempotent-intersection-types.html#27491&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;27494&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;27497&quot; href=&quot;non-idempotent-intersection-types.html#27497&quot; class=&quot;Bound&quot;&gt;x₂&lt;/a&gt;&lt;a id=&quot;27499&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;27501&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27502&quot; href=&quot;non-idempotent-intersection-types.html#27502&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;27504&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;27507&quot; href=&quot;non-idempotent-intersection-types.html#27507&quot; class=&quot;Bound&quot;&gt;x₃&lt;/a&gt;&lt;a id=&quot;27509&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;27511&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;27513&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27514&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;27524&quot; href=&quot;non-idempotent-intersection-types.html#27502&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;27526&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;27527&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt; &lt;a id=&quot;27533&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;27536&quot; href=&quot;non-idempotent-intersection-types.html#26468&quot; class=&quot;Function&quot;&gt;clo-split&lt;/a&gt; &lt;a id=&quot;27546&quot; href=&quot;non-idempotent-intersection-types.html#27507&quot; class=&quot;Bound&quot;&gt;x₃&lt;/a&gt; &lt;a id=&quot;27549&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;27550&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;27555&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;27557&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;27559&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27560&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;27570&quot; href=&quot;non-idempotent-intersection-types.html#27502&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;27572&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;27573&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt; &lt;a id=&quot;27579&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;27582&quot; href=&quot;non-idempotent-intersection-types.html#26468&quot; class=&quot;Function&quot;&gt;clo-split&lt;/a&gt; &lt;a id=&quot;27592&quot; href=&quot;non-idempotent-intersection-types.html#27507&quot; class=&quot;Bound&quot;&gt;x₃&lt;/a&gt; &lt;a id=&quot;27595&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;27596&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;27601&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;The splitting of typing derivations by &lt;code&gt;env-split&lt;/code&gt; preserves sizes, but to prove this we first need a lemma about addition:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;interchange&quot;&gt;&lt;/a&gt;&lt;a id=&quot;27741&quot; href=&quot;non-idempotent-intersection-types.html#27741&quot; class=&quot;Function&quot;&gt;interchange&lt;/a&gt; &lt;a id=&quot;27753&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;27755&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;27757&quot; href=&quot;non-idempotent-intersection-types.html#27757&quot; class=&quot;Bound&quot;&gt;a&lt;/a&gt; &lt;a id=&quot;27759&quot; href=&quot;non-idempotent-intersection-types.html#27759&quot; class=&quot;Bound&quot;&gt;b&lt;/a&gt; &lt;a id=&quot;27761&quot; href=&quot;non-idempotent-intersection-types.html#27761&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;27763&quot; href=&quot;non-idempotent-intersection-types.html#27763&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;27765&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;27767&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27768&quot; href=&quot;non-idempotent-intersection-types.html#27757&quot; class=&quot;Bound&quot;&gt;a&lt;/a&gt; &lt;a id=&quot;27770&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27772&quot; href=&quot;non-idempotent-intersection-types.html#27759&quot; class=&quot;Bound&quot;&gt;b&lt;/a&gt;&lt;a id=&quot;27773&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;27775&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27777&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27778&quot; href=&quot;non-idempotent-intersection-types.html#27761&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;27780&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27782&quot; href=&quot;non-idempotent-intersection-types.html#27763&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;27783&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;27785&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;27787&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27788&quot; href=&quot;non-idempotent-intersection-types.html#27757&quot; class=&quot;Bound&quot;&gt;a&lt;/a&gt; &lt;a id=&quot;27790&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27792&quot; href=&quot;non-idempotent-intersection-types.html#27761&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;27793&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;27795&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27797&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27798&quot; href=&quot;non-idempotent-intersection-types.html#27759&quot; class=&quot;Bound&quot;&gt;b&lt;/a&gt; &lt;a id=&quot;27800&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27802&quot; href=&quot;non-idempotent-intersection-types.html#27763&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;27803&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;27805&quot; href=&quot;non-idempotent-intersection-types.html#27741&quot; class=&quot;Function&quot;&gt;interchange&lt;/a&gt; &lt;a id=&quot;27817&quot; href=&quot;non-idempotent-intersection-types.html#27817&quot; class=&quot;Bound&quot;&gt;a&lt;/a&gt; &lt;a id=&quot;27819&quot; href=&quot;non-idempotent-intersection-types.html#27819&quot; class=&quot;Bound&quot;&gt;b&lt;/a&gt; &lt;a id=&quot;27821&quot; href=&quot;non-idempotent-intersection-types.html#27821&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;27823&quot; href=&quot;non-idempotent-intersection-types.html#27823&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;27825&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt;
  &lt;a id=&quot;27829&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2517&quot; class=&quot;Function Operator&quot;&gt;begin&lt;/a&gt;
    &lt;a id=&quot;27839&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27840&quot; href=&quot;non-idempotent-intersection-types.html#27817&quot; class=&quot;Bound&quot;&gt;a&lt;/a&gt; &lt;a id=&quot;27842&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27844&quot; href=&quot;non-idempotent-intersection-types.html#27819&quot; class=&quot;Bound&quot;&gt;b&lt;/a&gt;&lt;a id=&quot;27845&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;27847&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27849&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27850&quot; href=&quot;non-idempotent-intersection-types.html#27821&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;27852&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27854&quot; href=&quot;non-idempotent-intersection-types.html#27823&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;27855&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
  &lt;a id=&quot;27859&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;27862&quot; href=&quot;Data.Nat.Properties.html#12490&quot; class=&quot;Function&quot;&gt;+-assoc&lt;/a&gt; &lt;a id=&quot;27870&quot; href=&quot;non-idempotent-intersection-types.html#27817&quot; class=&quot;Bound&quot;&gt;a&lt;/a&gt; &lt;a id=&quot;27872&quot; href=&quot;non-idempotent-intersection-types.html#27819&quot; class=&quot;Bound&quot;&gt;b&lt;/a&gt; &lt;a id=&quot;27874&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27875&quot; href=&quot;non-idempotent-intersection-types.html#27821&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;27877&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27879&quot; href=&quot;non-idempotent-intersection-types.html#27823&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;27880&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;27882&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
    &lt;a id=&quot;27888&quot; href=&quot;non-idempotent-intersection-types.html#27817&quot; class=&quot;Bound&quot;&gt;a&lt;/a&gt; &lt;a id=&quot;27890&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27892&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27893&quot; href=&quot;non-idempotent-intersection-types.html#27819&quot; class=&quot;Bound&quot;&gt;b&lt;/a&gt; &lt;a id=&quot;27895&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27897&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27898&quot; href=&quot;non-idempotent-intersection-types.html#27821&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;27900&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27902&quot; href=&quot;non-idempotent-intersection-types.html#27823&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;27903&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt;
  &lt;a id=&quot;27908&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;27911&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;27916&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;27919&quot; href=&quot;non-idempotent-intersection-types.html#27919&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;27921&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;27923&quot; href=&quot;non-idempotent-intersection-types.html#27817&quot; class=&quot;Bound&quot;&gt;a&lt;/a&gt; &lt;a id=&quot;27925&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27927&quot; href=&quot;non-idempotent-intersection-types.html#27919&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt;&lt;a id=&quot;27928&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;27930&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27931&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#980&quot; class=&quot;Function&quot;&gt;sym&lt;/a&gt; &lt;a id=&quot;27935&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27936&quot; href=&quot;Data.Nat.Properties.html#12490&quot; class=&quot;Function&quot;&gt;+-assoc&lt;/a&gt; &lt;a id=&quot;27944&quot; href=&quot;non-idempotent-intersection-types.html#27819&quot; class=&quot;Bound&quot;&gt;b&lt;/a&gt; &lt;a id=&quot;27946&quot; href=&quot;non-idempotent-intersection-types.html#27821&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;27948&quot; href=&quot;non-idempotent-intersection-types.html#27823&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;27949&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;27952&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
    &lt;a id=&quot;27958&quot; href=&quot;non-idempotent-intersection-types.html#27817&quot; class=&quot;Bound&quot;&gt;a&lt;/a&gt; &lt;a id=&quot;27960&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27962&quot; class=&quot;Symbol&quot;&gt;((&lt;/a&gt;&lt;a id=&quot;27964&quot; href=&quot;non-idempotent-intersection-types.html#27819&quot; class=&quot;Bound&quot;&gt;b&lt;/a&gt; &lt;a id=&quot;27966&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27968&quot; href=&quot;non-idempotent-intersection-types.html#27821&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;27969&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;27971&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27973&quot; href=&quot;non-idempotent-intersection-types.html#27823&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;27974&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
  &lt;a id=&quot;27978&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;27981&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;27986&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;27989&quot; href=&quot;non-idempotent-intersection-types.html#27989&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;27991&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;27993&quot; href=&quot;non-idempotent-intersection-types.html#27817&quot; class=&quot;Bound&quot;&gt;a&lt;/a&gt; &lt;a id=&quot;27995&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;27997&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;27998&quot; href=&quot;non-idempotent-intersection-types.html#27989&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;28000&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28002&quot; href=&quot;non-idempotent-intersection-types.html#27823&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;28003&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;28006&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28007&quot; href=&quot;Data.Nat.Properties.html#12823&quot; class=&quot;Function&quot;&gt;+-comm&lt;/a&gt; &lt;a id=&quot;28014&quot; href=&quot;non-idempotent-intersection-types.html#27819&quot; class=&quot;Bound&quot;&gt;b&lt;/a&gt; &lt;a id=&quot;28016&quot; href=&quot;non-idempotent-intersection-types.html#27821&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;28017&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;28019&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
    &lt;a id=&quot;28025&quot; href=&quot;non-idempotent-intersection-types.html#27817&quot; class=&quot;Bound&quot;&gt;a&lt;/a&gt; &lt;a id=&quot;28027&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28029&quot; class=&quot;Symbol&quot;&gt;((&lt;/a&gt;&lt;a id=&quot;28031&quot; href=&quot;non-idempotent-intersection-types.html#27821&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;28033&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28035&quot; href=&quot;non-idempotent-intersection-types.html#27819&quot; class=&quot;Bound&quot;&gt;b&lt;/a&gt;&lt;a id=&quot;28036&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;28038&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28040&quot; href=&quot;non-idempotent-intersection-types.html#27823&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;28041&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
  &lt;a id=&quot;28045&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;28048&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;28053&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;28056&quot; href=&quot;non-idempotent-intersection-types.html#28056&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;28058&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;28060&quot; href=&quot;non-idempotent-intersection-types.html#27817&quot; class=&quot;Bound&quot;&gt;a&lt;/a&gt; &lt;a id=&quot;28062&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28064&quot; href=&quot;non-idempotent-intersection-types.html#28056&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt;&lt;a id=&quot;28065&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;28067&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28068&quot; href=&quot;Data.Nat.Properties.html#12490&quot; class=&quot;Function&quot;&gt;+-assoc&lt;/a&gt; &lt;a id=&quot;28076&quot; href=&quot;non-idempotent-intersection-types.html#27821&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;28078&quot; href=&quot;non-idempotent-intersection-types.html#27819&quot; class=&quot;Bound&quot;&gt;b&lt;/a&gt; &lt;a id=&quot;28080&quot; href=&quot;non-idempotent-intersection-types.html#27823&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;28081&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;28083&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
    &lt;a id=&quot;28089&quot; href=&quot;non-idempotent-intersection-types.html#27817&quot; class=&quot;Bound&quot;&gt;a&lt;/a&gt; &lt;a id=&quot;28091&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28093&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28094&quot; href=&quot;non-idempotent-intersection-types.html#27821&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;28096&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28098&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28099&quot; href=&quot;non-idempotent-intersection-types.html#27819&quot; class=&quot;Bound&quot;&gt;b&lt;/a&gt; &lt;a id=&quot;28101&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28103&quot; href=&quot;non-idempotent-intersection-types.html#27823&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;28104&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt;
  &lt;a id=&quot;28109&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;28112&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#980&quot; class=&quot;Function&quot;&gt;sym&lt;/a&gt; &lt;a id=&quot;28116&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28117&quot; href=&quot;Data.Nat.Properties.html#12490&quot; class=&quot;Function&quot;&gt;+-assoc&lt;/a&gt; &lt;a id=&quot;28125&quot; href=&quot;non-idempotent-intersection-types.html#27817&quot; class=&quot;Bound&quot;&gt;a&lt;/a&gt; &lt;a id=&quot;28127&quot; href=&quot;non-idempotent-intersection-types.html#27821&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;28129&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28130&quot; href=&quot;non-idempotent-intersection-types.html#27819&quot; class=&quot;Bound&quot;&gt;b&lt;/a&gt; &lt;a id=&quot;28132&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28134&quot; href=&quot;non-idempotent-intersection-types.html#27823&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;28135&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;28138&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
    &lt;a id=&quot;28144&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28145&quot; href=&quot;non-idempotent-intersection-types.html#27817&quot; class=&quot;Bound&quot;&gt;a&lt;/a&gt; &lt;a id=&quot;28147&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28149&quot; href=&quot;non-idempotent-intersection-types.html#27821&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;28150&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;28152&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28154&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28155&quot; href=&quot;non-idempotent-intersection-types.html#27819&quot; class=&quot;Bound&quot;&gt;b&lt;/a&gt; &lt;a id=&quot;28157&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28159&quot; href=&quot;non-idempotent-intersection-types.html#27823&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;28160&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
  &lt;a id=&quot;28164&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2816&quot; class=&quot;Function Operator&quot;&gt;∎&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;With this lemma, we can prove that splitting an environment typing derivation is size preserving:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;env-split-size&quot;&gt;&lt;/a&gt;&lt;a id=&quot;28278&quot; href=&quot;non-idempotent-intersection-types.html#28278&quot; class=&quot;Function&quot;&gt;env-split-size&lt;/a&gt; &lt;a id=&quot;28293&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;28295&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;28297&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28298&quot; href=&quot;non-idempotent-intersection-types.html#28298&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;28299&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;28301&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28302&quot; href=&quot;non-idempotent-intersection-types.html#28302&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;28304&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;28306&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;28310&quot; href=&quot;non-idempotent-intersection-types.html#28298&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;28311&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;28313&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28314&quot; href=&quot;non-idempotent-intersection-types.html#28314&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;28317&quot; href=&quot;non-idempotent-intersection-types.html#28317&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt;&lt;a id=&quot;28319&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;28321&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;28323&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28324&quot; href=&quot;non-idempotent-intersection-types.html#28324&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;28326&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;28328&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;28331&quot; href=&quot;non-idempotent-intersection-types.html#28302&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;28333&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;28335&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28336&quot; href=&quot;non-idempotent-intersection-types.html#28314&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;28339&quot; href=&quot;non-idempotent-intersection-types.html#12553&quot; class=&quot;Function Operator&quot;&gt;+++&lt;/a&gt; &lt;a id=&quot;28343&quot; href=&quot;non-idempotent-intersection-types.html#28317&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt;&lt;a id=&quot;28345&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;28348&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;28350&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;28357&quot; href=&quot;non-idempotent-intersection-types.html#28324&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;28359&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;28361&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;28368&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28369&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;28379&quot; href=&quot;non-idempotent-intersection-types.html#28324&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;28381&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;28382&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;28387&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;28389&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28391&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;28398&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28399&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;28409&quot; href=&quot;non-idempotent-intersection-types.html#28324&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;28411&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;28412&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;28417&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;28419&quot; href=&quot;non-idempotent-intersection-types.html#28278&quot; class=&quot;Function&quot;&gt;env-split-size&lt;/a&gt; &lt;a id=&quot;28434&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28435&quot; class=&quot;Argument&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;28437&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;28439&quot; href=&quot;Agda.Builtin.Nat.html#210&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;28443&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;  &lt;a id=&quot;28446&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28447&quot; href=&quot;non-idempotent-intersection-types.html#3767&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;28450&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;    &lt;a id=&quot;28455&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28456&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;28459&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;      &lt;a id=&quot;28466&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28467&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;28470&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;     &lt;a id=&quot;28476&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;      &lt;a id=&quot;28485&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;28487&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt;
&lt;a id=&quot;28492&quot; href=&quot;non-idempotent-intersection-types.html#28278&quot; class=&quot;Function&quot;&gt;env-split-size&lt;/a&gt; &lt;a id=&quot;28507&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28508&quot; class=&quot;Argument&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;28510&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;28512&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;28516&quot; href=&quot;non-idempotent-intersection-types.html#28516&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;28517&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;28519&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28520&quot; href=&quot;non-idempotent-intersection-types.html#28520&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;28522&quot; href=&quot;non-idempotent-intersection-types.html#3787&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;28525&quot; href=&quot;non-idempotent-intersection-types.html#28525&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;28526&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;28528&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28529&quot; href=&quot;non-idempotent-intersection-types.html#28529&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;28532&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;28535&quot; href=&quot;non-idempotent-intersection-types.html#28535&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;28537&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;28539&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28540&quot; href=&quot;non-idempotent-intersection-types.html#28540&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;28543&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;28546&quot; href=&quot;non-idempotent-intersection-types.html#28546&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;&lt;a id=&quot;28548&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;28550&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28551&quot; href=&quot;non-idempotent-intersection-types.html#28551&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;28553&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;28556&quot; href=&quot;non-idempotent-intersection-types.html#28556&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;28557&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;28559&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt;
  &lt;a id=&quot;28563&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2517&quot; class=&quot;Function Operator&quot;&gt;begin&lt;/a&gt;
     &lt;a id=&quot;28574&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;28581&quot; href=&quot;non-idempotent-intersection-types.html#28551&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;28583&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28585&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;28593&quot; href=&quot;non-idempotent-intersection-types.html#28556&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;
   &lt;a id=&quot;28598&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;28601&quot; href=&quot;Relation.Binary.PropositionalEquality.html#1524&quot; class=&quot;Function&quot;&gt;cong₂&lt;/a&gt; &lt;a id=&quot;28607&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;_+_&lt;/a&gt; &lt;a id=&quot;28611&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28612&quot; href=&quot;non-idempotent-intersection-types.html#28278&quot; class=&quot;Function&quot;&gt;env-split-size&lt;/a&gt; &lt;a id=&quot;28627&quot; href=&quot;non-idempotent-intersection-types.html#28551&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;28628&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;28630&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28631&quot; href=&quot;non-idempotent-intersection-types.html#26660&quot; class=&quot;Function&quot;&gt;clo-split-size&lt;/a&gt; &lt;a id=&quot;28646&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28647&quot; href=&quot;non-idempotent-intersection-types.html#28525&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;28648&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;28650&quot; href=&quot;non-idempotent-intersection-types.html#28535&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;28652&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;28654&quot; href=&quot;non-idempotent-intersection-types.html#28556&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;28655&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;28657&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;28664&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28665&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;28672&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28673&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;28683&quot; href=&quot;non-idempotent-intersection-types.html#28551&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;28685&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;28686&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;28691&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;28693&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28695&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;28702&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28703&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;28713&quot; href=&quot;non-idempotent-intersection-types.html#28551&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;28715&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;28716&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;28721&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;28724&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28726&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28727&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;28735&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28736&quot; href=&quot;non-idempotent-intersection-types.html#26468&quot; class=&quot;Function&quot;&gt;clo-split&lt;/a&gt; &lt;a id=&quot;28746&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28747&quot; href=&quot;non-idempotent-intersection-types.html#28525&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;28748&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;28750&quot; href=&quot;non-idempotent-intersection-types.html#28535&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;28752&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;28754&quot; href=&quot;non-idempotent-intersection-types.html#28556&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;28756&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;28757&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;28762&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;28764&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28766&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;28774&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28775&quot; href=&quot;non-idempotent-intersection-types.html#26468&quot; class=&quot;Function&quot;&gt;clo-split&lt;/a&gt; &lt;a id=&quot;28785&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28786&quot; href=&quot;non-idempotent-intersection-types.html#28525&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;28787&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;28789&quot; href=&quot;non-idempotent-intersection-types.html#28535&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;28791&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;28793&quot; href=&quot;non-idempotent-intersection-types.html#28556&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;28795&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;28796&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;28801&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt;
   &lt;a id=&quot;28807&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;28810&quot; href=&quot;non-idempotent-intersection-types.html#27741&quot; class=&quot;Function&quot;&gt;interchange&lt;/a&gt; &lt;a id=&quot;28822&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28823&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;28830&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28831&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;28841&quot; href=&quot;non-idempotent-intersection-types.html#28551&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;28843&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;28844&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;28849&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;28852&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28853&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;28860&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28861&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;28871&quot; href=&quot;non-idempotent-intersection-types.html#28551&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;28873&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;28874&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;28879&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;28882&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28883&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;28891&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28892&quot; href=&quot;non-idempotent-intersection-types.html#26468&quot; class=&quot;Function&quot;&gt;clo-split&lt;/a&gt; &lt;a id=&quot;28902&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28903&quot; href=&quot;non-idempotent-intersection-types.html#28525&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;28904&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;28906&quot; href=&quot;non-idempotent-intersection-types.html#28535&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;28908&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;28910&quot; href=&quot;non-idempotent-intersection-types.html#28556&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;28912&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;28913&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;28918&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;28921&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28922&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;28930&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28931&quot; href=&quot;non-idempotent-intersection-types.html#26468&quot; class=&quot;Function&quot;&gt;clo-split&lt;/a&gt; &lt;a id=&quot;28941&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;28942&quot; href=&quot;non-idempotent-intersection-types.html#28525&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;28943&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;28945&quot; href=&quot;non-idempotent-intersection-types.html#28535&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;28947&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;28949&quot; href=&quot;non-idempotent-intersection-types.html#28556&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;28951&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;28952&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;28957&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;28960&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;28967&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;28974&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;28975&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;28985&quot; href=&quot;non-idempotent-intersection-types.html#28551&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;28987&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;28988&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;28993&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;28995&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;28997&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;29005&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;29006&quot; href=&quot;non-idempotent-intersection-types.html#26468&quot; class=&quot;Function&quot;&gt;clo-split&lt;/a&gt; &lt;a id=&quot;29016&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;29017&quot; href=&quot;non-idempotent-intersection-types.html#28525&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;29018&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;29020&quot; href=&quot;non-idempotent-intersection-types.html#28535&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;29022&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;29024&quot; href=&quot;non-idempotent-intersection-types.html#28556&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;29026&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;29027&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;29032&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;29034&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;29036&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;29037&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;29044&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;29045&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;29055&quot; href=&quot;non-idempotent-intersection-types.html#28551&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;29057&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;29058&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;29063&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;29065&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;29067&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;29075&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;29076&quot; href=&quot;non-idempotent-intersection-types.html#26468&quot; class=&quot;Function&quot;&gt;clo-split&lt;/a&gt; &lt;a id=&quot;29086&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;29087&quot; href=&quot;non-idempotent-intersection-types.html#28525&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;29088&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;29090&quot; href=&quot;non-idempotent-intersection-types.html#28535&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;29092&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;29094&quot; href=&quot;non-idempotent-intersection-types.html#28556&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;29096&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;29097&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;29102&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt;
   &lt;a id=&quot;29108&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2816&quot; class=&quot;Function Operator&quot;&gt;∎&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;We also have nullary version of &lt;code&gt;clo-split&lt;/code&gt; and &lt;code&gt;env-split&lt;/code&gt;: whenever a closure has is typed to have no behaviours, or an environment consists of closures that have no required behaviours, then the sizes of their derivations is zero:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;c&amp;#39;-empty&quot;&gt;&lt;/a&gt;&lt;a id=&quot;29358&quot; href=&quot;non-idempotent-intersection-types.html#29358&quot; class=&quot;Function&quot;&gt;c&amp;#39;-empty&lt;/a&gt; &lt;a id=&quot;29367&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;29369&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;29371&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;29372&quot; href=&quot;non-idempotent-intersection-types.html#29372&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;29373&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;29375&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;29377&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;29378&quot; href=&quot;non-idempotent-intersection-types.html#29378&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;29380&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;29382&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;29385&quot; href=&quot;non-idempotent-intersection-types.html#29372&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;29387&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;29390&quot; href=&quot;Agda.Builtin.List.html#185&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt;&lt;a id=&quot;29392&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;29394&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;29396&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;29404&quot; href=&quot;non-idempotent-intersection-types.html#29378&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;29406&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;29408&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;
&lt;a id=&quot;29410&quot; href=&quot;non-idempotent-intersection-types.html#29358&quot; class=&quot;Function&quot;&gt;c&amp;#39;-empty&lt;/a&gt; &lt;a id=&quot;29419&quot; href=&quot;non-idempotent-intersection-types.html#20154&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;29423&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;29425&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt;

&lt;a id=&quot;e-empty&quot;&gt;&lt;/a&gt;&lt;a id=&quot;29431&quot; href=&quot;non-idempotent-intersection-types.html#29431&quot; class=&quot;Function&quot;&gt;e-empty&lt;/a&gt; &lt;a id=&quot;29439&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;29441&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;29443&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;29444&quot; href=&quot;non-idempotent-intersection-types.html#29444&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;29445&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;29447&quot; href=&quot;non-idempotent-intersection-types.html#29447&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;29449&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;29451&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;29455&quot; href=&quot;non-idempotent-intersection-types.html#29444&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;29456&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;29458&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;29460&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;29461&quot; href=&quot;non-idempotent-intersection-types.html#29461&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;29463&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;29465&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;29468&quot; href=&quot;non-idempotent-intersection-types.html#29447&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;29470&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;29472&quot; href=&quot;non-idempotent-intersection-types.html#12243&quot; class=&quot;Function&quot;&gt;empty&lt;/a&gt;&lt;a id=&quot;29477&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;29479&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;29481&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;29488&quot; href=&quot;non-idempotent-intersection-types.html#29461&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;29490&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;29492&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;
&lt;a id=&quot;29494&quot; href=&quot;non-idempotent-intersection-types.html#29431&quot; class=&quot;Function&quot;&gt;e-empty&lt;/a&gt; &lt;a id=&quot;29502&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;29506&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;29508&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt;
&lt;a id=&quot;29513&quot; href=&quot;non-idempotent-intersection-types.html#29431&quot; class=&quot;Function&quot;&gt;e-empty&lt;/a&gt; &lt;a id=&quot;29521&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;29522&quot; href=&quot;non-idempotent-intersection-types.html#29522&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;29524&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;29527&quot; href=&quot;non-idempotent-intersection-types.html#29527&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;29528&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;29530&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;29532&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2517&quot; class=&quot;Function Operator&quot;&gt;begin&lt;/a&gt;
                      &lt;a id=&quot;29560&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;29567&quot; href=&quot;non-idempotent-intersection-types.html#29522&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;29569&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;29571&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;29579&quot; href=&quot;non-idempotent-intersection-types.html#29527&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;
                   &lt;a id=&quot;29600&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;29603&quot; href=&quot;Relation.Binary.PropositionalEquality.html#1524&quot; class=&quot;Function&quot;&gt;cong₂&lt;/a&gt; &lt;a id=&quot;29609&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;_+_&lt;/a&gt; &lt;a id=&quot;29613&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;29614&quot; href=&quot;non-idempotent-intersection-types.html#29431&quot; class=&quot;Function&quot;&gt;e-empty&lt;/a&gt; &lt;a id=&quot;29622&quot; href=&quot;non-idempotent-intersection-types.html#29522&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;29623&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;29625&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;29626&quot; href=&quot;non-idempotent-intersection-types.html#29358&quot; class=&quot;Function&quot;&gt;c&amp;#39;-empty&lt;/a&gt; &lt;a id=&quot;29635&quot; href=&quot;non-idempotent-intersection-types.html#29527&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;29636&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;29638&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
                      &lt;a id=&quot;29662&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;
                   &lt;a id=&quot;29683&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2816&quot; class=&quot;Function Operator&quot;&gt;∎&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;The final piece we need before proving subject reduction is the following derived typing rule for constructing typings of closures against intersections from typings of terms against intersections, assuming an appropriately typed environment. This uses the &lt;code&gt;env-split&lt;/code&gt; and &lt;code&gt;env-permute&lt;/code&gt; lemmas.&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;mk-clo&quot;&gt;&lt;/a&gt;&lt;a id=&quot;29994&quot; href=&quot;non-idempotent-intersection-types.html#29994&quot; class=&quot;Function&quot;&gt;mk-clo&lt;/a&gt; &lt;a id=&quot;30001&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;30003&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;30005&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;30006&quot; href=&quot;non-idempotent-intersection-types.html#30006&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;30007&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;30009&quot; href=&quot;non-idempotent-intersection-types.html#30009&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;30011&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;30013&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;30017&quot; href=&quot;non-idempotent-intersection-types.html#30006&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;30018&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;30020&quot; href=&quot;non-idempotent-intersection-types.html#30020&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;30022&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;30024&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;30028&quot; href=&quot;non-idempotent-intersection-types.html#30006&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;30029&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;30031&quot; href=&quot;non-idempotent-intersection-types.html#30031&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;30033&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;30035&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;30040&quot; href=&quot;non-idempotent-intersection-types.html#30006&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;30041&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;30043&quot; href=&quot;non-idempotent-intersection-types.html#30043&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;30044&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;30046&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
         &lt;a id=&quot;30057&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;30060&quot; href=&quot;non-idempotent-intersection-types.html#30009&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;30062&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;30064&quot; href=&quot;non-idempotent-intersection-types.html#30020&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;30066&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
         &lt;a id=&quot;30077&quot; href=&quot;non-idempotent-intersection-types.html#30020&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;30079&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;30081&quot; href=&quot;non-idempotent-intersection-types.html#30031&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;30083&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;30086&quot; href=&quot;non-idempotent-intersection-types.html#30043&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;30088&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
         &lt;a id=&quot;30099&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;30102&quot; href=&quot;non-idempotent-intersection-types.html#30006&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;30104&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;30106&quot; href=&quot;non-idempotent-intersection-types.html#30009&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;30108&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;30110&quot; href=&quot;non-idempotent-intersection-types.html#30031&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;30112&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;30115&quot; href=&quot;non-idempotent-intersection-types.html#30043&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;
&lt;a id=&quot;30117&quot; href=&quot;non-idempotent-intersection-types.html#29994&quot; class=&quot;Function&quot;&gt;mk-clo&lt;/a&gt; &lt;a id=&quot;30124&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;30125&quot; class=&quot;Argument&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;30127&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;30129&quot; href=&quot;Agda.Builtin.List.html#185&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt;&lt;a id=&quot;30131&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;30133&quot; href=&quot;non-idempotent-intersection-types.html#30133&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;30138&quot; href=&quot;non-idempotent-intersection-types.html#15192&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;  &lt;a id=&quot;30143&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;30145&quot; href=&quot;non-idempotent-intersection-types.html#20154&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;
&lt;a id=&quot;30149&quot; href=&quot;non-idempotent-intersection-types.html#29994&quot; class=&quot;Function&quot;&gt;mk-clo&lt;/a&gt; &lt;a id=&quot;30156&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;30157&quot; class=&quot;Argument&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;30159&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;30161&quot; href=&quot;non-idempotent-intersection-types.html#30161&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;30163&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;30165&quot; href=&quot;non-idempotent-intersection-types.html#30165&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;30166&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;30168&quot; href=&quot;non-idempotent-intersection-types.html#30168&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;30173&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;30174&quot; href=&quot;non-idempotent-intersection-types.html#30174&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;30176&quot; href=&quot;non-idempotent-intersection-types.html#15248&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,~&lt;/a&gt; &lt;a id=&quot;30179&quot; href=&quot;non-idempotent-intersection-types.html#30179&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;30181&quot; href=&quot;non-idempotent-intersection-types.html#15248&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;30183&quot; href=&quot;non-idempotent-intersection-types.html#30183&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt;&lt;a id=&quot;30187&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;30189&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt;
  &lt;a id=&quot;30193&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;30199&quot; href=&quot;non-idempotent-intersection-types.html#30174&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;30201&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;30202&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;30212&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;30213&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;30225&quot; href=&quot;non-idempotent-intersection-types.html#30168&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;30230&quot; href=&quot;non-idempotent-intersection-types.html#30179&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;30231&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;30233&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;30234&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;30239&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;30241&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;30243&quot; href=&quot;non-idempotent-intersection-types.html#29994&quot; class=&quot;Function&quot;&gt;mk-clo&lt;/a&gt; &lt;a id=&quot;30250&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;30251&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;30261&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;30262&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;30274&quot; href=&quot;non-idempotent-intersection-types.html#30168&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;30279&quot; href=&quot;non-idempotent-intersection-types.html#30179&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;30280&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;30282&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;30283&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;30288&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;30290&quot; href=&quot;non-idempotent-intersection-types.html#30183&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;This derived rule is again size preserving, using the fact that &lt;code&gt;env-split&lt;/code&gt; and &lt;code&gt;env-permute&lt;/code&gt; are size preserving:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;mk-clo-size&quot;&gt;&lt;/a&gt;&lt;a id=&quot;30424&quot; href=&quot;non-idempotent-intersection-types.html#30424&quot; class=&quot;Function&quot;&gt;mk-clo-size&lt;/a&gt; &lt;a id=&quot;30436&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;30438&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;30440&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;30441&quot; href=&quot;non-idempotent-intersection-types.html#30441&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;30442&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;30444&quot; href=&quot;non-idempotent-intersection-types.html#30444&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;30446&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;30448&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;30452&quot; href=&quot;non-idempotent-intersection-types.html#30441&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;30453&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;30455&quot; href=&quot;non-idempotent-intersection-types.html#30455&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;30457&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;30459&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;30463&quot; href=&quot;non-idempotent-intersection-types.html#30441&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;30464&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;30466&quot; href=&quot;non-idempotent-intersection-types.html#30466&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;30468&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;30470&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;30475&quot; href=&quot;non-idempotent-intersection-types.html#30441&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;30476&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;30478&quot; href=&quot;non-idempotent-intersection-types.html#30478&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;30479&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;30481&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
              &lt;a id=&quot;30497&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;30498&quot; href=&quot;non-idempotent-intersection-types.html#30498&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;30503&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;30505&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;30508&quot; href=&quot;non-idempotent-intersection-types.html#30444&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;30510&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;30512&quot; href=&quot;non-idempotent-intersection-types.html#30455&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt;&lt;a id=&quot;30513&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;30515&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
              &lt;a id=&quot;30531&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;30532&quot; href=&quot;non-idempotent-intersection-types.html#30532&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt; &lt;a id=&quot;30537&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;30539&quot; href=&quot;non-idempotent-intersection-types.html#30455&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;30541&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;30543&quot; href=&quot;non-idempotent-intersection-types.html#30466&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;30545&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;30548&quot; href=&quot;non-idempotent-intersection-types.html#30478&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;30549&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;30551&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
              &lt;a id=&quot;30567&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;30573&quot; href=&quot;non-idempotent-intersection-types.html#30532&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt; &lt;a id=&quot;30578&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;30580&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;30587&quot; href=&quot;non-idempotent-intersection-types.html#30498&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;30592&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;30594&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;30602&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;30603&quot; href=&quot;non-idempotent-intersection-types.html#29994&quot; class=&quot;Function&quot;&gt;mk-clo&lt;/a&gt; &lt;a id=&quot;30610&quot; href=&quot;non-idempotent-intersection-types.html#30498&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;30615&quot; href=&quot;non-idempotent-intersection-types.html#30532&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt;&lt;a id=&quot;30619&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;30621&quot; href=&quot;non-idempotent-intersection-types.html#30424&quot; class=&quot;Function&quot;&gt;mk-clo-size&lt;/a&gt; &lt;a id=&quot;30633&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;30634&quot; class=&quot;Argument&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;30636&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;30638&quot; href=&quot;Agda.Builtin.List.html#185&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt;&lt;a id=&quot;30640&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;30642&quot; href=&quot;non-idempotent-intersection-types.html#30642&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;30647&quot; href=&quot;non-idempotent-intersection-types.html#15192&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;30651&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;30653&quot; href=&quot;non-idempotent-intersection-types.html#29431&quot; class=&quot;Function&quot;&gt;e-empty&lt;/a&gt; &lt;a id=&quot;30661&quot; href=&quot;non-idempotent-intersection-types.html#30642&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt;
&lt;a id=&quot;30666&quot; href=&quot;non-idempotent-intersection-types.html#30424&quot; class=&quot;Function&quot;&gt;mk-clo-size&lt;/a&gt; &lt;a id=&quot;30678&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;30679&quot; class=&quot;Argument&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;30681&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;30683&quot; href=&quot;non-idempotent-intersection-types.html#30683&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;30685&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;30687&quot; href=&quot;non-idempotent-intersection-types.html#30687&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;30688&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;30690&quot; href=&quot;non-idempotent-intersection-types.html#30690&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;30695&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;30696&quot; href=&quot;non-idempotent-intersection-types.html#30696&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;30698&quot; href=&quot;non-idempotent-intersection-types.html#15248&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,~&lt;/a&gt; &lt;a id=&quot;30701&quot; href=&quot;non-idempotent-intersection-types.html#30701&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;30703&quot; href=&quot;non-idempotent-intersection-types.html#15248&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;30705&quot; href=&quot;non-idempotent-intersection-types.html#30705&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt;&lt;a id=&quot;30709&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;30711&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt;
  &lt;a id=&quot;30715&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2517&quot; class=&quot;Function Operator&quot;&gt;begin&lt;/a&gt;
     &lt;a id=&quot;30726&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;30731&quot; href=&quot;non-idempotent-intersection-types.html#30696&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;30733&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;30735&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;30741&quot; href=&quot;non-idempotent-intersection-types.html#30705&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt; &lt;a id=&quot;30746&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;30748&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;30755&quot; href=&quot;non-idempotent-intersection-types.html#30690&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt;
   &lt;a id=&quot;30763&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;30766&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;30771&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;30774&quot; href=&quot;non-idempotent-intersection-types.html#30774&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;30776&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;30778&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;30783&quot; href=&quot;non-idempotent-intersection-types.html#30696&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;30785&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;30787&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;30793&quot; href=&quot;non-idempotent-intersection-types.html#30705&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt; &lt;a id=&quot;30798&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;30800&quot; href=&quot;non-idempotent-intersection-types.html#30774&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt;&lt;a id=&quot;30801&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;30803&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;30804&quot; href=&quot;non-idempotent-intersection-types.html#25968&quot; class=&quot;Function&quot;&gt;env-permute-size&lt;/a&gt; &lt;a id=&quot;30821&quot; href=&quot;non-idempotent-intersection-types.html#30690&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;30826&quot; href=&quot;non-idempotent-intersection-types.html#30701&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;30827&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;30829&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;30836&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;30841&quot; href=&quot;non-idempotent-intersection-types.html#30696&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;30843&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;30845&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;30851&quot; href=&quot;non-idempotent-intersection-types.html#30705&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt; &lt;a id=&quot;30856&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;30858&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;30865&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;30866&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;30878&quot; href=&quot;non-idempotent-intersection-types.html#30690&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;30883&quot; href=&quot;non-idempotent-intersection-types.html#30701&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;30884&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
   &lt;a id=&quot;30889&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;30892&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;30897&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;30900&quot; href=&quot;non-idempotent-intersection-types.html#30900&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;30902&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;30904&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;30909&quot; href=&quot;non-idempotent-intersection-types.html#30696&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;30911&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;30913&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;30919&quot; href=&quot;non-idempotent-intersection-types.html#30705&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt; &lt;a id=&quot;30924&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;30926&quot; href=&quot;non-idempotent-intersection-types.html#30900&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt;&lt;a id=&quot;30927&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;30929&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;30930&quot; href=&quot;non-idempotent-intersection-types.html#28278&quot; class=&quot;Function&quot;&gt;env-split-size&lt;/a&gt; &lt;a id=&quot;30945&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;30946&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;30958&quot; href=&quot;non-idempotent-intersection-types.html#30690&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;30963&quot; href=&quot;non-idempotent-intersection-types.html#30701&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;30964&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;30967&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;30974&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;30979&quot; href=&quot;non-idempotent-intersection-types.html#30696&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;30981&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;30983&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;30989&quot; href=&quot;non-idempotent-intersection-types.html#30705&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt; &lt;a id=&quot;30994&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;30996&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;30997&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;31004&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31005&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;31015&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31016&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;31028&quot; href=&quot;non-idempotent-intersection-types.html#30690&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;31033&quot; href=&quot;non-idempotent-intersection-types.html#30701&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;31034&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31036&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;31037&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;31042&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31044&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;31046&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;31053&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31054&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;31064&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31065&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;31077&quot; href=&quot;non-idempotent-intersection-types.html#30690&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;31082&quot; href=&quot;non-idempotent-intersection-types.html#30701&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;31083&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31085&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;31086&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;31091&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt;
   &lt;a id=&quot;31097&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;31100&quot; href=&quot;non-idempotent-intersection-types.html#27741&quot; class=&quot;Function&quot;&gt;interchange&lt;/a&gt; &lt;a id=&quot;31112&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31113&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;31118&quot; href=&quot;non-idempotent-intersection-types.html#30696&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;31119&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31121&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31122&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;31128&quot; href=&quot;non-idempotent-intersection-types.html#30705&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt;&lt;a id=&quot;31132&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31134&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31135&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;31142&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31143&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;31153&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31154&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;31166&quot; href=&quot;non-idempotent-intersection-types.html#30690&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;31171&quot; href=&quot;non-idempotent-intersection-types.html#30701&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;31172&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31174&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;31175&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;31180&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;31183&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31184&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;31191&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31192&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;31202&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31203&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;31215&quot; href=&quot;non-idempotent-intersection-types.html#30690&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;31220&quot; href=&quot;non-idempotent-intersection-types.html#30701&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;31221&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31223&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;31224&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;31229&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;31232&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;31239&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;31244&quot; href=&quot;non-idempotent-intersection-types.html#30696&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;31246&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;31248&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;31255&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31256&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;31266&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31267&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;31279&quot; href=&quot;non-idempotent-intersection-types.html#30690&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;31284&quot; href=&quot;non-idempotent-intersection-types.html#30701&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;31285&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31287&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;31288&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;31293&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31295&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;31297&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31298&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;31304&quot; href=&quot;non-idempotent-intersection-types.html#30705&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt; &lt;a id=&quot;31309&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;31311&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;31318&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31319&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;31329&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31330&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;31342&quot; href=&quot;non-idempotent-intersection-types.html#30690&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;31347&quot; href=&quot;non-idempotent-intersection-types.html#30701&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;31348&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31350&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;31351&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;31356&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt;
   &lt;a id=&quot;31362&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;31365&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;31370&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;31373&quot; href=&quot;non-idempotent-intersection-types.html#31373&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;31375&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;31377&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;31382&quot; href=&quot;non-idempotent-intersection-types.html#30696&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;31384&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;31386&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;31393&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31394&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;31404&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31405&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;31417&quot; href=&quot;non-idempotent-intersection-types.html#30690&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;31422&quot; href=&quot;non-idempotent-intersection-types.html#30701&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;31423&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31425&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;31426&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;31431&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31433&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;31435&quot; href=&quot;non-idempotent-intersection-types.html#31373&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt;&lt;a id=&quot;31436&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31438&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31439&quot; href=&quot;non-idempotent-intersection-types.html#30424&quot; class=&quot;Function&quot;&gt;mk-clo-size&lt;/a&gt; &lt;a id=&quot;31451&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31452&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;31462&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31463&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;31475&quot; href=&quot;non-idempotent-intersection-types.html#30690&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;31480&quot; href=&quot;non-idempotent-intersection-types.html#30701&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;31481&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31483&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;31484&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;31489&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31491&quot; href=&quot;non-idempotent-intersection-types.html#30705&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt;&lt;a id=&quot;31495&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31497&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;31504&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;31509&quot; href=&quot;non-idempotent-intersection-types.html#30696&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;31511&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;31513&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;31520&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31521&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;31531&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31532&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;31544&quot; href=&quot;non-idempotent-intersection-types.html#30690&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;31549&quot; href=&quot;non-idempotent-intersection-types.html#30701&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;31550&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31552&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;31553&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;31558&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31560&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;31562&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;31570&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31571&quot; href=&quot;non-idempotent-intersection-types.html#29994&quot; class=&quot;Function&quot;&gt;mk-clo&lt;/a&gt; &lt;a id=&quot;31578&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31579&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;31589&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;31590&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;31602&quot; href=&quot;non-idempotent-intersection-types.html#30690&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;31607&quot; href=&quot;non-idempotent-intersection-types.html#30701&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;31608&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31610&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;31611&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;31616&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;31618&quot; href=&quot;non-idempotent-intersection-types.html#30705&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt;&lt;a id=&quot;31622&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
   &lt;a id=&quot;31627&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2816&quot; class=&quot;Function Operator&quot;&gt;∎&lt;/a&gt;
&lt;/pre&gt;
&lt;h4&gt;Subject Reduction&lt;/h4&gt;&lt;p&gt;Using the lemmas in the previous section, we can now prove the subject reduction property for the non-idempotent intersection type system. The proof consists of taking each possible KAM step in turn, pattern matching on the possible starting configurations' typing derivations, and constructing the corresponding typing derivation for the ending configuration:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;subject-reduction&quot;&gt;&lt;/a&gt;&lt;a id=&quot;32027&quot; href=&quot;non-idempotent-intersection-types.html#32027&quot; class=&quot;Function&quot;&gt;subject-reduction&lt;/a&gt; &lt;a id=&quot;32045&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;32047&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;32049&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;32050&quot; href=&quot;non-idempotent-intersection-types.html#32050&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;32052&quot; href=&quot;non-idempotent-intersection-types.html#32052&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt; &lt;a id=&quot;32054&quot; href=&quot;non-idempotent-intersection-types.html#32054&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;32055&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;32057&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;32059&quot; href=&quot;non-idempotent-intersection-types.html#32050&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;32061&quot; href=&quot;non-idempotent-intersection-types.html#5072&quot; class=&quot;Datatype Operator&quot;&gt;⇒&lt;/a&gt; &lt;a id=&quot;32063&quot; href=&quot;non-idempotent-intersection-types.html#32052&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt; &lt;a id=&quot;32065&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;32067&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⊢p&lt;/a&gt; &lt;a id=&quot;32070&quot; href=&quot;non-idempotent-intersection-types.html#32050&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;32072&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;32074&quot; href=&quot;non-idempotent-intersection-types.html#32054&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;32076&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;32078&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⊢p&lt;/a&gt; &lt;a id=&quot;32081&quot; href=&quot;non-idempotent-intersection-types.html#32052&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt; &lt;a id=&quot;32083&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;32085&quot; href=&quot;non-idempotent-intersection-types.html#32054&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;
&lt;a id=&quot;32087&quot; href=&quot;non-idempotent-intersection-types.html#32027&quot; class=&quot;Function&quot;&gt;subject-reduction&lt;/a&gt; &lt;a id=&quot;32105&quot; href=&quot;non-idempotent-intersection-types.html#5122&quot; class=&quot;InductiveConstructor&quot;&gt;grab&lt;/a&gt; &lt;a id=&quot;32110&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32111&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;32115&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32116&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;32122&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32123&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;32127&quot; href=&quot;non-idempotent-intersection-types.html#14132&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;32131&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;    &lt;a id=&quot;32136&quot; class=&quot;Symbol&quot;&gt;(_&lt;/a&gt;    &lt;a id=&quot;32142&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;32145&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32146&quot; href=&quot;non-idempotent-intersection-types.html#32146&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;32148&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;32150&quot; href=&quot;non-idempotent-intersection-types.html#20154&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;32153&quot; class=&quot;Symbol&quot;&gt;)))&lt;/a&gt; &lt;a id=&quot;32157&quot; href=&quot;non-idempotent-intersection-types.html#32157&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;32161&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;        &lt;a id=&quot;32170&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;32172&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;32176&quot; href=&quot;non-idempotent-intersection-types.html#32146&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;32178&quot; href=&quot;non-idempotent-intersection-types.html#32157&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;
&lt;a id=&quot;32183&quot; href=&quot;non-idempotent-intersection-types.html#32027&quot; class=&quot;Function&quot;&gt;subject-reduction&lt;/a&gt; &lt;a id=&quot;32201&quot; href=&quot;non-idempotent-intersection-types.html#5220&quot; class=&quot;InductiveConstructor&quot;&gt;skip&lt;/a&gt; &lt;a id=&quot;32206&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32207&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;32211&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32212&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;32218&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32219&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;32223&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32224&quot; href=&quot;non-idempotent-intersection-types.html#14184&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;32228&quot; href=&quot;non-idempotent-intersection-types.html#32228&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;32229&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;32232&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32233&quot; href=&quot;non-idempotent-intersection-types.html#32233&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;32238&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;32241&quot; class=&quot;Symbol&quot;&gt;_))&lt;/a&gt;         &lt;a id=&quot;32253&quot; href=&quot;non-idempotent-intersection-types.html#32253&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;32257&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;        &lt;a id=&quot;32266&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;32268&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;32272&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32273&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;32279&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32280&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;32284&quot; href=&quot;non-idempotent-intersection-types.html#32228&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;32285&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;32287&quot; href=&quot;non-idempotent-intersection-types.html#32233&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt;&lt;a id=&quot;32291&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;32293&quot; href=&quot;non-idempotent-intersection-types.html#32253&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;
&lt;a id=&quot;32298&quot; href=&quot;non-idempotent-intersection-types.html#32027&quot; class=&quot;Function&quot;&gt;subject-reduction&lt;/a&gt; &lt;a id=&quot;32316&quot; href=&quot;non-idempotent-intersection-types.html#5318&quot; class=&quot;InductiveConstructor&quot;&gt;push&lt;/a&gt; &lt;a id=&quot;32321&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32322&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;32326&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32327&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;32333&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32334&quot; href=&quot;non-idempotent-intersection-types.html#14924&quot; class=&quot;InductiveConstructor&quot;&gt;app&lt;/a&gt; &lt;a id=&quot;32338&quot; href=&quot;non-idempotent-intersection-types.html#32338&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;32340&quot; href=&quot;non-idempotent-intersection-types.html#32340&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;32342&quot; href=&quot;non-idempotent-intersection-types.html#32342&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;32343&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;   &lt;a id=&quot;32347&quot; href=&quot;non-idempotent-intersection-types.html#32347&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt;&lt;a id=&quot;32351&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;                &lt;a id=&quot;32368&quot; href=&quot;non-idempotent-intersection-types.html#32368&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;32372&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;        &lt;a id=&quot;32381&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt;
  &lt;a id=&quot;32385&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;32389&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32390&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;32396&quot; href=&quot;non-idempotent-intersection-types.html#32338&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;32398&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32399&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;32409&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32410&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;32422&quot; href=&quot;non-idempotent-intersection-types.html#32347&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;32427&quot; href=&quot;non-idempotent-intersection-types.html#32342&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;32428&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;32430&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;32431&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;32436&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;32439&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32440&quot; href=&quot;non-idempotent-intersection-types.html#29994&quot; class=&quot;Function&quot;&gt;mk-clo&lt;/a&gt; &lt;a id=&quot;32447&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32448&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;32458&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32459&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;32471&quot; href=&quot;non-idempotent-intersection-types.html#32347&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;32476&quot; href=&quot;non-idempotent-intersection-types.html#32342&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;32477&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;32479&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;32480&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;32485&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;32487&quot; href=&quot;non-idempotent-intersection-types.html#32340&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;32489&quot; href=&quot;non-idempotent-intersection-types.html#21127&quot; class=&quot;InductiveConstructor Operator&quot;&gt;-,&lt;/a&gt; &lt;a id=&quot;32492&quot; href=&quot;non-idempotent-intersection-types.html#32368&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;32496&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;32498&quot; href=&quot;non-idempotent-intersection-types.html#32027&quot; class=&quot;Function&quot;&gt;subject-reduction&lt;/a&gt; &lt;a id=&quot;32516&quot; href=&quot;non-idempotent-intersection-types.html#5431&quot; class=&quot;InductiveConstructor&quot;&gt;pop&lt;/a&gt;  &lt;a id=&quot;32521&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32522&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;32526&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32527&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;32533&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32534&quot; href=&quot;non-idempotent-intersection-types.html#14832&quot; class=&quot;InductiveConstructor&quot;&gt;lam&lt;/a&gt; &lt;a id=&quot;32538&quot; href=&quot;non-idempotent-intersection-types.html#32538&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;32539&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;       &lt;a id=&quot;32547&quot; href=&quot;non-idempotent-intersection-types.html#32547&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt;&lt;a id=&quot;32551&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;                &lt;a id=&quot;32568&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32569&quot; href=&quot;non-idempotent-intersection-types.html#32569&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;32571&quot; href=&quot;non-idempotent-intersection-types.html#21127&quot; class=&quot;InductiveConstructor Operator&quot;&gt;-,&lt;/a&gt; &lt;a id=&quot;32574&quot; href=&quot;non-idempotent-intersection-types.html#32574&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;32578&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;32581&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;32583&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;32587&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32588&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;32594&quot; href=&quot;non-idempotent-intersection-types.html#32538&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;32596&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;32597&quot; href=&quot;non-idempotent-intersection-types.html#32547&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;32602&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;32605&quot; href=&quot;non-idempotent-intersection-types.html#32569&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;32606&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;32609&quot; href=&quot;non-idempotent-intersection-types.html#32574&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;In most of the cases, the final typing derivation is constructed from parts of the initial one. In the application case, we need to use &lt;code&gt;env-split&lt;/code&gt; to distribute the typing derivation of the environment (&lt;code&gt;η-ok&lt;/code&gt;) between the closures for the function and its argument.&lt;/p&gt;&lt;p&gt;We now prove that subject reduction is &lt;em&gt;quantitative&lt;/em&gt;: the typing derivation generated by subject reduction is always of size one smaller than the initial one. This is a consequence of the fact that most of the operations we perform on typing derivations in he subject reduction proof are size preserving, except for the fact that we remove the top level term former, which accounts for the decrementing by one.&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;sr-size&quot;&gt;&lt;/a&gt;&lt;a id=&quot;33309&quot; href=&quot;non-idempotent-intersection-types.html#33309&quot; class=&quot;Function&quot;&gt;sr-size&lt;/a&gt; &lt;a id=&quot;33317&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;33319&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;33321&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;33322&quot; href=&quot;non-idempotent-intersection-types.html#33322&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;33324&quot; href=&quot;non-idempotent-intersection-types.html#33324&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt; &lt;a id=&quot;33326&quot; href=&quot;non-idempotent-intersection-types.html#33326&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;33327&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;33329&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;33341&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33342&quot; href=&quot;non-idempotent-intersection-types.html#33342&quot; class=&quot;Bound&quot;&gt;step&lt;/a&gt; &lt;a id=&quot;33347&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;33349&quot; href=&quot;non-idempotent-intersection-types.html#33322&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;33351&quot; href=&quot;non-idempotent-intersection-types.html#5072&quot; class=&quot;Datatype Operator&quot;&gt;⇒&lt;/a&gt; &lt;a id=&quot;33353&quot; href=&quot;non-idempotent-intersection-types.html#33324&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt;&lt;a id=&quot;33354&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;33356&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;33368&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33369&quot; href=&quot;non-idempotent-intersection-types.html#33369&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;33371&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;33373&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⊢p&lt;/a&gt; &lt;a id=&quot;33376&quot; href=&quot;non-idempotent-intersection-types.html#33322&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;33378&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;33380&quot; href=&quot;non-idempotent-intersection-types.html#33326&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;33381&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;33383&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
          &lt;a id=&quot;33395&quot; href=&quot;non-idempotent-intersection-types.html#21935&quot; class=&quot;Function&quot;&gt;cfg-size&lt;/a&gt; &lt;a id=&quot;33404&quot; href=&quot;non-idempotent-intersection-types.html#33369&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;33406&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;33408&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;33412&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33413&quot; href=&quot;non-idempotent-intersection-types.html#21935&quot; class=&quot;Function&quot;&gt;cfg-size&lt;/a&gt; &lt;a id=&quot;33422&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33423&quot; href=&quot;non-idempotent-intersection-types.html#32027&quot; class=&quot;Function&quot;&gt;subject-reduction&lt;/a&gt; &lt;a id=&quot;33441&quot; href=&quot;non-idempotent-intersection-types.html#33342&quot; class=&quot;Bound&quot;&gt;step&lt;/a&gt; &lt;a id=&quot;33446&quot; href=&quot;non-idempotent-intersection-types.html#33369&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;33447&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt;
&lt;a id=&quot;33450&quot; href=&quot;non-idempotent-intersection-types.html#33309&quot; class=&quot;Function&quot;&gt;sr-size&lt;/a&gt; &lt;a id=&quot;33458&quot; href=&quot;non-idempotent-intersection-types.html#5122&quot; class=&quot;InductiveConstructor&quot;&gt;grab&lt;/a&gt; &lt;a id=&quot;33463&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33464&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;33468&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33469&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;33475&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33476&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;33480&quot; href=&quot;non-idempotent-intersection-types.html#14132&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;33484&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;    &lt;a id=&quot;33489&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33490&quot; href=&quot;non-idempotent-intersection-types.html#33490&quot; class=&quot;Bound&quot;&gt;η-emp&lt;/a&gt; &lt;a id=&quot;33496&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;33499&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33500&quot; href=&quot;non-idempotent-intersection-types.html#33500&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;33502&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;33504&quot; href=&quot;non-idempotent-intersection-types.html#20154&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;33507&quot; class=&quot;Symbol&quot;&gt;)))&lt;/a&gt; &lt;a id=&quot;33511&quot; href=&quot;non-idempotent-intersection-types.html#33511&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;33515&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;        &lt;a id=&quot;33524&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt;
  &lt;a id=&quot;33528&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2517&quot; class=&quot;Function Operator&quot;&gt;begin&lt;/a&gt;
     &lt;a id=&quot;33539&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;33543&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33544&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;33551&quot; href=&quot;non-idempotent-intersection-types.html#33490&quot; class=&quot;Bound&quot;&gt;η-emp&lt;/a&gt; &lt;a id=&quot;33557&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33559&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33560&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;33567&quot; href=&quot;non-idempotent-intersection-types.html#33500&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;33569&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33571&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;&lt;a id=&quot;33572&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;33574&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33576&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;33583&quot; href=&quot;non-idempotent-intersection-types.html#33511&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;33587&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
   &lt;a id=&quot;33592&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;33595&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;33600&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;33603&quot; href=&quot;non-idempotent-intersection-types.html#33603&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;33605&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;33607&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;33611&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33612&quot; href=&quot;non-idempotent-intersection-types.html#33603&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;33614&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33616&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33617&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;33624&quot; href=&quot;non-idempotent-intersection-types.html#33500&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;33626&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33628&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;&lt;a id=&quot;33629&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;33631&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33633&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;33640&quot; href=&quot;non-idempotent-intersection-types.html#33511&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;33644&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;33647&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33648&quot; href=&quot;non-idempotent-intersection-types.html#29431&quot; class=&quot;Function&quot;&gt;e-empty&lt;/a&gt; &lt;a id=&quot;33656&quot; href=&quot;non-idempotent-intersection-types.html#33490&quot; class=&quot;Bound&quot;&gt;η-emp&lt;/a&gt;&lt;a id=&quot;33661&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;33663&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;33670&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;33674&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33675&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt; &lt;a id=&quot;33677&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33679&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33680&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;33687&quot; href=&quot;non-idempotent-intersection-types.html#33500&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;33689&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33691&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;&lt;a id=&quot;33692&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;33694&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33696&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;33703&quot; href=&quot;non-idempotent-intersection-types.html#33511&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;33707&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
   &lt;a id=&quot;33712&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2575&quot; class=&quot;Function Operator&quot;&gt;≡⟨⟩&lt;/a&gt;
     &lt;a id=&quot;33721&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;33725&quot; class=&quot;Symbol&quot;&gt;((&lt;/a&gt;&lt;a id=&quot;33727&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;33734&quot; href=&quot;non-idempotent-intersection-types.html#33500&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;33736&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33738&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;&lt;a id=&quot;33739&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;33741&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33743&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;33750&quot; href=&quot;non-idempotent-intersection-types.html#33511&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;33754&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
   &lt;a id=&quot;33759&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;33762&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;33767&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;33770&quot; href=&quot;non-idempotent-intersection-types.html#33770&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;33772&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;33774&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;33778&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33779&quot; href=&quot;non-idempotent-intersection-types.html#33770&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;33781&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33783&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;33790&quot; href=&quot;non-idempotent-intersection-types.html#33511&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;33794&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;33797&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33798&quot; href=&quot;Data.Nat.Properties.html#12646&quot; class=&quot;Function&quot;&gt;+-identityʳ&lt;/a&gt; &lt;a id=&quot;33810&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33811&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;33818&quot; href=&quot;non-idempotent-intersection-types.html#33500&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;33819&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;33822&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;33829&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;33833&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33834&quot; href=&quot;non-idempotent-intersection-types.html#20542&quot; class=&quot;Function&quot;&gt;c-size&lt;/a&gt; &lt;a id=&quot;33841&quot; href=&quot;non-idempotent-intersection-types.html#33500&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;33843&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33845&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;33852&quot; href=&quot;non-idempotent-intersection-types.html#33511&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;33856&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
   &lt;a id=&quot;33861&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2816&quot; class=&quot;Function Operator&quot;&gt;∎&lt;/a&gt;
&lt;a id=&quot;33863&quot; href=&quot;non-idempotent-intersection-types.html#33309&quot; class=&quot;Function&quot;&gt;sr-size&lt;/a&gt; &lt;a id=&quot;33871&quot; href=&quot;non-idempotent-intersection-types.html#5220&quot; class=&quot;InductiveConstructor&quot;&gt;skip&lt;/a&gt; &lt;a id=&quot;33876&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33877&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;33881&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33882&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;33888&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33889&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;33893&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33894&quot; href=&quot;non-idempotent-intersection-types.html#14184&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;33898&quot; href=&quot;non-idempotent-intersection-types.html#33898&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;33899&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;33902&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33903&quot; href=&quot;non-idempotent-intersection-types.html#33903&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt;  &lt;a id=&quot;33909&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;33912&quot; href=&quot;non-idempotent-intersection-types.html#33912&quot; class=&quot;Bound&quot;&gt;c&amp;#39;&lt;/a&gt;&lt;a id=&quot;33914&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt;        &lt;a id=&quot;33924&quot; href=&quot;non-idempotent-intersection-types.html#33924&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;33928&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;        &lt;a id=&quot;33937&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt;
  &lt;a id=&quot;33941&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2517&quot; class=&quot;Function Operator&quot;&gt;begin&lt;/a&gt;
     &lt;a id=&quot;33952&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;33956&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33957&quot; href=&quot;non-idempotent-intersection-types.html#18061&quot; class=&quot;Function&quot;&gt;v-size&lt;/a&gt; &lt;a id=&quot;33964&quot; href=&quot;non-idempotent-intersection-types.html#33898&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;33966&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33968&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;33969&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;33976&quot; href=&quot;non-idempotent-intersection-types.html#33903&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;33981&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33983&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;33991&quot; href=&quot;non-idempotent-intersection-types.html#33912&quot; class=&quot;Bound&quot;&gt;c&amp;#39;&lt;/a&gt;&lt;a id=&quot;33993&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;33995&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;33997&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;34004&quot; href=&quot;non-idempotent-intersection-types.html#33924&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;34008&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
   &lt;a id=&quot;34013&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;34016&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;34021&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;34024&quot; href=&quot;non-idempotent-intersection-types.html#34024&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;34026&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;34028&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;34032&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34033&quot; href=&quot;non-idempotent-intersection-types.html#18061&quot; class=&quot;Function&quot;&gt;v-size&lt;/a&gt; &lt;a id=&quot;34040&quot; href=&quot;non-idempotent-intersection-types.html#33898&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;34042&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34044&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34045&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;34052&quot; href=&quot;non-idempotent-intersection-types.html#33903&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;34057&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34059&quot; href=&quot;non-idempotent-intersection-types.html#34024&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt;&lt;a id=&quot;34060&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;34062&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34064&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;34071&quot; href=&quot;non-idempotent-intersection-types.html#33924&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;34075&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;34078&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34079&quot; href=&quot;non-idempotent-intersection-types.html#29358&quot; class=&quot;Function&quot;&gt;c&amp;#39;-empty&lt;/a&gt; &lt;a id=&quot;34088&quot; href=&quot;non-idempotent-intersection-types.html#33912&quot; class=&quot;Bound&quot;&gt;c&amp;#39;&lt;/a&gt;&lt;a id=&quot;34090&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;34092&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;34099&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;34103&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34104&quot; href=&quot;non-idempotent-intersection-types.html#18061&quot; class=&quot;Function&quot;&gt;v-size&lt;/a&gt; &lt;a id=&quot;34111&quot; href=&quot;non-idempotent-intersection-types.html#33898&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;34113&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34115&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34116&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;34123&quot; href=&quot;non-idempotent-intersection-types.html#33903&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;34128&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34130&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;&lt;a id=&quot;34131&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;34133&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34135&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;34142&quot; href=&quot;non-idempotent-intersection-types.html#33924&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;34146&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
   &lt;a id=&quot;34151&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;34154&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;34159&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;34162&quot; href=&quot;non-idempotent-intersection-types.html#34162&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;34164&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;34166&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;34170&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34171&quot; href=&quot;non-idempotent-intersection-types.html#18061&quot; class=&quot;Function&quot;&gt;v-size&lt;/a&gt; &lt;a id=&quot;34178&quot; href=&quot;non-idempotent-intersection-types.html#33898&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;34180&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34182&quot; href=&quot;non-idempotent-intersection-types.html#34162&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;34184&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34186&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;34193&quot; href=&quot;non-idempotent-intersection-types.html#33924&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;34197&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;34200&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34201&quot; href=&quot;Data.Nat.Properties.html#12646&quot; class=&quot;Function&quot;&gt;+-identityʳ&lt;/a&gt; &lt;a id=&quot;34213&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34214&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;34221&quot; href=&quot;non-idempotent-intersection-types.html#33903&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt;&lt;a id=&quot;34225&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;34228&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;34235&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;34239&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34240&quot; href=&quot;non-idempotent-intersection-types.html#18061&quot; class=&quot;Function&quot;&gt;v-size&lt;/a&gt; &lt;a id=&quot;34247&quot; href=&quot;non-idempotent-intersection-types.html#33898&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;34249&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34251&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;34258&quot; href=&quot;non-idempotent-intersection-types.html#33903&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;34263&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34265&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;34272&quot; href=&quot;non-idempotent-intersection-types.html#33924&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;34276&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
   &lt;a id=&quot;34281&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2816&quot; class=&quot;Function Operator&quot;&gt;∎&lt;/a&gt;
&lt;a id=&quot;34283&quot; href=&quot;non-idempotent-intersection-types.html#33309&quot; class=&quot;Function&quot;&gt;sr-size&lt;/a&gt; &lt;a id=&quot;34291&quot; href=&quot;non-idempotent-intersection-types.html#5318&quot; class=&quot;InductiveConstructor&quot;&gt;push&lt;/a&gt; &lt;a id=&quot;34296&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34297&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;34301&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34302&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;34308&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34309&quot; href=&quot;non-idempotent-intersection-types.html#14924&quot; class=&quot;InductiveConstructor&quot;&gt;app&lt;/a&gt; &lt;a id=&quot;34313&quot; href=&quot;non-idempotent-intersection-types.html#34313&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;34315&quot; href=&quot;non-idempotent-intersection-types.html#34315&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;34317&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;34318&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;   &lt;a id=&quot;34322&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt;&lt;a id=&quot;34326&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;                 &lt;a id=&quot;34344&quot; href=&quot;non-idempotent-intersection-types.html#34344&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;34348&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;        &lt;a id=&quot;34357&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt;
  &lt;a id=&quot;34361&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2517&quot; class=&quot;Function Operator&quot;&gt;begin&lt;/a&gt;
     &lt;a id=&quot;34372&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;34376&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34377&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;34382&quot; href=&quot;non-idempotent-intersection-types.html#34313&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;34384&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34386&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;34392&quot; href=&quot;non-idempotent-intersection-types.html#34315&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;34394&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34396&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;34403&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;34408&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34410&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;34417&quot; href=&quot;non-idempotent-intersection-types.html#34344&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;34421&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
  &lt;a id=&quot;34425&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;34428&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;34433&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;34436&quot; href=&quot;non-idempotent-intersection-types.html#34436&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;34438&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;34440&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;34444&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34445&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;34450&quot; href=&quot;non-idempotent-intersection-types.html#34313&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;34452&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34454&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;34460&quot; href=&quot;non-idempotent-intersection-types.html#34315&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;34462&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34464&quot; href=&quot;non-idempotent-intersection-types.html#34436&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;34466&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34468&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;34475&quot; href=&quot;non-idempotent-intersection-types.html#34344&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;34479&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;34482&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34483&quot; href=&quot;non-idempotent-intersection-types.html#25968&quot; class=&quot;Function&quot;&gt;env-permute-size&lt;/a&gt; &lt;a id=&quot;34500&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;34505&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;34506&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;34508&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;34515&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;34519&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34520&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;34525&quot; href=&quot;non-idempotent-intersection-types.html#34313&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;34527&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34529&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;34535&quot; href=&quot;non-idempotent-intersection-types.html#34315&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;34537&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34539&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;34546&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34547&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;34559&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;34564&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;34565&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;34567&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34569&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;34576&quot; href=&quot;non-idempotent-intersection-types.html#34344&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;34580&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
  &lt;a id=&quot;34584&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;34587&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;34592&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;34595&quot; href=&quot;non-idempotent-intersection-types.html#34595&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;34597&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;34599&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;34603&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34604&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;34609&quot; href=&quot;non-idempotent-intersection-types.html#34313&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;34611&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34613&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;34619&quot; href=&quot;non-idempotent-intersection-types.html#34315&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;34621&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34623&quot; href=&quot;non-idempotent-intersection-types.html#34595&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;34625&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34627&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;34634&quot; href=&quot;non-idempotent-intersection-types.html#34344&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;34638&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;34641&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34642&quot; href=&quot;non-idempotent-intersection-types.html#28278&quot; class=&quot;Function&quot;&gt;env-split-size&lt;/a&gt; &lt;a id=&quot;34657&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34658&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;34670&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;34675&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;34676&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;34679&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;34686&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;34690&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34691&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;34696&quot; href=&quot;non-idempotent-intersection-types.html#34313&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;34698&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34700&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;34706&quot; href=&quot;non-idempotent-intersection-types.html#34315&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;34708&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34710&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34711&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;34718&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34719&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;34729&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34730&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;34742&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;34747&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;34748&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;34750&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;34751&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;34756&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;34758&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34760&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;34767&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34768&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;34778&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34779&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;34791&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;34796&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;34797&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;34799&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;34800&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;34805&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;34808&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34810&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;34817&quot; href=&quot;non-idempotent-intersection-types.html#34344&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;34821&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
  &lt;a id=&quot;34825&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;34828&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;34833&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;34836&quot; href=&quot;non-idempotent-intersection-types.html#34836&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;34838&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;34840&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;34844&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34845&quot; href=&quot;non-idempotent-intersection-types.html#34836&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;34847&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;34849&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;34856&quot; href=&quot;non-idempotent-intersection-types.html#34344&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;34860&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;34863&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34864&quot; href=&quot;non-idempotent-intersection-types.html#27741&quot; class=&quot;Function&quot;&gt;interchange&lt;/a&gt; &lt;a id=&quot;34876&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34877&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;34882&quot; href=&quot;non-idempotent-intersection-types.html#34313&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;34883&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;34885&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34886&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;34892&quot; href=&quot;non-idempotent-intersection-types.html#34315&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt;&lt;a id=&quot;34893&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;34895&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34896&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;34903&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34904&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;34914&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34915&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;34927&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;34932&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;34933&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;34935&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;34936&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;34941&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;34944&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34945&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;34952&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34953&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;34963&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;34964&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;34976&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;34981&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;34982&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;34984&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;34985&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;34990&quot; class=&quot;Symbol&quot;&gt;)))&lt;/a&gt; &lt;a id=&quot;34994&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;35001&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;35005&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35006&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;35011&quot; href=&quot;non-idempotent-intersection-types.html#34313&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;35013&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35015&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;35022&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35023&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;35033&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35034&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;35046&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;35051&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;35052&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35054&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;35055&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;35060&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35062&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35064&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35065&quot; href=&quot;non-idempotent-intersection-types.html#18350&quot; class=&quot;Function&quot;&gt;size&amp;#39;&lt;/a&gt; &lt;a id=&quot;35071&quot; href=&quot;non-idempotent-intersection-types.html#34315&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;35073&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35075&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;35082&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35083&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;35093&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35094&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;35106&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;35111&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;35112&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35114&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;35115&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;35120&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;35123&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35125&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;35132&quot; href=&quot;non-idempotent-intersection-types.html#34344&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;35136&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
  &lt;a id=&quot;35140&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;35143&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;35148&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;35151&quot; href=&quot;non-idempotent-intersection-types.html#35151&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;35153&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;35155&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;35159&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35160&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;35165&quot; href=&quot;non-idempotent-intersection-types.html#34313&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;35167&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35169&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;35176&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35177&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;35187&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35188&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;35200&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;35205&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;35206&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35208&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;35209&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;35214&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35216&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35218&quot; href=&quot;non-idempotent-intersection-types.html#35151&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;35220&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35222&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;35229&quot; href=&quot;non-idempotent-intersection-types.html#34344&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;35233&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;35236&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35237&quot; href=&quot;non-idempotent-intersection-types.html#30424&quot; class=&quot;Function&quot;&gt;mk-clo-size&lt;/a&gt; &lt;a id=&quot;35249&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35250&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;35260&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35261&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;35273&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;35278&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;35279&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35281&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;35282&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;35287&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35289&quot; href=&quot;non-idempotent-intersection-types.html#34315&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt;&lt;a id=&quot;35290&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35292&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;35299&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;35303&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35304&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;35309&quot; href=&quot;non-idempotent-intersection-types.html#34313&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;35311&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35313&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;35320&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35321&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;35331&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35332&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;35344&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;35349&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;35350&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35352&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;35353&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;35358&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35360&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35362&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;35370&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35371&quot; href=&quot;non-idempotent-intersection-types.html#29994&quot; class=&quot;Function&quot;&gt;mk-clo&lt;/a&gt; &lt;a id=&quot;35378&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35379&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;35389&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35390&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;35402&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;35407&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;35408&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35410&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;35411&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;35416&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35418&quot; href=&quot;non-idempotent-intersection-types.html#34315&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt;&lt;a id=&quot;35419&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35421&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35423&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;35430&quot; href=&quot;non-idempotent-intersection-types.html#34344&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;35434&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
  &lt;a id=&quot;35438&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;35441&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;35446&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;35449&quot; href=&quot;non-idempotent-intersection-types.html#35449&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;35451&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;35453&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;35457&quot; href=&quot;non-idempotent-intersection-types.html#35449&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt;&lt;a id=&quot;35458&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35460&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35461&quot; href=&quot;Data.Nat.Properties.html#12490&quot; class=&quot;Function&quot;&gt;+-assoc&lt;/a&gt; &lt;a id=&quot;35469&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35470&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;35475&quot; href=&quot;non-idempotent-intersection-types.html#34313&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;35477&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35479&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;35486&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35487&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;35497&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35498&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;35510&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;35515&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;35516&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35518&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;35519&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;35524&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;35527&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35528&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;35536&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35537&quot; href=&quot;non-idempotent-intersection-types.html#29994&quot; class=&quot;Function&quot;&gt;mk-clo&lt;/a&gt; &lt;a id=&quot;35544&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35545&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;35555&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35556&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;35568&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;35573&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;35574&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35576&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;35577&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;35582&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35584&quot; href=&quot;non-idempotent-intersection-types.html#34315&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt;&lt;a id=&quot;35585&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;35588&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35589&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;35596&quot; href=&quot;non-idempotent-intersection-types.html#34344&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;35600&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;35603&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;35610&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;35614&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35615&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;35620&quot; href=&quot;non-idempotent-intersection-types.html#34313&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;35622&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35624&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;35631&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35632&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;35642&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35643&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;35655&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;35660&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;35661&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35663&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;35664&quot; href=&quot;Agda.Builtin.Sigma.html#252&quot; class=&quot;Field&quot;&gt;proj₁&lt;/a&gt;&lt;a id=&quot;35669&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35671&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35673&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35674&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;35682&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35683&quot; href=&quot;non-idempotent-intersection-types.html#29994&quot; class=&quot;Function&quot;&gt;mk-clo&lt;/a&gt; &lt;a id=&quot;35690&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35691&quot; href=&quot;non-idempotent-intersection-types.html#27291&quot; class=&quot;Function&quot;&gt;env-split&lt;/a&gt; &lt;a id=&quot;35701&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35702&quot; href=&quot;non-idempotent-intersection-types.html#25739&quot; class=&quot;Function&quot;&gt;env-permute&lt;/a&gt; &lt;a id=&quot;35714&quot; href=&quot;non-idempotent-intersection-types.html#34322&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;35719&quot; href=&quot;non-idempotent-intersection-types.html#34317&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;35720&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35722&quot; class=&quot;Symbol&quot;&gt;.&lt;/a&gt;&lt;a id=&quot;35723&quot; href=&quot;Agda.Builtin.Sigma.html#264&quot; class=&quot;Field&quot;&gt;proj₂&lt;/a&gt;&lt;a id=&quot;35728&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35730&quot; href=&quot;non-idempotent-intersection-types.html#34315&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt;&lt;a id=&quot;35731&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35733&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35735&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;35742&quot; href=&quot;non-idempotent-intersection-types.html#34344&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;35746&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt;
  &lt;a id=&quot;35751&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2816&quot; class=&quot;Function Operator&quot;&gt;∎&lt;/a&gt;
&lt;a id=&quot;35753&quot; href=&quot;non-idempotent-intersection-types.html#33309&quot; class=&quot;Function&quot;&gt;sr-size&lt;/a&gt; &lt;a id=&quot;35761&quot; href=&quot;non-idempotent-intersection-types.html#5431&quot; class=&quot;InductiveConstructor&quot;&gt;pop&lt;/a&gt;  &lt;a id=&quot;35766&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35767&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;35771&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35772&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;35778&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35779&quot; href=&quot;non-idempotent-intersection-types.html#14832&quot; class=&quot;InductiveConstructor&quot;&gt;lam&lt;/a&gt; &lt;a id=&quot;35783&quot; href=&quot;non-idempotent-intersection-types.html#35783&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;35784&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;       &lt;a id=&quot;35792&quot; href=&quot;non-idempotent-intersection-types.html#35792&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt;&lt;a id=&quot;35796&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;                 &lt;a id=&quot;35814&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35815&quot; href=&quot;non-idempotent-intersection-types.html#35815&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;35817&quot; href=&quot;non-idempotent-intersection-types.html#21127&quot; class=&quot;InductiveConstructor Operator&quot;&gt;-,&lt;/a&gt; &lt;a id=&quot;35820&quot; href=&quot;non-idempotent-intersection-types.html#35820&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;35824&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;35827&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt;
  &lt;a id=&quot;35831&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2517&quot; class=&quot;Function Operator&quot;&gt;begin&lt;/a&gt;
     &lt;a id=&quot;35842&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;35846&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35847&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;35852&quot; href=&quot;non-idempotent-intersection-types.html#35783&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;35854&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35856&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;35863&quot; href=&quot;non-idempotent-intersection-types.html#35792&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;35868&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35870&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35871&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;35879&quot; href=&quot;non-idempotent-intersection-types.html#35815&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;35881&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35883&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;35890&quot; href=&quot;non-idempotent-intersection-types.html#35820&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;35894&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt;
  &lt;a id=&quot;35899&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;35902&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;35907&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;35910&quot; href=&quot;non-idempotent-intersection-types.html#35910&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;35912&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;35914&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;35918&quot; href=&quot;non-idempotent-intersection-types.html#35910&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt;&lt;a id=&quot;35919&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35921&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35922&quot; href=&quot;Data.Nat.Properties.html#12490&quot; class=&quot;Function&quot;&gt;+-assoc&lt;/a&gt; &lt;a id=&quot;35930&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35931&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;35936&quot; href=&quot;non-idempotent-intersection-types.html#35783&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;35937&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35939&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35940&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;35947&quot; href=&quot;non-idempotent-intersection-types.html#35792&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt;&lt;a id=&quot;35951&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;35953&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35954&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;35962&quot; href=&quot;non-idempotent-intersection-types.html#35815&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;35964&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;35966&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;35973&quot; href=&quot;non-idempotent-intersection-types.html#35820&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;35977&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;35980&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;35987&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;35991&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;35992&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;35997&quot; href=&quot;non-idempotent-intersection-types.html#35783&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;35999&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;36001&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36002&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;36009&quot; href=&quot;non-idempotent-intersection-types.html#35792&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;36014&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;36016&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36017&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;36025&quot; href=&quot;non-idempotent-intersection-types.html#35815&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;36027&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;36029&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;36036&quot; href=&quot;non-idempotent-intersection-types.html#35820&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;36040&quot; class=&quot;Symbol&quot;&gt;)))&lt;/a&gt;
  &lt;a id=&quot;36046&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;36049&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;36054&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;36057&quot; href=&quot;non-idempotent-intersection-types.html#36057&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;36059&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;36061&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;36065&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36066&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;36071&quot; href=&quot;non-idempotent-intersection-types.html#35783&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;36073&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;36075&quot; href=&quot;non-idempotent-intersection-types.html#36057&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt;&lt;a id=&quot;36076&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;36079&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36080&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#980&quot; class=&quot;Function&quot;&gt;sym&lt;/a&gt; &lt;a id=&quot;36084&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36085&quot; href=&quot;Data.Nat.Properties.html#12490&quot; class=&quot;Function&quot;&gt;+-assoc&lt;/a&gt; &lt;a id=&quot;36093&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36094&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;36101&quot; href=&quot;non-idempotent-intersection-types.html#35792&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt;&lt;a id=&quot;36105&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;36107&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36108&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;36116&quot; href=&quot;non-idempotent-intersection-types.html#35815&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;36117&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;36119&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36120&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;36127&quot; href=&quot;non-idempotent-intersection-types.html#35820&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;36131&quot; class=&quot;Symbol&quot;&gt;)))&lt;/a&gt; &lt;a id=&quot;36135&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;36142&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;36146&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36147&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;36152&quot; href=&quot;non-idempotent-intersection-types.html#35783&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;36154&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;36156&quot; class=&quot;Symbol&quot;&gt;((&lt;/a&gt;&lt;a id=&quot;36158&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;36165&quot; href=&quot;non-idempotent-intersection-types.html#35792&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;36170&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;36172&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;36180&quot; href=&quot;non-idempotent-intersection-types.html#35815&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;36181&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;36183&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;36185&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;36192&quot; href=&quot;non-idempotent-intersection-types.html#35820&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;36196&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt;
  &lt;a id=&quot;36201&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;≡⟨&lt;/a&gt; &lt;a id=&quot;36204&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1131&quot; class=&quot;Function&quot;&gt;cong&lt;/a&gt; &lt;a id=&quot;36209&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;36213&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36214&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#980&quot; class=&quot;Function&quot;&gt;sym&lt;/a&gt; &lt;a id=&quot;36218&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36219&quot; href=&quot;Data.Nat.Properties.html#12490&quot; class=&quot;Function&quot;&gt;+-assoc&lt;/a&gt; &lt;a id=&quot;36227&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36228&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;36233&quot; href=&quot;non-idempotent-intersection-types.html#35783&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;36234&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;36236&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36237&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;36244&quot; href=&quot;non-idempotent-intersection-types.html#35792&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;36249&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;36251&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;36259&quot; href=&quot;non-idempotent-intersection-types.html#35815&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;36260&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;36262&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36263&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;36270&quot; href=&quot;non-idempotent-intersection-types.html#35820&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;36274&quot; class=&quot;Symbol&quot;&gt;)))&lt;/a&gt; &lt;a id=&quot;36278&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2634&quot; class=&quot;Function&quot;&gt;⟩&lt;/a&gt;
     &lt;a id=&quot;36285&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;36289&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36290&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;36295&quot; href=&quot;non-idempotent-intersection-types.html#35783&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;36297&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;36299&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;36300&quot; href=&quot;non-idempotent-intersection-types.html#20618&quot; class=&quot;Function&quot;&gt;e-size&lt;/a&gt; &lt;a id=&quot;36307&quot; href=&quot;non-idempotent-intersection-types.html#35792&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;36312&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;36314&quot; href=&quot;non-idempotent-intersection-types.html#20723&quot; class=&quot;Function&quot;&gt;c&amp;#39;-size&lt;/a&gt; &lt;a id=&quot;36322&quot; href=&quot;non-idempotent-intersection-types.html#35815&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;36323&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;36325&quot; href=&quot;Agda.Builtin.Nat.html#325&quot; class=&quot;Primitive Operator&quot;&gt;+&lt;/a&gt; &lt;a id=&quot;36327&quot; href=&quot;non-idempotent-intersection-types.html#21373&quot; class=&quot;Function&quot;&gt;s-size&lt;/a&gt; &lt;a id=&quot;36334&quot; href=&quot;non-idempotent-intersection-types.html#35820&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;36338&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
  &lt;a id=&quot;36342&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#2816&quot; class=&quot;Function Operator&quot;&gt;∎&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;When we combine these two lemmas with the progress lemma we prove below, we will be able to prove by induction on the size of the typing derivation that the execution of the KAM terminates. This is the content of the soundness lemma below.&lt;/p&gt;&lt;h4&gt;Subject expansion&lt;/h4&gt;&lt;p&gt;A feature of intersection type systems is that they often enjoy subject expansion as well as subject reduction. The type information is a precise enough description of a term's behaviour that we are always able to reconstruct typing derivations backwards through execution.&lt;/p&gt;&lt;p&gt;To prove subject expansion we will need the inverse to the closure and environment splitting lemmas we proved for subject reduction:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;clo-join&quot;&gt;&lt;/a&gt;&lt;a id=&quot;37030&quot; href=&quot;non-idempotent-intersection-types.html#37030&quot; class=&quot;Function&quot;&gt;clo-join&lt;/a&gt; &lt;a id=&quot;37039&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;37041&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;37043&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37044&quot; href=&quot;non-idempotent-intersection-types.html#37044&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;37046&quot; href=&quot;non-idempotent-intersection-types.html#37046&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;37049&quot; href=&quot;non-idempotent-intersection-types.html#37049&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;&lt;a id=&quot;37051&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;37053&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;37055&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;37058&quot; href=&quot;non-idempotent-intersection-types.html#37044&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;37060&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;37063&quot; href=&quot;non-idempotent-intersection-types.html#37046&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;37066&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;37068&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;37071&quot; href=&quot;non-idempotent-intersection-types.html#37044&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;37073&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;37076&quot; href=&quot;non-idempotent-intersection-types.html#37049&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt; &lt;a id=&quot;37079&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;37081&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;37084&quot; href=&quot;non-idempotent-intersection-types.html#37044&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;37086&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;37089&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;37090&quot; href=&quot;non-idempotent-intersection-types.html#37046&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;37093&quot; href=&quot;Data.List.Base.html#1763&quot; class=&quot;Function Operator&quot;&gt;++&lt;/a&gt; &lt;a id=&quot;37096&quot; href=&quot;non-idempotent-intersection-types.html#37049&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;&lt;a id=&quot;37098&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;37100&quot; href=&quot;non-idempotent-intersection-types.html#37030&quot; class=&quot;Function&quot;&gt;clo-join&lt;/a&gt; &lt;a id=&quot;37109&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37110&quot; class=&quot;Argument&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;37113&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;37115&quot; href=&quot;Agda.Builtin.List.html#185&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt;&lt;a id=&quot;37117&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;     &lt;a id=&quot;37123&quot; href=&quot;non-idempotent-intersection-types.html#20154&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;      &lt;a id=&quot;37132&quot; href=&quot;non-idempotent-intersection-types.html#37132&quot; class=&quot;Bound&quot;&gt;c₂&lt;/a&gt; &lt;a id=&quot;37135&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;37137&quot; href=&quot;non-idempotent-intersection-types.html#37132&quot; class=&quot;Bound&quot;&gt;c₂&lt;/a&gt;
&lt;a id=&quot;37140&quot; href=&quot;non-idempotent-intersection-types.html#37030&quot; class=&quot;Function&quot;&gt;clo-join&lt;/a&gt; &lt;a id=&quot;37149&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37150&quot; class=&quot;Argument&quot;&gt;σ₁&lt;/a&gt; &lt;a id=&quot;37153&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;37155&quot; href=&quot;non-idempotent-intersection-types.html#37155&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;37157&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;37159&quot; href=&quot;non-idempotent-intersection-types.html#37159&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;37161&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;37163&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;37164&quot; href=&quot;non-idempotent-intersection-types.html#37164&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;37166&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;37168&quot; href=&quot;non-idempotent-intersection-types.html#37168&quot; class=&quot;Bound&quot;&gt;c₁&lt;/a&gt;&lt;a id=&quot;37170&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;37172&quot; href=&quot;non-idempotent-intersection-types.html#37172&quot; class=&quot;Bound&quot;&gt;c₂&lt;/a&gt; &lt;a id=&quot;37175&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;37177&quot; href=&quot;non-idempotent-intersection-types.html#37164&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;37179&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;37181&quot; href=&quot;non-idempotent-intersection-types.html#37030&quot; class=&quot;Function&quot;&gt;clo-join&lt;/a&gt; &lt;a id=&quot;37190&quot; href=&quot;non-idempotent-intersection-types.html#37168&quot; class=&quot;Bound&quot;&gt;c₁&lt;/a&gt; &lt;a id=&quot;37193&quot; href=&quot;non-idempotent-intersection-types.html#37172&quot; class=&quot;Bound&quot;&gt;c₂&lt;/a&gt;

&lt;a id=&quot;env-join&quot;&gt;&lt;/a&gt;&lt;a id=&quot;37197&quot; href=&quot;non-idempotent-intersection-types.html#37197&quot; class=&quot;Function&quot;&gt;env-join&lt;/a&gt; &lt;a id=&quot;37206&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;37208&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;37210&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37211&quot; href=&quot;non-idempotent-intersection-types.html#37211&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;37212&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;37214&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37215&quot; href=&quot;non-idempotent-intersection-types.html#37215&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;37217&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;37219&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;37223&quot; href=&quot;non-idempotent-intersection-types.html#37211&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;37224&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;37226&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37227&quot; href=&quot;non-idempotent-intersection-types.html#37227&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;37230&quot; href=&quot;non-idempotent-intersection-types.html#37230&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt;&lt;a id=&quot;37232&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;37234&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;37236&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;37239&quot; href=&quot;non-idempotent-intersection-types.html#37215&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;37241&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;37243&quot; href=&quot;non-idempotent-intersection-types.html#37227&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;37246&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;37248&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;37251&quot; href=&quot;non-idempotent-intersection-types.html#37215&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;37253&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;37255&quot; href=&quot;non-idempotent-intersection-types.html#37230&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;37258&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;37260&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;37263&quot; href=&quot;non-idempotent-intersection-types.html#37215&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;37265&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;37267&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;37268&quot; href=&quot;non-idempotent-intersection-types.html#37227&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;37271&quot; href=&quot;non-idempotent-intersection-types.html#12553&quot; class=&quot;Function Operator&quot;&gt;+++&lt;/a&gt; &lt;a id=&quot;37275&quot; href=&quot;non-idempotent-intersection-types.html#37230&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt;&lt;a id=&quot;37277&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;37279&quot; href=&quot;non-idempotent-intersection-types.html#37197&quot; class=&quot;Function&quot;&gt;env-join&lt;/a&gt; &lt;a id=&quot;37288&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37289&quot; class=&quot;Argument&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;37291&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;37293&quot; href=&quot;Agda.Builtin.Nat.html#210&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;37297&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;  &lt;a id=&quot;37300&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37301&quot; href=&quot;non-idempotent-intersection-types.html#3767&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;37304&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;    &lt;a id=&quot;37309&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37310&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;37313&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;      &lt;a id=&quot;37320&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37321&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;37324&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;     &lt;a id=&quot;37330&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;       &lt;a id=&quot;37340&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;        &lt;a id=&quot;37351&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;37353&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;
&lt;a id=&quot;37357&quot; href=&quot;non-idempotent-intersection-types.html#37197&quot; class=&quot;Function&quot;&gt;env-join&lt;/a&gt; &lt;a id=&quot;37366&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37367&quot; class=&quot;Argument&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;37369&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;37371&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;37375&quot; href=&quot;non-idempotent-intersection-types.html#37375&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;37376&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;37378&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37379&quot; href=&quot;non-idempotent-intersection-types.html#37379&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;37381&quot; href=&quot;non-idempotent-intersection-types.html#3787&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;37384&quot; href=&quot;non-idempotent-intersection-types.html#37384&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt;&lt;a id=&quot;37385&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;37387&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37388&quot; href=&quot;non-idempotent-intersection-types.html#37388&quot; class=&quot;Bound&quot;&gt;Γ₁&lt;/a&gt; &lt;a id=&quot;37391&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;37394&quot; href=&quot;non-idempotent-intersection-types.html#37394&quot; class=&quot;Bound&quot;&gt;σ₁&lt;/a&gt;&lt;a id=&quot;37396&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;37398&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37399&quot; href=&quot;non-idempotent-intersection-types.html#37399&quot; class=&quot;Bound&quot;&gt;Γ₂&lt;/a&gt; &lt;a id=&quot;37402&quot; href=&quot;non-idempotent-intersection-types.html#11952&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;37405&quot; href=&quot;non-idempotent-intersection-types.html#37405&quot; class=&quot;Bound&quot;&gt;σ₂&lt;/a&gt;&lt;a id=&quot;37407&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;37409&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;37410&quot; href=&quot;non-idempotent-intersection-types.html#37410&quot; class=&quot;Bound&quot;&gt;e₁&lt;/a&gt; &lt;a id=&quot;37413&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;37416&quot; href=&quot;non-idempotent-intersection-types.html#37416&quot; class=&quot;Bound&quot;&gt;c₁&lt;/a&gt;&lt;a id=&quot;37418&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;37420&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;37421&quot; href=&quot;non-idempotent-intersection-types.html#37421&quot; class=&quot;Bound&quot;&gt;e₂&lt;/a&gt; &lt;a id=&quot;37424&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;37427&quot; href=&quot;non-idempotent-intersection-types.html#37427&quot; class=&quot;Bound&quot;&gt;c₂&lt;/a&gt;&lt;a id=&quot;37429&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;37431&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;37433&quot; href=&quot;non-idempotent-intersection-types.html#37197&quot; class=&quot;Function&quot;&gt;env-join&lt;/a&gt; &lt;a id=&quot;37442&quot; href=&quot;non-idempotent-intersection-types.html#37410&quot; class=&quot;Bound&quot;&gt;e₁&lt;/a&gt; &lt;a id=&quot;37445&quot; href=&quot;non-idempotent-intersection-types.html#37421&quot; class=&quot;Bound&quot;&gt;e₂&lt;/a&gt; &lt;a id=&quot;37448&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;37451&quot; href=&quot;non-idempotent-intersection-types.html#37030&quot; class=&quot;Function&quot;&gt;clo-join&lt;/a&gt; &lt;a id=&quot;37460&quot; href=&quot;non-idempotent-intersection-types.html#37416&quot; class=&quot;Bound&quot;&gt;c₁&lt;/a&gt; &lt;a id=&quot;37463&quot; href=&quot;non-idempotent-intersection-types.html#37427&quot; class=&quot;Bound&quot;&gt;c₂&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;We also need the fact that every environment is well typed if the types we use make no demands:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;env-empty&quot;&gt;&lt;/a&gt;&lt;a id=&quot;37576&quot; href=&quot;non-idempotent-intersection-types.html#37576&quot; class=&quot;Function&quot;&gt;env-empty&lt;/a&gt; &lt;a id=&quot;37586&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;37588&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;37590&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37591&quot; href=&quot;non-idempotent-intersection-types.html#37591&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;37592&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;37594&quot; href=&quot;non-idempotent-intersection-types.html#37594&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;37596&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;37598&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;37602&quot; href=&quot;non-idempotent-intersection-types.html#37591&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;37603&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;37605&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;37607&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;37610&quot; href=&quot;non-idempotent-intersection-types.html#37594&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;37612&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;37614&quot; href=&quot;non-idempotent-intersection-types.html#12243&quot; class=&quot;Function&quot;&gt;empty&lt;/a&gt;
&lt;a id=&quot;37620&quot; href=&quot;non-idempotent-intersection-types.html#37576&quot; class=&quot;Function&quot;&gt;env-empty&lt;/a&gt; &lt;a id=&quot;37630&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37631&quot; class=&quot;Argument&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;37633&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;37635&quot; href=&quot;non-idempotent-intersection-types.html#3767&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;37638&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt;    &lt;a id=&quot;37643&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;37645&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;
&lt;a id=&quot;37649&quot; href=&quot;non-idempotent-intersection-types.html#37576&quot; class=&quot;Function&quot;&gt;env-empty&lt;/a&gt; &lt;a id=&quot;37659&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37660&quot; class=&quot;Argument&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;37662&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;37664&quot; href=&quot;non-idempotent-intersection-types.html#37664&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;37666&quot; href=&quot;non-idempotent-intersection-types.html#3787&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;37669&quot; href=&quot;non-idempotent-intersection-types.html#37669&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;37670&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;37672&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;37674&quot; href=&quot;non-idempotent-intersection-types.html#37576&quot; class=&quot;Function&quot;&gt;env-empty&lt;/a&gt; &lt;a id=&quot;37684&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;37687&quot; href=&quot;non-idempotent-intersection-types.html#20154&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;Together, these allow us to prove that the derived rule for building closures typed with intersection types (&lt;code&gt;mkclo&lt;/code&gt;) is invertible:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;unmk-clo&quot;&gt;&lt;/a&gt;&lt;a id=&quot;37838&quot; href=&quot;non-idempotent-intersection-types.html#37838&quot; class=&quot;Function&quot;&gt;unmk-clo&lt;/a&gt; &lt;a id=&quot;37847&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;37849&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;37851&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37852&quot; href=&quot;non-idempotent-intersection-types.html#37852&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;37853&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;37855&quot; href=&quot;non-idempotent-intersection-types.html#37855&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;37857&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;37859&quot; href=&quot;non-idempotent-intersection-types.html#3743&quot; class=&quot;Datatype&quot;&gt;env&lt;/a&gt; &lt;a id=&quot;37863&quot; href=&quot;non-idempotent-intersection-types.html#37852&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;37864&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;37866&quot; href=&quot;non-idempotent-intersection-types.html#37866&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;37868&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;37870&quot; href=&quot;non-idempotent-intersection-types.html#2373&quot; class=&quot;Datatype&quot;&gt;term&lt;/a&gt; &lt;a id=&quot;37875&quot; href=&quot;non-idempotent-intersection-types.html#37852&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;37876&quot; class=&quot;Symbol&quot;&gt;}{&lt;/a&gt;&lt;a id=&quot;37878&quot; href=&quot;non-idempotent-intersection-types.html#37878&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;37879&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;37881&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
         &lt;a id=&quot;37892&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⊢c&lt;/a&gt; &lt;a id=&quot;37895&quot; href=&quot;non-idempotent-intersection-types.html#37852&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;37897&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;37899&quot; href=&quot;non-idempotent-intersection-types.html#37855&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;37901&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;37903&quot; href=&quot;non-idempotent-intersection-types.html#37866&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;37905&quot; href=&quot;non-idempotent-intersection-types.html#20103&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;37908&quot; href=&quot;non-idempotent-intersection-types.html#37878&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;37910&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt;
         &lt;a id=&quot;37921&quot; href=&quot;Data.Product.html#916&quot; class=&quot;Function&quot;&gt;Σ[&lt;/a&gt; &lt;a id=&quot;37924&quot; href=&quot;non-idempotent-intersection-types.html#37924&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;37926&quot; href=&quot;Data.Product.html#916&quot; class=&quot;Function&quot;&gt;∈&lt;/a&gt; &lt;a id=&quot;37928&quot; href=&quot;non-idempotent-intersection-types.html#11913&quot; class=&quot;Datatype&quot;&gt;ctx&lt;/a&gt; &lt;a id=&quot;37932&quot; href=&quot;non-idempotent-intersection-types.html#37852&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;37934&quot; href=&quot;Data.Product.html#916&quot; class=&quot;Function&quot;&gt;]&lt;/a&gt; &lt;a id=&quot;37936&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;37937&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⊢e&lt;/a&gt; &lt;a id=&quot;37940&quot; href=&quot;non-idempotent-intersection-types.html#37855&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;37942&quot; href=&quot;non-idempotent-intersection-types.html#19905&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;37944&quot; href=&quot;non-idempotent-intersection-types.html#37924&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;37946&quot; href=&quot;Data.Product.html#1167&quot; class=&quot;Function Operator&quot;&gt;×&lt;/a&gt; &lt;a id=&quot;37948&quot; href=&quot;non-idempotent-intersection-types.html#37924&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;37950&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;37952&quot; href=&quot;non-idempotent-intersection-types.html#37866&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;37954&quot; href=&quot;non-idempotent-intersection-types.html#15132&quot; class=&quot;Datatype Operator&quot;&gt;⦂&amp;#39;&lt;/a&gt; &lt;a id=&quot;37957&quot; href=&quot;non-idempotent-intersection-types.html#37878&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;37958&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;37960&quot; href=&quot;non-idempotent-intersection-types.html#37838&quot; class=&quot;Function&quot;&gt;unmk-clo&lt;/a&gt; &lt;a id=&quot;37969&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;37970&quot; class=&quot;Argument&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;37972&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;37974&quot; href=&quot;Agda.Builtin.List.html#185&quot; class=&quot;InductiveConstructor&quot;&gt;[]&lt;/a&gt;&lt;a id=&quot;37976&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;37978&quot; href=&quot;non-idempotent-intersection-types.html#20154&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;37982&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;37984&quot; href=&quot;non-idempotent-intersection-types.html#12243&quot; class=&quot;Function&quot;&gt;empty&lt;/a&gt; &lt;a id=&quot;37990&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;37992&quot; href=&quot;non-idempotent-intersection-types.html#37576&quot; class=&quot;Function&quot;&gt;env-empty&lt;/a&gt; &lt;a id=&quot;38002&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;38004&quot; href=&quot;non-idempotent-intersection-types.html#15192&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;
&lt;a id=&quot;38008&quot; href=&quot;non-idempotent-intersection-types.html#37838&quot; class=&quot;Function&quot;&gt;unmk-clo&lt;/a&gt; &lt;a id=&quot;38017&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;38018&quot; class=&quot;Argument&quot;&gt;σ&lt;/a&gt; &lt;a id=&quot;38020&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;38022&quot; href=&quot;non-idempotent-intersection-types.html#38022&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;38024&quot; href=&quot;Agda.Builtin.List.html#200&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;38026&quot; href=&quot;non-idempotent-intersection-types.html#38026&quot; class=&quot;Bound&quot;&gt;σ&lt;/a&gt;&lt;a id=&quot;38027&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;38029&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38030&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;38036&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;38037&quot; class=&quot;Argument&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;38039&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;38041&quot; href=&quot;non-idempotent-intersection-types.html#38041&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt;&lt;a id=&quot;38042&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;38044&quot; href=&quot;non-idempotent-intersection-types.html#38044&quot; class=&quot;Bound&quot;&gt;s-τ&lt;/a&gt; &lt;a id=&quot;38048&quot; href=&quot;non-idempotent-intersection-types.html#38048&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;38053&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;38055&quot; href=&quot;non-idempotent-intersection-types.html#38055&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;38056&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;38058&quot; class=&quot;Keyword&quot;&gt;with&lt;/a&gt; &lt;a id=&quot;38063&quot; href=&quot;non-idempotent-intersection-types.html#37838&quot; class=&quot;Function&quot;&gt;unmk-clo&lt;/a&gt; &lt;a id=&quot;38072&quot; href=&quot;non-idempotent-intersection-types.html#38055&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;
&lt;a id=&quot;38074&quot; class=&quot;Symbol&quot;&gt;...&lt;/a&gt; &lt;a id=&quot;38078&quot; class=&quot;Symbol&quot;&gt;|&lt;/a&gt; &lt;a id=&quot;38080&quot; href=&quot;non-idempotent-intersection-types.html#38080&quot; class=&quot;Bound&quot;&gt;Γ&amp;#39;&lt;/a&gt; &lt;a id=&quot;38083&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;38085&quot; href=&quot;non-idempotent-intersection-types.html#38085&quot; class=&quot;Bound&quot;&gt;η-ok&amp;#39;&lt;/a&gt; &lt;a id=&quot;38091&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;38093&quot; href=&quot;non-idempotent-intersection-types.html#38093&quot; class=&quot;Bound&quot;&gt;s-σ&lt;/a&gt; &lt;a id=&quot;38097&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;38099&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38100&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;38102&quot; href=&quot;non-idempotent-intersection-types.html#12553&quot; class=&quot;Function Operator&quot;&gt;+++&lt;/a&gt; &lt;a id=&quot;38106&quot; href=&quot;non-idempotent-intersection-types.html#38080&quot; class=&quot;Bound&quot;&gt;Γ&amp;#39;&lt;/a&gt;&lt;a id=&quot;38108&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;38110&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;38112&quot; href=&quot;non-idempotent-intersection-types.html#37197&quot; class=&quot;Function&quot;&gt;env-join&lt;/a&gt; &lt;a id=&quot;38121&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;38126&quot; href=&quot;non-idempotent-intersection-types.html#38085&quot; class=&quot;Bound&quot;&gt;η-ok&amp;#39;&lt;/a&gt; &lt;a id=&quot;38132&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;38134&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38135&quot; class=&quot;Bound&quot;&gt;s-τ&lt;/a&gt; &lt;a id=&quot;38139&quot; href=&quot;non-idempotent-intersection-types.html#15248&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,~&lt;/a&gt; &lt;a id=&quot;38142&quot; href=&quot;non-idempotent-intersection-types.html#13759&quot; class=&quot;Function&quot;&gt;⋈ctx-refl&lt;/a&gt; &lt;a id=&quot;38152&quot; href=&quot;non-idempotent-intersection-types.html#15248&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;38154&quot; href=&quot;non-idempotent-intersection-types.html#38093&quot; class=&quot;Bound&quot;&gt;s-σ&lt;/a&gt;&lt;a id=&quot;38157&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;The proof of subject expansion is now has a similar structure to the proof of subject reduction:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;subject-expansion&quot;&gt;&lt;/a&gt;&lt;a id=&quot;38270&quot; href=&quot;non-idempotent-intersection-types.html#38270&quot; class=&quot;Function&quot;&gt;subject-expansion&lt;/a&gt; &lt;a id=&quot;38288&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;38290&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;38292&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;38293&quot; href=&quot;non-idempotent-intersection-types.html#38293&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;38295&quot; href=&quot;non-idempotent-intersection-types.html#38295&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt; &lt;a id=&quot;38297&quot; href=&quot;non-idempotent-intersection-types.html#38297&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;&lt;a id=&quot;38298&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;38300&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;38302&quot; href=&quot;non-idempotent-intersection-types.html#38293&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;38304&quot; href=&quot;non-idempotent-intersection-types.html#5072&quot; class=&quot;Datatype Operator&quot;&gt;⇒&lt;/a&gt; &lt;a id=&quot;38306&quot; href=&quot;non-idempotent-intersection-types.html#38295&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt; &lt;a id=&quot;38308&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;38310&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⊢p&lt;/a&gt; &lt;a id=&quot;38313&quot; href=&quot;non-idempotent-intersection-types.html#38295&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt; &lt;a id=&quot;38315&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;38317&quot; href=&quot;non-idempotent-intersection-types.html#38297&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt; &lt;a id=&quot;38319&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;38321&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⊢p&lt;/a&gt; &lt;a id=&quot;38324&quot; href=&quot;non-idempotent-intersection-types.html#38293&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;38326&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;38328&quot; href=&quot;non-idempotent-intersection-types.html#38297&quot; class=&quot;Bound&quot;&gt;τ&lt;/a&gt;
&lt;a id=&quot;38330&quot; href=&quot;non-idempotent-intersection-types.html#38270&quot; class=&quot;Function&quot;&gt;subject-expansion&lt;/a&gt; &lt;a id=&quot;38348&quot; href=&quot;non-idempotent-intersection-types.html#5122&quot; class=&quot;InductiveConstructor&quot;&gt;grab&lt;/a&gt; &lt;a id=&quot;38353&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38354&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;38358&quot; href=&quot;non-idempotent-intersection-types.html#38358&quot; class=&quot;Bound&quot;&gt;c-ok&lt;/a&gt; &lt;a id=&quot;38363&quot; href=&quot;non-idempotent-intersection-types.html#38363&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;38367&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;38369&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;38371&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;38375&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38376&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;38382&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38383&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;38387&quot; href=&quot;non-idempotent-intersection-types.html#14132&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;38391&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;38393&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38394&quot; href=&quot;non-idempotent-intersection-types.html#37576&quot; class=&quot;Function&quot;&gt;env-empty&lt;/a&gt; &lt;a id=&quot;38404&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;38407&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38408&quot; href=&quot;non-idempotent-intersection-types.html#38358&quot; class=&quot;Bound&quot;&gt;c-ok&lt;/a&gt; &lt;a id=&quot;38413&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;38415&quot; href=&quot;non-idempotent-intersection-types.html#20154&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;38418&quot; class=&quot;Symbol&quot;&gt;)))&lt;/a&gt; &lt;a id=&quot;38422&quot; href=&quot;non-idempotent-intersection-types.html#38363&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;
&lt;a id=&quot;38427&quot; href=&quot;non-idempotent-intersection-types.html#38270&quot; class=&quot;Function&quot;&gt;subject-expansion&lt;/a&gt; &lt;a id=&quot;38445&quot; href=&quot;non-idempotent-intersection-types.html#5220&quot; class=&quot;InductiveConstructor&quot;&gt;skip&lt;/a&gt; &lt;a id=&quot;38450&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38451&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;38455&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38456&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;38462&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38463&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;38467&quot; href=&quot;non-idempotent-intersection-types.html#38467&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;38468&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;38470&quot; href=&quot;non-idempotent-intersection-types.html#38470&quot; class=&quot;Bound&quot;&gt;x₂&lt;/a&gt;&lt;a id=&quot;38472&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;38474&quot; href=&quot;non-idempotent-intersection-types.html#38474&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt;&lt;a id=&quot;38476&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;38478&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;38480&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;38484&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38485&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;38491&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38492&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;38496&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38497&quot; href=&quot;non-idempotent-intersection-types.html#14184&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;38501&quot; href=&quot;non-idempotent-intersection-types.html#38467&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;38502&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;38505&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38506&quot; href=&quot;non-idempotent-intersection-types.html#38470&quot; class=&quot;Bound&quot;&gt;x₂&lt;/a&gt; &lt;a id=&quot;38509&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;38512&quot; href=&quot;non-idempotent-intersection-types.html#20154&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;38515&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;38518&quot; href=&quot;non-idempotent-intersection-types.html#38474&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt;
&lt;a id=&quot;38521&quot; href=&quot;non-idempotent-intersection-types.html#38270&quot; class=&quot;Function&quot;&gt;subject-expansion&lt;/a&gt; &lt;a id=&quot;38539&quot; href=&quot;non-idempotent-intersection-types.html#5318&quot; class=&quot;InductiveConstructor&quot;&gt;push&lt;/a&gt; &lt;a id=&quot;38544&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38545&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;38549&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38550&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;38556&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;38557&quot; class=&quot;Argument&quot;&gt;Γ&lt;/a&gt; &lt;a id=&quot;38559&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;38561&quot; href=&quot;non-idempotent-intersection-types.html#38561&quot; class=&quot;Bound&quot;&gt;Γ&lt;/a&gt;&lt;a id=&quot;38562&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;38564&quot; href=&quot;non-idempotent-intersection-types.html#38564&quot; class=&quot;Bound&quot;&gt;t-ok&lt;/a&gt; &lt;a id=&quot;38569&quot; href=&quot;non-idempotent-intersection-types.html#38569&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt;&lt;a id=&quot;38573&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;38575&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38576&quot; href=&quot;non-idempotent-intersection-types.html#38576&quot; class=&quot;Bound&quot;&gt;c-ok&lt;/a&gt; &lt;a id=&quot;38581&quot; href=&quot;non-idempotent-intersection-types.html#21127&quot; class=&quot;InductiveConstructor Operator&quot;&gt;-,&lt;/a&gt; &lt;a id=&quot;38584&quot; href=&quot;non-idempotent-intersection-types.html#38584&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;38588&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;38591&quot; class=&quot;Keyword&quot;&gt;with&lt;/a&gt; &lt;a id=&quot;38596&quot; href=&quot;non-idempotent-intersection-types.html#37838&quot; class=&quot;Function&quot;&gt;unmk-clo&lt;/a&gt; &lt;a id=&quot;38605&quot; href=&quot;non-idempotent-intersection-types.html#38576&quot; class=&quot;Bound&quot;&gt;c-ok&lt;/a&gt;
&lt;a id=&quot;38610&quot; class=&quot;Symbol&quot;&gt;...&lt;/a&gt; &lt;a id=&quot;38614&quot; class=&quot;Symbol&quot;&gt;|&lt;/a&gt; &lt;a id=&quot;38616&quot; href=&quot;non-idempotent-intersection-types.html#38616&quot; class=&quot;Bound&quot;&gt;Γ&amp;#39;&lt;/a&gt; &lt;a id=&quot;38619&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;38621&quot; href=&quot;non-idempotent-intersection-types.html#38621&quot; class=&quot;Bound&quot;&gt;η-ok&amp;#39;&lt;/a&gt; &lt;a id=&quot;38627&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;38629&quot; href=&quot;non-idempotent-intersection-types.html#38629&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt; &lt;a id=&quot;38634&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;38636&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;38640&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38641&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;38647&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38648&quot; href=&quot;non-idempotent-intersection-types.html#14924&quot; class=&quot;InductiveConstructor&quot;&gt;app&lt;/a&gt; &lt;a id=&quot;38652&quot; class=&quot;Bound&quot;&gt;t-ok&lt;/a&gt; &lt;a id=&quot;38657&quot; href=&quot;non-idempotent-intersection-types.html#38629&quot; class=&quot;Bound&quot;&gt;s-ok&lt;/a&gt; &lt;a id=&quot;38662&quot; href=&quot;non-idempotent-intersection-types.html#13759&quot; class=&quot;Function&quot;&gt;⋈ctx-refl&lt;/a&gt;&lt;a id=&quot;38671&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;38673&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38674&quot; href=&quot;non-idempotent-intersection-types.html#37197&quot; class=&quot;Function&quot;&gt;env-join&lt;/a&gt; &lt;a id=&quot;38683&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;38688&quot; href=&quot;non-idempotent-intersection-types.html#38621&quot; class=&quot;Bound&quot;&gt;η-ok&amp;#39;&lt;/a&gt;&lt;a id=&quot;38693&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;38696&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;
&lt;a id=&quot;38701&quot; href=&quot;non-idempotent-intersection-types.html#38270&quot; class=&quot;Function&quot;&gt;subject-expansion&lt;/a&gt; &lt;a id=&quot;38719&quot; href=&quot;non-idempotent-intersection-types.html#5431&quot; class=&quot;InductiveConstructor&quot;&gt;pop&lt;/a&gt;  &lt;a id=&quot;38724&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38725&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;38729&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38730&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;38736&quot; href=&quot;non-idempotent-intersection-types.html#38736&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;38738&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38739&quot; href=&quot;non-idempotent-intersection-types.html#38739&quot; class=&quot;Bound&quot;&gt;x₂&lt;/a&gt; &lt;a id=&quot;38742&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;38745&quot; href=&quot;non-idempotent-intersection-types.html#38745&quot; class=&quot;Bound&quot;&gt;x₃&lt;/a&gt;&lt;a id=&quot;38747&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;38750&quot; href=&quot;non-idempotent-intersection-types.html#38750&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt;&lt;a id=&quot;38752&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;38754&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;38756&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;38760&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38761&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;38767&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38768&quot; href=&quot;non-idempotent-intersection-types.html#14832&quot; class=&quot;InductiveConstructor&quot;&gt;lam&lt;/a&gt; &lt;a id=&quot;38772&quot; href=&quot;non-idempotent-intersection-types.html#38736&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;38773&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;38775&quot; href=&quot;non-idempotent-intersection-types.html#38739&quot; class=&quot;Bound&quot;&gt;x₂&lt;/a&gt;&lt;a id=&quot;38777&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;38779&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;38780&quot; href=&quot;non-idempotent-intersection-types.html#38745&quot; class=&quot;Bound&quot;&gt;x₃&lt;/a&gt; &lt;a id=&quot;38783&quot; href=&quot;non-idempotent-intersection-types.html#21127&quot; class=&quot;InductiveConstructor Operator&quot;&gt;-,&lt;/a&gt; &lt;a id=&quot;38786&quot; href=&quot;non-idempotent-intersection-types.html#38750&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt;&lt;a id=&quot;38788&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;/pre&gt;
&lt;h4&gt;Progress&lt;/h4&gt;&lt;p&gt;As is usual progress only holds for complete programs. In our case, that means configurations that are typed with the observation &lt;code&gt;⋆&lt;/code&gt;, meaning that we expect the configuration to terminate with a value. Our formulation of progress is quantitative, so rather than examining the configuration &lt;code&gt;p&lt;/code&gt; to see whether it is a value or not, we rely on measuring the amount of “potential” left in the configuration by measuring its size. If this is non-zero, then the KAM will make progress.&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;progress&quot;&gt;&lt;/a&gt;&lt;a id=&quot;39300&quot; href=&quot;non-idempotent-intersection-types.html#39300&quot; class=&quot;Function&quot;&gt;progress&lt;/a&gt; &lt;a id=&quot;39309&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;39311&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;39313&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;39314&quot; href=&quot;non-idempotent-intersection-types.html#39314&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;39315&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;39317&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;39319&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39320&quot; href=&quot;non-idempotent-intersection-types.html#39320&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;39322&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;39324&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⊢p&lt;/a&gt; &lt;a id=&quot;39327&quot; href=&quot;non-idempotent-intersection-types.html#39314&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;39329&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;39331&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt;&lt;a id=&quot;39332&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;39334&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;39336&quot; href=&quot;non-idempotent-intersection-types.html#21935&quot; class=&quot;Function&quot;&gt;cfg-size&lt;/a&gt; &lt;a id=&quot;39345&quot; href=&quot;non-idempotent-intersection-types.html#39320&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;39347&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#840&quot; class=&quot;Function Operator&quot;&gt;≢&lt;/a&gt; &lt;a id=&quot;39349&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt; &lt;a id=&quot;39351&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;39353&quot; href=&quot;Data.Product.html#916&quot; class=&quot;Function&quot;&gt;Σ[&lt;/a&gt; &lt;a id=&quot;39356&quot; href=&quot;non-idempotent-intersection-types.html#39356&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt; &lt;a id=&quot;39358&quot; href=&quot;Data.Product.html#916&quot; class=&quot;Function&quot;&gt;∈&lt;/a&gt; &lt;a id=&quot;39360&quot; href=&quot;non-idempotent-intersection-types.html#4786&quot; class=&quot;Record&quot;&gt;configuration&lt;/a&gt; &lt;a id=&quot;39374&quot; href=&quot;Data.Product.html#916&quot; class=&quot;Function&quot;&gt;]&lt;/a&gt; &lt;a id=&quot;39376&quot; href=&quot;non-idempotent-intersection-types.html#39314&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;39378&quot; href=&quot;non-idempotent-intersection-types.html#5072&quot; class=&quot;Datatype Operator&quot;&gt;⇒&lt;/a&gt; &lt;a id=&quot;39380&quot; href=&quot;non-idempotent-intersection-types.html#39356&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt;
&lt;a id=&quot;39382&quot; href=&quot;non-idempotent-intersection-types.html#39300&quot; class=&quot;Function&quot;&gt;progress&lt;/a&gt; &lt;a id=&quot;39391&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39392&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;39396&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39397&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;39403&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39404&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;39408&quot; href=&quot;non-idempotent-intersection-types.html#14132&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;39412&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;    &lt;a id=&quot;39417&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39418&quot; href=&quot;non-idempotent-intersection-types.html#39418&quot; class=&quot;Bound&quot;&gt;η-emp&lt;/a&gt; &lt;a id=&quot;39424&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;39427&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39428&quot; href=&quot;non-idempotent-intersection-types.html#39428&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;39430&quot; href=&quot;non-idempotent-intersection-types.html#20194&quot; class=&quot;InductiveConstructor Operator&quot;&gt;∷&lt;/a&gt; &lt;a id=&quot;39432&quot; class=&quot;Symbol&quot;&gt;_)))&lt;/a&gt; &lt;a id=&quot;39437&quot; href=&quot;non-idempotent-intersection-types.html#39437&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;39441&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;        &lt;a id=&quot;39450&quot; class=&quot;Symbol&quot;&gt;_&lt;/a&gt; &lt;a id=&quot;39452&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;39454&quot; class=&quot;Symbol&quot;&gt;_&lt;/a&gt; &lt;a id=&quot;39456&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;39458&quot; href=&quot;non-idempotent-intersection-types.html#5122&quot; class=&quot;InductiveConstructor&quot;&gt;grab&lt;/a&gt;
&lt;a id=&quot;39463&quot; href=&quot;non-idempotent-intersection-types.html#39300&quot; class=&quot;Function&quot;&gt;progress&lt;/a&gt; &lt;a id=&quot;39472&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39473&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;39477&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39478&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;39484&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39485&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;39489&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39490&quot; href=&quot;non-idempotent-intersection-types.html#14184&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;39494&quot; href=&quot;non-idempotent-intersection-types.html#39494&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;&lt;a id=&quot;39495&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;39498&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39499&quot; href=&quot;non-idempotent-intersection-types.html#39499&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;39504&quot; href=&quot;non-idempotent-intersection-types.html#19974&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,-&lt;/a&gt; &lt;a id=&quot;39507&quot; href=&quot;non-idempotent-intersection-types.html#20154&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;39510&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt;      &lt;a id=&quot;39518&quot; href=&quot;non-idempotent-intersection-types.html#39518&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;39522&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;        &lt;a id=&quot;39531&quot; class=&quot;Symbol&quot;&gt;_&lt;/a&gt; &lt;a id=&quot;39533&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;39535&quot; class=&quot;Symbol&quot;&gt;_&lt;/a&gt; &lt;a id=&quot;39537&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;39539&quot; href=&quot;non-idempotent-intersection-types.html#5220&quot; class=&quot;InductiveConstructor&quot;&gt;skip&lt;/a&gt;
&lt;a id=&quot;39544&quot; href=&quot;non-idempotent-intersection-types.html#39300&quot; class=&quot;Function&quot;&gt;progress&lt;/a&gt; &lt;a id=&quot;39553&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39554&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;39558&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39559&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;39565&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39566&quot; href=&quot;non-idempotent-intersection-types.html#14832&quot; class=&quot;InductiveConstructor&quot;&gt;lam&lt;/a&gt; &lt;a id=&quot;39570&quot; href=&quot;non-idempotent-intersection-types.html#39570&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;39571&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;       &lt;a id=&quot;39579&quot; href=&quot;non-idempotent-intersection-types.html#39579&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt;&lt;a id=&quot;39583&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;               &lt;a id=&quot;39599&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39600&quot; href=&quot;non-idempotent-intersection-types.html#39600&quot; class=&quot;Bound&quot;&gt;c&lt;/a&gt; &lt;a id=&quot;39602&quot; href=&quot;non-idempotent-intersection-types.html#21127&quot; class=&quot;InductiveConstructor Operator&quot;&gt;-,&lt;/a&gt; &lt;a id=&quot;39605&quot; href=&quot;non-idempotent-intersection-types.html#39605&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;39609&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;39612&quot; class=&quot;Symbol&quot;&gt;_&lt;/a&gt; &lt;a id=&quot;39614&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;39616&quot; class=&quot;Symbol&quot;&gt;_&lt;/a&gt; &lt;a id=&quot;39618&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;39620&quot; href=&quot;non-idempotent-intersection-types.html#5431&quot; class=&quot;InductiveConstructor&quot;&gt;pop&lt;/a&gt;
&lt;a id=&quot;39624&quot; href=&quot;non-idempotent-intersection-types.html#39300&quot; class=&quot;Function&quot;&gt;progress&lt;/a&gt; &lt;a id=&quot;39633&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39634&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;39638&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39639&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;39645&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39646&quot; href=&quot;non-idempotent-intersection-types.html#14924&quot; class=&quot;InductiveConstructor&quot;&gt;app&lt;/a&gt; &lt;a id=&quot;39650&quot; href=&quot;non-idempotent-intersection-types.html#39650&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;39652&quot; href=&quot;non-idempotent-intersection-types.html#39652&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;39654&quot; href=&quot;non-idempotent-intersection-types.html#39654&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;39655&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;   &lt;a id=&quot;39659&quot; href=&quot;non-idempotent-intersection-types.html#39659&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt;&lt;a id=&quot;39663&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;               &lt;a id=&quot;39679&quot; href=&quot;non-idempotent-intersection-types.html#39679&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;39683&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;        &lt;a id=&quot;39692&quot; class=&quot;Symbol&quot;&gt;_&lt;/a&gt; &lt;a id=&quot;39694&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;39696&quot; class=&quot;Symbol&quot;&gt;_&lt;/a&gt; &lt;a id=&quot;39698&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;39700&quot; href=&quot;non-idempotent-intersection-types.html#5318&quot; class=&quot;InductiveConstructor&quot;&gt;push&lt;/a&gt;
&lt;a id=&quot;39705&quot; href=&quot;non-idempotent-intersection-types.html#39300&quot; class=&quot;Function&quot;&gt;progress&lt;/a&gt; &lt;a id=&quot;39714&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39715&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;39719&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;39720&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;39726&quot; href=&quot;non-idempotent-intersection-types.html#15077&quot; class=&quot;InductiveConstructor&quot;&gt;lam⋆&lt;/a&gt;          &lt;a id=&quot;39740&quot; href=&quot;non-idempotent-intersection-types.html#39740&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt;&lt;a id=&quot;39744&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;               &lt;a id=&quot;39760&quot; href=&quot;non-idempotent-intersection-types.html#21086&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt;&lt;a id=&quot;39763&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;         &lt;a id=&quot;39773&quot; href=&quot;non-idempotent-intersection-types.html#39773&quot; class=&quot;Bound&quot;&gt;r&lt;/a&gt; &lt;a id=&quot;39775&quot; class=&quot;Keyword&quot;&gt;rewrite&lt;/a&gt; &lt;a id=&quot;39783&quot; href=&quot;non-idempotent-intersection-types.html#29431&quot; class=&quot;Function&quot;&gt;e-empty&lt;/a&gt; &lt;a id=&quot;39791&quot; href=&quot;non-idempotent-intersection-types.html#39740&quot; class=&quot;Bound&quot;&gt;η-ok&lt;/a&gt; &lt;a id=&quot;39796&quot; class=&quot;Keyword&quot;&gt;with&lt;/a&gt; &lt;a id=&quot;39801&quot; href=&quot;non-idempotent-intersection-types.html#39773&quot; class=&quot;Bound&quot;&gt;r&lt;/a&gt; &lt;a id=&quot;39803&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt;
&lt;a id=&quot;39808&quot; class=&quot;Symbol&quot;&gt;...&lt;/a&gt; &lt;a id=&quot;39812&quot; class=&quot;Symbol&quot;&gt;|&lt;/a&gt; &lt;a id=&quot;39814&quot; class=&quot;Symbol&quot;&gt;()&lt;/a&gt;
&lt;/pre&gt;
&lt;h3&gt;Quantitative Soundness and Completeness&lt;/h3&gt;&lt;p&gt;Putting all our results together, we can now prove that non-idempotent intersection types are a sound and complete characterisation of termination in the CBN λ-calculus, and moreover the size of the typing derivation is exactly the number of steps taken to terminate.&lt;/p&gt;&lt;p&gt;We first do soundness: if a closed term &lt;code&gt;t&lt;/code&gt; has a typing derivation &lt;code&gt;d&lt;/code&gt; that shows that &lt;code&gt;⋆&lt;/code&gt; is a possible observation of &lt;code&gt;t&lt;/code&gt;, then &lt;code&gt;t&lt;/code&gt; will reduce in the KAM to WHNF in &lt;code&gt;size d&lt;/code&gt; steps:&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;soundness&quot;&gt;&lt;/a&gt;&lt;a id=&quot;40329&quot; href=&quot;non-idempotent-intersection-types.html#40329&quot; class=&quot;Function&quot;&gt;soundness&lt;/a&gt; &lt;a id=&quot;40339&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;40341&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;40343&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;40344&quot; href=&quot;non-idempotent-intersection-types.html#40344&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;40345&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;40347&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;40349&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40350&quot; href=&quot;non-idempotent-intersection-types.html#40350&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;40352&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;40354&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;40358&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;40360&quot; href=&quot;non-idempotent-intersection-types.html#40344&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;40362&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;40364&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt;&lt;a id=&quot;40365&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;40367&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;40369&quot; href=&quot;non-idempotent-intersection-types.html#7174&quot; class=&quot;Datatype&quot;&gt;reduces&lt;/a&gt; &lt;a id=&quot;40377&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40378&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;40383&quot; href=&quot;non-idempotent-intersection-types.html#40350&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;40384&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;40386&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt; &lt;a id=&quot;40388&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt; &lt;a id=&quot;40390&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;40392&quot; href=&quot;non-idempotent-intersection-types.html#3767&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;40396&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;40398&quot; href=&quot;non-idempotent-intersection-types.html#40344&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;40400&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;40402&quot; href=&quot;non-idempotent-intersection-types.html#4473&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt; &lt;a id=&quot;40406&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt;
&lt;a id=&quot;40408&quot; href=&quot;non-idempotent-intersection-types.html#40329&quot; class=&quot;Function&quot;&gt;soundness&lt;/a&gt; &lt;a id=&quot;40418&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;40419&quot; href=&quot;non-idempotent-intersection-types.html#40419&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;40420&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;40422&quot; href=&quot;non-idempotent-intersection-types.html#40422&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;40424&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;40426&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1076&quot; class=&quot;Function&quot;&gt;subst&lt;/a&gt; &lt;a id=&quot;40432&quot; class=&quot;Symbol&quot;&gt;(λ&lt;/a&gt; &lt;a id=&quot;40435&quot; href=&quot;non-idempotent-intersection-types.html#40435&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;40437&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;40439&quot; href=&quot;non-idempotent-intersection-types.html#7174&quot; class=&quot;Datatype&quot;&gt;reduces&lt;/a&gt; &lt;a id=&quot;40447&quot; href=&quot;non-idempotent-intersection-types.html#40435&quot; class=&quot;Bound&quot;&gt;□&lt;/a&gt; &lt;a id=&quot;40449&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt; &lt;a id=&quot;40451&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt; &lt;a id=&quot;40453&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;40455&quot; href=&quot;non-idempotent-intersection-types.html#3767&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;40459&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;40461&quot; href=&quot;non-idempotent-intersection-types.html#40419&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;40463&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;40465&quot; href=&quot;non-idempotent-intersection-types.html#4473&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt; &lt;a id=&quot;40469&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt;&lt;a id=&quot;40470&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
                        &lt;a id=&quot;40496&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40497&quot; href=&quot;non-idempotent-intersection-types.html#22341&quot; class=&quot;Function&quot;&gt;init-typed-size&lt;/a&gt; &lt;a id=&quot;40513&quot; href=&quot;non-idempotent-intersection-types.html#40422&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;40514&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
                        &lt;a id=&quot;40540&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40541&quot; href=&quot;non-idempotent-intersection-types.html#40901&quot; class=&quot;Function&quot;&gt;run&lt;/a&gt; &lt;a id=&quot;40545&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40546&quot; href=&quot;non-idempotent-intersection-types.html#22136&quot; class=&quot;Function&quot;&gt;init-typed&lt;/a&gt; &lt;a id=&quot;40557&quot; href=&quot;non-idempotent-intersection-types.html#40422&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;40558&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;40560&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40561&quot; href=&quot;non-idempotent-intersection-types.html#21935&quot; class=&quot;Function&quot;&gt;cfg-size&lt;/a&gt; &lt;a id=&quot;40570&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40571&quot; href=&quot;non-idempotent-intersection-types.html#22136&quot; class=&quot;Function&quot;&gt;init-typed&lt;/a&gt; &lt;a id=&quot;40582&quot; href=&quot;non-idempotent-intersection-types.html#40422&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;40583&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;40586&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt;&lt;a id=&quot;40590&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
  &lt;a id=&quot;40594&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
    &lt;a id=&quot;40604&quot; href=&quot;non-idempotent-intersection-types.html#40604&quot; class=&quot;Function&quot;&gt;helper&lt;/a&gt; &lt;a id=&quot;40611&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;40613&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;40615&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;40616&quot; href=&quot;non-idempotent-intersection-types.html#40616&quot; class=&quot;Bound&quot;&gt;k&lt;/a&gt; &lt;a id=&quot;40618&quot; href=&quot;non-idempotent-intersection-types.html#40618&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;40619&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;40621&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;40623&quot; href=&quot;non-idempotent-intersection-types.html#40618&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;40625&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;40627&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;40631&quot; href=&quot;non-idempotent-intersection-types.html#40616&quot; class=&quot;Bound&quot;&gt;k&lt;/a&gt; &lt;a id=&quot;40633&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;40635&quot; href=&quot;non-idempotent-intersection-types.html#40618&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;40637&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#840&quot; class=&quot;Function Operator&quot;&gt;≢&lt;/a&gt; &lt;a id=&quot;40639&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt;
    &lt;a id=&quot;40645&quot; href=&quot;non-idempotent-intersection-types.html#40604&quot; class=&quot;Function&quot;&gt;helper&lt;/a&gt; &lt;a id=&quot;40652&quot; href=&quot;Agda.Builtin.Equality.html#208&quot; class=&quot;InductiveConstructor&quot;&gt;refl&lt;/a&gt; &lt;a id=&quot;40657&quot; class=&quot;Symbol&quot;&gt;()&lt;/a&gt;

    &lt;a id=&quot;40665&quot; href=&quot;non-idempotent-intersection-types.html#40665&quot; class=&quot;Function&quot;&gt;final&lt;/a&gt; &lt;a id=&quot;40671&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;40673&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;40675&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;40676&quot; href=&quot;non-idempotent-intersection-types.html#40676&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;40677&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;40679&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;40681&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40682&quot; href=&quot;non-idempotent-intersection-types.html#40682&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;40684&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;40686&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⊢p&lt;/a&gt; &lt;a id=&quot;40689&quot; href=&quot;non-idempotent-intersection-types.html#40676&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;40691&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;40693&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt;&lt;a id=&quot;40694&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;40696&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;40698&quot; href=&quot;non-idempotent-intersection-types.html#21935&quot; class=&quot;Function&quot;&gt;cfg-size&lt;/a&gt; &lt;a id=&quot;40707&quot; href=&quot;non-idempotent-intersection-types.html#40682&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;40709&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;40711&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt; &lt;a id=&quot;40713&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;40715&quot; href=&quot;non-idempotent-intersection-types.html#7174&quot; class=&quot;Datatype&quot;&gt;reduces&lt;/a&gt; &lt;a id=&quot;40723&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt; &lt;a id=&quot;40725&quot; href=&quot;non-idempotent-intersection-types.html#40676&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;
    &lt;a id=&quot;40731&quot; href=&quot;non-idempotent-intersection-types.html#40665&quot; class=&quot;Function&quot;&gt;final&lt;/a&gt; &lt;a id=&quot;40737&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40738&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;40742&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40743&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;40749&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40750&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;40754&quot; href=&quot;non-idempotent-intersection-types.html#14132&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;&lt;a id=&quot;40758&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;40760&quot; class=&quot;Symbol&quot;&gt;_)&lt;/a&gt;    &lt;a id=&quot;40766&quot; href=&quot;non-idempotent-intersection-types.html#40766&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;40770&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;40772&quot; class=&quot;Symbol&quot;&gt;()&lt;/a&gt;
    &lt;a id=&quot;40779&quot; href=&quot;non-idempotent-intersection-types.html#40665&quot; class=&quot;Function&quot;&gt;final&lt;/a&gt; &lt;a id=&quot;40785&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40786&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;40790&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40791&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;40797&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40798&quot; href=&quot;non-idempotent-intersection-types.html#14754&quot; class=&quot;InductiveConstructor&quot;&gt;var&lt;/a&gt; &lt;a id=&quot;40802&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40803&quot; href=&quot;non-idempotent-intersection-types.html#14184&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;40807&quot; class=&quot;Symbol&quot;&gt;_))&lt;/a&gt; &lt;a id=&quot;40811&quot; class=&quot;Symbol&quot;&gt;_)&lt;/a&gt; &lt;a id=&quot;40814&quot; href=&quot;non-idempotent-intersection-types.html#40814&quot; class=&quot;Bound&quot;&gt;π-ok&lt;/a&gt;&lt;a id=&quot;40818&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;40820&quot; class=&quot;Symbol&quot;&gt;()&lt;/a&gt;
    &lt;a id=&quot;40827&quot; href=&quot;non-idempotent-intersection-types.html#40665&quot; class=&quot;Function&quot;&gt;final&lt;/a&gt; &lt;a id=&quot;40833&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;40834&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt; &lt;a id=&quot;40836&quot; href=&quot;non-idempotent-intersection-types.html#40836&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;40838&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;40840&quot; href=&quot;non-idempotent-intersection-types.html#40840&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;40842&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;40844&quot; href=&quot;non-idempotent-intersection-types.html#2427&quot; class=&quot;InductiveConstructor&quot;&gt;ƛ&lt;/a&gt; &lt;a id=&quot;40846&quot; href=&quot;non-idempotent-intersection-types.html#40846&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;40848&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;40850&quot; href=&quot;non-idempotent-intersection-types.html#4473&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt; &lt;a id=&quot;40854&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt;&lt;a id=&quot;40855&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;40857&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40858&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;40862&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40863&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;40869&quot; href=&quot;non-idempotent-intersection-types.html#15077&quot; class=&quot;InductiveConstructor&quot;&gt;lam⋆&lt;/a&gt; &lt;a id=&quot;40874&quot; href=&quot;non-idempotent-intersection-types.html#40874&quot; class=&quot;Bound&quot;&gt;x₁&lt;/a&gt;&lt;a id=&quot;40876&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;40878&quot; href=&quot;non-idempotent-intersection-types.html#21086&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt;&lt;a id=&quot;40881&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;40883&quot; href=&quot;non-idempotent-intersection-types.html#40883&quot; class=&quot;Bound&quot;&gt;e&lt;/a&gt; &lt;a id=&quot;40885&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;40887&quot; href=&quot;non-idempotent-intersection-types.html#7216&quot; class=&quot;InductiveConstructor&quot;&gt;stop&lt;/a&gt; &lt;a id=&quot;40892&quot; href=&quot;non-idempotent-intersection-types.html#40840&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;40894&quot; href=&quot;non-idempotent-intersection-types.html#40846&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;

    &lt;a id=&quot;40901&quot; href=&quot;non-idempotent-intersection-types.html#40901&quot; class=&quot;Function&quot;&gt;run&lt;/a&gt; &lt;a id=&quot;40905&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;40907&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;40909&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;40910&quot; href=&quot;non-idempotent-intersection-types.html#40910&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;&lt;a id=&quot;40911&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;40913&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;40915&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;40916&quot; href=&quot;non-idempotent-intersection-types.html#40916&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;40918&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;40920&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⊢p&lt;/a&gt; &lt;a id=&quot;40923&quot; href=&quot;non-idempotent-intersection-types.html#40910&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;40925&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;40927&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt;&lt;a id=&quot;40928&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;40930&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;40932&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;40934&quot; href=&quot;non-idempotent-intersection-types.html#40934&quot; class=&quot;Bound&quot;&gt;k&lt;/a&gt; &lt;a id=&quot;40936&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;40938&quot; href=&quot;non-idempotent-intersection-types.html#21935&quot; class=&quot;Function&quot;&gt;cfg-size&lt;/a&gt; &lt;a id=&quot;40947&quot; href=&quot;non-idempotent-intersection-types.html#40916&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;40949&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;40951&quot; href=&quot;non-idempotent-intersection-types.html#40934&quot; class=&quot;Bound&quot;&gt;k&lt;/a&gt; &lt;a id=&quot;40953&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;40955&quot; href=&quot;non-idempotent-intersection-types.html#7174&quot; class=&quot;Datatype&quot;&gt;reduces&lt;/a&gt; &lt;a id=&quot;40963&quot; href=&quot;non-idempotent-intersection-types.html#40934&quot; class=&quot;Bound&quot;&gt;k&lt;/a&gt; &lt;a id=&quot;40965&quot; href=&quot;non-idempotent-intersection-types.html#40910&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt;
    &lt;a id=&quot;40971&quot; href=&quot;non-idempotent-intersection-types.html#40901&quot; class=&quot;Function&quot;&gt;run&lt;/a&gt; &lt;a id=&quot;40975&quot; href=&quot;non-idempotent-intersection-types.html#40975&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;40977&quot; href=&quot;Agda.Builtin.Nat.html#210&quot; class=&quot;InductiveConstructor&quot;&gt;zero&lt;/a&gt;    &lt;a id=&quot;40985&quot; href=&quot;non-idempotent-intersection-types.html#40985&quot; class=&quot;Bound&quot;&gt;e&lt;/a&gt; &lt;a id=&quot;40987&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;40989&quot; href=&quot;non-idempotent-intersection-types.html#40665&quot; class=&quot;Function&quot;&gt;final&lt;/a&gt; &lt;a id=&quot;40995&quot; href=&quot;non-idempotent-intersection-types.html#40975&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;40997&quot; href=&quot;non-idempotent-intersection-types.html#40985&quot; class=&quot;Bound&quot;&gt;e&lt;/a&gt;
    &lt;a id=&quot;41003&quot; href=&quot;non-idempotent-intersection-types.html#40901&quot; class=&quot;Function&quot;&gt;run&lt;/a&gt; &lt;a id=&quot;41007&quot; href=&quot;non-idempotent-intersection-types.html#41007&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;41009&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;41010&quot; href=&quot;Agda.Builtin.Nat.html#223&quot; class=&quot;InductiveConstructor&quot;&gt;suc&lt;/a&gt; &lt;a id=&quot;41014&quot; href=&quot;non-idempotent-intersection-types.html#41014&quot; class=&quot;Bound&quot;&gt;k&lt;/a&gt;&lt;a id=&quot;41015&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;41017&quot; href=&quot;non-idempotent-intersection-types.html#41017&quot; class=&quot;Bound&quot;&gt;e&lt;/a&gt; &lt;a id=&quot;41019&quot; class=&quot;Keyword&quot;&gt;with&lt;/a&gt; &lt;a id=&quot;41024&quot; href=&quot;non-idempotent-intersection-types.html#39300&quot; class=&quot;Function&quot;&gt;progress&lt;/a&gt; &lt;a id=&quot;41033&quot; href=&quot;non-idempotent-intersection-types.html#41007&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;41035&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;41036&quot; href=&quot;non-idempotent-intersection-types.html#40604&quot; class=&quot;Function&quot;&gt;helper&lt;/a&gt; &lt;a id=&quot;41043&quot; href=&quot;non-idempotent-intersection-types.html#41017&quot; class=&quot;Bound&quot;&gt;e&lt;/a&gt;&lt;a id=&quot;41044&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
    &lt;a id=&quot;41050&quot; class=&quot;Symbol&quot;&gt;...&lt;/a&gt; &lt;a id=&quot;41054&quot; class=&quot;Symbol&quot;&gt;|&lt;/a&gt; &lt;a id=&quot;41056&quot; href=&quot;non-idempotent-intersection-types.html#41056&quot; class=&quot;Bound&quot;&gt;q&lt;/a&gt; &lt;a id=&quot;41058&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;41060&quot; href=&quot;non-idempotent-intersection-types.html#41060&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;41062&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;41064&quot; href=&quot;non-idempotent-intersection-types.html#7269&quot; class=&quot;InductiveConstructor&quot;&gt;step&lt;/a&gt; &lt;a id=&quot;41069&quot; href=&quot;non-idempotent-intersection-types.html#41060&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;41071&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;41072&quot; href=&quot;non-idempotent-intersection-types.html#40901&quot; class=&quot;Function&quot;&gt;run&lt;/a&gt; &lt;a id=&quot;41076&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;41077&quot; href=&quot;non-idempotent-intersection-types.html#32027&quot; class=&quot;Function&quot;&gt;subject-reduction&lt;/a&gt; &lt;a id=&quot;41095&quot; href=&quot;non-idempotent-intersection-types.html#41060&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;41097&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;41098&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;41100&quot; class=&quot;Bound&quot;&gt;k&lt;/a&gt; &lt;a id=&quot;41102&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;41103&quot; href=&quot;Data.Nat.Properties.html#1607&quot; class=&quot;Function&quot;&gt;suc-injective&lt;/a&gt; &lt;a id=&quot;41117&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;41118&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#1025&quot; class=&quot;Function&quot;&gt;trans&lt;/a&gt; &lt;a id=&quot;41124&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;41125&quot; href=&quot;Relation.Binary.PropositionalEquality.Core.html#980&quot; class=&quot;Function&quot;&gt;sym&lt;/a&gt; &lt;a id=&quot;41129&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;41130&quot; href=&quot;non-idempotent-intersection-types.html#33309&quot; class=&quot;Function&quot;&gt;sr-size&lt;/a&gt; &lt;a id=&quot;41138&quot; href=&quot;non-idempotent-intersection-types.html#41060&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;41140&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;41141&quot; class=&quot;Symbol&quot;&gt;))&lt;/a&gt; &lt;a id=&quot;41144&quot; class=&quot;Bound&quot;&gt;e&lt;/a&gt;&lt;a id=&quot;41145&quot; class=&quot;Symbol&quot;&gt;)))&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;The bulk of the work in this lemma is performed by the &lt;code&gt;run&lt;/code&gt; function which uses induction on the size of the typing derivation to repeatedly call &lt;code&gt;progress&lt;/code&gt; to get the next step, &lt;code&gt;subject-reduction&lt;/code&gt; to preserve typability, and &lt;code&gt;sr-size&lt;/code&gt; to show that the size of the derivation goes down.&lt;/p&gt;&lt;p&gt;The converse of soundness is completeness: every term that reduces to WHNF has a typing derivation. This is proved by induction on the reduction sequence: in the base case all WHNFs are typable by the &lt;code&gt;lam⋆&lt;/code&gt; rule, and in the step case by using subject expansion. We also know by soundness and the determinism of length of reduction sequences that the computed typing derivation has the same size as the length of the reduction.&lt;/p&gt;&lt;pre class=&quot;Agda&quot;&gt;&lt;a id=&quot;completeness&quot;&gt;&lt;/a&gt;&lt;a id=&quot;41881&quot; href=&quot;non-idempotent-intersection-types.html#41881&quot; class=&quot;Function&quot;&gt;completeness&lt;/a&gt; &lt;a id=&quot;41894&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;41896&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;41898&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;41899&quot; href=&quot;non-idempotent-intersection-types.html#41899&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;41901&quot; href=&quot;non-idempotent-intersection-types.html#41901&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;41902&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;41904&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;41906&quot; href=&quot;non-idempotent-intersection-types.html#7174&quot; class=&quot;Datatype&quot;&gt;reduces&lt;/a&gt; &lt;a id=&quot;41914&quot; href=&quot;non-idempotent-intersection-types.html#41901&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt; &lt;a id=&quot;41916&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt; &lt;a id=&quot;41918&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt; &lt;a id=&quot;41920&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;41922&quot; href=&quot;non-idempotent-intersection-types.html#3767&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;41926&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;41928&quot; href=&quot;non-idempotent-intersection-types.html#41899&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;41930&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;41932&quot; href=&quot;non-idempotent-intersection-types.html#4473&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt; &lt;a id=&quot;41936&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt; &lt;a id=&quot;41938&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;41940&quot; href=&quot;Data.Product.html#916&quot; class=&quot;Function&quot;&gt;Σ[&lt;/a&gt; &lt;a id=&quot;41943&quot; href=&quot;non-idempotent-intersection-types.html#41943&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;41945&quot; href=&quot;Data.Product.html#916&quot; class=&quot;Function&quot;&gt;∈&lt;/a&gt; &lt;a id=&quot;41947&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;41951&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;41953&quot; href=&quot;non-idempotent-intersection-types.html#41899&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;41955&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;41957&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;41959&quot; href=&quot;Data.Product.html#916&quot; class=&quot;Function&quot;&gt;]&lt;/a&gt; &lt;a id=&quot;41961&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;41962&quot; href=&quot;non-idempotent-intersection-types.html#18168&quot; class=&quot;Function&quot;&gt;size&lt;/a&gt; &lt;a id=&quot;41967&quot; href=&quot;non-idempotent-intersection-types.html#41943&quot; class=&quot;Bound&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;41969&quot; href=&quot;Agda.Builtin.Equality.html#151&quot; class=&quot;Datatype Operator&quot;&gt;≡&lt;/a&gt; &lt;a id=&quot;41971&quot; href=&quot;non-idempotent-intersection-types.html#41901&quot; class=&quot;Bound&quot;&gt;n&lt;/a&gt;&lt;a id=&quot;41972&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;a id=&quot;41974&quot; href=&quot;non-idempotent-intersection-types.html#41881&quot; class=&quot;Function&quot;&gt;completeness&lt;/a&gt; &lt;a id=&quot;41987&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;41988&quot; href=&quot;non-idempotent-intersection-types.html#41988&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;41989&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;41991&quot; href=&quot;non-idempotent-intersection-types.html#41991&quot; class=&quot;Bound&quot;&gt;r&lt;/a&gt; &lt;a id=&quot;41993&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;41995&quot; href=&quot;non-idempotent-intersection-types.html#42320&quot; class=&quot;Function&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;41997&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;41999&quot; href=&quot;non-idempotent-intersection-types.html#7858&quot; class=&quot;Function&quot;&gt;reduces-det&lt;/a&gt; &lt;a id=&quot;42011&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;42012&quot; href=&quot;non-idempotent-intersection-types.html#40329&quot; class=&quot;Function&quot;&gt;soundness&lt;/a&gt; &lt;a id=&quot;42022&quot; href=&quot;non-idempotent-intersection-types.html#42320&quot; class=&quot;Function&quot;&gt;d&lt;/a&gt;&lt;a id=&quot;42023&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;42025&quot; href=&quot;non-idempotent-intersection-types.html#41991&quot; class=&quot;Bound&quot;&gt;r&lt;/a&gt;
  &lt;a id=&quot;42029&quot; class=&quot;Keyword&quot;&gt;where&lt;/a&gt;
   &lt;a id=&quot;42038&quot; href=&quot;non-idempotent-intersection-types.html#42038&quot; class=&quot;Function&quot;&gt;config-typed&lt;/a&gt; &lt;a id=&quot;42051&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;42053&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;42055&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;42056&quot; href=&quot;non-idempotent-intersection-types.html#42056&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;42058&quot; href=&quot;non-idempotent-intersection-types.html#42058&quot; class=&quot;Bound&quot;&gt;k&lt;/a&gt;&lt;a id=&quot;42059&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;42061&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;42063&quot; href=&quot;non-idempotent-intersection-types.html#7174&quot; class=&quot;Datatype&quot;&gt;reduces&lt;/a&gt; &lt;a id=&quot;42071&quot; href=&quot;non-idempotent-intersection-types.html#42058&quot; class=&quot;Bound&quot;&gt;k&lt;/a&gt; &lt;a id=&quot;42073&quot; href=&quot;non-idempotent-intersection-types.html#42056&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;42075&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;42077&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⊢p&lt;/a&gt; &lt;a id=&quot;42080&quot; href=&quot;non-idempotent-intersection-types.html#42056&quot; class=&quot;Bound&quot;&gt;p&lt;/a&gt; &lt;a id=&quot;42082&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;42084&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt;
   &lt;a id=&quot;42089&quot; href=&quot;non-idempotent-intersection-types.html#42038&quot; class=&quot;Function&quot;&gt;config-typed&lt;/a&gt; &lt;a id=&quot;42102&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;42103&quot; href=&quot;non-idempotent-intersection-types.html#7216&quot; class=&quot;InductiveConstructor&quot;&gt;stop&lt;/a&gt; &lt;a id=&quot;42108&quot; href=&quot;non-idempotent-intersection-types.html#42108&quot; class=&quot;Bound&quot;&gt;η&lt;/a&gt; &lt;a id=&quot;42110&quot; href=&quot;non-idempotent-intersection-types.html#42110&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;42111&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;42113&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;42115&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;42119&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;42120&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;42126&quot; href=&quot;non-idempotent-intersection-types.html#15077&quot; class=&quot;InductiveConstructor&quot;&gt;lam⋆&lt;/a&gt; &lt;a id=&quot;42131&quot; href=&quot;non-idempotent-intersection-types.html#37576&quot; class=&quot;Function&quot;&gt;env-empty&lt;/a&gt;&lt;a id=&quot;42140&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;42142&quot; href=&quot;non-idempotent-intersection-types.html#21086&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt;
   &lt;a id=&quot;42149&quot; href=&quot;non-idempotent-intersection-types.html#42038&quot; class=&quot;Function&quot;&gt;config-typed&lt;/a&gt; &lt;a id=&quot;42162&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;42163&quot; href=&quot;non-idempotent-intersection-types.html#7269&quot; class=&quot;InductiveConstructor&quot;&gt;step&lt;/a&gt; &lt;a id=&quot;42168&quot; href=&quot;non-idempotent-intersection-types.html#42168&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;42170&quot; href=&quot;non-idempotent-intersection-types.html#42170&quot; class=&quot;Bound&quot;&gt;r&lt;/a&gt;&lt;a id=&quot;42171&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;42173&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;42175&quot; href=&quot;non-idempotent-intersection-types.html#38270&quot; class=&quot;Function&quot;&gt;subject-expansion&lt;/a&gt; &lt;a id=&quot;42193&quot; href=&quot;non-idempotent-intersection-types.html#42168&quot; class=&quot;Bound&quot;&gt;s&lt;/a&gt; &lt;a id=&quot;42195&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;42196&quot; href=&quot;non-idempotent-intersection-types.html#42038&quot; class=&quot;Function&quot;&gt;config-typed&lt;/a&gt; &lt;a id=&quot;42209&quot; href=&quot;non-idempotent-intersection-types.html#42170&quot; class=&quot;Bound&quot;&gt;r&lt;/a&gt;&lt;a id=&quot;42210&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;

   &lt;a id=&quot;42216&quot; href=&quot;non-idempotent-intersection-types.html#42216&quot; class=&quot;Function&quot;&gt;extract&lt;/a&gt; &lt;a id=&quot;42224&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;42226&quot; class=&quot;Symbol&quot;&gt;∀&lt;/a&gt; &lt;a id=&quot;42228&quot; class=&quot;Symbol&quot;&gt;{&lt;/a&gt;&lt;a id=&quot;42229&quot; href=&quot;non-idempotent-intersection-types.html#42229&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt;&lt;a id=&quot;42230&quot; class=&quot;Symbol&quot;&gt;}&lt;/a&gt; &lt;a id=&quot;42232&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;42234&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⊢p&lt;/a&gt; &lt;a id=&quot;42237&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟨&lt;/a&gt; &lt;a id=&quot;42239&quot; class=&quot;Number&quot;&gt;0&lt;/a&gt; &lt;a id=&quot;42241&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;42243&quot; href=&quot;non-idempotent-intersection-types.html#3767&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;42247&quot; href=&quot;Agda.Builtin.Sigma.html#236&quot; class=&quot;InductiveConstructor Operator&quot;&gt;,&lt;/a&gt; &lt;a id=&quot;42249&quot; href=&quot;non-idempotent-intersection-types.html#42229&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;42251&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;42253&quot; href=&quot;non-idempotent-intersection-types.html#4473&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt; &lt;a id=&quot;42257&quot; href=&quot;non-idempotent-intersection-types.html#4826&quot; class=&quot;InductiveConstructor Operator&quot;&gt;⟩&lt;/a&gt; &lt;a id=&quot;42259&quot; href=&quot;non-idempotent-intersection-types.html#21798&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;42261&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt; &lt;a id=&quot;42263&quot; class=&quot;Symbol&quot;&gt;→&lt;/a&gt; &lt;a id=&quot;42265&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;42269&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;42271&quot; href=&quot;non-idempotent-intersection-types.html#42229&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;42273&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;42275&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt;
   &lt;a id=&quot;42280&quot; href=&quot;non-idempotent-intersection-types.html#42216&quot; class=&quot;Function&quot;&gt;extract&lt;/a&gt; &lt;a id=&quot;42288&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;42289&quot; href=&quot;non-idempotent-intersection-types.html#21841&quot; class=&quot;InductiveConstructor&quot;&gt;cfg&lt;/a&gt; &lt;a id=&quot;42293&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;42294&quot; href=&quot;non-idempotent-intersection-types.html#19792&quot; class=&quot;InductiveConstructor&quot;&gt;t-clo&lt;/a&gt; &lt;a id=&quot;42300&quot; href=&quot;non-idempotent-intersection-types.html#42300&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt; &lt;a id=&quot;42302&quot; href=&quot;non-idempotent-intersection-types.html#19951&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt;&lt;a id=&quot;42305&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;42307&quot; href=&quot;non-idempotent-intersection-types.html#21086&quot; class=&quot;InductiveConstructor&quot;&gt;emp&lt;/a&gt;&lt;a id=&quot;42310&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt; &lt;a id=&quot;42312&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;42314&quot; href=&quot;non-idempotent-intersection-types.html#42300&quot; class=&quot;Bound&quot;&gt;x&lt;/a&gt;

   &lt;a id=&quot;42320&quot; href=&quot;non-idempotent-intersection-types.html#42320&quot; class=&quot;Function&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;42322&quot; class=&quot;Symbol&quot;&gt;:&lt;/a&gt; &lt;a id=&quot;42324&quot; href=&quot;non-idempotent-intersection-types.html#11935&quot; class=&quot;InductiveConstructor&quot;&gt;nil&lt;/a&gt; &lt;a id=&quot;42328&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⊢&lt;/a&gt; &lt;a id=&quot;42330&quot; href=&quot;non-idempotent-intersection-types.html#41988&quot; class=&quot;Bound&quot;&gt;t&lt;/a&gt; &lt;a id=&quot;42332&quot; href=&quot;non-idempotent-intersection-types.html#14700&quot; class=&quot;Datatype Operator&quot;&gt;⦂&lt;/a&gt; &lt;a id=&quot;42334&quot; href=&quot;non-idempotent-intersection-types.html#8742&quot; class=&quot;InductiveConstructor&quot;&gt;⋆&lt;/a&gt;
   &lt;a id=&quot;42339&quot; href=&quot;non-idempotent-intersection-types.html#42320&quot; class=&quot;Function&quot;&gt;d&lt;/a&gt; &lt;a id=&quot;42341&quot; class=&quot;Symbol&quot;&gt;=&lt;/a&gt; &lt;a id=&quot;42343&quot; href=&quot;non-idempotent-intersection-types.html#42216&quot; class=&quot;Function&quot;&gt;extract&lt;/a&gt; &lt;a id=&quot;42351&quot; class=&quot;Symbol&quot;&gt;(&lt;/a&gt;&lt;a id=&quot;42352&quot; href=&quot;non-idempotent-intersection-types.html#42038&quot; class=&quot;Function&quot;&gt;config-typed&lt;/a&gt; &lt;a id=&quot;42365&quot; href=&quot;non-idempotent-intersection-types.html#41991&quot; class=&quot;Bound&quot;&gt;r&lt;/a&gt;&lt;a id=&quot;42366&quot; class=&quot;Symbol&quot;&gt;)&lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;Inspecting the proof of subject expansion, we can also see that the computed typing derivation never uses a non-identity permutation, indicating that we might be able to use a variant of non-idempotent intersection types to predict the ordering of usage, as well as quantity of usage.&lt;/p&gt;&lt;p&gt;A possible application of this type system would be to proving that optimisations actually optimise. If we have an optimisation that replaces a term &lt;code&gt;M&lt;/code&gt; with a term &lt;code&gt;N&lt;/code&gt;, then if for all typings &lt;code&gt;Γ ⊢ M ⦂ τ&lt;/code&gt; we can get a typing &lt;code&gt;Γ ⊢ N ⦂ τ&lt;/code&gt; that is smaller, then any context which uses &lt;code&gt;M&lt;/code&gt; can replace it with &lt;code&gt;N&lt;/code&gt;, preserving meaning, and take fewer steps to terminate.&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2020-08-13-non-idempotent-intersection-types.html</guid><pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate></item><item><title>Slides for “Resource Constrained Programming with Full Dependent Types”</title><link>https://bentnib.org/posts/2020-01-24-qtt-polytime.html</link><description>&lt;p&gt;Yesterday, I gave a talk entitled “Resource Constrained Programming with Full Dependent Types” at the &lt;a href=&quot;https://www.irif.fr/en/seminaires/pps/index&quot;&gt;IRIF Proofs, Programs and systems seminar&lt;/a&gt; in Paris. Many thanks to Paul-André Melliès for inviting me to give a talk.&lt;/p&gt;&lt;p&gt;Abstract:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;I will talk about a system that combines Dependent Types and Linear Types. As an application of this system, I will show how to transport Martin Hofmann's LFPL and Amortised Resource analysis systems for resource constrained computing to full dependent types. This results in a theory where unconstrained computations are allowed at the type level, but only polynomial time computations at the term level. The combined system allows one to explore the world of propositions whose proofs are not only constructive, but also of restricted complexity.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Slides:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/docs/qtt-irif-20200123.pdf&quot;&gt;&lt;img alt=&quot;Thumbnail of slides for “Resource Constrained Programming with Full Dependent Types” talk&quot; src=&quot;https://bentnib.org/thumbnails/slides-qtt-irif-20200123.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2020-01-24-qtt-polytime.html</guid><pubDate>Fri, 24 Jan 2020 00:00:00 +0000</pubDate></item><item><title>Off the Beaten Track 2017: Call for Talk Proposals</title><link>https://bentnib.org/posts/2016-10-10-off-the-beaten-track.html</link><description>&lt;p&gt;This year I am the programme chair for &lt;a href=&quot;http://conf.researchr.org/track/POPL-2017/OBT-2017&quot;&gt;Off the Beaten Track 2017&lt;/a&gt;! This will be held on 21st January 2017, co-located with POPL 2017 in Paris, France.&lt;/p&gt;&lt;h3&gt;Background&lt;/h3&gt;&lt;p&gt;Programming language researchers have the principles, tools, algorithms and abstractions to solve all kinds of problems, in all areas of computer science. However, identifying and evaluating new problems, particularly those that lie outside the typical core PL problems we all know and love, can be a significant challenge. This workshop’s goal is to identify and discuss problems that do not often show up in our top conferences, but where programming language research can make a substantial impact. We hope fora like this will increase the diversity of problems that are studied by PL researchers and thus increase our community’s impact on the world.&lt;/p&gt;&lt;p&gt;While many workshops associated with POPL have become more like mini-conferences themselves, this is an anti-goal for OBT. The workshop will be informal and structured to encourage discussion. We are at least as interested in problems as in solutions.&lt;/p&gt;&lt;h3&gt;Scope&lt;/h3&gt;&lt;p&gt;A good submission is one that outlines a new problem or an interesting, underrepresented problem domain. Good submissions may also remind the PL community of problems that were once in vogue but have not recently been seen in top PL conferences. Good submissions do not need to propose complete or even partial solutions, though there should be some reason to believe that programming languages researchers have the tools necessary to search for solutions in the area at hand. Submissions that seem likely to stimulate discussion about the direction of programming language research are encouraged.&lt;/p&gt;&lt;p&gt;Use your imagination. It's hard to imagine how a paper that discusses programming languages could be considered out of scope. If in doubt, ask the program chair.&lt;/p&gt;&lt;h3&gt;Previous OBTs&lt;/h3&gt;&lt;p&gt;2017 marks the sixth year of OBT and its co-location with POPL. The previous five workshops were:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://conf.researchr.org/track/POPL-2016/OBT-2016-talks&quot;&gt;OBT 2016&lt;/a&gt;, St. Petersburg, USA&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://www.cs.rice.edu/~sc40/obt15/&quot;&gt;OBT 2015&lt;/a&gt;, Mumbai, India&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://popl-obt-2014.cs.brown.edu/&quot;&gt;OBT 2014&lt;/a&gt;, San Diego, USA&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://goto.ucsd.edu/~rjhala/OBT2013/&quot;&gt;OBT 2013&lt;/a&gt;, Rome, Italy&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://www.cs.princeton.edu/~dpw/obt/&quot;&gt;OBT 2012&lt;/a&gt;, Philadelphia, USA&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Important Dates&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;10th November 2016: Submission deadline&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;8th December 2016: Notification&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;(18th December 2016: POPL early registration)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;21st January 2017: Workshop&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Submission&lt;/h3&gt;&lt;p&gt;Please submit your talk proposal via EasyChair:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://easychair.org/conferences/?conf=obt2017&quot;&gt;https://easychair.org/conferences/?conf=obt2017&lt;/a&gt;&lt;/p&gt;&lt;p&gt;All submissions should be in PDF format, two pages or less, in at least 10pt font, printable on A4 and on US Letter paper. Authors are welcome to include links to multimedia content such as YouTube videos or online demos. Reviewers may or may not view linked documents; it is up to authors to convince the reviewers to do so.&lt;/p&gt;&lt;p&gt;For each accepted submission, one of the authors will give a talk at the workshop. The length of the talk will depend on the submissions received and how the program committee decides to assemble the program.&lt;/p&gt;&lt;p&gt;Reviewing of submissions will be very light. Authors should not expect a detailed analysis of their submission by the program committee. Accepted submissions will be posted as is on this web site. By submitting a document, you agree that if it is accepted, it may be posted and you agree that one of the co-authors will attend the workshop and give a talk there. There will be no revision process and no formal publication.&lt;/p&gt;&lt;h3&gt;Organisers&lt;/h3&gt;&lt;p&gt;General chair:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Lindsey Kuper, Intel Labs, USA&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Programme chair:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Robert Atkey, University of Strathclyde, UK&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Programme committee:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Ekaterina Komendantskaya, Heriot-Watt University, UK&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Chris Martens, North Carolina State University, USA&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Tomas Petricek, University of Cambridge, UK&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Wren Romano, Google Inc., USA&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Mary Sheeran, Chalmers University of Technology, Sweden&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;KC Sivaramakrishnan, University of Cambridge, UK&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Wouter Swierstra, Utrecht University, Netherlands&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2016-10-10-off-the-beaten-track.html</guid><pubDate>Mon, 10 Oct 2016 00:00:00 +0000</pubDate></item><item><title>Authenticated Data Structures, as a Library, for Free!</title><link>https://bentnib.org/posts/2016-04-12-authenticated-data-structures-as-a-library.html</link><description>&lt;p&gt;Let's assume that you're querying to some database stored in the cloud (i.e., on someone else’s computer). Being of a sceptical mind, you worry whether or not the answers you get back are from the database you expect. Or is the cloud lying to you?&lt;/p&gt;&lt;p&gt;Authenticated Data Structures (ADSs) are a proposed solution to this problem. When the server sends back its answers, it also sends back a “proof” that the answer came from the database it claims. You, the client, verify this proof. If the proof doesn't verify, then you’ve got evidence that the server was lying. If the proof does verify, then there is a guarantee that the server’s response is legitimate (usually up to the possibility of a hash collision).&lt;/p&gt;&lt;p&gt;This all seems great, but doesn’t address the question of how anyone might build an ADS, and, crucially, prove that it has the security of unforgable (up to hash collisions) verification. A brute-force way to implement an ADS is for the client to retain a copy of the database, and to check the server’s results against the copy. But then what would be the point of the server?&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Merkle_tree&quot;&gt;Merkle Trees&lt;/a&gt; are the original example of an ADS. Merkle trees solve the problem of needing a complete copy of the database by having the client store a &lt;em&gt;hash&lt;/em&gt; of the database. The server’s proof is then verified against the hash. But what if we want a data structure that isn’t trees? Will we have to implement our own ADS? How will we know that we have done it correctly? Implementing a completely new ADS has three problems. We need: to invent a way to do the authentication, a proof that authentication has been done correctly, and a proof that we have correctly implemented it.&lt;/p&gt;&lt;p&gt;Andrew Miller, Michael Hicks, Jonathan Katz, and Elaine Shi have a solution to this meta-problem in their POPL2014 paper &lt;a href=&quot;http://www.cs.umd.edu/~mwh/papers/gpads.pdf&quot;&gt;Authenticated Data Structures, Generically&lt;/a&gt;, by describing a new language “Lambda-Auth” for implementing correct-by-construction ADSs.&lt;/p&gt;&lt;p&gt;Miller et al. describe a programming language with special constructs for writing ADSs. Once you’ve written an implementation of your data structure, you annotate the implementation with ‘authentication’ markers that indicate points in the structure that act as authentication checkpoints. On the client (verifier) side, each checkpoint becomes a hash code representing the real data, which will be checked against the proof sent by the server. On the server (prover) side, each checkpoint is an indicator of where to generate a piece of proof. The key insight of Miller et al. is that the client and server run &lt;em&gt;the same code&lt;/em&gt;, just with two different interpretations of what the authentication checkpoints mean. They are then able to prove, &lt;em&gt;for all programs&lt;/em&gt;, that the server and client sides will always agree, and that proofs of authentication are unforgable (up to hash collisions). The authors wrote a &lt;a href=&quot;http://www.pl-enthusiast.net/2014/06/11/authenticated-data-structures-generically/&quot;&gt;PL Enthusiast blog post&lt;/a&gt; with a gentle introduction, and &lt;a href=&quot;http://www.pl-enthusiast.net/2014/06/23/ads-generically-part-ii/&quot;&gt;a second part&lt;/a&gt; with more detail.&lt;/p&gt;&lt;p&gt;In this post, I'll show that in a language with sufficiently powerful abstraction facilities (in this case &lt;a href=&quot;http://ocaml.org&quot;&gt;OCaml&lt;/a&gt;), it is possible to implement Miller et al.’s solution as a &lt;em&gt;library&lt;/em&gt; within the language, with no need to create a new language, or to alter an existing language’s implementation.&lt;/p&gt;&lt;p&gt;Moreover, although I won’t give any details in this blog post, I claim that the correctness proof given by Miller et al. will be an instance of &lt;a href=&quot;http://bentnib.org/fomega-parametricity.html&quot;&gt;parametricity for higher-kinded types&lt;/a&gt;. I’ll give a few sketchy details at the end.&lt;/p&gt;&lt;h3&gt;Authenticated Data Structures as a Library&lt;/h3&gt;&lt;p&gt;To get started, I need to isolate a description of the bits and pieces we need to be able to write authenticated data structures, taking Miller et al.’s paper as a guide. OCaml provides module signatures as a handy way of collecting together requirements for the existence of certain types and functions. I'll call the types and functions we need for making ADSs an &lt;code&gt;AUTHENTIKIT&lt;/code&gt;: a kit for implementing authenticated data structures:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; AUTHENTIKIT &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;sig&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first thing is to postulate the existence of the type constructor &lt;code&gt;auth&lt;/code&gt; that represents the type of authenticated values. This is the OCaml rendering of the “•” type constructor used in Miller et al.’s language for representing authenticated values. Note that I haven’t committed to any implementation of this type: it is left completely abstract in the &lt;code&gt;AUTHENTIKIT&lt;/code&gt; interface:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; 'a auth
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We’ll need is a way of describing abstract authenticated computations: computations that are either generating proofs or verifying proofs. In Miller et al.’s setup, authenticated computations are built in to the language. However, OCaml comes with with its own fixed notion of computation, so we have to use a monad to layer our own notions on top:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; 'a authenticated_computation
  &lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; return &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; 'a &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; 'a authenticated_computation
  &lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;&gt;&gt;=&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; 'a authenticated_computation &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
               &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;'a &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; 'b authenticated_computation&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
               'b authenticated_computation
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The third thing I’ll need is a way of proving that the types of data that we want to authenticate are “authenticatable”. This will essentially mean that they are serialisable to a string representation in way that is suitable for proof construction and verification. The requirement to be serialisable is hidden in Miller et al.’s formalism because they assume that all data in the language is serialisable. This is a somewhat fishy assumption (how do you serialise and deserialise a function without breaking abstraction boundaries?), so here I’m being a bit more formal, and requiring the programmer to build evidence of serialisability using the following combinators tucked away in a submodule of any &lt;code&gt;AUTHENTIKIT&lt;/code&gt; implementation:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;ocamlkeyword&quot;&gt;module&lt;/span&gt; Authenticatable &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;sig&lt;/span&gt;
    &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; 'a evidence
    &lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; auth   &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; 'a auth evidence
    &lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; pair   &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; 'a evidence &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; 'b evidence &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;'a &lt;span class=&quot;ocamlsymbol&quot;&gt;*&lt;/span&gt; 'b&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; evidence
    &lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; sum    &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; 'a evidence &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; 'b evidence &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
                      &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`left &lt;span class=&quot;ocamlkeyword&quot;&gt;of&lt;/span&gt; 'a &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `right &lt;span class=&quot;ocamlkeyword&quot;&gt;of&lt;/span&gt; 'b&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; evidence
    &lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; string &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; string evidence
    &lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; int    &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; int evidence
  &lt;span class=&quot;ocamlkeyword&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, I postulate the existence of the &lt;code&gt;auth&lt;/code&gt; and &lt;code&gt;unauth&lt;/code&gt; functions as Miller et al. do. The difference here is that I have explicitly requested evidence that the data type involved is authenticatable. Also, the &lt;code&gt;unauth&lt;/code&gt; function returns a computation in our authenticated computation monad, indicating that this is where some of the work to get an authenticated data structure to work will happen.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; auth   &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; 'a Authenticatable&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;evidence &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; 'a &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; 'a auth

  &lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; unauth &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; 'a Authenticatable&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;evidence &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
               'a auth &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
               'a authenticated_computation
&lt;span class=&quot;ocamlkeyword&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h4&gt;An Autheticated Data Structure: Merkle Trees&lt;/h4&gt;&lt;p&gt;Before I describe the prover and verifier implementations of the &lt;code&gt;AUTHENTIKIT&lt;/code&gt; module type, I’ll give an example of an authenticated data structure implementation. I’ll do a basic Merkle tree, with the following interface:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; MERKLE &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
  &lt;span class=&quot;ocamlkeyword&quot;&gt;functor&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;A &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; AUTHENTIKIT&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;sig&lt;/span&gt;
    &lt;span class=&quot;ocamlkeyword&quot;&gt;open&lt;/span&gt; A

    &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; path &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`L &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `R&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; list
    &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; tree &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`left &lt;span class=&quot;ocamlkeyword&quot;&gt;of&lt;/span&gt; string &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `right &lt;span class=&quot;ocamlkeyword&quot;&gt;of&lt;/span&gt; tree &lt;span class=&quot;ocamlsymbol&quot;&gt;*&lt;/span&gt; tree&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; auth

    &lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; make_leaf &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; string &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; tree
    &lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; make_branch &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; tree &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; tree &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; tree
    &lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; retrieve &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt;
	  path &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; tree &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; string option authenticated_computation
    &lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; update &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt;
	  path &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; string &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; tree &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; tree option authenticated_computation
  &lt;span class=&quot;ocamlkeyword&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first thing to note about this module signature is that its implementations are parameterised by implementations of &lt;code&gt;AUTHENTIKIT&lt;/code&gt;. This will be characteristic of any authenticated data structure implementation we implement in this style: we need the freedom to instantiate the implementation with alternative &lt;code&gt;AUTHENTIKIT&lt;/code&gt;s to get the prover and verifier sides of the system.&lt;/p&gt;&lt;p&gt;The second thing to note is that the data structure interface is a very lightly annotated version of a completely boring binary tree interface. We have types for trees and paths, and operations to construct trees, query trees, and update trees. The only differences from a normal interface is that the tree type is annotated with an extra &lt;code&gt;auth&lt;/code&gt; type constructor, indicating how the tree is augmented with authentication information, and the &lt;code&gt;authenticated_computation&lt;/code&gt; type constructors on the &lt;code&gt;retrieve&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt; operations, indicating that they are authenticated operations.&lt;/p&gt;&lt;p&gt;The implementation is likewise a straightforward implementation of a binary tree in OCaml, with a couple of extra annotations for the authentication. The &lt;code&gt;Merkle&lt;/code&gt; module signature states that implementations are parameterised by &lt;code&gt;AUTHENTIKITs&lt;/code&gt;, so we declare the &lt;code&gt;Merkle&lt;/code&gt; implementation like so:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;module&lt;/span&gt; Merkle &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; MERKLE &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
  &lt;span class=&quot;ocamlkeyword&quot;&gt;functor&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;A &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; AUTHENTIKIT&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;struct&lt;/span&gt;
    &lt;span class=&quot;ocamlkeyword&quot;&gt;open&lt;/span&gt; A
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;open A&lt;/code&gt; introduces all the members of the &lt;code&gt;AUTHENTIKIT&lt;/code&gt; into scope, so we don't have to qualify any names.  The first thing to do is to fulfil the promise of definitions for the types &lt;code&gt;path&lt;/code&gt; and &lt;code&gt;tree&lt;/code&gt; that we gave in the interface:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;    &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; path &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`L&lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt;`R&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; list
    &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; tree &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`left &lt;span class=&quot;ocamlkeyword&quot;&gt;of&lt;/span&gt; string &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `right &lt;span class=&quot;ocamlkeyword&quot;&gt;of&lt;/span&gt; tree &lt;span class=&quot;ocamlsymbol&quot;&gt;*&lt;/span&gt; tree &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; auth
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Next, we construct some evidence that the body of the tree type is authenticatable, so we will be able to use &lt;code&gt;auth&lt;/code&gt; and &lt;code&gt;unauth&lt;/code&gt; on trees.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; tree &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt;
     &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`left &lt;span class=&quot;ocamlkeyword&quot;&gt;of&lt;/span&gt; string &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `right &lt;span class=&quot;ocamlkeyword&quot;&gt;of&lt;/span&gt; tree &lt;span class=&quot;ocamlsymbol&quot;&gt;*&lt;/span&gt; tree&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; Authenticatable&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;evidence &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
      Authenticatable&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;sum string &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;pair auth auth&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;make_leaf&lt;/code&gt; and &lt;code&gt;make_branch&lt;/code&gt; functions build leaves and branches using the appropriate constructors.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; make_leaf s &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
      auth tree &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;`left s&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; make_branch l r &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
      auth tree &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;`right &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;l&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;r&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To query our authenticated data structure, we have two functions &lt;code&gt;retrieve&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt;. First, the implementation of &lt;code&gt;retrieve&lt;/code&gt; which takes a path and a tree and returns the data identified by that path, if it exists.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;rec&lt;/span&gt; retrieve path t &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
      unauth tree t &lt;span class=&quot;ocamlsymbol&quot;&gt;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;fun&lt;/span&gt; t &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
      &lt;span class=&quot;ocamlkeyword&quot;&gt;match&lt;/span&gt; path&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; t &lt;span class=&quot;ocamlkeyword&quot;&gt;with&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;       `left s      &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; return &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;Some s&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `L&lt;span class=&quot;ocamlsymbol&quot;&gt;::&lt;/span&gt;path&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; `right &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;l&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;r&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; retrieve path l
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `R&lt;span class=&quot;ocamlsymbol&quot;&gt;::&lt;/span&gt;path&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; `right &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;l&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;r&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; retrieve path r
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;        &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt;            &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; return None
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As I mentioned above, this is really nothing more than a standard binary tree search implementation, obfuscated by the need to unwrap the authenticated input, and the additional &lt;code&gt;&gt;&gt;=&lt;/code&gt; and &lt;code&gt;return&lt;/code&gt;s needed to track the authenticated computation. The &lt;code&gt;update&lt;/code&gt; implemention is similar in its similarlity to a standard binary tree update function:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;rec&lt;/span&gt; update path v t &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
      unauth tree t &lt;span class=&quot;ocamlsymbol&quot;&gt;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;fun&lt;/span&gt; t &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
      &lt;span class=&quot;ocamlkeyword&quot;&gt;match&lt;/span&gt; path&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; t &lt;span class=&quot;ocamlkeyword&quot;&gt;with&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;       `left &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt;      &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
           return &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;Some &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_leaf v&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `L&lt;span class=&quot;ocamlsymbol&quot;&gt;::&lt;/span&gt;path&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; `right &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;l&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;r&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
           &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;update path v l &lt;span class=&quot;ocamlsymbol&quot;&gt;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;function&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; None    &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; return None
             &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Some l' &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; return &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;Some &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_branch l' r&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `R&lt;span class=&quot;ocamlsymbol&quot;&gt;::&lt;/span&gt;path&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; `right &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;l&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;r&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
           &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;update path v r &lt;span class=&quot;ocamlsymbol&quot;&gt;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;function&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; None    &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; return None
             &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Some r' &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; return &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;Some &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_branch l r'&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
         return None
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, an &lt;code&gt;end&lt;/code&gt; to complete the definition of &lt;code&gt;Merkle&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;ocamlkeyword&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Just to emphasise again, this implementation is essentially the same as a standard binary tree implementation written in OCaml. In the code, we didn’t have to mention anything to do with authenticated data structures, except for placing &lt;code&gt;auth&lt;/code&gt; and &lt;code&gt;unauth&lt;/code&gt; in the correct places. And even if we get in a muddle doing that, the OCaml type checker will helpfully inform us where we’ve made a mistake. One wrinkle is that I've had to give up writing in “direct style” and had to write in monadic style.&lt;/p&gt;&lt;h4&gt;The Prover&lt;/h4&gt;&lt;p&gt;The &lt;code&gt;Merkle&lt;/code&gt; module is not yet ready for use. To use it we need an implementation of the &lt;code&gt;AUTHENTIKIT&lt;/code&gt; interface. The different implementations of &lt;code&gt;AUTHENTIKIT&lt;/code&gt; will correspond to the different semantics in Miller et al.’s presentation: the prover and the verifier.&lt;/p&gt;&lt;p&gt;The first implementation of &lt;code&gt;AUTHENTIKIT&lt;/code&gt; I'll give is the prover.&lt;/p&gt;&lt;h5&gt;Proofs&lt;/h5&gt;&lt;p&gt;The prover constructs proofs, which I'll represent as lists of JSON values, using the &lt;a href=&quot;https://opam.ocaml.org/packages/ezjsonm/ezjsonm.0.4.3/&quot;&gt;Ezjsonm&lt;/a&gt; library.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; proof &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; Ezjsonm&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;value list
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We will also need to compute cryptographic hashes of JSON values, which I'll do using the &lt;a href=&quot;https://opam.ocaml.org/packages/cryptokit/cryptokit.1.10/&quot;&gt;Cryptokit&lt;/a&gt; library. I'm using the SHA1 algorithm here, but obviously any secure hashing algorithm would work.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; hash_json &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
  &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; hash_algo &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; Cryptokit&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;Hash&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;sha1 &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; in
  &lt;span class=&quot;ocamlkeyword&quot;&gt;fun&lt;/span&gt; json_value &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
    Cryptokit&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;hash_string hash_algo &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;Ezjsonm&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;to_string &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;`A json_value&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h5&gt;Prover Implementation&lt;/h5&gt;&lt;p&gt;The module &lt;code&gt;Prover&lt;/code&gt; implements the &lt;code&gt;AUTHENTIKIT&lt;/code&gt; signature, plus the additional knowledge that a) authenticated computations generate proofs as well as values, and b) that we have a &lt;code&gt;get_hash&lt;/code&gt; function that returns the hashed representation of any authenticated value. The prover’s interface is captured by its module signature:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;module&lt;/span&gt; Prover &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;sig&lt;/span&gt;
  &lt;span class=&quot;ocamlkeyword&quot;&gt;include&lt;/span&gt; AUTHENTIKIT &lt;span class=&quot;ocamlkeyword&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; 'a authenticated_computation &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; proof &lt;span class=&quot;ocamlsymbol&quot;&gt;*&lt;/span&gt; 'a
  &lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; get_hash &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; 'a auth &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; string
&lt;span class=&quot;ocamlkeyword&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;struct&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;First, we implement the prover’s view of authenticated values by defining its implementation of the &lt;code&gt;auth&lt;/code&gt; type. The prover sees an authenticated value as a pair of an underlying value &lt;code&gt;x&lt;/code&gt; and a hash of &lt;code&gt;x&lt;/code&gt;’s representation:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; 'a auth &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; 'a &lt;span class=&quot;ocamlsymbol&quot;&gt;*&lt;/span&gt; string

  &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; get_hash &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;h&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; h
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It will be up to the rest of the functions in this module to maintain the invariant that the second half of the pair will always be the hash code of the serialised representation of the first half.&lt;/p&gt;&lt;p&gt;Authenticated computations on the prover side are represented using a specialisation of the standard Writer monad, which collects a proof (list of JSON values) as a side-effect. This implementation is quite slow, because I have used lists, but could be speeded up by using a better data structure.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; 'a authenticated_computation &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
    proof &lt;span class=&quot;ocamlsymbol&quot;&gt;*&lt;/span&gt; 'a

  &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; return a &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; a&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;&gt;&gt;=&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;prf&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;a&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; f &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;prf'&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;b&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; f a in
    &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;prf &lt;span class=&quot;ocamlsymbol&quot;&gt;@&lt;/span&gt; prf'&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;b&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The prover's view of authenticatable values are ones for which it is possible to serialise them to JSON. We represent the evidence that such a thing is possible as the existence of a function from values to JSON values.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;ocamlkeyword&quot;&gt;module&lt;/span&gt; Authenticatable &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;struct&lt;/span&gt;
    &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; 'a evidence &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; 'a &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; Ezjsonm&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;value

    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; auth &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;h&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
      `String h

    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; pair a_serialiser b_serialiser &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;b&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
      `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;a_serialiser a&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; b_serialiser b&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; sum a_serialiser b_serialiser &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;function&lt;/span&gt;
      &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `left a  &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;left&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; a_serialiser a&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `right b &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;right&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; b_serialiser b&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; string s &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; `String s
    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; int i &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; `String &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;string_of_int i&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;ocamlkeyword&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the &lt;code&gt;auth&lt;/code&gt; case, we only serialise the hash code, not the underlying value. This ensures that the prover does not end up sending whole data structures back to the client. In the &lt;code&gt;int&lt;/code&gt; case, I'm serialising OCaml’s &lt;code&gt;int&lt;/code&gt; values as strings, to avoid complications arising from JSON’s use of floating point representations for numbers.&lt;/p&gt;&lt;p&gt;Now the &lt;code&gt;auth&lt;/code&gt; and &lt;code&gt;unauth&lt;/code&gt; functions. Creation of authenticated values means pairing the value with its hashed serialised representation:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; auth serialiser a &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; hash_json &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;serialiser a&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Extracting the underlying value from an authenticated value has the “side effect” of producing a step in the proof, which is the JSON representation of the value we expect to see:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; unauth serialiser &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; h&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;serialiser a&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; a&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, we complete the definition of &lt;code&gt;Prover&lt;/code&gt; with an &lt;code&gt;end&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h5&gt;Trying out the Prover&lt;/h5&gt;&lt;p&gt;We get a prover-side Merkle tree implementation by instantiating the &lt;code&gt;Merkle&lt;/code&gt; module with the &lt;code&gt;Prover&lt;/code&gt; implementation of &lt;code&gt;AUTHENTIKIT&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;module&lt;/span&gt; Merkle_Prover &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; Merkle &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;Prover&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let’s make a little prover-side tree, in the OCaml REPL:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlprompt&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; tree &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
    Merkle_Prover&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_branch
                     &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_branch &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_leaf &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_leaf &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;b&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
                     &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_branch &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_leaf &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;c&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_leaf &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;d&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlprompt&quot;&gt;;;&lt;/span&gt;
&lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; tree &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; Merkle_Prover&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;tree &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlabstr&quot;&gt;&amp;lt;abstr&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The returned value is abstract, because it is really a pair of the underlying data and it hash code. Using the prover’s &lt;code&gt;get_hash&lt;/code&gt; function, we can get the hash code of the tree, which is what the verifier will use to authenticate the prover’s actions:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlprompt&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; code &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; Prover&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;get_hash tree&lt;span class=&quot;ocamlprompt&quot;&gt;;;&lt;/span&gt;
&lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; code &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; string &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;.z\129w\199J\224\\\254\220\bo\246W\158\243S\029\177\190&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can also ask the prover to do queries on the tree. For example, if we ask for the value at position “left, left”, it returns the result “a”, and a proof that the verifier will be able to use to check that this result actually came from the tree with the hash code above.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlprompt&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; proof&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; result &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; Merkle_Prover&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;retrieve &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`L&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt;`L&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; tree&lt;span class=&quot;ocamlprompt&quot;&gt;;;&lt;/span&gt;
&lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; proof &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; proof &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;right&quot;&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;?\250m&amp;amp;,\251\129\031\r\252QJ\001\141|d}\242\016l&quot;&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;i?B\230p\158D\201\248\145\000\1400p\224\018\023\219\1935&quot;&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;right&quot;&lt;/span&gt;
         &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;X\140\005\028\146\1891L\224\246\224\229\201\018o\b\187\163\240\160&quot;&lt;/span&gt;
              &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;\223\231\194\230\1362=\157\187\226;?\143&gt;\127\248\014;\201\254&quot;&lt;/span&gt;
              &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
         &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;left&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; result &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; string option &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; Some &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;a&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This proof looks quite long, and in this case is several times the size of the original database. So it might look like Merkle trees might not save us anything. In general, however, the proof size is logarithmic in the size of the tree and so will be much smaller than sending the entire tree.&lt;/p&gt;&lt;h4&gt;The Verifier&lt;/h4&gt;&lt;p&gt;We’ve got a prover generating query responses and proofs, but this is a bit useless if we don’t have a verifier to check them.&lt;/p&gt;&lt;p&gt;Our verifier is another implementation of the &lt;code&gt;AUTHENTIKIT&lt;/code&gt; signature, with the additional information that authenticated computations are now functions that consume proofs and return either a value (and possibly some left-over proof) or return failure. Also, we specify that, on the verifier side, an authenticated value is represented as just its hash code (represented as an OCaml string).&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;module&lt;/span&gt; Verifier &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;sig&lt;/span&gt;
  &lt;span class=&quot;ocamlkeyword&quot;&gt;include&lt;/span&gt; AuthentiKit
    &lt;span class=&quot;ocamlkeyword&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; 'a authenticated_computation &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
                   proof &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt; `Ok &lt;span class=&quot;ocamlkeyword&quot;&gt;of&lt;/span&gt; proof &lt;span class=&quot;ocamlsymbol&quot;&gt;*&lt;/span&gt; 'a &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `ProofFailure &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
     &lt;span class=&quot;ocamlkeyword&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; 'a auth &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; string
&lt;span class=&quot;ocamlkeyword&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;struct&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The basic idea behind the verifier is that, given a hash code and a proof, it checks the hash code against the proof, and then uses the hash code to rebuild the parts of the data structure that will be explored by the program.&lt;/p&gt;&lt;p&gt;We start by fulfilling our statement that the verifier’s view of authenticated values is as OCaml strings:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; 'a auth &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; string
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And that the verifier’s version of authenticated computations is as a “parser” of proofs. Note how the definitions here are very similar to the definitions used for parser combinators. In some sense, verification is a process of “parsing” the proof sequence supplied by the prover.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; 'a authenticated_computation &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
    json list &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`Ok &lt;span class=&quot;ocamlkeyword&quot;&gt;of&lt;/span&gt; proof &lt;span class=&quot;ocamlsymbol&quot;&gt;*&lt;/span&gt; 'a &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `ProofFailure&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;

  &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; return a &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;ocamlkeyword&quot;&gt;fun&lt;/span&gt; proof &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; `Ok &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;proof&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; a&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;&gt;&gt;=&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; c f &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;ocamlkeyword&quot;&gt;fun&lt;/span&gt; prfs &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
      &lt;span class=&quot;ocamlkeyword&quot;&gt;match&lt;/span&gt; c prfs &lt;span class=&quot;ocamlkeyword&quot;&gt;with&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `ProofFailure &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; `ProofFailure
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `Ok &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;prfs'&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;a&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; f a prfs'
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The verifier’s view of authenticable values is slightly more involved than the prover’s, because it needs to be able to serialise and deserialise values to and from JSON. There isn’t anything particularly special going on here, but we do have to be careful to ensure that this implementation uses the same format as the prover’s. (An obvious improvement is to make the &lt;code&gt;Prover&lt;/code&gt; and &lt;code&gt;Verifier&lt;/code&gt; implementations share an implementation of this sub-module.)&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;ocamlkeyword&quot;&gt;module&lt;/span&gt; Authenticatable &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;struct&lt;/span&gt;
    &lt;span class=&quot;ocamlkeyword&quot;&gt;type&lt;/span&gt; 'a evidence &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
      &lt;span class=&quot;ocamlsymbol&quot;&gt;{&lt;/span&gt; serialise   &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; 'a            &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; Ezjsonm&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;value
      &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; deserialise &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; Ezjsonm&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; 'a option
      &lt;span class=&quot;ocamlsymbol&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; auth &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
      &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; serialise h &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; `String h
      &lt;span class=&quot;ocamlkeyword&quot;&gt;and&lt;/span&gt; deserialise &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;function&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `String s &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; Some s
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt;         &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; None
      in
      &lt;span class=&quot;ocamlsymbol&quot;&gt;{&lt;/span&gt; serialise&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; deserialise &lt;span class=&quot;ocamlsymbol&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; pair a_s b_s &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
      &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; serialise &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;b&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
        `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;a_s&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;serialise a&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; b_s&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;serialise b&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;ocamlkeyword&quot;&gt;and&lt;/span&gt; deserialise &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;function&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;x&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt;y&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
           &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;match&lt;/span&gt; a_s&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;deserialise x&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; b_s&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;deserialise y &lt;span class=&quot;ocamlkeyword&quot;&gt;with&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Some a&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; Some b &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; Some &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt;b&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; None&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
           None
      in
      &lt;span class=&quot;ocamlsymbol&quot;&gt;{&lt;/span&gt; serialise&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; deserialise &lt;span class=&quot;ocamlsymbol&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; sum a_s b_s &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
      &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; serialise &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;function&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `left a  &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;left&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; a_s&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;serialise a&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `right b &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;right&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; b_s&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;serialise b&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;ocamlkeyword&quot;&gt;and&lt;/span&gt; deserialise &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;function&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;left&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; x&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
           &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;match&lt;/span&gt; a_s&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;deserialise x &lt;span class=&quot;ocamlkeyword&quot;&gt;with&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Some a &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; Some &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;`left a&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; None&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;right&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; y&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
           &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;match&lt;/span&gt; b_s&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;deserialise y &lt;span class=&quot;ocamlkeyword&quot;&gt;with&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Some b &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; Some &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;`right b&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; None&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
           None
      in
      &lt;span class=&quot;ocamlsymbol&quot;&gt;{&lt;/span&gt; serialise&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; deserialise &lt;span class=&quot;ocamlsymbol&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; string &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
      &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; serialise s &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; `String s
      &lt;span class=&quot;ocamlkeyword&quot;&gt;and&lt;/span&gt; deserialise &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;function&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `String s &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; Some s
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt;         &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; None
      in
      &lt;span class=&quot;ocamlsymbol&quot;&gt;{&lt;/span&gt; serialise&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; deserialise &lt;span class=&quot;ocamlsymbol&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; int &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
      &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; serialise i &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; `String &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;string_of_int i&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;ocamlkeyword&quot;&gt;and&lt;/span&gt; deserialise &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;function&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `String i &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;try Some &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;int_of_string i&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;with&lt;/span&gt; Failure &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; None&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt;         &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; None
      in
      &lt;span class=&quot;ocamlsymbol&quot;&gt;{&lt;/span&gt; serialise&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; deserialise &lt;span class=&quot;ocamlsymbol&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;ocamlkeyword&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we get to the crucial &lt;code&gt;auth&lt;/code&gt; and &lt;code&gt;unauth&lt;/code&gt; functions. Creation of authenticated values on the verifier side is nothing more than serialising them and computing their hash code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;ocamlkeyword&quot;&gt;open&lt;/span&gt; Authenticatable

  &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; auth auth_evidence a &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
    hash_json &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;auth_evidence&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;serialise a&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, we get to the actual proof checking. The &lt;code&gt;unauth&lt;/code&gt; function is supplied with &lt;em&gt;a)&lt;/em&gt; a (de)serialiser for the type of value to be produced; &lt;em&gt;b)&lt;/em&gt; a hash code for the expected value; and &lt;em&gt;c)&lt;/em&gt; a proof which will be used to reconstitute the actual value. If we have run out of proof elements, then we fail immediately. Otherwise, we check that the hash code of the first item in the proof is the same as our required code. If so, we deserialise the proof item and return it with the remainder of the proof. If the hash codes do not match, then the verifier reports that proof checking has failed.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; unauth auth_evidence h proof &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;match&lt;/span&gt; proof &lt;span class=&quot;ocamlkeyword&quot;&gt;with&lt;/span&gt;
    &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; `ProofFailure
    &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; p&lt;span class=&quot;ocamlsymbol&quot;&gt;::&lt;/span&gt;ps when hash_json p &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; h &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt;
       &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;match&lt;/span&gt; auth_evidence&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;deserialise p &lt;span class=&quot;ocamlkeyword&quot;&gt;with&lt;/span&gt;
         &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; None   &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; `ProofFailure
         &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; Some a &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; `Ok &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;ps&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; a&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;-&gt;&lt;/span&gt; `ProofFailure
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, the &lt;code&gt;Verifier&lt;/code&gt; ends with an &lt;code&gt;end&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h5&gt;Trying out the Verifier&lt;/h5&gt;&lt;p&gt;Above, we used the &lt;code&gt;Merkle_Prover&lt;/code&gt; module to generate a small Merkle tree and run a query on it. We can now verify the prover’s execution of &lt;code&gt;retrieve&lt;/code&gt;. Recall that we extracted a hash code representing the tree from the prover’s representation:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; code &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; string &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;.z\129w\199J\224\\\254\220\bo\246W\158\243S\029\177\190&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let’s assume that this code was conveyed to the client somehow, and the client trusts that it is an accurate representation of the tree it wants to query.&lt;/p&gt;&lt;p&gt;Now the client/verifier asks the server/prover to perform a query. The server sends back the result and a proof, which we computed above:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; proof &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; proof &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;right&quot;&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;?\250m&amp;amp;,\251\129\031\r\252QJ\001\141|d}\242\016l&quot;&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;i?B\230p\158D\201\248\145\000\1400p\224\018\023\219\1935&quot;&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;right&quot;&lt;/span&gt;
         &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;X\140\005\028\146\1891L\224\246\224\229\201\018o\b\187\163\240\160&quot;&lt;/span&gt;
              &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;\223\231\194\230\1362=\157\187\226;?\143&gt;\127\248\014;\201\254&quot;&lt;/span&gt;
              &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
         &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;left&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; result &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; string option &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; Some &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;a&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can now use &lt;code&gt;Merkle_Verifier&lt;/code&gt; to verify the prover’s proof against &lt;code&gt;code&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlprompt&quot;&gt;#&lt;/span&gt; Merkle_Verifier&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;retrieve &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`L&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt;`L&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; code proof&lt;span class=&quot;ocamlprompt&quot;&gt;;;&lt;/span&gt;
&lt;span class=&quot;ocamlsymbol&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt; `Ok &lt;span class=&quot;ocamlkeyword&quot;&gt;of&lt;/span&gt; proof &lt;span class=&quot;ocamlsymbol&quot;&gt;*&lt;/span&gt; string option &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `ProofFailure &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; `Ok &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; Some &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h5&gt;Attempting to trick the verifier&lt;/h5&gt;&lt;p&gt;Let’s try simulating an attempt by the prover to trick the verifier by running the query against a different tree. First we create a tree with the same shape, but with different values in it:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; other_tree &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
    Merkle_Prover&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_branch
                     &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_branch &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_leaf &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_leaf &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;B&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;
                     &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_branch &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_leaf &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;C&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;(&lt;/span&gt;make_leaf &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;D&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;ocamlprompt&quot;&gt;;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we run the “left, left” query on this alternative tree, and we get back a result and a proof:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlprompt&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;ocamlkeyword&quot;&gt;let&lt;/span&gt; proof&lt;span class=&quot;ocamlsymbol&quot;&gt;,&lt;/span&gt; result &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; Merkle_Prover&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;retrieve &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`L&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt;`L&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; other_tree&lt;span class=&quot;ocamlprompt&quot;&gt;;;&lt;/span&gt;
&lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; proof &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; proof &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt;
   &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;right&quot;&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;Q\217G\000\246\238!\248\212\127\194\184\179&gt;\017zW\0182(&quot;&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;0\239\238\002b4\172\145\127\143\002@-=g\179\197\022\154|&quot;&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
   &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;right&quot;&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;\157\134\234N\234QS\136\165\196\0038\133j\018uY\133\030\005&quot;&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;\2272|\223M\230\241\132\167\029-\016\141\221\005nx\239\190\184&quot;&lt;/span&gt;
             &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
   &lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `A &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;left&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt; `String &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
   &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;ocamlkeyword&quot;&gt;val&lt;/span&gt; result &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; bytes option &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; Some &lt;span class=&quot;ocamlstringconst&quot;&gt;&quot;A&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We send the result and proof back to the sceptical client, who verifies the proof against their hash code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;ocamlprompt&quot;&gt;#&lt;/span&gt; Merkle_Verifier&lt;span class=&quot;ocamlsymbol&quot;&gt;.&lt;/span&gt;retrieve &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt;`L&lt;span class=&quot;ocamlsymbol&quot;&gt;;&lt;/span&gt;`L&lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; code proof&lt;span class=&quot;ocamlprompt&quot;&gt;;;&lt;/span&gt;
&lt;span class=&quot;ocamlsymbol&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;[&lt;/span&gt; `Ok &lt;span class=&quot;ocamlkeyword&quot;&gt;of&lt;/span&gt; proof &lt;span class=&quot;ocamlsymbol&quot;&gt;*&lt;/span&gt; bytes option &lt;span class=&quot;ocamlsymbol&quot;&gt;|&lt;/span&gt; `ProofFailure &lt;span class=&quot;ocamlsymbol&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;ocamlsymbol&quot;&gt;=&lt;/span&gt; `ProofFailure
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It fails! The cheating server has been thwarted.&lt;/p&gt;&lt;h3&gt;Correctness from Parametricity&lt;/h3&gt;&lt;p&gt;Of course, the examples above don’t prove that the server/prover can never cheat. For their calculus, Miller et al. provide a proof that the prover and verifier implementations satisfy the following property, which I’ve stated informally here:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;If the verifier accepts a proof (i.e., returns &lt;code&gt;Ok&lt;/code&gt;) then either it came from the prover, or is the result of a hash collision.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;If we assume that hash collisions are unlikely (Miller et al. make this assumption more formal), then we get the security property we want: up to the possibility of hash collision, we can spot cheating clouds.&lt;/p&gt;&lt;p&gt;I claim, but I’m not going to prove here, that this property is provable as an instance of the &lt;a href=&quot;http://homepages.inf.ed.ac.uk/wadler/papers/free/free.ps&quot;&gt;“Free Theorem”&lt;/a&gt; we get from the fact that the &lt;code&gt;Merkle&lt;/code&gt; implementation is parameterised by &lt;code&gt;AUTHENTIKIT&lt;/code&gt; implementations. The full proof involves &lt;a href=&quot;http://www.mpi-sws.org/~dreyer/papers/f-ing/journal.pdf&quot;&gt;F-ing Modules&lt;/a&gt; to translate the use of modules and functors into the higher-kinded calculus System Fω, my &lt;a href=&quot;http://bentnib.org/fomega-parametricity.html&quot;&gt;Relational Parametricity for Higher Kinds&lt;/a&gt; for the higher-kinded version of free theorems, and Katsumata’s &lt;a href=&quot;http://www.kurims.kyoto-u.ac.jp/~sinya/paper/csl05-69.pdf&quot;&gt;A Semantic Formulation of TT-lifting and Logical Predicates for Computational Metalanguage&lt;/a&gt; to handle the authenticated computations monads.&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2016-04-12-authenticated-data-structures-as-a-library.html</guid><pubDate>Tue, 12 Apr 2016 00:00:00 +0000</pubDate></item><item><title>Slides and notes for my OBT “Generalising Abstraction” talk</title><link>https://bentnib.org/posts/2016-01-26-obt.html</link><description>&lt;p&gt;Here are the slides I used for my keynote talk for the afternoon at this year’s &lt;a href=&quot;http://conf.researchr.org/track/POPL-2016/OBT-2016-talks&quot;&gt;Off the Beaten Track&lt;/a&gt; workshop in St. Petersburg, Florida, USA. Many thanks to &lt;a href=&quot;http://decomposition.al/&quot;&gt;Lindsey Kuper&lt;/a&gt; for inviting me to give a talk and for organising it all.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/docs/generalising-abstraction.pdf&quot;&gt;&lt;img alt=&quot;Slides for “Generalising Abstraction” talk&quot; src=&quot;https://bentnib.org/thumbnails/slides-generalising-abstraction.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The talk wasn’t recorded, but here is a collection of notes to go with the things I talked about:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://people.cs.vt.edu/~kafura/CS6604/Papers/Alternative-Perspectives-to-CT.pdf&quot;&gt;The Abstract is ‘an Enemy’&lt;/a&gt; is a paper by Alan F. Blackwell, Luke Church, and Thomas Green, written in response to Jeannette Wing’s highly influential &lt;a href=&quot;http://www.cs.cmu.edu/afs/cs/usr/wing/www/publications/Wing06.pdf&quot;&gt;Computational Thinking&lt;/a&gt;. Wing argues, amongst other things, that abstraction is a key feature of the set of techniques that computer scientists use when thinking about problems, and that people working in other disciplines could profitably make use of some of the abstraction tools developed by computer scientists. Blackwell et al. disagree with Wing’s emphasis on abstraction, noting that it can lead to system designs that de-emphasise and dehumanise users in favour of simple and tractable models designed for programmers. They also argue that abstraction can also lead to excessive literalism, conflation of the goals of a system with the goal of “the perfect abstraction”, and mathematical abstraction as a tool for theoreticians to hide behind when defending their theories. Admittedly, I put this slide up to get a cheap laugh from their abstract, but I do think the paper is worth reading in its own right.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The “Pedestrian or Equestrian” sign is from Stanley Park in Vancouver. I went over the equestrian side. The combination of the pine forest visuals and the water dripping from the ceiling in the room where OBT was held made for quite the Vancouverean experience.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Jean-Yves Girard’s &lt;a href=&quot;http://iml.univ-mrs.fr/~girard/0.ps.gz&quot;&gt;Locus Solum&lt;/a&gt; is the paper that introduces Ludics, a logical formalism whose details persist in eluding my understanding. An interesting feature of the paper is the extensive glossary covering a large portion of logic, semantics, proof theory, and computer science in a unique way (Appendix A: A pure waste of paper).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Barbara Liskov and Stephen Zilles’ &lt;a href=&quot;http://web.cs.iastate.edu/~hridesh/teaching/362/07/01/papers/p50-liskov.pdf&quot;&gt;Programming with Abstract Data Types&lt;/a&gt; was the first paper to really nail down the idea of an &lt;em&gt;abstract data type&lt;/em&gt; as a structured thing described through a set of operations, instead of the more negative definition in terms of information hiding. This lead to the design of the language &lt;a href=&quot;http://www.cs.virginia.edu/~weimer/615/reading/liskov-clu-abstraction.pdf&quot;&gt;CLU&lt;/a&gt;, led by Liskov, and to a great amount of work in algebraic specification. &lt;a href=&quot;https://www.youtube.com/watch?v=GDVAHA0oyJU&quot;&gt;The Power of Abstraction&lt;/a&gt; is a excellent and informative talk by Liskov covering the history of how she invented abstract data types.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://www.cse.chalmers.se/edu/year/2010/course/DAT140_Types/Reynolds_typesabpara.pdf&quot;&gt;Types, Abstraction, and Parametric Polymorphism&lt;/a&gt; by John Reynolds is the founding paper of a &lt;em&gt;semantic&lt;/em&gt; theory of abstraction, now called parametricity. Christopher Strachey’s &lt;a href=&quot;http://itu.dk/courses/BPRD/E2009/fundamental-1967.pdf&quot;&gt;original definition of parametricity&lt;/a&gt; was informally defined in terms of parametricity polymorphic functions being “uniformly defined” with respect to their type parameter. There are many ways to formalise this notion. We could strictly interpreting it as meaning there is a single implementation, ignoring the type parameter, as is done in &lt;a href=&quot;http://www.sciencedirect.com/science/article/pii/0304397590901517&quot;&gt;PER models&lt;/a&gt; that interpret quantification over all types as intersection. Reynolds chooses to interpret parametricity as preservation of relations, generalising the invariance under homomorphism idea from algebra. This is formalised in the Abstraction Theorem which appears in this paper. As he notes, the Abstraction Theorem is closely related to the “fundamental”, or “basic”, lemma of Logical Relations, first used for the lambda-calculus by Gordon Plotkin for proving &lt;a href=&quot;http://homepages.inf.ed.ac.uk/gdp/publications/logical_relations_1973.pdf&quot;&gt;definability results&lt;/a&gt;. I believe the origin of logical relations goes back to Robin Gandy, who used them (or at least logical relations that are equivalence relations) to ensure extensionality in models of calculi with higher-order functions.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;John Harrison’s &lt;a href=&quot;http://www.cl.cam.ac.uk/~jrh13/papers/wlog.pdf&quot;&gt;Without Loss of Generality&lt;/a&gt; is a genuinely practical paper for reducing the effort involved in proving geometric theorems in an interactive theorem prover. Harrison takes inspiration from the way that mathematicians reduce problems to simpler ones by exploiting symmetry. The idea being that “without loss of generality” one can consider a special case that soundly represents all of the instances of the general case. The paper presents an extension to the HOL Light theorem prover that pattern matches on goals containing geometric statements and reduces them to simpler goals using symmetry.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The quote “&lt;em&gt;A rose by any other name would smell as sweet&lt;/em&gt;” is from &lt;em&gt;Romeo and Julliet&lt;/em&gt; by William Shakespeare. According to Wikipedia, this play about a catastrophic lack of invariance under renaming was written some time between 1591 and 1594.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Andy Pitts’ work on Nominal Sets is collected in his book &lt;a href=&quot;http://www.cambridge.org/9781107017788&quot;&gt;Nominal Sets: Names and Symmetry in Computer Science&lt;/a&gt;. The quote on the slide is taken from the introductory notes &lt;a href=&quot;http://www.cl.cam.ac.uk/~amp12/papers/nomt/nomt.pdf&quot;&gt;Nominal Techniques&lt;/a&gt;. The essence of nominal sets is that everything ought to be invariant under the swapping of names; it is only the relationships between names that matter.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The reflexive graph model for System F is originally due to &lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.51.9972&quot;&gt;Edmund Robinson and Giuseppe Rosolini&lt;/a&gt;, who showed that it is possible to take existing denotational models of System F (i.e., typed lambda-calculus with “for all” types) and complete them to a relationally parametric ones by considering reflexive graphs whose sets of nodes and edges are denotations of types in the original model. I used this approach to give a relationally parametric model of System Fomega (i.e., System F plus type-level functions) in &lt;a href=&quot;https://bentnib.org/fomega-parametricity.html&quot;&gt;Relational Parametricity for Higher Kinds&lt;/a&gt;. A similar approach had been used by Ryu Hasegawa in &lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.57.1003&quot;&gt;Relational limits in general polymorphism&lt;/a&gt;. Neil Ghani, Patricia Johann, and myself used the reflexive graph approach to give a relationally parametric model of dependent types in &lt;a href=&quot;https://bentnib.org/dtt-parametricity.html&quot;&gt;A Relationally Parametric Model of Dependent Type Theory&lt;/a&gt;. The model I presented in the talk is essentially the same as the one in that paper, except that the reflexive graphs are presented in “indexed-style”, rather than “display-style”.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Dimension Types seem quite popular at the moment, with libraries popping up for many different languages that encode dimension types. However, most of these systems concentrate on the &lt;a href=&quot;https://www.youtube.com/watch?v=AJQ3TM-p2QI&quot;&gt;computer says “no”&lt;/a&gt; aspect. They are only interested in the type system preventing things, and womble on about Mars rockets going missing and so forth, like using a different programming language would have fixed that. Andrew Kennedy’s &lt;a href=&quot;http://research.microsoft.com/en-us/um/people/akenn/units/RelationalParametricityAndUnitsOfMeasure.pdf&quot;&gt;Relational Parametricity and Units of Measure&lt;/a&gt; is much more insightful because it shows how unit-correctness actually yields interesting results: including scale invariance results, type isomorphisms, and indefinability results. This was really the point of my talk: abstraction yields properties.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Philip Wadler dubbed some of the consequences of type abstraction that arise from Reynolds’ work &lt;a href=&quot;http://homepages.inf.ed.ac.uk/wadler/papers/free/free.ps&quot;&gt;“Theorems for Free!”&lt;/a&gt;, because the theorem is derived from the type instead of inspection of the program, which will often be more complex. This has led to many paper titles that end with “... for free!” when they use parametricity to prove something.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Distance-indexed types, where two objects are related if they are within a certain distance, are originally from &lt;a href=&quot;http://www.cis.upenn.edu/~bcpierce/papers/dp.pdf&quot;&gt;Distance makes the Types Grow Stronger&lt;/a&gt; by Jason Reed and Benjamin C. Pierce. The intended application there was to &lt;a href=&quot;http://research.microsoft.com/en-us/projects/databaseprivacy/dwork.pdf&quot;&gt;differential privacy&lt;/a&gt;, where programs (interpreted as queries on a database), are constrained to have limited dependence on small changes to the input. Roughly speaking, limiting the precise dependence of the output on the exact values input ensures that the privacy of the people whose information is in the database is protected. The Reed-Pierce paper presents a &lt;em&gt;linear&lt;/em&gt; type system that treats information leakage as a resource that needs to be conserved. The model I presented in the talk doesn’t mention linearity anywhere at all. However, it can be encoded in the reflexive graph model by treating the Reed-Pierce resource-limited types as types indexed by &lt;code&gt;Dist&lt;/code&gt;, and building up the other connectives using the same techniques as the Day-construction models of Bunched Implications.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Geometric-group indexed types first appeared in &lt;a href=&quot;https://bentnib.org/algebraic-indexed.html&quot;&gt;Abstraction and Invariance for Algebraically-indexed Types&lt;/a&gt; by myself, Patricia Johann, and Andrew Kennedy. They are a generalisation of the unit-indexed types from Andrew’s previous work, but allow for a richer set of transformations that the program can be invariant under. We looked at two other forms of “algebraically-indexed types”: one for information flow, and one for distance indexing. The indefinability results from Andrew’s work carry over to this more general setting too.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The classical mechanics types, terms, and examples are taken from my paper &lt;a href=&quot;https://bentnib.org/conservation-laws.html&quot;&gt;From Parametricity to Conservation Laws, via Noether’s Theorem&lt;/a&gt;. Emmy Noether’s Theorem is a result in the Calculus of Variations that shows that it is possible to derive conserved properties of the stationary solutions of variational problems from continuous symmetries of their actions, and in some cases to go back again. This theorem is very important in physics. Many physical theories, not just in classical mechanics, are described in terms of stationary solutions of variational problems. Noether’s theorem gives a way to deduce properties of solutions without having to explicitly solve the system. In computer science terms, roughly speaking, Noether’s Theorem shows how to derive time-global invariants over runs of a system from time-local invariants of the single-step behaviour of the system (though in Noether’s case, there are no “single-steps” because everything is continuous). My paper showed that it was possible to derive the local symmetries as consequences of free theorems, which can then be plugged into Noether’s theorem. Note that I &lt;strong&gt;didn’t&lt;/strong&gt; show that parametricity implies Noether’s theorem, though the idea doesn’t necessarily seem too outlandish, if one could give a suitable account of continuous change. Noether’s original paper &lt;a href=&quot;http://arxiv.org/pdf/physics/0503066.pdf&quot;&gt;Invariant Variation Problems&lt;/a&gt; is available in translation. I found the book &lt;a href=&quot;http://www.springer.com/gb/book/9780387950006&quot;&gt;Applications of Lie Groups to Differential Equations&lt;/a&gt; by &lt;a href=&quot;http://www.math.umn.edu/~olver/&quot;&gt;Peter Olver&lt;/a&gt; extremely helpful in understanding the basic theorem, and its generalisations, which were also proved by Noether. The book &lt;a href=&quot;http://www.amazon.co.uk/Noethers-Wonderful-Theorem-Dwight-Neuenschwander/dp/0801896940&quot;&gt;Emmy Noether’s Wonderful Theorem&lt;/a&gt; gives a readable account of the background and how the theorem is applied in physics applications.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The non-example of Higher Order Abstract Syntax is from my paper &lt;a href=&quot;https://bentnib.org/syntaxforfree.html&quot;&gt;Syntax for Free: Representing Syntax with Binding using Parametricity&lt;/a&gt;, which proved that the (denotation of the) type &lt;code&gt;forall a. ((a → a) → a) → (a → a → a) → a&lt;/code&gt; is isomorphic to the set of closed lambda-terms. This result appears to require Kripke-indexed relations, which are not included in the simple reflexive graph model I used in the talk. After my talk, Ambrus Kaposi mentioned some ideas to me of how to incorporate Kripke-indexed relations, which I need to follow up.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The final section of the talk reported on unpublished work in progress on &lt;em&gt;internalising&lt;/em&gt; relational parametricity into the type theory. Using the reflexive graph model at a meta-theoretical level is all very well, but it would be extremely useful to be able to prove invariance results internally, just as one can prove equalities between programs internally in dependent type theories. The approach I presented here is based on the observation that “relatedness” is sort of like a weakened version of equality in Martin-Löf type theory (MLTT). (For simplicity I only considered MLTT with equality reflection.) The resulting system is something like Ambrus Kaposi and Thorsten Altenkirch’s &lt;a href=&quot;http://www.cs.nott.ac.uk/~txa/publ/ctt.pdf&quot;&gt;Cubical Type Theory&lt;/a&gt;, but differs in how it considers equality within in the universe &lt;code&gt;U&lt;/code&gt; of small types. &lt;a href=&quot;http://publications.lib.chalmers.se/publication/230735&quot;&gt;Jean-Phillipe Bernardy, Thierry Coquand, and Guilhem Moulin&lt;/a&gt; have published a syntax and model for internalised parametricity. Their system has unary, but higher-dimensional, relations, and does not (as far as I understand) have an explicit relationship with equality.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;After the talk there were a few questions, which were written down on 5x3 index cards and read out by the session chair. This style of questions is an innovation by Lindsey for OBT to try to encourage people who wouldn’t normally ask questions to ask, and to share time more equally between questions. My impression was that possibly more questions were asked than I would have normally expected. Also, I got to keep the cards with the questions on:&lt;/p&gt;&lt;p&gt;&lt;img alt=&quot;Coloured Index cards with the questions below written on them&quot; src=&quot;https://bentnib.org/docs/obt-questions.jpg&quot;&gt;&lt;/p&gt;&lt;p&gt;The questions, and my answers, are listed below. These answers are with the benefit of hindsight and a long plane journey to ruminate on “what I should have said”, so they aren’t exactly what I said at the time.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;How is that related to homotopy type theory/univalence?&lt;/strong&gt; This is an especially natural question given the formal similarities between the higher-dimensional models for both. I used to think that relationally parametric type theory would be a “baby” version of univalent type theory, where the composable, reversible paths between objects are replaced by a weaker notion of relatedness. However, I now think that relational parametricity and homotopy type theory are orthogonal. Relational Parametricity is agnostic with respect to the notion of equality it uses, and so it is possible to speak about relationally parametric (extensional type theory | type theory with equality reflection | intensional type theory | observational type theory | univalent type theory). However, thinking a bit more, it might be possible that Homotopy Type Theory might be a sub-system of relationally parametric type theory, where relatedness just so happens to be slightly richer.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;What ever came out of John Harrison’s “WLOG” work? Any useful tools for automatic theorem proving?&lt;/strong&gt; I don’t know about tools for automatic theorem proving, though I think that it would be interesting (I vaguely remember that constraint solving systems often involve the use of symmetry to cut down the search space; the name &lt;a href=&quot;https://scholar.google.com/citations?user=pJB7cjoAAAAJ&amp;hl=en&quot;&gt;Karen Petrie&lt;/a&gt; springs to mind). Harrison’s original work is now part of the HOL light theorem prover, in the &lt;a href=&quot;https://github.com/jrh13/hol-light/blob/c44fc7909eb68d68afa33b9bd0dc66c467bf481e/Multivariate/wlog.ml&quot;&gt;Multivariate&lt;/a&gt; library.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Have you looked at Lorentz invariance?&lt;/strong&gt; This is in reference to how all the examples I showed of mechanics systems were invariant under Galliean invariance, which doesn’t account for the effects of special relativity. Lorentz invariance does account for special relativity. I haven’t looked at Lorentz invariance explicitly, but I think that it can be handled by the system I presented.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Where can I get your slides and/or papers you used as examples?&lt;/strong&gt; This page.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;How about Calculus?&lt;/strong&gt; At the time I interpreted this question as being about the special type constructor &lt;code&gt;C^\infty&lt;/code&gt; I used to internalise smooth functions for the purposes of classical mechanics models, and I muttered something about Synthetic Differential Geometry. Looking back, I think it probable that the questioner was actually asking about the relationship between the “theory of change” model I talked about here, and differential calculus as a theory of continuous change. I think that this is a really interesting question, which might have a lot to say about incremental computation, bidirectional computation and reversible computation. The paper &lt;a href=&quot;http://www.informatik.uni-marburg.de/~pgiarrusso/papers/pldi14-ilc-author-final.pdf&quot;&gt;A theory of changes for higher-order languages — incrementalizing λ-calculi by static differentiation&lt;/a&gt; gives an account of a static “differentiation” process for lambda-calculus terms for the purposes of doing incremental computation. Gabriel Scherer noted a similarity between that work and relational parametricity, which I wrote a &lt;a href=&quot;https://bentnib.org/posts/2015-04-23-incremental-lambda-calculus-and-parametricity.html&quot;&gt;blog post&lt;/a&gt; about.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2016-01-26-obt.html</guid><pubDate>Tue, 26 Jan 2016 00:00:00 +0000</pubDate></item><item><title>The Incremental λ-Calculus and Relational Parametricity</title><link>https://bentnib.org/posts/2015-04-23-incremental-lambda-calculus-and-parametricity.html</link><description>&lt;p&gt;Back in February, the paper &lt;a href=&quot;http://www.informatik.uni-marburg.de/~pgiarrusso/papers/pldi14-ilc-author-final.pdf&quot;&gt;A theory of changes for higher-order languages — incrementalizing λ-calculi by static differentiation&lt;/a&gt; by Cai, Giarusso, Rendel, and Ostermann, was posted to &lt;a href=&quot;http://lambda-the-ultimate.org/node/5115&quot;&gt;Lambda-the-Ultimate&lt;/a&gt;. The poster, gasche, made the following parenthetical comment at the end of the L-t-U post:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;(The program transformation seems related to the program-level parametricity transformation. Parametricity abstract over equality justifications, differentiation on small differences.)&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;In this post, I’m going to substantiate gasche’s conjecture by showing how (a very slight simplification of) the theory of changes presented in the paper is formally &lt;em&gt;the same thing as&lt;/em&gt; relational parametricity. Where Reynolds’ relational parametricity for System F is a theory of how programs act under change of data representation — &lt;em&gt;i.e.,&lt;/em&gt; change of types; Cai *et al.*’s theory of changes is a theory of how programs act under change of values.&lt;/p&gt;&lt;h3&gt;A Theory of Changes, and Change Structures&lt;/h3&gt;&lt;p&gt;Cai &lt;em&gt;et al.&lt;/em&gt; are interested in translating purely functional programs that map values of type &lt;code&gt;A&lt;/code&gt; to values of type &lt;code&gt;B&lt;/code&gt; into programs that map changes in values of type &lt;code&gt;A&lt;/code&gt; to changes in values of type &lt;code&gt;B&lt;/code&gt;. The intention is that the translated version of the program that maps changes to changes will more efficiently handle incremental updates to the input than doing a full recomputation.&lt;/p&gt;&lt;p&gt;In any attempt to define such a translation, you are going to need to define what you mean by “changes in the values of type &lt;code&gt;A&lt;/code&gt;”. To this end, Cai &lt;em&gt;et al.&lt;/em&gt; define the following notion of &lt;em&gt;change structure&lt;/em&gt;. A change structure (for a particular type) consists of:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;A set &lt;code&gt;A&lt;/code&gt; of the possible values of this type;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;For each value &lt;code&gt;a ∈ A&lt;/code&gt;, a set &lt;code&gt;∂A(a)&lt;/code&gt; of possible changes that can be applied to the value &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;An operation &lt;code&gt;⊕&lt;/code&gt; that takes a value &lt;code&gt;a ∈ A&lt;/code&gt; and a change &lt;code&gt;δa ∈ ∂A(a)&lt;/code&gt; and produces a value &lt;code&gt;a ⊕ δa ∈ A&lt;/code&gt; that represents the result of applying the change &lt;code&gt;δa&lt;/code&gt; to the value &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;An operation &lt;code&gt;⊖&lt;/code&gt; that takes an &lt;code&gt;a ∈ A&lt;/code&gt; and a &lt;code&gt;b ∈ A&lt;/code&gt; and produces a change &lt;code&gt;b ⊖ a ∈ ∂A(a)&lt;/code&gt; that represents the change required to get from &lt;code&gt;a&lt;/code&gt; to &lt;code&gt;b&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;These operations are subject to several laws that are laid out in Section 2 of the paper.&lt;/p&gt;&lt;p&gt;Requiring the existence of the &lt;code&gt;⊖&lt;/code&gt; operation for every change structure seems to be quite strong to me. By requiring &lt;code&gt;⊖&lt;/code&gt;, we are requiring that for &lt;em&gt;any&lt;/em&gt; two values &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;, there must be at least one change that connects them, and for some reason we have chosen this change out of possibly many choices as “special”. Just by requiring the existence of a change that translates us from &lt;code&gt;a&lt;/code&gt; to &lt;code&gt;b&lt;/code&gt;, we are making a commitment that the “space” of &lt;code&gt;A&lt;/code&gt; values is connected in some way, which may not be justified in some applications. What if there are states that we can get into that are not get-out-able? What if we only want to consider changes that are appending of new data?&lt;/p&gt;&lt;p&gt;As far as I can see, the &lt;code&gt;⊖&lt;/code&gt; operation is only used in the paper to define the zero change &lt;code&gt;0 ∈ ∂A(a)&lt;/code&gt; for every value &lt;code&gt;a ∈ A&lt;/code&gt;, and then is never mentioned again. To me, the existence of a zero change for every value seems much easier to justify than a general &lt;code&gt;⊖&lt;/code&gt; operation. Therefore, I propose the following mild generalisation of change structure, which only differs from the Cai *et al.*’s definition in the final point:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;A set &lt;code&gt;A&lt;/code&gt; of possible values;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;For each value &lt;code&gt;a ∈ A&lt;/code&gt;, a set &lt;code&gt;∂A(a)&lt;/code&gt; of possible changes that can be applied to the value &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;An operation &lt;code&gt;⊕&lt;/code&gt; that takes a value &lt;code&gt;a ∈ A&lt;/code&gt; and a change &lt;code&gt;δa ∈ ∂A(a)&lt;/code&gt; and produces a value &lt;code&gt;a ⊕ δa ∈ A&lt;/code&gt; that represents the result of applying the change &lt;code&gt;δa&lt;/code&gt; to the value &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;For every &lt;code&gt;a ∈ A&lt;/code&gt;, a &lt;em&gt;zero change&lt;/em&gt; &lt;code&gt;0 ∈ ∂A(a)&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Change structures allow Cai &lt;em&gt;et al.&lt;/em&gt; to define the notion of a &lt;em&gt;derivative&lt;/em&gt; of a function &lt;em&gt;f&lt;/em&gt;. The idea is that if &lt;code&gt;f&lt;/code&gt; is the original function, then &lt;code&gt;f'&lt;/code&gt; is a function that can compute changes in the output, given the original input value and the change in the input value.&lt;/p&gt;&lt;p&gt;Formally, given a pair of change structures, &lt;code&gt;(A, ∂A, ⊕, 0)&lt;/code&gt; and &lt;code&gt;(B, ∂B, ⊕, 0)&lt;/code&gt;, and a function &lt;code&gt;f : A → B&lt;/code&gt; Cai &lt;em&gt;et al.&lt;/em&gt; define a derivative of &lt;code&gt;f&lt;/code&gt; to be a function &lt;code&gt;f' : (a : A) → ∂A(a) → ∂B(f a)&lt;/code&gt; such that: &lt;em&gt;i)&lt;/em&gt; &lt;code&gt;f(a ⊕ δa) = (f a) ⊕ (f' a δa)&lt;/code&gt;; and &lt;em&gt;ii)&lt;/em&gt; &lt;code&gt;f' a 0 = 0&lt;/code&gt;. (Notes: point &lt;em&gt;ii&lt;/em&gt; is actually a lemma in the paper, which I think is provable if you have &lt;code&gt;⊖&lt;/code&gt;, but I have to state explicitly; also, the paper calls &lt;code&gt;f'&lt;/code&gt; &lt;em&gt;the&lt;/em&gt; derivative, but in general it isn’t unique for a given &lt;code&gt;f&lt;/code&gt;.)&lt;/p&gt;&lt;p&gt;Given these definitions, we can define a category of change structures: the objects are change structures, and the morphisms are pairs &lt;code&gt;(f,f')&lt;/code&gt; of functions &lt;code&gt;f&lt;/code&gt; between the sets of values, and derivatives &lt;code&gt;f'&lt;/code&gt;. Looking at change structures as a category, we can see that the middle four pages of Cai *et al.*’s paper, from Section 2.2 to the end of Section 3, essentially boils down to proving that this category is cartesian closed, and so can model the simply typed λ-calculus.&lt;/p&gt;&lt;h3&gt;Relational Parametricity via Reflexive Graphs&lt;/h3&gt;&lt;p&gt;Relational parametricity is usually introduced in terms of &lt;em&gt;logical relations&lt;/em&gt;. A logical relation is a relation between two interpretations of the same syntactic type &lt;code&gt;A&lt;/code&gt; that is defined by looking at the “logical” structure of the type &lt;code&gt;A&lt;/code&gt; (that is: looking at the “logical” constructors &lt;code&gt;→&lt;/code&gt;, &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;×&lt;/code&gt; and so on used to construct &lt;code&gt;A&lt;/code&gt;). The general idea is that we relate two interpretations of the same type &lt;code&gt;A&lt;/code&gt; to capture the idea of “change of representation” for that type.&lt;/p&gt;&lt;p&gt;An alternative approach to relational parametricity, that ends up being equivalent when we are just talking about types uses &lt;em&gt;reflexive graphs&lt;/em&gt;. This approach is originally due to Robinson and Rosolini in their &lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.51.9972&quot;&gt;“Reflexive Graphs and Parametric Polymorphism” paper&lt;/a&gt; from 1994. The idea is to abstract logical relations away from types and relations, and to look at just the bare structure of what we are defining. A reflexive graph consists of:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;A set &lt;code&gt;O&lt;/code&gt;, which we will call abstract &lt;em&gt;objects&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;A set &lt;code&gt;R&lt;/code&gt;, which we will call abstract &lt;em&gt;relations&lt;/em&gt; or &lt;em&gt;edges&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;A function &lt;code&gt;src : R → O&lt;/code&gt; (“source of an edge”) that maps each edge to its source object.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;A function &lt;code&gt;tgt : R → O&lt;/code&gt; (“target of an edge”) that maps each edge to its target object.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;A function &lt;code&gt;refl : O → R&lt;/code&gt; (“reflexive edge”) that maps each object &lt;code&gt;o&lt;/code&gt; to a reflexive edge with source &lt;code&gt;o&lt;/code&gt; and target &lt;code&gt;o&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Conceptually, we can think of the objects in &lt;code&gt;O&lt;/code&gt; as the actual data we compute with, and the edges in &lt;code&gt;R&lt;/code&gt; as telling us about abstract relationships between pairs of data items. A reflexive graph morphism will tell us how to map data to data and relationships to relationships, in such a way that the two mappings agree.&lt;/p&gt;&lt;p&gt;Formally, a &lt;em&gt;morphism&lt;/em&gt; between two reflexive graphs &lt;code&gt;(O₁, R₁, src₁, tgt₁, refl₁)&lt;/code&gt; and &lt;code&gt;(O₂, R₂, src₂, tgt₂, refl₂)&lt;/code&gt; consists of a pair of functions &lt;code&gt;f : O₁ → O₂&lt;/code&gt;, mapping objects to objects, and &lt;code&gt;r : R₁ → R₂&lt;/code&gt;, mapping relations to relations, such that the three operations &lt;code&gt;src&lt;/code&gt;, &lt;code&gt;tgt&lt;/code&gt; and &lt;code&gt;refl&lt;/code&gt; are preserved.&lt;/p&gt;&lt;p&gt;As with change structures, we can make reflexive graphs and reflexive graph morphisms into a category, which is cartesian closed for general reasons (specifically, the category of reflexive graphs is a presheaf category, which are always cartesian closed).&lt;/p&gt;&lt;p&gt;I think it is useful to consider reflexive graphs because they are a larger world where normal logical relations live, alongside many other interesting things. We can define a particular reflexive graph that captures the idea of “relation between two interpretations of a type”, but we can also go on to define other reflexive graphs to represent other things, like &lt;a href=&quot;https://bentnib.org/fomega-parametricity.html&quot;&gt;higher kinds&lt;/a&gt;, or &lt;a href=&quot;https://bentnib.org/conservation-laws.html&quot;&gt;geometric transformation groups&lt;/a&gt;, and, as I’ll demonstrate below, Cai *et al.*’s change structures.&lt;/p&gt;&lt;p&gt;In more detail, the reflexive graph that captures the idea of “relation between two interpretations of a type” is defined as having objects that are (small) sets, edges that are triples &lt;code&gt;(A,B,R)&lt;/code&gt;, where &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt; are small sets, and &lt;code&gt;R&lt;/code&gt; is binary relation between &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt;. We define &lt;code&gt;src(A,B,R) = A&lt;/code&gt;, &lt;code&gt;tgt(A,B,R) = B&lt;/code&gt;. The “reflexive edge” for each small set is defined to be the equality relation: &lt;code&gt;refl(A) = (A,A,{(a,a) | a ∈ A})&lt;/code&gt;. Making the reflexive edge from every set to itself be equality captures the &lt;em&gt;Identity Extension&lt;/em&gt; property identified by Reynolds.&lt;/p&gt;&lt;p&gt;For interpreting System F, and the higher kinded variant System Fω, we interpret &lt;em&gt;kinds&lt;/em&gt; (i.e., &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;* → *&lt;/code&gt;, &lt;code&gt;(* → *) → *&lt;/code&gt; and so on) as reflexive graphs, &lt;em&gt;types&lt;/em&gt; (possibly with free variables) as morphisms of reflexive graphs, and &lt;em&gt;terms&lt;/em&gt; as transformations between morphisms of reflexive graphs. See my paper &lt;a href=&quot;https://bentnib.org/fomega-parametricity.html&quot;&gt;Relational Parametricity for Higher Kinds&lt;/a&gt; for more details.&lt;/p&gt;&lt;p&gt;When interpreting &lt;em&gt;dependent types&lt;/em&gt; in a relationally parametric model, we get to make a simplification: we unify the interpretations of types and kinds. Now all types are interpreted as (families of) reflexive graphs, and terms are interpreted as (families of) reflexive graph morphisms. The type of small types, &lt;code&gt;U&lt;/code&gt;, is interpreted using the reflexive graph &lt;code&gt;Type&lt;/code&gt; I gave the definition of above. See the paper &lt;a href=&quot;https://bentnib.org/dtt-parametricity.html&quot;&gt;A Relationally Parametric Model of Dependent Type Theory&lt;/a&gt;, that I wrote with Neil and Patty, for more details.&lt;/p&gt;&lt;p&gt;So, the category of reflexive graphs is the natural place for interpreting relational parametricity for type systems that are more expressive than plain System F.&lt;/p&gt;&lt;h3&gt;Change Structures and Reflexive Graphs are equivalent&lt;/h3&gt;&lt;p&gt;I’m now going to show that Cai *et al.*’s change structures (or at least my slight variant) and reflexive graphs are the same thing. More precisely, the categories involved are equivalent, but here I’ll just stick to showing how to convert a change structure to reflexive graph and back.&lt;/p&gt;&lt;p&gt;Given a change structure &lt;code&gt;(A, ∂A, ⊕, 0)&lt;/code&gt;, we define a reflexive graph as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;The set of objects is the set &lt;code&gt;A&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The set of relations is the set consisting of pairs &lt;code&gt;(a, δa)&lt;/code&gt;, where &lt;code&gt;a ∈ A&lt;/code&gt; and &lt;code&gt;δa ∈ ∂A(a)&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The source map is defined as &lt;code&gt;src(a, δa) = a&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The target map is defined as &lt;code&gt;tgt(a, δa) = a ⊕ δa&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The reflexive maps is defined as &lt;code&gt;refl(a) = (a,0)&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Conversely, given a reflexive graph &lt;code&gt;(O, R, src, tgt, refl)&lt;/code&gt;, we define a change structure as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;The set of values is &lt;code&gt;O&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;For each value &lt;code&gt;o ∈ O&lt;/code&gt;, the set of changes at &lt;code&gt;o&lt;/code&gt; is &lt;code&gt;∂O(o) = { r ∈ R | src(r) = o }&lt;/code&gt; — &lt;em&gt;i.e.&lt;/em&gt;, the set of relations with source &lt;code&gt;o&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The &lt;code&gt;⊕&lt;/code&gt; operation is defined as &lt;code&gt;o ⊕ r = tgt(r)&lt;/code&gt; — &lt;em&gt;i.e.&lt;/em&gt;, we take the target of a relation whose source is &lt;code&gt;o&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;For each &lt;code&gt;o ∈ O&lt;/code&gt;, the &lt;code&gt;0&lt;/code&gt; change in &lt;code&gt;∂O(o)&lt;/code&gt; is &lt;code&gt;refl(o)&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If we start with either a change structure or a reflexive graph then translating to the other and back again will always give us something that is isomorphic to what we started with. After a bit more work, we can see that this will give us an equivalence of categories.&lt;/p&gt;&lt;h3&gt;So what?&lt;/h3&gt;&lt;p&gt;So we’ve got an equivalence of categories: one intended for interpreting incremental recomputation, and one intended for interpreting relational parametricity. What does this give us?&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Since the category of reflexive graphs can interpret dependent type theory (&lt;a href=&quot;https://bentnib.org/dtt-parametricity.html&quot;&gt;see here&lt;/a&gt;), the fact that the categories of change structures and reflexive graphs are equivalent means that we automatically have a notion of static differentiation of programs in the sense of Cai &lt;em&gt;et al.&lt;/em&gt; for dependently typed languages.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;I think this equivalence gives us a way to &lt;em&gt;think&lt;/em&gt; about relational parametricity. Relational parametricity (and “theorems for free”) are sometimes characterised as holding because programs “cannot inspect their type parameters”, or “don’t know what type is being used”. But the equivalence with change structures indicates to me that thinking of parametricity as a theory of how programs act under changes of their parameters. This viewpoint is explicit in Kennedy’s &lt;a href=&quot;http://research.microsoft.com/en-us/um/people/akenn/units/RelationalParametricityAndUnitsOfMeasure.pdf&quot;&gt;Relational Parametricity and Units of Measure&lt;/a&gt; from 1997, where he treats polymorphism over dimensions as invariance under scaling. However, the “theory of change” viewpoint does not seem to be a common way to think about parametricity or polymorphism in the literature in general.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;I hope that a unified viewpoint on parametricity &lt;em&gt;and&lt;/em&gt; change structures may lead to interesting advances in both. As one example: what about having additional structure on the set of changes?  Could we arrange changes into a partial order to say that one change was “bigger” than another? This might give us a way of stating that an incremental recomputation gives us the &lt;em&gt;least&lt;/em&gt; change in the output for a given change in the input. Then what does that mean for parametricity? Another example: if the derivative function maps changes in the input to changes in the output, then can we formulate what is required of a function that maps changes back? (Fun exercise: show that “well-behaved lenses” are equivalent to change structure morphisms between certain change structures, where the derivative function partially applied to a value — &lt;code&gt;f' a : ∂A(a) → ∂B(f a)&lt;/code&gt; — always has an inverse.)&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2015-04-23-incremental-lambda-calculus-and-parametricity.html</guid><pubDate>Thu, 23 Apr 2015 00:00:00 +0000</pubDate></item><item><title>Slides for “An Algebraic Approach to Typechecking and Elaboration”</title><link>https://bentnib.org/posts/2015-04-19-algebraic-approach-typechecking-and-elaboration.html</link><description>&lt;p&gt;Two months at the &lt;a href=&quot;http://www.dcs.gla.ac.uk/research/spls/&quot;&gt;Scottish Programming Languages Seminar&lt;/a&gt;, February 2015 Strathclyde Edition, I gave a talk entitled “&lt;em&gt;An Algebraic Approach to Typechecking and Elaboration&lt;/em&gt;”. Several people have asked me to put the slides online, so here they are:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/docs/algebraic-typechecking-20150218.pdf&quot;&gt;&lt;img alt=&quot;Thumbnail of slides for &amp;quot;An Algebraic Approach to Typechecking and Elaboration&amp;quot; talk&quot; src=&quot;https://bentnib.org/thumbnails/slides-algebraic-typechecking-20150218.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The point of the talk was to present an algebraic approach to specifying type systems ─ algebraic in the sense of algebraic theories with operations and equations. I reckon this presentation leads naturally to a unification of the way that typed functional languages like ML and Haskell elaborate their source language into explicitly typed core languages, and the tactic languages in interactive theorem provers like Coq and Isabelle.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; (2015-05-20) I gave this talk again at the &lt;a href=&quot;http://staff.computing.dundee.ac.uk/frantisekfarka/tiap/&quot;&gt;Workshop on Type Inference and Automated Proving&lt;/a&gt; in Dundee, and it was &lt;a href=&quot;https://www.youtube.com/watch?v=R5NMX8FBlWU&quot;&gt;recorded (link to video)&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; (2015-09-03) I gave this talk a third time at the &lt;a href=&quot;http://users-cs.au.dk/birke/hope-2015/&quot;&gt;Higher Order Programming with Effects (HOPE)&lt;/a&gt; workshop colocated with ICFP 2015 in Vancouver, and it was again &lt;a href=&quot;https://www.youtube.com/watch?v=ypU3j6Wpkoo&quot;&gt;recorded (link to video)&lt;/a&gt;.&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2015-04-19-algebraic-approach-typechecking-and-elaboration.html</guid><pubDate>Sun, 19 Apr 2015 00:00:00 +0000</pubDate></item><item><title>Propositions as Filenames, Builds as Proofs: The Essence of Make</title><link>https://bentnib.org/posts/2015-04-17-propositions-as-filenames-essence-of-make.html</link><description>&lt;p&gt;The &lt;a href=&quot;http://en.wikipedia.org/wiki/Make_%28software%29&quot;&gt;&lt;code&gt;make&lt;/code&gt;&lt;/a&gt; program is a widely used tool for building files from existing files, according to a set of build rules specified by the user. It is usually used to compile executable programs from source code, but can also be used for many other jobs where a bunch of things are generated from other things, like this website, for example.&lt;/p&gt;&lt;p&gt;Many alternatives to &lt;code&gt;make&lt;/code&gt; have been proposed. Motivations for replacing &lt;code&gt;make&lt;/code&gt; range from a desire to replace &lt;code&gt;make&lt;/code&gt;'s very Unix-philosophy inspired domain-specific language for describing build rules (Unix-philosophy in the sense that it often &lt;a href=&quot;https://pragprog.com/the-pragmatic-programmer/extracts/coincidence&quot;&gt;works by coincidence&lt;/a&gt;, but falls over if you do something exotic, like have filenames with spaces in, or have an environment variable with the “wrong” name), or &lt;code&gt;make&lt;/code&gt;'s slowness at some tasks, or a perception that &lt;code&gt;make&lt;/code&gt; doesn't treat the &lt;code&gt;make&lt;/code&gt;-alternative implementor's favourite programming language with the special treatment it so obviously deserves.&lt;/p&gt;&lt;p&gt;Nevertheless, I think that &lt;code&gt;make&lt;/code&gt; (or at least the GNU variant I am most familiar with) has a core essence that can be profitably extracted and analysed.&lt;/p&gt;&lt;h3&gt;The Essence of &lt;code&gt;make&lt;/code&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;The essence of &lt;code&gt;make&lt;/code&gt; is this&lt;/strong&gt;: &lt;code&gt;make&lt;/code&gt; is an implementation of &lt;em&gt;constructive logic programming&lt;/em&gt;, using the following instantiation of the “&lt;a href=&quot;http://homepages.inf.ed.ac.uk/wadler/papers/propositions-as-types/propositions-as-types.pdf&quot;&gt;Propositions-as-X&lt;/a&gt;” paradigm:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Atomic propositions are &lt;em&gt;filenames&lt;/em&gt;. The filenames &lt;code&gt;main.c&lt;/code&gt;, &lt;code&gt;main.o&lt;/code&gt; and &lt;code&gt;myprogram&lt;/code&gt; are all examples of atomic propositions in &lt;code&gt;make&lt;/code&gt;'s logic. For &lt;code&gt;make&lt;/code&gt;, the idea of “well-formed formula” from traditional logic means “doesn't have spaces in”.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Compound propositions are &lt;em&gt;build rules&lt;/em&gt;. A build rule that states that &lt;code&gt;myprogram&lt;/code&gt; can be built from &lt;code&gt;main.o&lt;/code&gt; and &lt;code&gt;module.o&lt;/code&gt; is a statement that the atomic propositions &lt;code&gt;main.o&lt;/code&gt; and &lt;code&gt;module.o&lt;/code&gt; imply &lt;code&gt;myprogram&lt;/code&gt;. Pattern rules like &lt;code&gt;%.o: %.c; gcc -o $@ -c $&amp;lt;&lt;/code&gt; are &lt;em&gt;universally quantified&lt;/em&gt; compound propositions: this says that, for all &lt;em&gt;x&lt;/em&gt;, the atomic proposition &lt;em&gt;x&lt;/em&gt;&lt;code&gt;.c&lt;/code&gt; implies the atomic proposition &lt;em&gt;x&lt;/em&gt;&lt;code&gt;.o&lt;/code&gt;. Static pattern rules are essentially a form of bounded quantification.&lt;/p&gt;&lt;p&gt;Note that the form of compound propositions allowed is extremely restricted, even by the standards of logic programming: we are allowed at most one universal quantifier, which quantifies over space-less strings, the rest of proposition must be of the form “&lt;code&gt;f1&lt;/code&gt; and &lt;code&gt;f2&lt;/code&gt; and ... and &lt;code&gt;fn&lt;/code&gt; implies &lt;code&gt;g&lt;/code&gt;”, &lt;em&gt;and&lt;/em&gt; if there is a quantifier, the variable must appear in the goal formula &lt;code&gt;g&lt;/code&gt;. This format corresponds to a restricted form of &lt;a href=&quot;http://en.wikipedia.org/wiki/Horn_clause&quot;&gt;Horn Clauses&lt;/a&gt;, as used in normal logic programming.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;If we stopped here, then &lt;code&gt;make&lt;/code&gt; would not be any more than an extremely restricted form of Prolog. But what makes &lt;code&gt;make&lt;/code&gt; special is that it implements a &lt;em&gt;constructive&lt;/em&gt; logic: it generates proofs, or evidence, for the propositions it proves.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Proof, or evidence, of an atomic proposition &lt;code&gt;somefile&lt;/code&gt; is the &lt;em&gt;content of an actual file &lt;code&gt;somefile&lt;/code&gt; in the filesystem&lt;/em&gt;. Some evidence is provided by the user, in the form of source files. Evidence for deduced atomic propositions, e.g., &lt;code&gt;.o&lt;/code&gt; files, is generated by the proofs for compound propositions:&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Proof of a compound proposition “&lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; implies &lt;code&gt;z&lt;/code&gt;” is a &lt;em&gt;command&lt;/em&gt; to run that will generate the proof of the atomic proposition &lt;code&gt;z&lt;/code&gt; from the proofs of the atomic propositions &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;. For pattern rules, this proof is parameterised by the instantiation of the universally quantified variable. For some reason, in &lt;code&gt;make&lt;/code&gt;, the universally quantified variable is written as “&lt;code&gt;%&lt;/code&gt;” in the proposition, and “&lt;code&gt;$*&lt;/code&gt;” in the proof.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;What &lt;code&gt;make&lt;/code&gt; does&lt;/h3&gt;&lt;p&gt;Using this mapping between logic and &lt;code&gt;make&lt;/code&gt;, I see &lt;code&gt;make&lt;/code&gt; as conceptually performing three tasks when it is told to use &lt;code&gt;Makefile&lt;/code&gt; to generate the target &lt;code&gt;myprogram&lt;/code&gt;.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;It executes the &lt;code&gt;Makefile&lt;/code&gt;, expanding out variables. This generates a collection of build rules.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;It constructs a proof of the atomic proposition &lt;code&gt;myprogram&lt;/code&gt; using backward-chaining proof search from the goal, via the build rules (aka compound propositions), back to the evidence for atomic propositions provided by the user in the file system. In traditional logic, this proof would be represented using a tree, but obvious efficiency gains can be had by exploiting sharing and representing it as a directed acyclic graph.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;It &lt;em&gt;executes&lt;/em&gt; the proof to generate the evidence of the atomic proposition &lt;code&gt;myprogram&lt;/code&gt;. The evidence for the provability of &lt;code&gt;myprogram&lt;/code&gt; is a file &lt;code&gt;myprogram&lt;/code&gt; in the filesystem, generated by the proofs of the build rules and source files it's proof depends on. This step can often be made more efficient by reusing existing pieces of evidence if the evidence they were built from hasn't changed.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The GNU &lt;code&gt;make&lt;/code&gt; manual's description combines the last two steps into one “run-the-build” step, and in practice this is what an realistic implementation ought to do. (And the first step is, in GNU &lt;code&gt;make&lt;/code&gt;'s reality, more complex because &lt;code&gt;make&lt;/code&gt; can rebuild included files and restart itself, but I'm glossing over that for now.)&lt;/p&gt;&lt;h3&gt;So what?&lt;/h3&gt;&lt;p&gt;I think that there are real benefits to seeing &lt;code&gt;make&lt;/code&gt;-like systems as implementations of constructive logic programming:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;I believe that seeing &lt;code&gt;make&lt;/code&gt;-like systems as a form of constructive logic programming elucidates the differences between some of the &lt;code&gt;make&lt;/code&gt; alternatives that have been proposed. For instance, I think that the &lt;a href=&quot;http://martine.github.io/ninja/&quot;&gt;Ninja&lt;/a&gt; system essentially gets its speed ups by caching the some of results of the proof search step by storing the expansions of all of the universally quantified build rules that are needed. The &lt;a href=&quot;http://omake.metaprl.org/index.html&quot;&gt;OMake&lt;/a&gt; system allows for targets to dynamically depend on dependencies listed in generated files, via “scanner” dependencies. I think this corresponds to proof search in a &lt;em&gt;dependently-typed&lt;/em&gt; logic that allows propositions to depend on the generated evidence of other propositions.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;We can start to look at &lt;code&gt;makes&lt;/code&gt;'s restrictions through the lens of logic programming, and start to think about more expressive build tools:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Why are build rules restricted to at most one universal quantifier? What would we gain my allowing unrestricted Horn clauses? What if the universally quantified variables didn't have to appear in the goal formula, as in most other logic programming languages?&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Build rules that generate multiple files are Horn clauses with conclusions that are conjunctions (ands) of atomic propositions. GNU &lt;code&gt;make&lt;/code&gt; and others make multiple targets difficult, but from a logical point-of-view, there is no problem.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;What rules does &lt;code&gt;make&lt;/code&gt; use to resolve the choice between multiple proofs of the one atomic proposition? Could we have build systems that produce sets of proofs for each proposition? Can this be used to do multi-platform builds? Can we assign weightings to build rules so that &lt;code&gt;make&lt;/code&gt; picks the overall “best” proof/build strategy?&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;make&lt;/code&gt; implements a “top-down” approach to evaluating its logic program. Why not also implement a “bottom-up” evaluation too? This would enable us to ask questions like “what can be built using these rules and these source files?”. This might finally enable decent TAB-completion for &lt;code&gt;make&lt;/code&gt; at the command line, and IDE introspection capabilities.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Can logics that incorporate forms of (sound) circular reasoning be used to do build jobs that require iteration until a fixpoint. Can we use fixpoint logic to work around the tragedy of LaTeX's “Label(s) may have changed. Rerun to get cross-references right.”?&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Do all atomic propositions have to be filenames? Why not URLs? Why not proof-irrelevant ephemeral propositions?&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Can the connection between logic programming and relational databases be used? Can we use a &lt;code&gt;make&lt;/code&gt;-like tool to query a database, and generate reports?&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Can we automatically augment the proof graphs that &lt;code&gt;make&lt;/code&gt; implicitly generates to add provenance information?&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Interesting stuff, I think.&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2015-04-17-propositions-as-filenames-essence-of-make.html</guid><pubDate>Fri, 17 Apr 2015 00:00:00 +0000</pubDate></item><item><title>POPL Slides</title><link>https://bentnib.org/posts/2014-01-29-popl-slides.html</link><description>&lt;p&gt;I gave two talks at &lt;a href=&quot;http://popl.mpi-sws.org/2014/&quot;&gt;POPL 2014&lt;/a&gt;, back to back. This was pretty frightening beforehand, but seemed to go alright.&lt;/p&gt;&lt;p&gt;Here are the slides:&lt;/p&gt;&lt;h4&gt;From Parametricity to Conservation Laws, via Noether's Theorem&lt;/h4&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/docs/conservation-laws-20140124.pdf&quot;&gt;&lt;img alt=&quot;Thumbnail of slides for &amp;quot;From Parametricity to Conservation Laws, via Noether's Theorem&amp;quot; talk&quot; src=&quot;https://bentnib.org/thumbnails/slides-conservation-laws-20140124.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;A Relationally Parametric Model of Dependent Type Theory&lt;/h4&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/docs/dtt-parametricity-20140124.pdf&quot;&gt;&lt;img alt=&quot;Thumbnail of slides for &amp;quot;A Relationally Parametric Model of Dependent Type Theory&amp;quot;&quot; src=&quot;https://bentnib.org/thumbnails/slides-dtt-parametricity-20140124.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2014-01-29-popl-slides.html</guid><pubDate>Wed, 29 Jan 2014 00:00:00 +0000</pubDate></item><item><title>One Done, Two Submitted</title><link>https://bentnib.org/posts/2013-07-17-one-done-two-submitted.html</link><description>&lt;p&gt;One paper finished, two new ones submitted.&lt;/p&gt;&lt;h3&gt;Productive Coprogramming&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://personal.cis.strath.ac.uk/conor.mcbride&quot;&gt;Conor&lt;/a&gt; and I have just submitted the final version of &quot;Productive Coprogramming with Guarded Recursion&quot; to the publishers. Looking forward to ICFP in Boston!&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/productive.html&quot;&gt;&lt;img alt=&quot;Thumbnail of &amp;quot;Productive Coprogramming&amp;quot; paper&quot; src=&quot;https://bentnib.org/thumbnails/doc-productive.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Pair of Papers Pertaining to Parametricity&lt;/h3&gt;&lt;h4&gt;Dependent Types&lt;/h4&gt;&lt;p&gt;With &lt;a href=&quot;https://personal.cis.strath.ac.uk/neil.ghani&quot;&gt;Neil&lt;/a&gt; and &lt;a href=&quot;https://personal.cis.strath.ac.uk/patricia.johann&quot;&gt;Patty&lt;/a&gt;, we've constructed a relationally parametric model of impredicative and predicative dependent type theories. Highlights: &lt;em&gt;(1)&lt;/em&gt; we prove the existence of initial algebras for &lt;em&gt;all&lt;/em&gt; indexed functors; and *(2) the model is constructed using reflexive graphs, a kind of cut-down version of groupoids.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/dtt-parametricity.html&quot;&gt;&lt;img alt=&quot;Thumbnail of &amp;quot;A Relationally Parametric Model of Dependent Type Theory&amp;quot; paper&quot; src=&quot;https://bentnib.org/thumbnails/doc-dtt-parametricity.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;Classical Mechanics&lt;/h4&gt;&lt;p&gt;Just by myself, I've also done a paper on using relational parametricity to prove symmetry properties of Lagrangians in classical mechanics, so that you can derive conservation laws via Noether's theorem. The main point is to show that parametricity isn't just for computer programs; physics looks like it is ripe with opportunities for applications of theorems for free.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/conservation-laws.html&quot;&gt;&lt;img alt=&quot;Thumbnail of &amp;quot;From Parametricity to Conservation Laws, via Noether's Theorem&amp;quot; paper&quot; src=&quot;https://bentnib.org/thumbnails/doc-conservation-laws.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2013-07-17-one-done-two-submitted.html</guid><pubDate>Wed, 17 Jul 2013 00:00:00 +0000</pubDate></item><item><title>Productive Coprogramming with Guarded Recursion</title><link>https://bentnib.org/posts/2013-03-29-productive-coprogramming.html</link><description>&lt;p&gt;&lt;a href=&quot;https://personal.cis.strath.ac.uk/conor.mcbride/&quot;&gt;Conor McBride&lt;/a&gt; and I have just submitted a new paper to ICFP. In it, we attempt to use Nakano-style guarded recursion to write productive coprograms.&lt;/p&gt;&lt;p&gt;This is an elaboration of Conor's &lt;a href=&quot;http://www.e-pig.org/epilogue/?p=186&quot;&gt;blog post&lt;/a&gt; and the &lt;a href=&quot;https://bentnib.org/posts/2011-11-14-productive-programmer.html&quot;&gt;slides&lt;/a&gt; I posted here a while ago.&lt;/p&gt;&lt;p&gt;Here's a link to the paper, and the abstract:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/productive.html&quot;&gt;&lt;img alt=&quot;Productive Coprogramming with Guarded Recursion&quot; src=&quot;https://bentnib.org/thumbnails/doc-productive.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Total functional programming offers the beguiling vision that, just by virtue of the compiler accepting a program, we are guaranteed that it will always terminate. In the case of programs that are not intended to terminate, e.g., servers, we are guaranteed that programs will always be productive. Productivity means that, even if a program generates an infinite amount of data, each piece will generated in finite time. The theoretical underpinning for productive programming with infinite output is provided by the category theoretic notion of final coalgebras. Hence, we speak of coprogramming with non-well-founded codata, as a dual to programming with well-founded data like finite lists and trees.&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;Systems that offer facilities for productive coprogramming, such as the proof assistants Coq and Agda, currently do so through syntactic guardedness checkers. Syntactic guardedness checkers ensure that all self-recursive calls are guarded by a use of a constructor. Such a check ensures productivity. Unfortunately, these syntactic checks are not compositional, and severely complicate coprogramming.&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;p&gt;Guarded recursion, originally due to Nakano, is tantalising as a basis for a flexible and compositional type-based approach to coprogramming. However, as we show, by itself, guarded recursion is not suitable for coprogramming due to the fact that there is no way make finite observations on pieces of infinite data. In this paper, we introduce the concept of &lt;em&gt;clock variables&lt;/em&gt; that index Nakano’s guarded recursion. Clock variables allow us to ``close over’’ the generation of infinite data, and to make finite observations, something that is not possible with guarded recursion alone.&lt;/p&gt;&lt;/blockquote&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2013-03-29-productive-coprogramming.html</guid><pubDate>Fri, 29 Mar 2013 00:00:00 +0000</pubDate></item><item><title>Abstraction and Invariance for Algebraically Indexed Types</title><link>https://bentnib.org/posts/2012-11-07-algebraically-indexed-types.html</link><description>&lt;p&gt;&lt;a href=&quot;https://personal.cis.strath.ac.uk/patricia.johann/&quot;&gt;Patricia Johann&lt;/a&gt;, &lt;a href=&quot;http://research.microsoft.com/en-us/um/people/akenn/&quot;&gt;Andrew Kennedy&lt;/a&gt; and I have a new paper that will be presented at POPL in January! This paper is an extension of Andrew's POPL'97 paper on interpreting dimension types in terms of scaling invariance. Here's a link to the paper and the abstract:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/algebraic-indexed.html&quot;&gt;&lt;img alt=&quot;Thumbnail of paper &amp;quot;Abstraction and Invariance for Algebraically Indexed Types&quot; src=&quot;https://bentnib.org/thumbnails/doc-algebraic-indexed.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Reynolds' relational parametricity provides a powerful way to reason about programs in terms of invariance under changes of data representation. A dazzling array of applications of Reynolds' theory exists, exploiting invariance to yield “free theorems”, non-inhabitation results, and encodings of algebraic datatypes. Outside computer science, invariance is a common theme running through many areas of mathematics and physics. For example, the area of a triangle is unaltered by rotation or flipping. If we scale a triangle, then we scale its area, maintaining an invariant relationship between the two. The transformations under which properties are invariant are often organised into groups, with the algebraic structure reflecting the composability and invertibility of transformations.&lt;/p&gt;&lt;p&gt;In this paper, we investigate programming languages whose types are indexed by algebraic structures such as groups of geometric transformations. Other examples include types indexed by principals--for information flow security--and types indexed by distances--for analysis of analytic uniform continuity properties. Following Reynolds, we prove a general Abstraction Theorem that covers all these instances. Consequences of our Abstraction Theorem include free theorems expressing invariance properties of programs, type isomorphisms based on invariance properties, and non-definability results indicating when certain algebraically indexed types are uninhabited or only inhabited by trivial programs.  We have fully formalised our framework and most examples in Coq.&lt;/p&gt;&lt;/blockquote&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2012-11-07-algebraically-indexed-types.html</guid><pubDate>Wed, 07 Nov 2012 00:00:00 +0000</pubDate></item><item><title>Theorems for Free</title><link>https://bentnib.org/posts/2012-11-07-theorems-for-free.html</link><description>&lt;p&gt;I gave a talk last night at the &lt;a href=&quot;http://www.edlambda.co.uk&quot;&gt;Ed Lambda&lt;/a&gt;, the Edinburgh functional programming meetup, on “Theorems for Free”. This was (I hope) a fairly high-level talk about how free theorems are derived, and some extensions to other kinds of polymorphism that I've worked on recently. Here are the slides I used:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/docs/theorems-for-free-20121106.pdf&quot;&gt;&lt;img alt=&quot;Slides for &amp;quot;Theorems for free!&amp;quot; talk&quot; src=&quot;https://bentnib.org/thumbnails/slides-theorems-for-free-20121106.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I didn't include much in the way of references to the literature in the talk, but the main paper to look at if you are interested is Phil Wadler's classic &lt;a href=&quot;http://homepages.inf.ed.ac.uk/wadler/papers/free/free.ps&quot;&gt;Theorems for Free!&lt;/a&gt; (warning: PostScript!).&lt;/p&gt;&lt;p&gt;Thanks for Rob Stewart for organising things!&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2012-11-07-theorems-for-free.html</guid><pubDate>Wed, 07 Nov 2012 00:00:00 +0000</pubDate></item><item><title>Interleaving Data and Effects</title><link>https://bentnib.org/posts/2012-09-06-interleaving-data-and-effects.html</link><description>&lt;p&gt;Patricia Johann, Neil Ghani, Bart Jacobs and myself have just submitted a paper on interleaving pure data types with effects. This is a much more detailed version of the &lt;a href=&quot;https://bentnib.org/posts/2012-01-06-streams.html&quot;&gt;blog post&lt;/a&gt; I wrote back in January on reasoning about stream processing with effects.&lt;/p&gt;&lt;p&gt;Here is the abstract:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;The study of programming with and reasoning about inductive datatypes such as lists and trees has benefited from the simple categorical principle of initial algebras. In initial algebra semantics, each inductive datatype is represented by an initial &lt;em&gt;f&lt;/em&gt;-algebra for an appropriate functor &lt;em&gt;f&lt;/em&gt;. The initial algebra principle then supports the straightforward derivation of definitional principles and proof principles for these datatypes. This technique has been expanded to a whole methodology of structured functional programming, often called origami programming.&lt;/p&gt;&lt;p&gt;In this article, we show how to extend initial algebra semantics from pure inductive datatypes to inductive datatypes interleaved with computational effects. Inductive datatypes interleaved with effects arise naturally in many computational settings. For example, incrementally reading characters from a file generates a list of characters interleaved with input/output actions. Straightforward application of initial algebra techniques to effectful datatypes leads to unnecessarily complicated reasoning, because the pure and effectful concerns must be considered simultaneously. We show how these concerns can be separated the abstraction of initial &lt;em&gt;f&lt;/em&gt;-and-&lt;em&gt;m&lt;/em&gt;-algebras, where the functor &lt;em&gt;f&lt;/em&gt; describes the pure part of a datatype, and the monad &lt;em&gt;m&lt;/em&gt; describes the interleaved effects. Because initial &lt;em&gt;f&lt;/em&gt;-and-&lt;em&gt;m&lt;/em&gt;-algebras are the analogue for the effectful setting of initial &lt;em&gt;f&lt;/em&gt;-algebras, they support the extension of the standard definitional and proof principles to the effectful setting. Because initial &lt;em&gt;f&lt;/em&gt;-and-&lt;em&gt;m&lt;/em&gt;-algebras separate pure and effectful concerns, they support the direct transfer of definitions and proofs from the pure setting to the effectful setting.&lt;/p&gt;&lt;p&gt;Initial &lt;em&gt;f&lt;/em&gt;-and-&lt;em&gt;m&lt;/em&gt;-algebras are originally due to Filinski and Støvring, and were subsequently generalised to arbitrary categories by the authors of this article. In this article, we aim to introduce the concept of initial &lt;em&gt;f&lt;/em&gt;-and-&lt;em&gt;m&lt;/em&gt;-algebras to a general functional programming audience.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;The actual paper is available &lt;a href=&quot;https://bentnib.org/interleaving.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2012-09-06-interleaving-data-and-effects.html</guid><pubDate>Thu, 06 Sep 2012 00:00:00 +0000</pubDate></item><item><title>Relational Parametricity for Higher Kinds</title><link>https://bentnib.org/posts/2012-09-05-relational-parametricity-for-higher-kinds.html</link><description>&lt;p&gt;I just gave a talk at CSL 2012 on &quot;Relational Parametricity for Higher Kinds&quot;. In the paper I explain how to extend the usual relationally parametric models of polymorphic types to handle higher kinded types, like the ones found in Haskell and Scala. As a consequence, you get encodings of things like equality types, higher-kinded existential types and higher-kinded initial algebras, with nice reasoning principles.&lt;/p&gt;&lt;p&gt;The slides:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/docs/relparamfomega-csl2012-slides.pdf&quot;&gt;&lt;img alt=&quot;Thumbnail of slides for &amp;quot;Relational Parametricity for Higher Kinds&amp;quot; talk&quot; src=&quot;https://bentnib.org/thumbnails/slides-relparamfomega-csl2012-slides.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The paper, with abstract, is available &lt;a href=&quot;https://bentnib.org/fomega-parametricity.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2012-09-05-relational-parametricity-for-higher-kinds.html</guid><pubDate>Wed, 05 Sep 2012 00:00:00 +0000</pubDate></item><item><title>Reasoning about Stream Processing with Effects</title><link>https://bentnib.org/posts/2012-01-06-streams.html</link><description>&lt;p&gt;It is a truth, universally acknowledged, that any programming technique must be in want of a reasoning principle.&lt;/p&gt;&lt;p&gt;Stream processing in Haskell is very much in the air at the moment, what with &lt;a href=&quot;http://okmij.org/ftp/Streams.html&quot;&gt;Iteratees&lt;/a&gt; (as embodied in the &lt;a href=&quot;http://hackage.haskell.org/package/enumerator&quot;&gt;Enumerator&lt;/a&gt; library), &lt;a href=&quot;http://www.yesodweb.com/blog/2012/01/conduits-conduits&quot;&gt;Conduits&lt;/a&gt; and probably some more that I don't know about.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://personal.cis.strath.ac.uk/~patricia&quot;&gt;Patty Johann&lt;/a&gt;, &lt;a href=&quot;http://personal.cis.strath.ac.uk/~ng&quot;&gt;Neil Ghani&lt;/a&gt;, &lt;a href=&quot;http://www.cs.ru.nl/~bart/&quot;&gt;Bart Jacobs&lt;/a&gt; and I have recently had the paper &lt;a href=&quot;https://bentnib.org/induction-with-effects.html&quot;&gt;&quot;Fibrational Induction Meets Effects&quot;&lt;/a&gt; accepted to &lt;a href=&quot;http://www.itu.dk/research/fossacs-2012/&quot;&gt;FoSSaCS 2012&lt;/a&gt; that turns out to be very relevant to discussing and reasoning about the kinds of stream processing problems that these Haskell libraries seek to resolve.&lt;/p&gt;&lt;p&gt;In the paper we build upon the work of &lt;a href=&quot;http://www.diku.dk/hjemmesider/ansatte/stovring/papers/icfp07.pdf&quot;&gt;Andrzej Filinski and Kristian Støvring&lt;/a&gt; on induction principles for data structures that interleave pure data with effects, where the effects are defined in terms of some monad. Filinski and Støvring gave a induction principle for such interleaved effectful data types in a small programming language with effects and fixed notion of data type and predicate. In our FoSSaCS paper, we have generalised this to a more general categorical setting, and also generalised the notion of predicate that can be considered (so you can have proof-relevant predicates, or Kripke predicates, for instance).&lt;/p&gt;&lt;p&gt;Our paper is quite technical, since we need the structure of fibrations and so on to properly attain the right level of generality. Nevertheless, the core principle is a relatively simple and revolves around a recursion scheme for pure data interleaved with monadic effects (which generalises the one given by Filinski and Støvring). This turns out to have direct application to reasoning about the processing of streaming data.&lt;/p&gt;&lt;h3&gt;Effectful Streams&lt;/h3&gt;&lt;p&gt;Effectful streams generate potentially infinite amounts of data by executing effects as they do so. For example, an effectful stream may produce data by reading it from a network socket. An effectful stream is nothing more than an interleaving of some monad &quot;&lt;code&gt;m&lt;/code&gt;&quot; with news of whether the stream has stopped or has yielded an element. This can be expressed by the following Haskell declarations of a pair of mutually recursive types:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;newtype Stream m a = Stream { forceStream :: m (StreamStep m a) }

data StreamStep m a
    = StreamEmit a (Stream m a)
    | StreamStop
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Constructing streams with no (new) effects is accomplished by just using the &lt;code&gt;return&lt;/code&gt; of our chosen monad, and the appropriate constructor:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;nil :: Monad m =&gt; Stream m a
nil = Stream $ return StreamStop

cons :: Monad m =&gt; a -&gt; Stream m a -&gt; Stream m a
cons a s = Stream $ return (StreamEmit a s)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Given a value &lt;code&gt;stream&lt;/code&gt; of type &lt;code&gt;Stream m a&lt;/code&gt; we can kick it with &lt;code&gt;forceStream&lt;/code&gt; to give us a monadic action that will yield either &lt;code&gt;StreamEmit a moreStream&lt;/code&gt; or &lt;code&gt;StreamStop&lt;/code&gt;. The stream gets to execute some effect in the monad &lt;code&gt;m&lt;/code&gt; before telling us whether the stream has ended or not. It can use this monadic effect to do things like read from files, consult random number sources or use it as a side channel to report errors.&lt;/p&gt;&lt;p&gt;The stream &lt;code&gt;append&lt;/code&gt; function shows how a stream can be interrogated by a recursive function:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;append :: Monad m =&gt; Stream m a -&gt; Stream m a -&gt; Stream m a
append s1 s2 = Stream $ do
  streamStep &amp;lt;- forceStream s1
  case streamStep of
    StreamEmit a s1' -&gt; forceStream (cons a (append s1' s2))
    StreamStop       -&gt; forceStream s2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Streams look a lot like normal Haskell lists, except that rather than the ambient Haskell effect of &quot;possibly a non-terminating black hole&quot;, we have the effects described by the monad &lt;code&gt;m&lt;/code&gt; (plus the non-optional &quot;possibly a non-terminating black hole&quot; effect). For instance, we can define a stream that emits characters read from a &lt;code&gt;Handle&lt;/code&gt; until it hits the end of file:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ofHandle :: Handle -&gt; Stream IO Char
ofHandle handle = loop
  where
    loop = Stream $ do
      isEOF &amp;lt;- hIsEOF handle
      if isEOF then do hClose handle
                       return StreamStop
               else do c &amp;lt;- hGetChar handle
                       return (StreamEmit c loop)
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Stream Readers&lt;/h3&gt;&lt;p&gt;&lt;code&gt;Stream&lt;/code&gt;s constitute the supply-side of data processing. We can use a similar pattern to treat the consumption side. &lt;code&gt;Reader&lt;/code&gt;s are defined as follows, and look very similar to &lt;a href=&quot;http://okmij.org/ftp/Streams.html&quot;&gt;Iteratees&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;newtype Reader a m b = Reader { forceReader :: m (ReaderStep a m b) }

data ReaderStep a m b
    = ReaderRead (Maybe a -&gt; Reader a m b)
    | ReaderEmit b
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Similar to &lt;code&gt;Stream&lt;/code&gt;s, a value of type &lt;code&gt;Reader a m b&lt;/code&gt; can be prodded with &lt;code&gt;forceReader&lt;/code&gt;. It will then tell us (after some monadic effect) whether it wants to read some data (&lt;code&gt;ReaderRead&lt;/code&gt;) or if it has finished reading and wants to output some data (&lt;code&gt;ReaderEmit&lt;/code&gt;). The &lt;code&gt;Maybe&lt;/code&gt; type constructor in &lt;code&gt;ReaderRead&lt;/code&gt; is intended to indicate whether or not end-of-stream has been reached.&lt;/p&gt;&lt;p&gt;The obvious thing to do now is to connect up a &lt;code&gt;Stream&lt;/code&gt; and a &lt;code&gt;Reader&lt;/code&gt; to feed the data from one into the other. There are actually (at least) two different ways of doing this, depending on whether we execute the effects of the stream before the reader, or the other way round. Executing the stream before the reader gives the following definition:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(|&gt;|) :: Monad m =&gt; Stream m a -&gt; Reader a m b -&gt; m b
s |&gt;| r = do
    streamStep &amp;lt;- forceStream s
    case streamStep of
      StreamEmit a s' -&gt; do
        readerStep &amp;lt;- forceReader r
        case readerStep of
          ReaderRead k -&gt; s' |&gt;| k (Just a)
          ReaderEmit b -&gt; return b
      StreamStop -&gt; do
        runOnNothing r
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the stream stops early by returning &lt;code&gt;StreamStop&lt;/code&gt;, then we use the following function &lt;code&gt;runOnNothing&lt;/code&gt; to feed &lt;code&gt;Nothing&lt;/code&gt; to a &lt;code&gt;Reader&lt;/code&gt; until it yields a value:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;runOnNothing :: Monad m =&gt; Reader a m b -&gt; m b
runOnNothing r = do
    readerStep &amp;lt;- forceReader r
    case readerStep of
      ReaderRead k -&gt; runOnNothing (k Nothing)
      ReaderEmit b -&gt; return b
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Generic Interleaved Data and A Recursion Scheme&lt;/h3&gt;&lt;p&gt;I will now show that the &lt;code&gt;Stream&lt;/code&gt; and &lt;code&gt;Reader&lt;/code&gt; types may be generalised to a common pattern. By exploiting this common pattern, we obtain a powerful recursion principle for data interleaved with effects. This recursion principle also comes equipped with a reasoning principle, which allows us to prove things about functions that recurse over data interleaved with effects.&lt;/p&gt;&lt;p&gt;The common shape of the &lt;code&gt;Stream&lt;/code&gt; and &lt;code&gt;Reader&lt;/code&gt; types is captured by the following pair of Haskell type declarations. All the parts specific to &lt;code&gt;Stream&lt;/code&gt;s or &lt;code&gt;Reader&lt;/code&gt;s have been abstracted out into the argument &lt;code&gt;f :: * -&gt; *&lt;/code&gt; (which we will assume is an instance of the &lt;code&gt;Functor&lt;/code&gt; type class).&lt;/p&gt;&lt;pre&gt;&lt;code&gt;data Step m f = Step (f (D m f))

newtype D m f = D { force :: m (Step m f) }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A value of type &lt;code&gt;D m f&lt;/code&gt; is therefore an interleaving of the effects described by &lt;code&gt;m&lt;/code&gt; with the pure data described by &lt;code&gt;f&lt;/code&gt;. The function &lt;code&gt;force&lt;/code&gt; plays the part of the &lt;code&gt;forceStream&lt;/code&gt; and &lt;code&gt;forceReader&lt;/code&gt; functions defined above.&lt;/p&gt;&lt;p&gt;Effectful data can be constructed and deconstructed by the following functions:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;construct :: Monad m =&gt; f (D m f) -&gt; D m f
construct x = D $ return (Step x)

deconstruct :: Monad m =&gt; D m f -&gt; m (f (D m f))
deconstruct d = do Step x &amp;lt;- force d
                   return x
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When using &lt;code&gt;deconstruct&lt;/code&gt; there may be some effects to execute before we get access to the underlying pure data described by &lt;code&gt;f&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;To recover the &lt;code&gt;Stream&lt;/code&gt; type, we simply define the appropriate &lt;code&gt;f&lt;/code&gt; to describe the two things that &lt;code&gt;Stream&lt;/code&gt;s are allowed to do: emit values and cease to be.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;data StreamStep a x
    = StreamEmit a x
    | StreamStop
    deriving Functor

type Stream m a = D m (StreamStep a)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the new &lt;code&gt;StreamStep&lt;/code&gt; type, the type parameter &lt;code&gt;x&lt;/code&gt; indicates the hole where the next step of the recursion is placed.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;nil&lt;/code&gt; and &lt;code&gt;cons&lt;/code&gt; constructors can then be defined in terms of &lt;code&gt;construct&lt;/code&gt; and the appropriate part of the &lt;code&gt;StreamStep&lt;/code&gt; type:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;nil :: Monad m =&gt; Stream m a
nil = construct StreamStop

cons :: Monad m =&gt; a -&gt; Stream m a -&gt; Stream m a
cons a s = construct (StreamEmit a s)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The benefit of re-expressing the &lt;code&gt;Stream&lt;/code&gt; type in this way is that we can now define a powerful recursion scheme on values of type &lt;code&gt;D m f&lt;/code&gt;, including &lt;code&gt;Stream m a&lt;/code&gt;, and use this to define functions like &lt;code&gt;append&lt;/code&gt; and &lt;code&gt;(|&gt;|)&lt;/code&gt;. The interesting part is that this recursion scheme comes equipped with a reasoning principle, which allows us to prove things about our functions. To properly define the recursion scheme we first need to know what an Eilenberg-Moore algebra for a monad is.&lt;/p&gt;&lt;h4&gt;Eilenberg-Moore Algebras&lt;/h4&gt;&lt;p&gt;For any monad &lt;code&gt;m&lt;/code&gt;, an &lt;a href=&quot;http://en.wikipedia.org/wiki/Eilenberg-Moore_algebra#Algebras_for_a_monad&quot;&gt;&lt;code&gt;m&lt;/code&gt;-Eilenberg-Moore algebra&lt;/a&gt; consists of a pair of a type &lt;code&gt;a&lt;/code&gt; and a function &lt;code&gt;h :: m a -&gt; a&lt;/code&gt;, satisfying some laws that state that &lt;code&gt;h&lt;/code&gt; interacts nicely with the structure of the monad. I think of the existence of an Eilenberg-Moore algebra structure on &lt;code&gt;a&lt;/code&gt; as roughly stating that the type &lt;code&gt;a&lt;/code&gt; is effectful in the sense that it can have additional effects &quot;prepended&quot; on to it.&lt;/p&gt;&lt;p&gt;The existence of an Eilenberg-Moore algebra structure for a type can be expressed as a Haskell type class, &lt;code&gt;EMAlgebra&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class (Functor m, Monad m) =&gt; EMAlgebra m a where
    algebra :: m a -&gt; a
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Of course we cannot state the laws, so we shall just commit to promising that they hold. The type class mechanism also ties us to giving at most one Eilenberg-Moore structure for each pair of a monad &lt;code&gt;m&lt;/code&gt; and a type &lt;code&gt;a&lt;/code&gt;, where in fact there may be many, but this is a small price to pay for the convenience that type classes provide.&lt;/p&gt;&lt;p&gt;Every type of the form &lt;code&gt;m a&lt;/code&gt; for some monad &lt;code&gt;m&lt;/code&gt; is obviously effectful, so we can give it an Eilenberg-Moore algebra structure using the function &lt;code&gt;join :: m (m a) -&gt; m a&lt;/code&gt; defined in the &lt;code&gt;Control.Monad&lt;/code&gt; module:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;instance (Functor m, Monad m) =&gt; EMAlgebra m (m a) where
    algebra = join
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is the free Eilenberg-Moore algebra for the monad &lt;code&gt;m&lt;/code&gt; and the type &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;The property of having an Eilenberg-Moore algebra is also preserved by the construction of function types. If &lt;code&gt;b&lt;/code&gt; has an Eilenberg-Moore structure with respect to &lt;code&gt;m&lt;/code&gt;, then so does &lt;code&gt;a -&gt; b&lt;/code&gt; for any &lt;code&gt;a&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;annotation&quot;&gt;&lt;span class=&quot;time&quot;&gt;2012-01-07 13:15&lt;/span&gt; Unfortunately, this instance and the previous one overlap, so GHC needs &lt;code&gt;-XIncoherentInstances&lt;/code&gt; to handle it. This seems to work for the examples here, but probably a better solution is needed in general.  &lt;/div&gt;
&lt;pre&gt;&lt;code&gt;instance (EMAlgebra m b) =&gt; EMAlgebra m (a -&gt; b) where
    algebra x a = algebra $ do f &amp;lt;- x; return (f a)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, every one of our interleaved data and effects types carries a default Eilenberg-Moore structure, achieved by prepending the new effect before the first effect of the data:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;instance (Functor m, Monad m) =&gt; EMAlgebra m (D m f) where
    algebra x = D $ x &gt;&gt;= force
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that we now have two algebra structures on &lt;code&gt;D m f&lt;/code&gt;: the &lt;code&gt;m&lt;/code&gt;-Eilenberg-Moore structure defined here, and the &lt;code&gt;f&lt;/code&gt;-algebra structure defined by the &lt;code&gt;construct&lt;/code&gt; function above.&lt;/p&gt;&lt;div class=&quot;annotation&quot;&gt;&lt;span class=&quot;time&quot;&gt;2012-01-07 13:15&lt;/span&gt; Fixed a typo here, thanks to ehird in the comments below for spotting it.&lt;/div&gt;
&lt;h4&gt;A Recursion Scheme&lt;/h4&gt;&lt;p&gt;A basic recursion scheme is the &lt;em&gt;catamorphism&lt;/em&gt;, which allows us to eliminate an element of a recursive type &lt;code&gt;Rec f&lt;/code&gt; using an algebra &lt;code&gt;f a -&gt; a&lt;/code&gt;, where &lt;code&gt;Rec f&lt;/code&gt; is defined as follows:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;data Rec f = In (f (Rec f))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The catamorphism function, or to use its common name &lt;code&gt;fold&lt;/code&gt;, has the following type:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;fold :: Functor f =&gt; (f a -&gt; a) -&gt; Rec f -&gt; a
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A function of type &lt;code&gt;f a -&gt; a&lt;/code&gt; is the (structure part) of an &lt;code&gt;f&lt;/code&gt;-algebra. &lt;code&gt;f&lt;/code&gt;-algebras are similar to Eilenberg-Moore algebras, except that they do not need to satisfy any laws (because we do not assume that &lt;code&gt;f&lt;/code&gt; is a monad).&lt;/p&gt;&lt;p&gt;The &lt;code&gt;fold&lt;/code&gt; function itself satisfies the following law (which can also be taken to be the definition):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;fold h (In x) = h (fmap (fold h) x)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and is the &lt;em&gt;unique&lt;/em&gt; function of type &lt;code&gt;Rec f -&gt; a&lt;/code&gt; to do so. This uniqueness property can be used to reason about functions built from &lt;code&gt;fold&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;To define functions that eliminate our interleaved effects and data types &lt;code&gt;D m f&lt;/code&gt;, we could just use the fact that they are equivalent to the form &lt;code&gt;m (Rec (f :.: m))&lt;/code&gt;, where &lt;code&gt;- :.: -&lt;/code&gt; indicates composition of functors, and use &lt;code&gt;fold&lt;/code&gt; on the type &lt;code&gt;Rec (f :.: m)&lt;/code&gt;. However, in doing this we are forced to consider the pure and effectful parts of our data simultaneously.&lt;/p&gt;&lt;p&gt;A better approach, which is derivable from the basic &lt;code&gt;fold&lt;/code&gt; operator, is to eliminate values of type &lt;code&gt;D m f&lt;/code&gt; using &lt;code&gt;f&lt;/code&gt;-and-&lt;code&gt;m&lt;/code&gt;-algebras. That is, we assume that the result type &lt;code&gt;a&lt;/code&gt; has a an &lt;code&gt;f&lt;/code&gt;-algebra structure &lt;code&gt;f a -&gt; a&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; an Eilenberg-Moore structure &lt;code&gt;m a -&gt; a&lt;/code&gt;. In this way, we can separate the pure and effectful parts of our recursion. By making use of the &lt;code&gt;EMAlgebra&lt;/code&gt; type class defined above, we do not need to explicitly mention the effectful part at all.&lt;/p&gt;&lt;p&gt;Our new &lt;code&gt;effectfulFold&lt;/code&gt; combinator has the following type, and I have given the direct Haskell implementation. It is an interesting exercise to see now it can be defined in terms of the &lt;code&gt;fold&lt;/code&gt; combinator on &lt;code&gt;Rec (f :.: m)&lt;/code&gt;.&lt;/p&gt;&lt;div class=&quot;annotation&quot;&gt;&lt;span class=&quot;time&quot;&gt;2012-01-07 13:15&lt;/span&gt; Thanks to &lt;a href=&quot;http://www.reddit.com/r/haskell/comments/o5ioy/reasoning_about_stream_processing_with_effects/c3estki&quot;&gt;spacespacecomma&lt;/a&gt; on reddit for pointing out that the original definition here didn't type check. I was missing the applications of &lt;code&gt;force&lt;/code&gt;.&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;effectfulFold :: (Functor f, EMAlgebra m a) =&gt;
                 (f a -&gt; a)
              -&gt; D m f
              -&gt; a
effectfulFold h = algebra . fmap loop . force
  where
    loop (Step x) = 
      h $ fmap algebra $ fmap (fmap loop) $ fmap force $ x
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As we prove in the &lt;a href=&quot;https://bentnib.org/induction-with-effects.html&quot;&gt;paper&lt;/a&gt;, generalising Filinski and Støvring's proof, functions defined using &lt;code&gt;effectfulFold&lt;/code&gt; satisfy the following two properties. First, they preserve &lt;code&gt;f&lt;/code&gt;-algebras, taking the &lt;code&gt;f&lt;/code&gt;-algebra &lt;code&gt;construct&lt;/code&gt; to the supplied &lt;code&gt;f&lt;/code&gt;-algebra &lt;code&gt;h&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;effectfulFold h (construct x) = h (fmap (effectfulFold h) x)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Moreover, they preserve &lt;code&gt;m&lt;/code&gt;-Eilenberg-Moore algebras, taking the default Eilenberg-Moore structure on &lt;code&gt;D m f&lt;/code&gt; to the implicitly provided Eilenberg-Moore structure on &lt;code&gt;a&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;effectfulFold h (algebra x) = algebra (fmap (effectfulFold h) x)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Analogously to &lt;code&gt;fold h&lt;/code&gt;, &lt;code&gt;effectfulFold h&lt;/code&gt; is the &lt;em&gt;unique&lt;/em&gt; function satisfying these two properties. In the paper, we use uniqueness to derive an induction principle for data interleaved with monadic effects, but here we can use uniqueness directly to reason about functions defined using &lt;code&gt;effectfulFold&lt;/code&gt;.&lt;/p&gt;&lt;h4&gt;Using the Recursion Scheme&lt;/h4&gt;&lt;p&gt;The &lt;code&gt;append&lt;/code&gt; function on streams that I defined by hand above can be re-expressed using the &lt;code&gt;effectfulFold&lt;/code&gt; combinator:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;append :: (Functor m, Monad m) =&gt; Stream m a -&gt; Stream m a -&gt; Stream m a
append s1 s2 = effectfulFold h s1
  where h (StreamEmit a s) = cons a s
        h StreamStop       = s2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;By its definition in terms of &lt;code&gt;effectfulFold&lt;/code&gt; we know that &lt;code&gt;append&lt;/code&gt; preserves the Eilenberg-Moore structure on its first argument. This means that the following equation holds for &lt;code&gt;x :: m (Stream m a)&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;append (algebra x) s2 = algebra (fmap (\s -&gt; append s s2) x)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that &lt;code&gt;append&lt;/code&gt; does not preserve the Eilenberg-Moore structure on its second argument. The Eilenberg-Moore structure for streams prepends effects on to the stream, but these effects will not be executed by &lt;code&gt;append&lt;/code&gt; until &lt;em&gt;after&lt;/em&gt; all the effects in the first stream have been executed.&lt;/p&gt;&lt;p&gt;Also by its definition in terms of &lt;code&gt;effectfulFold&lt;/code&gt;, we know that &lt;code&gt;append&lt;/code&gt; satisfies the following equations with respect to the &quot;pure&quot; part of streams:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;append (construct StreamStop)        s2 = s2
append (construct (StreamEmit a s1)) s2 = construct (StreamEmit a (append s1 s2))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can now use the uniqueness of functions defined by &lt;code&gt;effectfulFold&lt;/code&gt; to see that &lt;code&gt;append&lt;/code&gt; is associative. To show this, I'll use the uniqueness of functions defined by &lt;code&gt;effectfulFold&lt;/code&gt;. We have two functions of type &lt;code&gt;Stream m a -&gt; Stream m a&lt;/code&gt; that we wish to prove equivalent:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;\s1 -&gt; append s1 (append s2 s3)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and&lt;/p&gt;&lt;pre&gt;&lt;code&gt;\s1 -&gt; append (append s1 s2) s3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where the first one is defined directly in terms of &lt;code&gt;effectfulFold&lt;/code&gt;. If we can show that the second function obeys the same properties as the first, i.e. that it preserves the &lt;code&gt;m&lt;/code&gt;-Eilenberg-Moore algebra and the &lt;code&gt;f&lt;/code&gt;-algebra used in the definition of &lt;code&gt;append&lt;/code&gt;, then by uniqueness we will have shown that they are the same function.&lt;/p&gt;&lt;p&gt;It is easy to check that the second function preserves the Eilenberg-Moore structure on &lt;code&gt;Stream m a&lt;/code&gt;, since it is just the composition of two functions that do so. So the meat of the proof is in showing that it preserves the &lt;code&gt;f&lt;/code&gt;-algebra structure. This splits into two cases, one for &lt;code&gt;StreamStop&lt;/code&gt; and one for &lt;code&gt;StreamEmit&lt;/code&gt;. For the former, we must show that&lt;/p&gt;&lt;pre&gt;&lt;code&gt;append (append (construct StreamStop) s2) s3 = append s2 s3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;but this follows directly from the properties we already know about &lt;code&gt;append&lt;/code&gt;. The second case is a little harder. We must show that&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  append (append (construct (StreamEmit a s1)) s2) s3
=
  construct (StreamEmit a (append (append s1 s2) s3))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This follows by repeated application of our knowledge about how &lt;code&gt;append&lt;/code&gt; operates on input of the form &lt;code&gt;construct (StreamEmit a s1)&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Thus we have used the uniqueness property of functions defined using &lt;code&gt;effectfulFold&lt;/code&gt; to show that &lt;code&gt;append&lt;/code&gt; is associative.&lt;/p&gt;&lt;h3&gt;Back to Readers&lt;/h3&gt;&lt;p&gt;Just as the &lt;code&gt;Stream&lt;/code&gt; type can be defined in terms of the generic &lt;code&gt;D m f&lt;/code&gt; type, the &lt;code&gt;Reader&lt;/code&gt; type can be defined in the same way:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;data ReaderStep a b x
    = ReaderRead (Maybe a -&gt; x)
    | ReaderEmit b
    deriving Functor

type Reader a m b = D m (ReaderStep a b)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;runOnNothing&lt;/code&gt; function can be defined in terms of &lt;code&gt;effectfulFold&lt;/code&gt;, by recursing on the &lt;code&gt;Reader&lt;/code&gt; argument:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;runOnNothing :: (Functor m, Monad m) =&gt; Reader a m b -&gt; m b
runOnNothing = effectfulFold f
  where f (ReaderRead k) = k Nothing
        f (ReaderEmit b) = return b
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Likewise, the &lt;code&gt;(|&gt;|)&lt;/code&gt; function that connects a stream with a reader can be defined in terms of &lt;code&gt;effectfulFold&lt;/code&gt;, by recursion on the stream argument, and using the Eilenberg-Moore structure on the type &lt;code&gt;Reader a m b -&gt; m b&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(|&gt;|) :: (Monad m, Functor m) =&gt; Stream m a -&gt; Reader a m b -&gt; m b
(|&gt;|) = effectfulFold f
  where f (StreamEmit a h) r = do
          readerStep &amp;lt;- deconstruct r
          case readerStep of
            ReaderRead k -&gt; h (k (Just a))
            ReaderEmit b -&gt; return b
        f StreamStop r = runOnNothing r
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;(|&gt;|)&lt;/code&gt; function executes the effects of the stream before the effects of the reader, letting the stream dictate how events proceed. An alternative is to execute the effects of the reader first, by defining the function in terms of recursion on the reader argument, again using &lt;code&gt;effectfulFold&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(|&gt;&gt;|) :: (Monad m, Functor m) =&gt; Stream m a -&gt; Reader a m b -&gt; m b
s |&gt;&gt;| r = effectfulFold f r s
  where f (ReaderRead k) s = do
            streamStep &amp;lt;- deconstruct s
            case streamStep of
              StreamEmit a s' -&gt; k (Just a) s'
              StreamStop      -&gt; k Nothing nil
        f (ReaderEmit b) s = return b
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There are obviously many other possibilities for connecting &lt;code&gt;Stream&lt;/code&gt;s to &lt;code&gt;Reader&lt;/code&gt;s. If the &lt;code&gt;Stream&lt;/code&gt; finishes early, we could return the uncompleted &lt;code&gt;Reader&lt;/code&gt; rather than passing it on to &lt;code&gt;runOnNothing&lt;/code&gt;. Likewise, if the &lt;code&gt;Reader&lt;/code&gt; emits a value before all the &lt;code&gt;Stream&lt;/code&gt; has been read, we could return the leftover stream instead of just dropping it on the floor. In any case, all these possibilities are definable in terms of &lt;code&gt;effectfulFold&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;code&gt;Reader&lt;/code&gt;s are an instance of the &lt;code&gt;Monad&lt;/code&gt; type class as the following Haskell declaration witnesses:&lt;/p&gt;&lt;div class=&quot;annotation&quot;&gt;&lt;span class=&quot;time&quot;&gt;2012-01-07 13:15&lt;/span&gt; Thanks again to &lt;a href=&quot;http://www.reddit.com/r/haskell/comments/o5ioy/reasoning_about_stream_processing_with_effects/c3estki&quot;&gt;spacespacecomma&lt;/a&gt; on reddit for pointing out that this doesn't directly work. You need to wrap the &lt;code&gt;Reader&lt;/code&gt; type in a &lt;code&gt;newtype&lt;/code&gt; to get it to work. I'll leave it as-is to give the general idea.&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;instance Monad m =&gt; Monad (Reader a m) where
    return b = construct (ReaderEmit b)
    c &gt;&gt;= k  = effectfulFold f c
        where f (ReaderRead k) = construct (ReaderRead k)
              f (ReaderEmit b) = k b
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Using the uniqueness property of &lt;code&gt;effectfulFold&lt;/code&gt; it is possible to prove that this instance really does satisfy the monads laws. In fact, it is possible to show that &lt;code&gt;Reader a m&lt;/code&gt; is the sum of the monad &lt;code&gt;m&lt;/code&gt; with the free monad on the functor &lt;code&gt;f x = Maybe a -&gt; x&lt;/code&gt;. This is an instance of a fact originally observed by &lt;a href=&quot;http://homepages.inf.ed.ac.uk/gdp/publications/Comb_Effects_Jour.pdf&quot;&gt;Hyland, Plotkin and Power&lt;/a&gt; (Theorem 4).&lt;/p&gt;&lt;h3&gt;Processors&lt;/h3&gt;&lt;p&gt;If &lt;code&gt;Stream&lt;/code&gt;s produce data and &lt;code&gt;Reader&lt;/code&gt;s consume data, then what goes in between? &lt;code&gt;Processor&lt;/code&gt;s! A &lt;code&gt;Processor&lt;/code&gt; is an instance of the same interleaved data and effects pattern as &lt;code&gt;Stream&lt;/code&gt;s and &lt;code&gt;Reader&lt;/code&gt;s:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;data ProcessorStep a b x
    = ProcessorRead (Maybe a -&gt; x)
    | ProcessorEmit b x
    | ProcessorStop

type Processor a m b = D m (ProcessorStep a b)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A &lt;code&gt;Processor&lt;/code&gt;, once kicked using &lt;code&gt;force&lt;/code&gt;, can either ask for more input (&lt;code&gt;ProcessorRead&lt;/code&gt;), can emit some output (&lt;code&gt;ProcessorEmit&lt;/code&gt;) with a promise to carry on, or can signal end of stream (&lt;code&gt;ProcessorStop&lt;/code&gt;). &lt;code&gt;Processor&lt;/code&gt;s are intended to fulfil the same role as &lt;code&gt;Enumeratees&lt;/code&gt; or &lt;code&gt;Conduit&lt;/code&gt;s as intermediaries that manipulate data in some way. They are also very similar to the StreamProcessor representation defined by &lt;a href=&quot;http://personal.cis.strath.ac.uk/~ng/papers/ghani-lmcs09.pdf&quot;&gt;Ghani, Hancock and Pattinson&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;With a few helper functions:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;processorRead :: Monad m =&gt; (Maybe a -&gt; Processor a m b) -&gt; Processor a m b
processorRead k = construct (ProcessorRead k)

processorStop :: Monad m =&gt; Processor a m b
processorStop = construct ProcessorStop

processorEmit :: Monad m =&gt; b -&gt; Processor a m b -&gt; Processor a m b
processorEmit b proc = construct (ProcessorEmit b proc)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;we can define a processor that filters:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;filter :: Monad m =&gt; (a -&gt; Maybe b) -&gt; Processor a m b
filter h = processorRead getInput
  where
    getInput Nothing  = processorStop
    getInput (Just a) =
      case h a of
        Nothing -&gt; filter h
        Just a  -&gt; processorEmit a (filter h)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is also possible to define several combinators that compose &lt;code&gt;Stream&lt;/code&gt;s with &lt;code&gt;Processor&lt;/code&gt;s, &lt;code&gt;Processor&lt;/code&gt;s with &lt;code&gt;Reader&lt;/code&gt;s and &lt;code&gt;Processor&lt;/code&gt;s with &lt;code&gt;Processor&lt;/code&gt;s in a similar manner to the &lt;a href=&quot;http://www.yesodweb.com/blog/2012/01/conduits-conduits&quot;&gt;Conduits library&lt;/a&gt;. We have same choices as with the composition of &lt;code&gt;Stream&lt;/code&gt;s and &lt;code&gt;Reader&lt;/code&gt;s in terms of the ordering of effects. The key point is that they may all be defined in terms of &lt;code&gt;effectfulFold&lt;/code&gt;, and reasoned about using the universal property. For instance, we can prove that composition of &lt;code&gt;Processor&lt;/code&gt;s is associative, which opens the door to justified optimisation principles for chains of stream processors.&lt;/p&gt;&lt;h4&gt;The Co-Inductive View&lt;/h4&gt;&lt;p&gt;In the above I have taken an inductive view on &lt;code&gt;Stream&lt;/code&gt;s, &lt;code&gt;Reader&lt;/code&gt;s and so on. In Haskell, each recursive type is simultaneously an inductive and co-inductive type. We can use this change-of-viewpoint to give another way of defining interleaved data and effects in terms of unfolds. The following function &lt;code&gt;unfold&lt;/code&gt; takes a seed state of type &lt;code&gt;s&lt;/code&gt; and an evolution function of type &lt;code&gt;s -&gt; m (f s)&lt;/code&gt; and generates a value of type &lt;code&gt;D m f&lt;/code&gt;.&lt;/p&gt;&lt;div class=&quot;annotation&quot;&gt;&lt;span class=&quot;time&quot;&gt;2012-01-07 13:15&lt;/span&gt; Was missing an additional
&lt;code&gt;Monad m&lt;/code&gt; constraint here.&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;unfold :: (Monad m, Functor f) =&gt; s -&gt; (s -&gt; m (f s)) -&gt; D m f
unfold s step = loop s
  where loop s = D $ do
    f &amp;lt;- step s
    return (Step (fmap loop f))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;ofHandle&lt;/code&gt; stream defined above can be re-expressed in terms of &lt;code&gt;unfold&lt;/code&gt; as follows:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ofHandle :: Handle -&gt; Stream IO Char
ofHandle handle = unfold () step
  where
    step () = do
      isEOF &amp;lt;- hIsEOF handle
      if isEOF then do hClose handle
                       return StreamStop
               else do c &amp;lt;- hGetChar handle
                       return (StreamEmit c ())
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In fact, we could change the representation of our interleaved data and effect type to be directly expressed in terms of &lt;code&gt;unfolds&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;data D m f where
    D :: s -&gt; (s -&gt; m (f s)) -&gt; D m f
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This representation makes it harder to define the &lt;code&gt;effectfulFold&lt;/code&gt; function and its associated reasoning principle. On the other hand, it does allow for fusion of chained sequences of &lt;code&gt;Stream&lt;/code&gt;s, &lt;code&gt;Processor&lt;/code&gt;s and &lt;code&gt;Reader&lt;/code&gt;s in a similar manner to the &lt;a href=&quot;http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.104.7401&quot;&gt;Stream Fusion&lt;/a&gt; (&lt;a href=&quot;http://dl.acm.org/citation.cfm?id=1291199&quot;&gt;alternative ACM paywall link&lt;/a&gt;) paper. Hopefully, this may allow for sequences of stream processing functions to be fused together and open up more possibilities for optimisation. But this remains to be seen.&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2012-01-06-streams.html</guid><pubDate>Fri, 06 Jan 2012 00:00:00 +0000</pubDate></item><item><title>A Type Checker that knows its Monad from its Elbow</title><link>https://bentnib.org/posts/2011-12-14-type-checker.html</link><description>&lt;p&gt;I've been hacking a bit on &lt;a href=&quot;https://github.com/bobatkey/foveran&quot;&gt;Foveran&lt;/a&gt; lately. The main new thing that I've added is the integration of the monad laws and functor laws into the definitional equality. These additions were inspired by some suggestions of Conor, and a post on &lt;a href=&quot;http://www.e-pig.org/epilogue/?p=504&quot;&gt;Epilogue&lt;/a&gt; by Pierre from some time back. I've taken a different implementation approach to the one sketched in that blog post. The scheme I am using is Filinski's &lt;a href=&quot;http://www.diku.dk/hjemmesider/ansatte/andrzej/papers/NbEftCLC-abstract.html&quot;&gt;normalisation by evaluation for the computational lambda-calculus&lt;/a&gt;, with some little extensions.&lt;/p&gt;&lt;h3&gt;Descriptions of Indexed Functors form a (Relative) Monad&lt;/h3&gt;&lt;p&gt;To describe (most of) its own data-types, Foveran implements the indexed descriptions (&lt;code&gt;IDesc&lt;/code&gt;) data-type from the paper &lt;a href=&quot;http://personal.cis.strath.ac.uk/~dagand/papers/levitation.pdf&quot;&gt;The Gentle Art of Levitation&lt;/a&gt;. Objects of type &lt;code&gt;IDesc I&lt;/code&gt; are codes for functors from &lt;code&gt;(I -&gt; Set)&lt;/code&gt; to &lt;code&gt;Set&lt;/code&gt;, where &lt;code&gt;I&lt;/code&gt; is a &lt;code&gt;Set&lt;/code&gt;. The &lt;code&gt;IDesc I&lt;/code&gt; type has the following constructors:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;“IId” : I -&gt; IDesc I
“K”   : Set -&gt; IDesc I
_“×”_ : IDesc I -&gt; IDesc I -&gt; IDesc I
“Sg”  : (A : Set) -&gt; (A -&gt; IDesc I) -&gt; IDesc I
“Pi”  : (A : Set) -&gt; (A -&gt; IDesc I) -&gt; IDesc I
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The codes are all given their actual meanings by the &lt;code&gt;semI&lt;/code&gt; operator I'll talk about below. But without really thinking about what the codes mean, one can easily see that there is a natural substitution operation on &lt;code&gt;IDesc&lt;/code&gt;s, simply because an object &lt;code&gt;D : IDesc I&lt;/code&gt; is really just a &lt;a href=&quot;http://blog.sigfpe.com/2010/01/monads-are-trees-with-grafting.html&quot;&gt;tree with holes&lt;/a&gt; labelled with &lt;code&gt;I&lt;/code&gt;s where the &lt;code&gt;“IId”&lt;/code&gt;s are. Such a substitution operation would have type:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;bind : (I J : Set) -&gt; IDesc I -&gt; (I -&gt; IDesc J) -&gt; IDesc J
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is pretty easy to implement: just recurse down the first &lt;code&gt;IDesc I&lt;/code&gt; argument until you hit an &lt;code&gt;“IId” i&lt;/code&gt; and then apply the &lt;code&gt;i&lt;/code&gt; to the provided function. If I just implement &lt;code&gt;bind&lt;/code&gt;, though, the type checker doesn't get to know that it satisfies the (relative) monad laws. (Side note: &lt;code&gt;IDesc&lt;/code&gt; itself has type &lt;code&gt;Set -&gt; Set 1&lt;/code&gt;, so it is a &lt;a href=&quot;http://www.cs.ioc.ee/~james/papers/Relative_Monads.pdf&quot;&gt;relative monad&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;So I've built-in the &lt;code&gt;bind&lt;/code&gt; operation into the Foveran system and given it the following syntax:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;bind x &amp;lt;- D1 in D2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where &lt;code&gt;x&lt;/code&gt; is bound in &lt;code&gt;D2&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;When the Foveran type checker normalises terms of type &lt;code&gt;IDesc I&lt;/code&gt;, it knows that they have one of two kinds of normal form: either they are constructed from one of the constructors above, and all the sub-&lt;code&gt;IDesc I&lt;/code&gt;s are in normal form; or they are of the form &lt;code&gt;bind x &amp;lt;- D1 in D2&lt;/code&gt; where &lt;code&gt;D1&lt;/code&gt; is stuck and &lt;code&gt;D2&lt;/code&gt; is in normal form. By representing all objects of type &lt;code&gt;IDesc I&lt;/code&gt; in this way, the normaliser is able to normalise terms up to the monad laws, as I'll now demonstrate.&lt;/p&gt;&lt;p&gt;If the normaliser is given a variable &lt;code&gt;D : IDesc I&lt;/code&gt; with no definition, or some other stuck term, then its normal form is &lt;code&gt;bind x &amp;lt;- D in “IId” x&lt;/code&gt;. So I automatically get the right-unit law for (relative) monads to hold definitionally in the Foveran type theory.&lt;/p&gt;&lt;p&gt;The internal implementation of the &lt;code&gt;bind&lt;/code&gt; operator rearranges terms to always get things into the form described above. So nested &lt;code&gt;bind&lt;/code&gt; applications get linearised:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  bind x &amp;lt;- (bind y &amp;lt;- D1 in D2) in D3
=
  bind y &amp;lt;- D1 in bind x &amp;lt;- D2 in D3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This implements the associativity laws of (relative) monads.&lt;/p&gt;&lt;p&gt;Finally &lt;code&gt;bind&lt;/code&gt; knows what to do with any of the constructors above for building up &lt;code&gt;IDesc I&lt;/code&gt; objects: it just commutes round them until it gets to an &lt;code&gt;“IId” i&lt;/code&gt;, where it performs the actual substitution:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  bind x &amp;lt;- “IId” i in D
=
  D[i/x]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where &lt;code&gt;D[i/x]&lt;/code&gt; means &lt;code&gt;D&lt;/code&gt; with &lt;code&gt;i&lt;/code&gt; substituted for &lt;code&gt;x&lt;/code&gt;. So the left-unit law for (relative) monads holds definitionally. This is less interesting though, since this law always holds even if I define &lt;code&gt;bind&lt;/code&gt; myself rather than building it into the type theory.&lt;/p&gt;&lt;h3&gt;The Interpretation of Descriptions...&lt;/h3&gt;&lt;p&gt;Given a object &lt;code&gt;D&lt;/code&gt; of type &lt;code&gt;IDesc I&lt;/code&gt; and a type &lt;code&gt;X&lt;/code&gt; with a free variable &lt;code&gt;i : I&lt;/code&gt;, the interpretation of &lt;code&gt;D&lt;/code&gt; at &lt;code&gt;X&lt;/code&gt; is given by the special type former &lt;code&gt;semI[D, i. X]&lt;/code&gt;, which obeys the following rules:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;semI[“IId” e,   i. X] = X[e/i]
semI[“K” A,     i. X] = A
semI[D1 “×” D2. i. X] = semI[D1, i. X] × semI[D2, i. X]
semI[“Sg” A D,  i. X] = (a : A) × semI[D a, i. X]
semI[“Pi” A D,  i. X] = (a : A) -&gt; semI[D a, i. X]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Given the description of the normal forms of the &lt;code&gt;IDesc I&lt;/code&gt; that I described above, it would seem odd that there is no clause for &lt;code&gt;semI&lt;/code&gt; on terms constructed from &lt;code&gt;bind&lt;/code&gt;. So let us add one:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;semI[bind x &amp;lt;- D1 in D2, i. X] = semI[D1, x. semI[D2, i. X]]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(remember that &lt;code&gt;x&lt;/code&gt; may be free in &lt;code&gt;D2&lt;/code&gt;).  By integrating this law into the normaliser, I immediately get that the semantics of composed descriptions of functors is definitionally equal to the composition of the semantics of the descriptions. In short: the normaliser, and hence the definitional equality, knows that &lt;code&gt;semI&lt;/code&gt; is a (relative) monad morphism!&lt;/p&gt;&lt;h3&gt;... is a Functor&lt;/h3&gt;&lt;p&gt;I've been saying that the &lt;code&gt;IDesc&lt;/code&gt; type describes functors, but the &lt;code&gt;semI&lt;/code&gt; operator only tells you what happens on objects. I could easily define a &lt;code&gt;mapI&lt;/code&gt; function to implement an action on morphisms:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;    mapI : (I : Set) -&gt;
           (D : I -&gt; IDesc I) -&gt;
           (X Y : I -&gt; Set) -&gt;
           ((i : I) -&gt; X i -&gt; Y i) -&gt;
           semI[D, i. X] -&gt; semI[D, i. Y]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If I just implement this though, I am in the same position as with the &lt;code&gt;bind&lt;/code&gt; function above: the definitional equality doesn't know that the functor laws hold. So I've added the following special operator to the Foveran type theory:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mapI[D, i. X, i. Y, f, x]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where &lt;code&gt;D : IDesc I&lt;/code&gt; (the &lt;code&gt;I&lt;/code&gt; gets inferred), &lt;code&gt;X&lt;/code&gt; and &lt;code&gt;Y&lt;/code&gt; are types each with a free &lt;code&gt;I&lt;/code&gt; variable &lt;code&gt;i&lt;/code&gt;, &lt;code&gt;f : (i : I) -&gt; X[i] -&gt; Y[i]&lt;/code&gt;, and &lt;code&gt;x : semI[D, i. X]&lt;/code&gt;. The whole thing has type &lt;code&gt;semI[D, i. Y]&lt;/code&gt;. (There's a lot more that could be inferred here, even without full-on type reconstruction, but this is what I've implemented at the moment).&lt;/p&gt;&lt;p&gt;Now I have to pull several tricks to get the functor laws to hold definitionally. The main one is forcing that the only normal forms of type &lt;code&gt;semI[D, i. Y]&lt;/code&gt; &lt;em&gt;when &lt;code&gt;D&lt;/code&gt; is stuck&lt;/em&gt; are of the form &lt;code&gt;mapI[D, i. X, i. Y, f, x]&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;So if it has a stuck term, like a variable &lt;code&gt;x&lt;/code&gt;, of type &lt;code&gt;semI[D, i. Y]&lt;/code&gt;, the normaliser always expands it to a map of the (&lt;code&gt;I&lt;/code&gt;-indexed) identity functor over &lt;code&gt;x&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;x = mapI[D, i. Y, i. Y, λi y. y, x]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This ensures that the identity preservation law always holds definitionally, similarly to the case for the right-unit law of the relative monad &lt;code&gt;IDesc&lt;/code&gt; above.&lt;/p&gt;&lt;p&gt;As one might imagine, the rest of the implementation of &lt;code&gt;mapI&lt;/code&gt; proceeds by recursion on the structure of the &lt;code&gt;IDesc I&lt;/code&gt; argument, until it gets to a &lt;code&gt;bind&lt;/code&gt;, whereupon it does something special:&lt;/p&gt;&lt;div class=&quot;annotation&quot;&gt; &lt;span class=&quot;time&quot;&gt;2011-12-15 14:00&lt;/span&gt;: Thanks to Andrea Vezzosi in the comments for pointing out the mistake in the old version here. I also found a bigger mistake in the types. I think the new version is correct.&lt;/div&gt;
&lt;pre&gt;&lt;code&gt;  mapI[bind x &amp;lt;- D1 in D2, i. Y, i. Z, f
      , mapI[D1, x. semI[D2 x, i. X], x. semI[D2 x, i. Y], g, z]]
=
  mapI[D1, x. semI[D2 x, i. X], x. semI[D2 x, i. Z]
      , λi x. mapI[D2 i, i. Y, i. Z, f, g i x]
      , z]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that the last argument on the top line must have this form, by the normal forms of stuck &lt;code&gt;IDesc&lt;/code&gt;s and the normal forms of values of type &lt;code&gt;semI&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;This rule ensures that &lt;code&gt;mapI&lt;/code&gt; both satisfies the preservation of composition, and tracks the monad morphism behaviour of &lt;code&gt;semI&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;Making use: Inductive Types with Strictly Positive Parameters&lt;/h3&gt;&lt;p&gt;There's an example of the use of the extended definitional equality in the file &lt;a href=&quot;https://github.com/bobatkey/foveran/blob/master/tests/parameters.fv&quot;&gt;&lt;code&gt;parameters.fv&lt;/code&gt;&lt;/a&gt; in the Foveran github repo. I'll give a quick overview below. Thanks to &lt;a href=&quot;http://www.cis.strath.ac.uk/cis/staff/index.php?uid=72830&quot;&gt;Stevan Andjelkovic&lt;/a&gt; for the idea.&lt;/p&gt;&lt;h4&gt;Codes for Inductive Types with Parameters&lt;/h4&gt;&lt;p&gt;The goal of the file is to give an account of inductive data types with parameters in such a way that I can define the functor laws generically (the &lt;code&gt;IDesc&lt;/code&gt; codes above cannot, alas, define inductive data-types). For example, the type of lists of some type &lt;code&gt;A&lt;/code&gt; uses the type &lt;code&gt;A&lt;/code&gt; in a particular way that ensures that I can always define a generic map operation.&lt;/p&gt;&lt;p&gt;So I define a new type of codes of types indexed by some set &lt;code&gt;I&lt;/code&gt;, with parameters indexed by some other set &lt;code&gt;P&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;IDescP : Set -&gt; Set -&gt; Set 1
IDescP P I = I -&gt; IDesc (P + I)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To realise these codes as actual inductive types, I must compose them with something that handles the extra &lt;code&gt;P +&lt;/code&gt; by instantiating it with the parameters:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;IDescP:fork : (P I : Set) -&gt; (P -&gt; Set) -&gt; P + I -&gt; IDesc I
IDescP:fork P I X x =
  case x with { inl p. “K” (X p); inr i. “IId” i }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The complete codes are built using the following definition, which uses the &lt;code&gt;bind&lt;/code&gt; operator to compose the descriptions:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;IDescP:code : (P I : Set) -&gt; IDescP P I -&gt; (P -&gt; Set) -&gt; I -&gt; IDesc I
IDescP:code P I D X =
  λi. bind x &amp;lt;- D i in IDescP:fork P I X x
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, they can be turned into actual &lt;code&gt;I&lt;/code&gt;-indexed types, given the &lt;code&gt;P&lt;/code&gt;-indexed family of parameters:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;muP : (P I : Set) -&gt; IDescP P I -&gt; (P -&gt; Set) -&gt; I -&gt; Set
muP P I D X = µI I (IDescP:code P I D X)
&lt;/code&gt;&lt;/pre&gt;&lt;h4&gt;Defining Generic Map&lt;/h4&gt;&lt;p&gt;The generic map function is now defined as follows (&lt;code&gt;cata&lt;/code&gt; is the generically defined catamorphism function, derived from the built-in induction on inductive types):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;map : (P I : Set) -&gt;
      (D : IDescP P I) -&gt;
      (X Y : P -&gt; Set) -&gt;
      ((p : P) -&gt; X p -&gt; Y p) -&gt;
      (i : I) -&gt; muP P I D X i -&gt; muP P I D Y i
map P I D X Y f =
  cata I (IDescP:code P I D X)
     « muP P I D Y
     , λi x. construct
         (mapI[D i, x. semI[IDescP:fork P I X x, i. muP P I D Y i]
                  , x. semI[IDescP:fork P I Y x, i. muP P I D Y i]
                  , λx. case x with { inl p. f p; inr i. λx. x }
                  , x])
     »
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This looks complicated, but this is mainly due to &lt;code&gt;mapI&lt;/code&gt; not yet inferring as many of its arguments as it could. What is important is what I haven't written. In the &lt;code&gt;λi x. construct&lt;/code&gt;... bit, the variable &lt;code&gt;x&lt;/code&gt; has type &lt;code&gt;semI[IDescP:code P I D X i, i. muP P I D Y i]&lt;/code&gt;. By the definition of &lt;code&gt;IDescP:code&lt;/code&gt; this &lt;em&gt;normalises&lt;/em&gt; to &lt;code&gt;semI[D i, x. semI[IDescP:fork P I X x, i. muP P I D Y i]&lt;/code&gt; and I can easily apply &lt;code&gt;mapI&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;If the normaliser didn't know that &lt;code&gt;semI&lt;/code&gt; was a relative monad morphism, then &lt;code&gt;x&lt;/code&gt;'s type would be &lt;code&gt;semI[bind x &amp;lt;- D i in IDescP:fork P I X x, i. muP P I D Y i]&lt;/code&gt; and I would've had to manually decompose into the two parts, apply the &lt;code&gt;mapI&lt;/code&gt; and then recompose. By making the definitional equality stronger, I can get away with writing less code.&lt;/p&gt;&lt;h3&gt;What other Laws can be built-in?&lt;/h3&gt;&lt;p&gt;What other laws can be built-in to the definitional equality? I believe that Conor wants to build the concept of free monad over a functor into &lt;a href=&quot;http://www.e-pig.org/&quot;&gt;Epigram&lt;/a&gt;, so that the monads laws automatically hold for all (for some intensionally defined version of &quot;all&quot;) free monads. In the full-blown &lt;a href=&quot;http://personal.cis.strath.ac.uk/~dagand/papers/levitation.pdf&quot;&gt;levitation&lt;/a&gt; scheme, &lt;code&gt;IDesc&lt;/code&gt; would itself just be one free monad among many, and the laws would automatically hold for it. I think the &lt;code&gt;semI&lt;/code&gt; and &lt;code&gt;mapI&lt;/code&gt; laws would have to be still added specially though.&lt;/p&gt;&lt;p&gt;There are also subsets of the functors described by &lt;code&gt;IDesc&lt;/code&gt; codes that have special properties. If one stays away from codes that introduce &quot;data&quot; (i.e. codes that describe containers with no shapes) then it is automatically an &lt;a href=&quot;http://www.soi.city.ac.uk/~ross/papers/Applicative.html&quot;&gt;applicative functor&lt;/a&gt;. The &lt;code&gt;lift&lt;/code&gt;/&lt;code&gt;All&lt;/code&gt; construction used for describing generic induction is the leading example of this type. Dually, if one stays away from codes that introduce a choice of positions, one automatically get the (nameless?)  dual of an applicative functor (e.g. the &lt;code&gt;Somewhere&lt;/code&gt; modality). Maybe it would be interesting to let the relevant laws hold automatically in these cases as well?&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2011-12-14-type-checker.html</guid><pubDate>Wed, 14 Dec 2011 00:00:00 +0000</pubDate></item><item><title>How to be a Productive Programmer</title><link>https://bentnib.org/posts/2011-11-14-productive-programmer.html</link><description>&lt;p&gt;On Friday, I gave a talk at the &lt;a href=&quot;http://www.dcs.gla.ac.uk/research/spls/Nov11/index.html&quot;&gt;Scottish Programming Languages Seminar (SPLS) at Heriot-Watt&lt;/a&gt;. Many thanks to Greg Michaelson for organising everything and giving me time to speak.&lt;/p&gt;&lt;p&gt;I've put the slides I used &lt;a href=&quot;https://bentnib.org/docs/productive-spls1111-slides.pdf&quot;&gt;on-line as a PDF file&lt;/a&gt; (with two small fixes, see below).&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bentnib.org/docs/productive-spls1111-slides.pdf&quot;&gt;&lt;img alt=&quot;Thumbnail of slides for &amp;quot;How to be a Productive Programmer&amp;quot; talk&quot; src=&quot;https://bentnib.org/thumbnails/slides-productive-spls1111-slides.png&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The talk presents an extension of a Nakano-style typed λ-calculus with a delay modality for guarded recursion. In short, this means:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;The type system presented has a type-former &lt;code&gt;▷&lt;/code&gt; so that for any type &lt;code&gt;A&lt;/code&gt;, there is another type &lt;code&gt;▷ A&lt;/code&gt; representing an &lt;code&gt;A&lt;/code&gt; delayed by one step in the current time stream.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Unlike Nakano's calculus, where the delay modality is presented using sub-typing rules, I have followed Conor's idea and presented the delay modality using applicative functor rules. I think this makes it a little easier to program with, and certainly easier to experiment with in an existing language like Haskell.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The really exciting new thing is the addition of &lt;em&gt;clock variables&lt;/em&gt;, which allows for multiple time streams to be in play at once. This means it is possible to look at “all” of a potentially infinite computation and extract useful information from it. In the slides I presented the &lt;code&gt;take&lt;/code&gt; and &lt;code&gt;replaceMin&lt;/code&gt; functions as examples of this.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As I mentioned during the talk, this is based on Conor's blog post &lt;a href=&quot;http://www.e-pig.org/epilogue/?p=186&quot;&gt;Time files like an Applicative Functor&lt;/a&gt; from over two years ago.&lt;/p&gt;&lt;p&gt;The hoped-for outcome is a nice way of programming with codata in a functional language like Haskell. Still more hopefully, this will extend to systems with dependently types too, though I am still confused about where the clock variables ought to live.&lt;/p&gt;&lt;p&gt;I fixed two typos that were present in copy of the slides that I used in the talk:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;On slide 18 (page 42 in the PDF), I had “Time Files like an Applicative Functor” as the title of Conor's blog post. Obviously, time is rubbish at filing, or at least not as good as applicative functors are.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;On slide 28 (page 57 in the PDF), I had the semantics of data type descriptions as an endofunction on some undefined curly D thing. It ought to be the powerset of the semantic domain.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2011-11-14-productive-programmer.html</guid><pubDate>Mon, 14 Nov 2011 00:00:00 +0000</pubDate></item><item><title>On Structural Recursion II: Folds and Induction</title><link>https://bentnib.org/posts/2011-04-28-folds-and-induction.html</link><description>&lt;p&gt;&lt;a href=&quot;https://bentnib.org/posts/2011-04-22-structural-recursion.html&quot;&gt;Last time&lt;/a&gt; I talked about the background on defining structurally recursive functions in Type Theory and why you might want it. The key point is that structural recursion is driven by the data that is being analysed, as opposed to just doing its own thing with a side-proof that it always terminates.&lt;/p&gt;&lt;p&gt;The goal here is to come up with a self-contained and syntax-free definition of a dependently-typed structural recursion principle for a type &lt;code&gt;A&lt;/code&gt;. To start with, this will be purely for normal structural recursion over inductively defined types. In future posts I will extend this to other types by combining existing structural induction principles.&lt;/p&gt;&lt;p&gt;In this post I'll cover how to present structural recursion and induction in a generic way. The first is probably well known to most people reading this, being just the standard stuff about initial &lt;code&gt;F&lt;/code&gt;-algebras, but hopefully the second will be new.&lt;/p&gt;&lt;p&gt;The generic approach to structural induction I'll describe below underlies how &lt;a href=&quot;http://www.e-pig.org/&quot;&gt;Epigram 2&lt;/a&gt; and my own language &lt;a href=&quot;https://github.com/bobatkey/foveran/&quot;&gt;Foveran&lt;/a&gt; implement structural induction in a generic way. More information on Epigram's representation of data types is available in the paper &lt;a href=&quot;http://personal.cis.strath.ac.uk/~dagand/papers/levitation.pdf&quot;&gt;The Gentle Art of Levitation&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;My last post led to a &lt;a href=&quot;http://www.reddit.com/r/haskell/comments/gv6ze/structural_recursion/&quot;&gt;very interesting discussion on reddit&lt;/a&gt;, which quickly left the measly content of my original behind. Just to clarify some of the points that came up in that discussion, I am only talking here about structural recursion/induction over inductively defined types---by which I mean types that arise as initial fixpoints of &lt;code&gt;F&lt;/code&gt;-algebras---not co-inductive types (though the general technique for handling structural induction I'll describe below does extend to co-induction, at least in a categorical setting).&lt;/p&gt;&lt;h3&gt;What is Structural Recursion?&lt;/h3&gt;&lt;p&gt;Structural recursion is often presented as a restriction. In Coq or Agda, the programmer enters a recursive definition, and the system inspects it to make sure it fits the template of acceptable definitions. This &quot;generate and test&quot; approach naturally leads most people to think that the system is just being stupid when it refuses to accept their definition.&lt;/p&gt;&lt;p&gt;An alternative is for the system to be up-front about the definitions it is prepared to accept. Instead of writing recursive definitions and having them rejected, the programmer uses special-purpose recursion combinators to write their programs. This is the basic idea behind recursion schemes, as in the classic paper &lt;a href=&quot;http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125&quot;&gt;Functional Programming with Bananas, Lenses and Barbed Wire&lt;/a&gt;. An important extra benefit of using recursion schemes, as pointed out in that paper, is that they often also come with reasoning principles.&lt;/p&gt;&lt;p&gt;I am interested in going beyond normal recursion schemes, and doing &lt;em&gt;dependent&lt;/em&gt; recursion schemes as well. This allows us to use structural recursion as a method of reasoning as well as a method of definition, and to intertwine the two if we feel like it. First though, I'll go over the standard stuff about how to treat the most basic recursion scheme at a general level.&lt;/p&gt;&lt;h4&gt;Folds, Catamorphisms and F-Algebras&lt;/h4&gt;&lt;p&gt;We can represent structural recursion on lists (with elements from a set &lt;code&gt;A&lt;/code&gt;) using the right fold function:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;foldr : (B : Set) → B → (A → B → B) → List → B
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which satisfies the following two equations:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;foldr B n c nil         = n
foldr B n c (cons a as) = c a (foldr B c n as)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As I mentioned &lt;a href=&quot;https://bentnib.org/posts/2011-04-22-structural-recursion.html&quot;&gt;last time&lt;/a&gt;, we can read these off directly as computation rules: when the implementation of &lt;code&gt;foldr&lt;/code&gt; sees &lt;code&gt;nil&lt;/code&gt; in its last argument, it knows to use its &quot;nil&quot; parameter; and when it sees &lt;code&gt;cons a as&lt;/code&gt; in its third argument it knows to use the &quot;cons&quot; parameter. Thus we have a method for computation, driven by the structure of the data we are processing.&lt;/p&gt;&lt;p&gt;The well-known category-theoretic generalisation of this makes use of &lt;code&gt;F&lt;/code&gt;-algebras. The basic idea is that the constructors of our inductive type are encoded as a functor &lt;code&gt;F : Set → Set&lt;/code&gt;. For instance, the constructors of lists, with elements from some set &lt;code&gt;A&lt;/code&gt; are encoded using the functor (I've only defined it here on objects, but the action on morphisms is obvious):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ListF : Set → Set
ListF X = 1 + A × X
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first two arguments of the &lt;code&gt;foldr&lt;/code&gt; function can now be captured as a function &lt;code&gt;f : ListF B → B&lt;/code&gt;. A pair of a set &lt;code&gt;B&lt;/code&gt; and such a function &lt;code&gt;f : F B → B&lt;/code&gt; is called an &lt;code&gt;F&lt;/code&gt;-algebra. Given two &lt;code&gt;F&lt;/code&gt;-algebras &lt;code&gt;(k₁ : F B → B)&lt;/code&gt; and &lt;code&gt;(k₂ : F C → C)&lt;/code&gt;, we define &lt;code&gt;F&lt;/code&gt;-algebra morphisms to be functions &lt;code&gt;h : B → C&lt;/code&gt; such that &lt;code&gt;h ○ k₁ = k₂ ○ F h&lt;/code&gt;. It is not too difficult to see that &lt;code&gt;F&lt;/code&gt;-algebras and their morphisms form a category, called &lt;code&gt;F&lt;/code&gt;-Alg.&lt;/p&gt;&lt;p&gt;For quite a large class of functors &lt;code&gt;F&lt;/code&gt;, &lt;code&gt;F&lt;/code&gt;-Alg has a (unique up-to isomorphism) initial object. Spelling this out, we have an &lt;code&gt;F&lt;/code&gt;-algebra &lt;code&gt;(in : F µF → µF)&lt;/code&gt; such that for any other &lt;code&gt;F&lt;/code&gt;-algebra &lt;code&gt;(k : F B → B)&lt;/code&gt; there is a &lt;em&gt;unique&lt;/em&gt; &lt;code&gt;F&lt;/code&gt;-algebra morphism from &lt;code&gt;(in : F µF → µF)&lt;/code&gt; to &lt;code&gt;(k : F B → B)&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;For the lists example, an initial algebra for the functor &lt;code&gt;ListF&lt;/code&gt; is the set of lists with elements from the set &lt;code&gt;A&lt;/code&gt;, with &lt;code&gt;(in : ListF (List A) → List A)&lt;/code&gt; defined simply as the construction of lists using &lt;code&gt;nil&lt;/code&gt; and &lt;code&gt;cons&lt;/code&gt;. By initiality, if we have a &lt;code&gt;ListF&lt;/code&gt;-algebra &lt;code&gt;(k : ListF B → B)&lt;/code&gt; we get a function of type &lt;code&gt;List A → B&lt;/code&gt;. Since it is a &lt;code&gt;ListF&lt;/code&gt;-morphism it satisfies the two equations for &lt;code&gt;foldr&lt;/code&gt; above, so we can interpret &lt;code&gt;foldr&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;More generally, we can interpret specifications of inductive types as functors &lt;code&gt;F&lt;/code&gt;, the inductive types themselves as the carriers of initial algebras and structural recursion on them as making use of the initiality property to generate homomorphisms. Note that not every &lt;code&gt;F&lt;/code&gt; you can write down necessarily has an initial algebra; for instance, &lt;code&gt;F X = (X → 2) → 2&lt;/code&gt; doesn't have an initial algebra in the category of sets and functions.&lt;/p&gt;&lt;p&gt;In the recursion schemes literature, folds are referred to as &lt;em&gt;catamorphisms&lt;/em&gt;. Edward Kmett has written &lt;a href=&quot;http://knol.google.com/k/catamorphisms&quot;&gt;a comprehensive Knol on catamorphisms&lt;/a&gt;. He also has a &lt;a href=&quot;http://comonad.com/reader/2009/recursion-schemes/&quot;&gt;field guide&lt;/a&gt; to recursion schemes, for both data and codata.&lt;/p&gt;&lt;h3&gt;What is Structural Induction?&lt;/h3&gt;&lt;p&gt;From a high level, (constructive) structural induction is just structural recursion with fancier types. And from a computation viewpoint this is fairly accurate: computation still proceeds by looking at data and then deciding what to do next. But we still need to work out what those types should be.&lt;/p&gt;&lt;h4&gt;Dependent Structural Recursion (a.k.a. Structural Induction)&lt;/h4&gt;&lt;p&gt;In pure Type Theory (i.e. without extensions for pattern matching and recursive definitions), structural recursion is presented in terms of elimination principles. Continuing the example of lists, we are provided with a pair of constructors &lt;code&gt;nil : List&lt;/code&gt; and &lt;code&gt;cons : A → List → List&lt;/code&gt; and an eliminator:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;elimList : (P : List → Set) →
           (P nil) →
           ((a : A) → (l : List) → P l → P (cons a l)) →
           (l : List) → P l
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This looks very similar to the type of the &lt;code&gt;foldr&lt;/code&gt; function above. The difference is that the return type depends on the input list, and this dependency is carried through in the types of the &quot;nil&quot; and &quot;cons&quot; parameters (the second and third parameters).&lt;/p&gt;&lt;p&gt;As with the &lt;code&gt;foldr&lt;/code&gt; function, &lt;code&gt;elimList&lt;/code&gt; satisfies a pair of equations, which are almost identical, except for some extra information being passed in the &lt;code&gt;cons&lt;/code&gt; case.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;elimList P n c nil         = n
elimList P n c (cons a as) = c a as (elimList P n c as)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In presentations of type theory, the construction of elimination principles is usually defined syntactically by looking at the types of the constructors. See, for example, &lt;a href=&quot;http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.37.74&quot;&gt;Dybjer's presentation of inductive families&lt;/a&gt;. This seems a little ad-hoc: one might hope for a generic way of extracting dependent eliminators for inductive types just from their presentations as initial &lt;code&gt;F&lt;/code&gt;-algebras. Happily, this is possible.&lt;/p&gt;&lt;h4&gt;Structural Induction for initial &lt;code&gt;F&lt;/code&gt;-algebras&lt;/h4&gt;&lt;p&gt;Given a functor &lt;code&gt;F : Set → Set&lt;/code&gt; that has an initial algebra &lt;code&gt;(in : F µF → µF)&lt;/code&gt; we first need to derive the type of the generic elimination principle for &lt;code&gt;µF&lt;/code&gt;. The generic fold operator for &lt;code&gt;µF&lt;/code&gt; has this type:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;fold : (B : Set) → (F B → B) → µ F → B
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Looking at the similarities between the &lt;code&gt;foldr&lt;/code&gt; function on lists and the &lt;code&gt;elimNat&lt;/code&gt; eliminator, we can guess that a generalisation should look like this for general &lt;code&gt;(in : F µF → µF)&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;elimF : (P : µF → Set) →
        ((x : F µF) → lift F P x → P (in x)) →
        (x : µF) → P x
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I'll attempt to explain this type with reference to the type of &lt;code&gt;elimList&lt;/code&gt;. The first parameter, &lt;code&gt;P : µF → Set&lt;/code&gt; is the dependent type we are eliminating to, and is exactly the same. The second parameter is the &quot;algebra&quot; component. It is a function that takes a value of type &lt;code&gt;F µF&lt;/code&gt;. In the case of lists, this would either be &lt;code&gt;inl *&lt;/code&gt; (representing nil) or &lt;code&gt;inr (a,l)&lt;/code&gt; representing cons. So, similarly to &lt;code&gt;F&lt;/code&gt;-algebras representing the multiple parameters to &lt;code&gt;fold&lt;/code&gt;, we are encoding all the cases into one. The second argument of the algebra component is a little trickier. I have assumed a functor &lt;code&gt;lift F : (µF → Set) → (F µF → Set)&lt;/code&gt; that takes &lt;code&gt;P&lt;/code&gt; and &lt;code&gt;x&lt;/code&gt; and produces some set. This part somehow encodes the &quot;inductive hypothesis&quot; for this structural recursion principle. I'll explain this further below. Finally, the &quot;algebra&quot; part ought to return a value of type &lt;code&gt;P (in x)&lt;/code&gt;, corresponding to the &lt;code&gt;P nil&lt;/code&gt; and &lt;code&gt;P (cons a l)&lt;/code&gt; parts of the &lt;code&gt;elimList&lt;/code&gt; type.&lt;/p&gt;&lt;p&gt;Given such an &quot;algebra&quot; parameter, &lt;code&gt;elimF&lt;/code&gt; promises to take any element &lt;code&gt;x&lt;/code&gt; of &lt;code&gt;µF&lt;/code&gt; and return a value of &lt;code&gt;P x&lt;/code&gt;.&lt;/p&gt;&lt;h5&gt;Lifting &lt;code&gt;F&lt;/code&gt;&lt;/h5&gt;&lt;p&gt;I need to give a definition for &lt;code&gt;lift F : (F µF → Set) → (µ F → Set)&lt;/code&gt; now. In the case of lists, we can see that the following definition gives the right answer:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;lift F P (inl *)     = ⊤
lift F P (inr (a,l)) = P l
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Unfolding this definition in the type of &lt;code&gt;elim&lt;/code&gt; above, it is easy to see that it is an encoding of the original type of &lt;code&gt;elimList&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;But how do we do this in general for any &lt;code&gt;F&lt;/code&gt;? &lt;a href=&quot;http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.36.7400&quot;&gt;Hermida and Jacobs&lt;/a&gt; did this back in the nineties for polynomial &lt;code&gt;F&lt;/code&gt; (i.e. &lt;code&gt;F&lt;/code&gt;s constructed from constants, sums, products and the identity functor) by induction on the structure:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;lift Id      P x       = P x
lift (K A)   P a       = ⊤
lift (F × G) P (x,y)   = (lift F P x) × (lift F P y)
lift (F + G) P (inl x) = lift F P x
lift (F + G) P (inr y) = lift G P y
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note there are two cases for &lt;code&gt;F + G&lt;/code&gt; depending on which component the &lt;code&gt;(F + G) µH&lt;/code&gt; argument is in. It is easy to see that &lt;code&gt;lift F&lt;/code&gt; is also a functor, so it has an action on morphisms between &lt;code&gt;µF → Set&lt;/code&gt; objects.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Aside&lt;/em&gt; Note that this definition doesn't depend on the type of &lt;code&gt;P&lt;/code&gt; being &lt;code&gt;µ F → Set&lt;/code&gt;. We can actually give &lt;code&gt;lift F&lt;/code&gt; the type &lt;code&gt;(A → Set) → (F A → Set)&lt;/code&gt; for any &lt;code&gt;A&lt;/code&gt;. So we can extend &lt;code&gt;lift F&lt;/code&gt; to be a functor on the category &lt;code&gt;Fam(Set)&lt;/code&gt;, where objects are pairs &lt;code&gt;(A : Set, P : A → Set)&lt;/code&gt;. This extra generality helps when proving that structural induction is derivable from structural recursion, and for further applications like doing &lt;a href=&quot;https://bentnib.org/inductive-refinement.html&quot;&gt;refinement of inductive types&lt;/a&gt;. Logical relations lovers will also see that this is the definition of the unary logical relation derived from the type scheme generated by a polynomial functor.&lt;/p&gt;&lt;p&gt;An important property of &lt;code&gt;lift F&lt;/code&gt; is that it is &lt;em&gt;truth-preserving&lt;/em&gt;. For any &lt;code&gt;x : F µF&lt;/code&gt;, there is a (unique) value of &lt;code&gt;lift F (λy. ⊤) x&lt;/code&gt;. I read this as saying that &lt;code&gt;x : F µF&lt;/code&gt; completely determines the shape of &lt;code&gt;lift F (λy. ⊤) x&lt;/code&gt;. We can use this to derive a useful function, using the functorality of &lt;code&gt;lift F&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;all : (P : µF → Set) →
      (x : F µF) →
      (k : (y : µF) → P y) →
      lift F P x
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Knowing that &lt;code&gt;lift F&lt;/code&gt; is truth preserving turns out to be just enough to prove that the &lt;code&gt;elimF&lt;/code&gt; rule above holds, and also that the following equation holds:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;elimF P h (in x) = h x (all P x (elimF P h))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Spelling this out for the case of lists, it is pretty easy to see that this gives us back the original elimination rule for lists. It is also true that &lt;code&gt;elimF P h : (x : µF) → P x&lt;/code&gt; is the &lt;em&gt;unique&lt;/em&gt; function that satisfies this equation, at least in the categorical setting. See &lt;a href=&quot;http://personal.cis.strath.ac.uk/~patricia/csl2010.pdf&quot;&gt;Neil, Patty and Clem's paper&lt;/a&gt; for the category-theoretic proof that this works. The proof only demands that we have an initial algebra for &lt;code&gt;F&lt;/code&gt; and a truth preserving lifting. As a hint of the proof, note that if we regard &lt;code&gt;lift F&lt;/code&gt; as an endofunctor on &lt;code&gt;Fam(Set)&lt;/code&gt; then the premises of the &lt;code&gt;elimF&lt;/code&gt; function amount to taking a &lt;code&gt;(lift F)&lt;/code&gt;-algebra with carrier &lt;code&gt;(µF, P)&lt;/code&gt; to a morphism &lt;code&gt;(x : µF) → K₁ µF x → P x&lt;/code&gt;, where &lt;code&gt;K₁ µF x = ⊤&lt;/code&gt;. The proof consists of showing that &lt;code&gt;K₁ µF&lt;/code&gt; is the carrier of the initial &lt;code&gt;(lift F)&lt;/code&gt;-algebra.&lt;/p&gt;&lt;h5&gt;Generalising to all &lt;code&gt;F&lt;/code&gt;&lt;/h5&gt;&lt;p&gt;I have only defined &lt;code&gt;lift F&lt;/code&gt; for polynomial &lt;code&gt;F&lt;/code&gt; so far, but it is possible to characterise &lt;code&gt;lift F&lt;/code&gt; for any arbitrary &lt;code&gt;F&lt;/code&gt;, as hinted by Hermida and Jacobs and fleshed out by Neil, Patty and Clem. Assuming we had extensional equality, we could define &lt;code&gt;lift F&lt;/code&gt; as:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;lift F P x = Σy : F (Σz : µF. P z). F π₁ y = x
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where &lt;code&gt;Σx : A. B x&lt;/code&gt; denotes a dependent pair type, and &lt;code&gt;π₁&lt;/code&gt; is the first projection. It is fairly easy to see that this is always truth-preserving, and that it coincides with the definition above for polynomial functors. This is particularly nice because it gives an extensional (i.e. we don't care about how &lt;code&gt;F&lt;/code&gt; is constructed) definition of what the lifting is. It is also possible to give a generic description that works in any fibration with the right structure, so we can generalise to indexed types, types over categories of domains and so on.&lt;/p&gt;&lt;p&gt;When actually implementing this in a intensional type theory, like in Epigram 2 or Foveran, it is better, both because of the lack of extensional quality and for pragmatic reasons, to define the lifting directly in terms of the descriptions of the functors. However, the extensional definition does give a guide as to the form that &lt;code&gt;lift F&lt;/code&gt; ought to take when we move beyond polynomial functors.&lt;/p&gt;&lt;h3&gt;Can we generalise Structural Induction?&lt;/h3&gt;&lt;p&gt;My goal in the next post is to show that structural induction on the structure of an inductively defined type is only one form of structural induction. Generalising from the set up above, my current thought for what a &quot;structural induction principle&quot; for some &lt;code&gt;A : Set&lt;/code&gt; should look like consists of:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Another set &lt;code&gt;B&lt;/code&gt;, which records the &quot;sub-structure&quot; of &lt;code&gt;A&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;A constructor &lt;code&gt;k : B → A&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;A predicate transformer &lt;code&gt;H : (A → Set) → (B → Set)&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;A witness to truth-preservation &lt;code&gt;tr : (b : B) → H (λa. ⊤) b&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;An eliminator &lt;code&gt;elim : (P : A → Set) → ((b : B) → H P b → P (k b)) → (a : A) → P a&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;satisfying the equality&lt;/p&gt;&lt;pre&gt;&lt;code&gt;elim P h (k b) = h b (all P b (elim P h))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where &lt;code&gt;all&lt;/code&gt; is derived from the witness to truth-preservation.&lt;/p&gt;&lt;p&gt;I should say that I'm not totally fixed on the details. My current thought is that I might need multiple constructors, or that more structure of &lt;code&gt;H&lt;/code&gt; is required. But I'm pretty sure that an explicit description of how elements of the data type we are analysing are constructed is essential to any description of &lt;em&gt;structural&lt;/em&gt; induction, because it allows us to state the computation rule. My plan is to push through examples and see what is required.&lt;/p&gt;&lt;p&gt;Previous work on this includes Nils Anders Danielsson's definition of &lt;a href=&quot;http://www.cse.chalmers.se/~nad/repos/lib/src/Induction.agda&quot;&gt;Recursor&lt;/a&gt; in the Agda standard library, but this doesn't include a notion of constructor, or a computation rule. Conor also has a definition called &lt;code&gt;Below&lt;/code&gt; which is pretty much identical.&lt;/p&gt;&lt;p&gt;Obviously structural induction on an inductively defined type fits into this schema, with &lt;code&gt;B = F µF&lt;/code&gt;, and &lt;code&gt;H = lift F&lt;/code&gt;. It is not so obvious that more general ones do. In the next few posts I'll cover how to generate new structural induction principles from old ones. For those of you that want to read ahead you can look at an outdated implementation, using an old definition of structural induction principle in the &lt;a href=&quot;https://github.com/bobatkey/foveran/blob/master/tests/inductors-descript.fv&quot;&gt;Foveran repository&lt;/a&gt;.&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2011-04-28-folds-and-induction.html</guid><pubDate>Thu, 28 Apr 2011 00:00:00 +0000</pubDate></item><item><title>On Structural Recursion</title><link>https://bentnib.org/posts/2011-04-22-structural-recursion.html</link><description>&lt;p&gt;This is the first in (hopefully) a series of blog posts on defining an algebra of structural induction principles in type theory, borrowing inspiration from category theory. This is joint work with &lt;a href=&quot;http://personal.cis.strath.ac.uk/~patricia&quot;&gt;Patty Johann&lt;/a&gt; and &lt;a href=&quot;http://personal.cis.strath.ac.uk/~ng&quot;&gt;Neil Ghani&lt;/a&gt;, and builds on work and ideas of many, notably &lt;a href=&quot;http://personal.cis.strath.ac.uk/~conor&quot;&gt;Conor McBride&lt;/a&gt;. In this post, I'll just explain the background.&lt;/p&gt;&lt;h3&gt;Structural Recursion&lt;/h3&gt;&lt;p&gt;Structural recursion is a fundamental part of the definition of functions in Type Theory, and also in functional programming languages. A standard example is that of &lt;code&gt;length&lt;/code&gt; on lists (in Haskell syntax):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;length : [a] -&gt; Int
length []     = 0
length (x:xs) = 1 + length xs
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Execution of &lt;code&gt;length&lt;/code&gt; proceeds by looking at the constructor — either &lt;code&gt;[]&lt;/code&gt; or &lt;code&gt;_:_&lt;/code&gt; — and then choosing a course of action. In the nil case, it evaluates to &lt;code&gt;0&lt;/code&gt;, in the cons case it recursively evaluates &lt;code&gt;length&lt;/code&gt;, on the sub-term exposed by the pattern matching, and then adds &lt;code&gt;1&lt;/code&gt; to it.&lt;/p&gt;&lt;p&gt;Definition by structural recursion has the following two features:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;It is always terminating, because we only ever call the function again on &lt;em&gt;smaller&lt;/em&gt; elements of the inductively defined type.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;It provides an obvious way of computing. The process is: look at the constructor, do an action. We can define what it means to &lt;em&gt;run&lt;/em&gt; functions, and hence use Type Theory as a programming language.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The first of these, while a nice to have feature in a functional programming setting, is essential in Type Theory, since we need totality of defined functions to retain decidability of type checking.&lt;/p&gt;&lt;h3&gt;Nothing’s Ever Perfect&lt;/h3&gt;&lt;p&gt;Definition by structural recursion is, at least on the surface, extremely restrictive. The restriction to recursive calls only on terms that are immediate sub-terms of the current argument is especially restrictive. The usual way to demonstrate this restrictiveness is the functional not-in-place &quot;quicksort&quot;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;quicksort :: [a] -&gt; [a]
quicksort []     = []
quicksort (x:xs) = quicksort l ++ quicksort (x:h)
  where (l,h) = partition x xs
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For any reasonable definition of &lt;code&gt;partition&lt;/code&gt;, the lists &lt;code&gt;l&lt;/code&gt; and &lt;code&gt;h&lt;/code&gt; will be sufficiently shorter than &lt;code&gt;x:xs&lt;/code&gt; to ensure termination, but naïve structural recursion cannot see this.&lt;/p&gt;&lt;p&gt;To get around this kind of limitation, people have tried several different approaches.&lt;/p&gt;&lt;h4&gt;General Recursion&lt;/h4&gt;&lt;p&gt;Give up on termination and just use general recursion. This is the approach taken by most functional programming languages. General recursion can also be encoded in Type Theory if you have co-inductive types, as shown by &lt;a href=&quot;http://www.lmcs-online.org/ojs/viewarticle.php?id=55&amp;layout=abstract&quot;&gt;Venanzio Capretta&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt;Termination Checkers&lt;/h4&gt;&lt;p&gt;Instead of requiring that everything be defined using structural recursion, bolt another termination checker on to the type checker. This is the approach taken by &lt;a href=&quot;http://wiki.portal.chalmers.se/agda/pmwiki.php&quot;&gt;Agda 2&lt;/a&gt;, and to a lesser extent by &lt;a href=&quot;http://coq.inria.fr&quot;&gt;Coq&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;This has the advantage that natural looking function definitions can be written, much as they would be written in a functional language with general recursion. The downside is that the termination checker is something separate to the core type theory, abrogating the claim of type theory to be a &quot;checkable language of evidence&quot; (I got this description from Conor McBride).&lt;/p&gt;&lt;h4&gt;Structural Recursion on Accessibility Predicates&lt;/h4&gt;&lt;p&gt;Exploit structural recursion by making use of a general purpose inductively defined type &lt;code&gt;Acc&lt;/code&gt; that allows us to encode recursion on arbitrary well-founded relations (in Agda syntax):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;data Acc (x : A) : Set where
    acc : (∀ y → y &amp;lt; x → Acc y) → Acc x
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Functions are defined by structural recursion on a special &lt;code&gt;Acc x&lt;/code&gt; argument. To actually call a function that requires such an argument we need to provide a proof that &lt;code&gt;Acc x&lt;/code&gt; for the our chosen relation &lt;code&gt;_&amp;lt;_&lt;/code&gt; and our argument &lt;code&gt;x&lt;/code&gt;. See &lt;a href=&quot;http://blog.ezyang.com/2010/06/well-founded-recursion-in-agda/&quot;&gt;Edward Z. Yang’s blog post&lt;/a&gt; for more information on doing this in Agda. As far as I am aware, this technique goes back to Bengt Nordström’s paper &lt;a href=&quot;http://www.cse.chalmers.se/~bengt/papers/genrec.ps&quot;&gt;Terminating General Recursion&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;In this technique, we are defining the function by structural recursion on the &lt;code&gt;Acc x&lt;/code&gt; argument, so it is this argument that drives the computation. Since we probably want to erase this argument at run-time, this creates a gap between the semantics of functions at compile-time and functions at run-time.&lt;/p&gt;&lt;p&gt;A variant on this method is to generate a new inductively-defined predicate for each recursive function that you want to define. This is the &lt;a href=&quot;http://www.cs.nott.ac.uk/~vxc/publications/General_Recursion_MSCS_2005.pdf&quot;&gt;Bove-Capretta method&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Can we regain a slavish devotion to structure?&lt;/h3&gt;&lt;p&gt;In this series of blog posts, I’m going to explore a different technique that allows more complex structural recursion principles to be built up from basic structural recursion on inductively defined datatypes, in such a way that the data we are analysing still drives the computation. This idea goes back to (I think) &lt;a href=&quot;http://www.springerlink.com/content/y3h26w6274664m6m/&quot;&gt;Eduardo Giménez&lt;/a&gt; (apologies for the paywall link), who used it to justify Coq’s termination checker. The ideas were also promoted by McBride and McKinna’s &lt;a href=&quot;http://strictlypositive.org/view.ps.gz&quot;&gt;The view from the left&lt;/a&gt;, where the systematic use of eliminators for defining functions in type theory was investigated. I’ll also be taking ideas from category-theoretic presentations of structural recursion, specifically Hermida and Jacobs’ &lt;a href=&quot;http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.36.7400&quot;&gt;original paper&lt;/a&gt; and Neil Ghani, Patricia Johann and Clement Fumex’s &lt;a href=&quot;http://personal.cis.strath.ac.uk/~patricia/csl2010.pdf&quot;&gt;generalisation of it&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;In the next post I’ll discuss how structural recursion is encoded in type theory and category theory.&lt;/p&gt;</description><guid isPermaLink="true">https://bentnib.org/posts/2011-04-22-structural-recursion.html</guid><pubDate>Fri, 22 Apr 2011 00:00:00 +0000</pubDate></item></channel></rss>