# LC Definitions
This module defines a denotational semantics of the untyped λ-calculus in Agda,
corresponding to Dana Scott's original $D_\infty$ model.
The following options are needed in connection with the lightweight
formalisation of [function domains] in Agda.
```agda
{-# OPTIONS --rewriting --confluence-check --lossy-unification #-}
module LC.Definitions where
open import Notation
```
## Abstract Syntax
```agda
module Abstract-Syntax where
```
### Variables
A variable is written `x n`. The argument `n` merely distinguishes between
variables – it is *not* a De Bruin index.
```agda
open import Agda.Builtin.Nat public using (Nat)
data Var : Set where
x : Nat → Var
variable v : Var
```
### Terms
The term constructor `var` below merely includes variables in terms.
In Agda, mixfix notation requires arguments to be separated by characters
other than spaces. Below, the notation for application `⦅ e₁ ␣ e₂ ⦆` and
λ-abstraction `⦅λ v ␣ e ⦆` uses the Unicode character `␣` (representing a
space) as a separator. Application terms are also parenthesised, but using
`⦅…⦆` instead of ordinary parentheses.
```agda
data Exp : Set where
var_ : Var → Exp
⦅λ_␣_⦆ : Var → Exp → Exp
⦅_␣_⦆ : Exp → Exp → Exp
variable e e₁ e₂ : Exp
```
Abstract syntax is *not* regarded as a domain. All abstract syntax terms
are finite, and semantic functions are defined inductively.
## Domain equations
The domain equation `D∞ ≅ (D∞ →ᶜ D∞)` below declares the functions
`unfold : ⟪ D∞ →ᶜ (D∞ →ᶜ D∞) ⟫` and `fold : ⟪ (D∞ →ᶜ D∞) →ᶜ D∞ ⟫`,
corresponging to a bijection between the postulated domain `D∞` and
the domain of all continuous endofunctions on `D∞`. (Simply defining
`D∞ = (D∞ →ᶜ D∞)` would lead to non-termination of the Agda type-checker.)
```agda
module Domain-Equations where
open Abstract-Syntax
open Notation.Recursion using (_≅_; fold; unfold) public
postulate
D∞ : Domain
instance eqD∞ : D∞ ≅ (D∞ →ᶜ D∞)
variable δ : ⟪ D∞ ⟫
```
The one-point domain `𝟙` is a trivial solution for the above domain equation.
It could be excluded by postulating an embedding of any non-trivial domain
into `D∞`.
Environments `ρ` map variables to elements of the carrier of the postulated
domain `D∞`. The type `Env` could be treated as a domain by ordering the maps
pointwise.
```agda
Env = Var →ˢ D∞
variable ρ : ⟪ Env ⟫
```
The following definitions instantiate the conventional notation `ρ [ δ / v ]`
for the environment that maps `v` to `δ`, and maps other arguments as `ρ` does.
```agda
open Notation.Flat.Booleans using (Bool; Eq; _==_)
open Notation.Flat.Naturals using (eqNat)
_==ⱽ_ : Var → Var → Bool
open import Agda.Builtin.Nat renaming (_==_ to _==ᴺ_) public
open Notation.Updates using (_[_/_]) public
(x n ==ⱽ x n′) = (n ==ᴺ n′)
instance eqVar : Eq Var; _==_ {{eqVar}} = _==ⱽ_
```
## Semantic functions
The semantic equations below correspond closely to those found in textbooks
on denotational semantics. (The inverse functions `unfold` and `fold` between
domains and their definitions reflect that solutions of domain equations are
up to isomorphism, and are conventionally elided.)
```agda
module Semantic-Functions where
open Abstract-Syntax
open Domain-Equations
⟦_⟧ : Exp → ⟪ Env →ᶜ D∞ ⟫
⟦ var v ⟧ ρ = ρ v
⟦ ⦅λ v ␣ e ⦆ ⟧ ρ = fold ( λ δ → ⟦ e ⟧ (ρ [ δ / v ]) )
⟦ ⦅ e₁ ␣ e₂ ⦆ ⟧ ρ = unfold ( ⟦ e₁ ⟧ ρ ) ( ⟦ e₂ ⟧ ρ )
```
See the [Tests] module for some examples of abstract syntax terms and
equivalence proofs.
[Function domains]: ../../Notation/index.md#function-domains
[Tests]: ../Tests/index.md