---
title: Equality
date: 2023-09-15T05:36:53.757Z
tags:
  - type-theory
draft: true
---

When learning type theory, it's important to make a distinction between several
kinds of "same"-ness. Whenever you talk about two things being equal, you'd want
to qualify it with one of these in order to make it clear which you're referring
to, since they're very different concepts.

- **Definitional**, or **judgmental** equality. This is usually written with
  $\equiv$ in math. If you see $x \equiv y$, this says "I've defined $x$ and $y$
  to be the same, so anytime you see $x$, you can replace it with $y$ and vice
  versa."

  > [!NOTE]
  > Technically speaking, definitional and judgmental are two separate concepts
  > but coincide in many type theories. You could think of multiple levels of
  > equalities like this:
  >
  > - Does $2$ equal $2$? Yes. This is the same object, and equality is reflexive.
  > - Does $s(s(z))$ equal $2$? Well, typically this is how natural numbers are
  >   defined in type systems: $2 \equiv s(s(z))$. If somewhere before this, you
  >   said "let $2$ equal $s(s(z))$", then _by definition_ these are identical.
  > - Does $1 + 1$ equal $2$? The operation $+$ is a function, and requires a
  >   &beta;-reduction to evaluate any further. This choice really comes down to the
  >   choice of the type theory designer; if you wanted a more intensional type
  >   theory, you could choose to not allow &beta;-reduction during evaluation of
  >   identities. Most type theories _do_ allow this though.
  > - Does $x = y$ for any $x$ and $y$?
  >
  > As far as I understand, you can choose whatever to _be_ your "definitional"
  > equality,

- **Propositional** equality. This describes a _value_ that potentially holds
  true or false. This is typically written $=$ in math.

## Helpful tips

- You can talk about propositional equalities conditionally, like "if $a$ equals
  $b$, then $c$ is true". This kind of expression doesn't really make sense for
  judgmental equality, like in the following example:

  Suppose you made the judgment: $x = 2$. It makes no sense to then say "if $x$
  equals $2$, then $c$ is true." You can just skip right to $c$ is true, because
  you've defined it to be true, so it's useless even thinking about
  the case where it's false because that would be a part of a completely
  different world entirely.

- Here's a concrete example of the difference between judgmental and
  propositional equality. Consider these 2 expressions:

  - $2 + 3 = 3 + 2$
  - $\forall x\ y \in \mathbb{N} . (x + y = y + x)$

  In the first case, performing &beta;-reduction on both terms reduces to $5 =
  5$, which is definitionally equal by virtue of being the exact same symbol.

  In the second case however, &beta;-reduction is impossible. Without a specific
  $x$ or $y$, there's actually no way to reduce either side more. You would need
  some other constructs to prove it, such as induction.

- Suppose you were expressing these concepts in a language like TypeScript. The
  analog of a judgment would be something like:

  ```ts
  type Foo = string;
  ```

  Any time you're using `Foo`, you really don't have to compare it with
  `string`, because just through a simple substitution you will get the same
  symbol:

  ```
  function sayHello(who: string) { console.log(`Hello, ${who}`); }
  function run(foo: Foo) { sayHello(foo); }
  ```

  On the other hand, a propositional equality type might look something like
  this instead:

  ```ts
  class Equal<A, B> {
    private constructor() {}
    static refl<A>(): Equal<A, A> {}
  }
  ```

  You could have a value of this type, and query on its truthiness:

  ```ts
  type TwoEqualsTwo = Equal<Two, 2>;

  function trans<A, B, C>(x: Equal<A, B>, y: Equal<B, C>): Equal<A, C> {
    // magic...
  }
  ```

## Notation gotcha

The syntax we use in most math papers and other literature and the syntax we use
for equalities in various dependently-typed programming languages are annoyingly
different:

|               | Math         | Agda    | Coq      | Idris   |
| ------------- | ------------ | ------- | -------- | ------- |
| Judgmental    | $x \equiv y$ | `x = y` | `x := y` | `x = y` |
| Propositional | $x = y$      | `x ≡ y` | `x = y`  | `x = y` |

Usually there'll be some other pre-fix way of writing the propositional equals
in your language too. In Agda, it's `Path {A} x y`.

## More reading

- https://ncatlab.org/nlab/show/definitional+equality
- https://ncatlab.org/nlab/show/judgment
- https://ncatlab.org/nlab/show/judgmental+equality
- https://ncatlab.org/nlab/show/propositional+equality
- https://hott.github.io/book/hott-ebook.pdf.html
