Nameless, Painless · Nameless, Painless Nicolas Pouillard INRIA ICFP 2011, Tokyo September 21,...

Post on 16-Oct-2020

4 views 0 download

Transcript of Nameless, Painless · Nameless, Painless Nicolas Pouillard INRIA ICFP 2011, Tokyo September 21,...

Nameless, Painless

Nicolas Pouillard

INRIA

ICFP 2011, TokyoSeptember 21, 2011

1

Safe programming withde Bruijn indices

2

Warm-up

Here is a program in its textual form:

let id = λ x → x in

id (λ x → id x )

3

Nominal style

The same program represented as a tree, graphically depicted:

let

id λ

x V

x

App

V

id

λ

x App

V

id

V

x

4

De Bruijn style

Variable are represented by their distance to the binding node:

let

λ

V

0

App

V

0

λ

App

V

1

V

0

let id = λ x → x in

id (λ x → id x )

5

Bare de Bruijn λ-terms

data TmB : Set where

V : (x : N ) → TmB

_ ·_ : (t u : TmB) → TmB

ň : (t : TmB) → TmB

Let : (t u : TmB) → TmB

Examples:

apTmB = ň ( ň (V 1 · V 0 ) ) -- λ f → λ x → f x

ididTmB = Let ( ň (V 0 ) ) -- let id = λ x → x in

( ň (V 1 · V 0 ) ) -- λ x → id x

non-closedB : TmB

non-closedB = ň (V 1 · V 0 ) -- λ x → f x

6

Bare de Bruijn λ-terms

data TmB : Set where

V : (x : N ) → TmB

_ ·_ : (t u : TmB) → TmB

ň : (t : TmB) → TmB

Let : (t u : TmB) → TmB

Examples:

apTmB = ň ( ň (V 1 · V 0 ) ) -- λ f → λ x → f x

ididTmB = Let ( ň (V 0 ) ) -- let id = λ x → x in

( ň (V 1 · V 0 ) ) -- λ x → id x

non-closedB : TmB

non-closedB = ň (V 1 · V 0 ) -- λ x → f x

6

Bare de Bruijn λ-terms

data TmB : Set where

V : (x : N ) → TmB

_ ·_ : (t u : TmB) → TmB

ň : (t : TmB) → TmB

Let : (t u : TmB) → TmB

Examples:

apTmB = ň ( ň (V 1 · V 0 ) ) -- λ f → λ x → f x

ididTmB = Let ( ň (V 0 ) ) -- let id = λ x → x in

( ň (V 1 · V 0 ) ) -- λ x → id x

non-closedB : TmB

non-closedB = ň (V 1 · V 0 ) -- λ x → f x

6

Bare de Bruijn λ-terms

data TmB : Set where

V : (x : N ) → TmB

_ ·_ : (t u : TmB) → TmB

ň : (t : TmB) → TmB

Let : (t u : TmB) → TmB

Examples:

apTmB = ň ( ň (V 1 · V 0 ) ) -- λ f → λ x → f x

ididTmB = Let ( ň (V 0 ) ) -- let id = λ x → x in

( ň (V 1 · V 0 ) ) -- λ x → id x

non-closedB : TmB

non-closedB = ň (V 1 · V 0 ) -- λ x → f x

6

Bare de Bruijn λ-terms

data TmB : Set where

V : (x : N ) → TmB

_ ·_ : (t u : TmB) → TmB

ň : (t : TmB) → TmB

Let : (t u : TmB) → TmB

Examples:

apTmB = ň ( ň (V 1 · V 0 ) ) -- λ f → λ x → f x

ididTmB = Let ( ň (V 0 ) ) -- let id = λ x → x in

( ň (V 1 · V 0 ) ) -- λ x → id x

non-closedB : TmB

non-closedB = ň (V 1 · V 0 ) -- λ x → f x

6

Bare de Bruijn λ-terms

data TmB : Set where

V : (x : N ) → TmB

_ ·_ : (t u : TmB) → TmB

ň : (t : TmB) → TmB

Let : (t u : TmB) → TmB

Examples:

apTmB = ň ( ň (V 1 · V 0 ) ) -- λ f → λ x → f x

ididTmB = Let ( ň (V 0 ) ) -- let id = λ x → x in

( ň (V 1 · V 0 ) ) -- λ x → id x

non-closedB : TmB

non-closedB = ň (V 1 · V 0 ) -- λ x → f x

6

A predicate for well-scoped λ-terms

is-closed? : TmB → Set

is-closed? t = WS 0 t

data WS (n : N ) : TmB → Set where

WS-V : ∀ x →x < n →WS n (V x )

WS- · : ∀ t u →WS n t → WS n u →WS n (t · u )

WS-ň : ∀ t →WS (1 + n ) t →WS n ( ň t )

WS-Let : ∀ t u →WS n t → WS (1 + n ) u →WS n (Let t u )

7

A predicate for well-scoped λ-terms

is-closed? : TmB → Set

is-closed? t = WS 0 t

data WS (n : N ) : TmB → Set where

WS-V : ∀ x →x < n →WS n (V x )

WS- · : ∀ t u →WS n t → WS n u →WS n (t · u )

WS-ň : ∀ t →WS (1 + n ) t →WS n ( ň t )

WS-Let : ∀ t u →WS n t → WS (1 + n ) u →WS n (Let t u )

7

The Fin approach

data Fin : N → Set where -- Fin n ⇔ { i | i < n }zero : {n : N} → Fin (suc n )suc : {n : N} (i : Fin n ) → Fin (suc n )

_f : ∀ n → Fin (suc n )

data Tmf n : Set where

V : (x : Fin n ) → Tmf n

_ ·_ : (t u : Tmf n ) → Tmf n

ň : (t : Tmf (suc n ) ) → Tmf n

Let : (t : Tmf n ) (u : Tmf (suc n ) ) → Tmf n

apTmf : Tmf 0

apTmf = ň ( ň (V (1 f) · V (0 f) ) )non-closedf : Tmf 1

non-closedf = ň (V (1 f) · V (0 f) )

8

The Fin approach

data Fin : N → Set where -- Fin n ⇔ { i | i < n }zero : {n : N} → Fin (suc n )suc : {n : N} (i : Fin n ) → Fin (suc n )

_f : ∀ n → Fin (suc n )

data Tmf n : Set where

V : (x : Fin n ) → Tmf n

_ ·_ : (t u : Tmf n ) → Tmf n

ň : (t : Tmf (suc n ) ) → Tmf n

Let : (t : Tmf n ) (u : Tmf (suc n ) ) → Tmf n

apTmf : Tmf 0

apTmf = ň ( ň (V (1 f) · V (0 f) ) )non-closedf : Tmf 1

non-closedf = ň (V (1 f) · V (0 f) )

8

The Fin approach

data Fin : N → Set where -- Fin n ⇔ { i | i < n }zero : {n : N} → Fin (suc n )suc : {n : N} (i : Fin n ) → Fin (suc n )

_f : ∀ n → Fin (suc n )

data Tmf n : Set where

V : (x : Fin n ) → Tmf n

_ ·_ : (t u : Tmf n ) → Tmf n

ň : (t : Tmf (suc n ) ) → Tmf n

Let : (t : Tmf n ) (u : Tmf (suc n ) ) → Tmf n

apTmf : Tmf 0

apTmf = ň ( ň (V (1 f) · V (0 f) ) )non-closedf : Tmf 1

non-closedf = ň (V (1 f) · V (0 f) )8

The nested data type approach

data Maybe A : Set where -- nothing | just A

Maybe^ : N → Set → Set

_M : ∀ {A} n → Maybe^ n A

The type TmM is parameterized by the type of variables:

data TmM A : Set where

V : (x : A ) → TmM A

_ ·_ : (t u : TmM A ) → TmM A

ň : (t : TmM (Maybe A ) ) → TmM A

Let : (t : TmM A ) (u : TmM (Maybe A ) ) → TmM A

apTmM : TmM ⊥apTmM = ň ( ň (V (1 M) · V (0 M) ) )non-closedM : TmM (Maybe ⊥ )non-closedM = ň (V (1 M) · V (0 M) )

9

The nested data type approach

data Maybe A : Set where -- nothing | just A

Maybe^ : N → Set → Set

_M : ∀ {A} n → Maybe^ n A

The type TmM is parameterized by the type of variables:

data TmM A : Set where

V : (x : A ) → TmM A

_ ·_ : (t u : TmM A ) → TmM A

ň : (t : TmM (Maybe A ) ) → TmM A

Let : (t : TmM A ) (u : TmM (Maybe A ) ) → TmM A

apTmM : TmM ⊥apTmM = ň ( ň (V (1 M) · V (0 M) ) )non-closedM : TmM (Maybe ⊥ )non-closedM = ň (V (1 M) · V (0 M) )

9

The nested data type approach

data Maybe A : Set where -- nothing | just A

Maybe^ : N → Set → Set

_M : ∀ {A} n → Maybe^ n A

The type TmM is parameterized by the type of variables:

data TmM A : Set where

V : (x : A ) → TmM A

_ ·_ : (t u : TmM A ) → TmM A

ň : (t : TmM (Maybe A ) ) → TmM A

Let : (t : TmM A ) (u : TmM (Maybe A ) ) → TmM A

apTmM : TmM ⊥apTmM = ň ( ň (V (1 M) · V (0 M) ) )non-closedM : TmM (Maybe ⊥ )non-closedM = ň (V (1 M) · V (0 M) )

9

Motivations

Safe, yet expressive programming in de Bruijn style:

Safer than bare de Bruijn indices

Safer than using Fin ` or Maybe^ ` ⊥, yet as expressive

More expressive than using Maybe and FreshLook approaches

Expressiveness enables more efficient programs

Built for PL programmers, to write:

Compilers, evaluators...

Static analysers, type-checkers...

Proof assistants, logic systems...

Code generators, specializers, generic programs...

Built for “name library” writers:

To optimize techniques like nested with rewrite rules

To implement lighter interfaces like Locally nameless/named, HOAS

10

Motivations

Safe, yet expressive programming in de Bruijn style:

Safer than bare de Bruijn indices

Safer than using Fin ` or Maybe^ ` ⊥, yet as expressive

More expressive than using Maybe and FreshLook approaches

Expressiveness enables more efficient programs

Built for PL programmers, to write:

Compilers, evaluators...

Static analysers, type-checkers...

Proof assistants, logic systems...

Code generators, specializers, generic programs...

Built for “name library” writers:

To optimize techniques like nested with rewrite rules

To implement lighter interfaces like Locally nameless/named, HOAS

10

Motivations

Safe, yet expressive programming in de Bruijn style:

Safer than bare de Bruijn indices

Safer than using Fin ` or Maybe^ ` ⊥, yet as expressive

More expressive than using Maybe and FreshLook approaches

Expressiveness enables more efficient programs

Built for PL programmers, to write:

Compilers, evaluators...

Static analysers, type-checkers...

Proof assistants, logic systems...

Code generators, specializers, generic programs...

Built for “name library” writers:

To optimize techniques like nested with rewrite rules

To implement lighter interfaces like Locally nameless/named, HOAS

10

Motivations

Safe, yet expressive programming in de Bruijn style:

Safer than bare de Bruijn indices

Safer than using Fin ` or Maybe^ ` ⊥, yet as expressive

More expressive than using Maybe and FreshLook approaches

Expressiveness enables more efficient programs

Built for PL programmers, to write:

Compilers, evaluators...

Static analysers, type-checkers...

Proof assistants, logic systems...

Code generators, specializers, generic programs...

Built for “name library” writers:

To optimize techniques like nested with rewrite rules

To implement lighter interfaces like Locally nameless/named, HOAS

10

Motivations

Safe, yet expressive programming in de Bruijn style:

Safer than bare de Bruijn indices

Safer than using Fin ` or Maybe^ ` ⊥, yet as expressive

More expressive than using Maybe and FreshLook approaches

Expressiveness enables more efficient programs

Built for PL programmers, to write:

Compilers, evaluators...

Static analysers, type-checkers...

Proof assistants, logic systems...

Code generators, specializers, generic programs...

Built for “name library” writers:

To optimize techniques like nested with rewrite rules

To implement lighter interfaces like Locally nameless/named, HOAS

10

Motivations

Safe, yet expressive programming in de Bruijn style:

Safer than bare de Bruijn indices

Safer than using Fin ` or Maybe^ ` ⊥, yet as expressive

More expressive than using Maybe and FreshLook approaches

Expressiveness enables more efficient programs

Built for PL programmers, to write:

Compilers, evaluators...

Static analysers, type-checkers...

Proof assistants, logic systems...

Code generators, specializers, generic programs...

Built for “name library” writers:

To optimize techniques like nested with rewrite rules

To implement lighter interfaces like Locally nameless/named, HOAS

10

Motivations

Safe, yet expressive programming in de Bruijn style:

Safer than bare de Bruijn indices

Safer than using Fin ` or Maybe^ ` ⊥, yet as expressive

More expressive than using Maybe and FreshLook approaches

Expressiveness enables more efficient programs

Built for PL programmers, to write:

Compilers, evaluators...

Static analysers, type-checkers...

Proof assistants, logic systems...

Code generators, specializers, generic programs...

Built for “name library” writers:

To optimize techniques like nested with rewrite rules

To implement lighter interfaces like Locally nameless/named, HOAS

10

Motivations

Safe, yet expressive programming in de Bruijn style:

Safer than bare de Bruijn indices

Safer than using Fin ` or Maybe^ ` ⊥, yet as expressive

More expressive than using Maybe and FreshLook approaches

Expressiveness enables more efficient programs

Built for PL programmers, to write:

Compilers, evaluators...

Static analysers, type-checkers...

Proof assistants, logic systems...

Code generators, specializers, generic programs...

Built for “name library” writers:

To optimize techniques like nested with rewrite rules

To implement lighter interfaces like Locally nameless/named, HOAS

10

Motivations

Safe, yet expressive programming in de Bruijn style:

Safer than bare de Bruijn indices

Safer than using Fin ` or Maybe^ ` ⊥, yet as expressive

More expressive than using Maybe and FreshLook approaches

Expressiveness enables more efficient programs

Built for PL programmers, to write:

Compilers, evaluators...

Static analysers, type-checkers...

Proof assistants, logic systems...

Code generators, specializers, generic programs...

Built for “name library” writers:

To optimize techniques like nested with rewrite rules

To implement lighter interfaces like Locally nameless/named, HOAS

10

Motivations

Safe, yet expressive programming in de Bruijn style:

Safer than bare de Bruijn indices

Safer than using Fin ` or Maybe^ ` ⊥, yet as expressive

More expressive than using Maybe and FreshLook approaches

Expressiveness enables more efficient programs

Built for PL programmers, to write:

Compilers, evaluators...

Static analysers, type-checkers...

Proof assistants, logic systems...

Code generators, specializers, generic programs...

Built for “name library” writers:

To optimize techniques like nested with rewrite rules

To implement lighter interfaces like Locally nameless/named, HOAS

10

Motivations

Safe, yet expressive programming in de Bruijn style:

Safer than bare de Bruijn indices

Safer than using Fin ` or Maybe^ ` ⊥, yet as expressive

More expressive than using Maybe and FreshLook approaches

Expressiveness enables more efficient programs

Built for PL programmers, to write:

Compilers, evaluators...

Static analysers, type-checkers...

Proof assistants, logic systems...

Code generators, specializers, generic programs...

Built for “name library” writers:

To optimize techniques like nested with rewrite rules

To implement lighter interfaces like Locally nameless/named, HOAS

10

Motivations

Safe, yet expressive programming in de Bruijn style:

Safer than bare de Bruijn indices

Safer than using Fin ` or Maybe^ ` ⊥, yet as expressive

More expressive than using Maybe and FreshLook approaches

Expressiveness enables more efficient programs

Built for PL programmers, to write:

Compilers, evaluators...

Static analysers, type-checkers...

Proof assistants, logic systems...

Code generators, specializers, generic programs...

Built for “name library” writers:

To optimize techniques like nested with rewrite rules

To implement lighter interfaces like Locally nameless/named, HOAS

10

Motivations

Safe, yet expressive programming in de Bruijn style:

Safer than bare de Bruijn indices

Safer than using Fin ` or Maybe^ ` ⊥, yet as expressive

More expressive than using Maybe and FreshLook approaches

Expressiveness enables more efficient programs

Built for PL programmers, to write:

Compilers, evaluators...

Static analysers, type-checkers...

Proof assistants, logic systems...

Code generators, specializers, generic programs...

Built for “name library” writers:

To optimize techniques like nested with rewrite rules

To implement lighter interfaces like Locally nameless/named, HOAS

10

NaPa types

record NaPa : Set1 where

field

-- Worlds can be thought of finite sets of numbers:

World : Set

-- Worlds are built out of these operations:

∅ : World

-- α +1 ⇔ { x + 1 | x ∈ α }_+1 : World → World

-- α ↑1 ⇔ { 0 } ∪ α +1

_↑1 : World → World

-- Names inhabits worlds:

Name : World → Set

-- World inclusion witnesses

_⊆_ : World → World → Set

11

NaPa types

record NaPa : Set1 where

field

-- Worlds can be thought of finite sets of numbers:

World : Set

-- Worlds are built out of these operations:

∅ : World

-- α +1 ⇔ { x + 1 | x ∈ α }_+1 : World → World

-- α ↑1 ⇔ { 0 } ∪ α +1

_↑1 : World → World

-- Names inhabits worlds:

Name : World → Set

-- World inclusion witnesses

_⊆_ : World → World → Set

11

NaPa types

record NaPa : Set1 where

field

-- Worlds can be thought of finite sets of numbers:

World : Set

-- Worlds are built out of these operations:

∅ : World

-- α +1 ⇔ { x + 1 | x ∈ α }_+1 : World → World

-- α ↑1 ⇔ { 0 } ∪ α +1

_↑1 : World → World

-- Names inhabits worlds:

Name : World → Set

-- World inclusion witnesses

_⊆_ : World → World → Set

11

NaPa types (cont.)

Iterated versions of _+1 and _↑1 are derived:

record NaPa : Set1 where

. . ._+W_ : World → N → World

α +W 0 = αα +W suc n = (α +W n )+1

_↑_ : World → N → World

α ↑ 0 = αα ↑ suc n = (α ↑ n )↑1

12

NaPa operations

record NaPa : Set1 where

. . .field

zeroN : ∀ {α} → Name (α ↑1 )

addN : ∀ {α} k → Name α → Name (α +W k )subtractN : ∀ {α} k → Name (α +W k ) → Name αcmpN : ∀ {α} k → Name (α ↑ k ) → Name (∅ ↑ k )

] Name (α +W k )

_==N_ : ∀ {α} → Name α → Name α → Bool

coerceN : ∀ {α β} → (α ⊆ β ) → (Name α → Name β )¬Name∅ : Name ∅ → ⊥

_N : ∀ {α} ` → Name (α ↑ suc ` )` N = coerceN {! omitted !} (addN ` zeroN)

13

NaPa operations

record NaPa : Set1 where

. . .field

zeroN : ∀ {α} → Name (α ↑1 )addN : ∀ {α} k → Name α → Name (α +W k )

subtractN : ∀ {α} k → Name (α +W k ) → Name αcmpN : ∀ {α} k → Name (α ↑ k ) → Name (∅ ↑ k )

] Name (α +W k )

_==N_ : ∀ {α} → Name α → Name α → Bool

coerceN : ∀ {α β} → (α ⊆ β ) → (Name α → Name β )¬Name∅ : Name ∅ → ⊥

_N : ∀ {α} ` → Name (α ↑ suc ` )` N = coerceN {! omitted !} (addN ` zeroN)

13

NaPa operations

record NaPa : Set1 where

. . .field

zeroN : ∀ {α} → Name (α ↑1 )addN : ∀ {α} k → Name α → Name (α +W k )subtractN : ∀ {α} k → Name (α +W k ) → Name α

cmpN : ∀ {α} k → Name (α ↑ k ) → Name (∅ ↑ k )] Name (α +W k )

_==N_ : ∀ {α} → Name α → Name α → Bool

coerceN : ∀ {α β} → (α ⊆ β ) → (Name α → Name β )¬Name∅ : Name ∅ → ⊥

_N : ∀ {α} ` → Name (α ↑ suc ` )` N = coerceN {! omitted !} (addN ` zeroN)

13

NaPa operations

record NaPa : Set1 where

. . .field

zeroN : ∀ {α} → Name (α ↑1 )addN : ∀ {α} k → Name α → Name (α +W k )subtractN : ∀ {α} k → Name (α +W k ) → Name αcmpN : ∀ {α} k → Name (α ↑ k ) → Name (∅ ↑ k )

] Name (α +W k )

_==N_ : ∀ {α} → Name α → Name α → Bool

coerceN : ∀ {α β} → (α ⊆ β ) → (Name α → Name β )¬Name∅ : Name ∅ → ⊥

_N : ∀ {α} ` → Name (α ↑ suc ` )` N = coerceN {! omitted !} (addN ` zeroN)

13

NaPa operations

record NaPa : Set1 where

. . .field

zeroN : ∀ {α} → Name (α ↑1 )addN : ∀ {α} k → Name α → Name (α +W k )subtractN : ∀ {α} k → Name (α +W k ) → Name αcmpN : ∀ {α} k → Name (α ↑ k ) → Name (∅ ↑ k )

] Name (α +W k )

_==N_ : ∀ {α} → Name α → Name α → Bool

coerceN : ∀ {α β} → (α ⊆ β ) → (Name α → Name β )¬Name∅ : Name ∅ → ⊥

_N : ∀ {α} ` → Name (α ↑ suc ` )` N = coerceN {! omitted !} (addN ` zeroN)

13

NaPa operations

record NaPa : Set1 where

. . .field

zeroN : ∀ {α} → Name (α ↑1 )addN : ∀ {α} k → Name α → Name (α +W k )subtractN : ∀ {α} k → Name (α +W k ) → Name αcmpN : ∀ {α} k → Name (α ↑ k ) → Name (∅ ↑ k )

] Name (α +W k )

_==N_ : ∀ {α} → Name α → Name α → Bool

coerceN : ∀ {α β} → (α ⊆ β ) → (Name α → Name β )¬Name∅ : Name ∅ → ⊥

_N : ∀ {α} ` → Name (α ↑ suc ` )` N = coerceN {! omitted !} (addN ` zeroN)

13

Terms indexed by worlds

data TmD α : Set where

V : (x : Name α) → TmD α_ ·_ : (t u : TmD α) → TmD αň : (t : TmD (α ↑1 ) ) → TmD αLet : (t : TmD α) (u : TmD (α ↑1 ) ) → TmD α

Examples:

apTmD : TmD ∅apTmD = ň ( ň (V (1 N) · V (0 N) ) )

non-closedD : TmD (∅ ↑ 1 )non-closedD = ň (V (1 N) · V (0 N) )

14

Terms indexed by worlds

data TmD α : Set where

V : (x : Name α) → TmD α_ ·_ : (t u : TmD α) → TmD αň : (t : TmD (α ↑1 ) ) → TmD αLet : (t : TmD α) (u : TmD (α ↑1 ) ) → TmD α

Examples:

apTmD : TmD ∅apTmD = ň ( ň (V (1 N) · V (0 N) ) )

non-closedD : TmD (∅ ↑ 1 )non-closedD = ň (V (1 N) · V (0 N) )

14

Building a renaming function

Derived from addN, cmpN, subtractN, and coerceN:

sucN↑ : ∀ {α} → Name α → Name (α ↑1 )predN? : ∀ {α} → Name (α ↑1 ) → Maybe (Name α)

Can we shift a function ?

protect↑1 : ∀ {α β} → (Name α → Name β )→ (Name (α ↑1 ) → Name (β ↑1 ) )

protect↑1 f = maybe (sucN↑ ◦ f ) zeroN ◦ predN?

We use protect↑1 to move under name-abstractions:

renameTmD : ∀ {α β} → (Name α → Name β )→ (TmD α → TmD β )

renameTmD f (V x ) = V (f x )renameTmD f (t · u ) = renameTmD f t · renameTmD f u

renameTmD f ( ň t ) = ň (renameTmD (protect↑1 f ) t )

15

Building a renaming function

Derived from addN, cmpN, subtractN, and coerceN:

sucN↑ : ∀ {α} → Name α → Name (α ↑1 )predN? : ∀ {α} → Name (α ↑1 ) → Maybe (Name α)

Can we shift a function ?

protect↑1 : ∀ {α β} → (Name α → Name β )→ (Name (α ↑1 ) → Name (β ↑1 ) )

protect↑1 f = maybe (sucN↑ ◦ f ) zeroN ◦ predN?

We use protect↑1 to move under name-abstractions:

renameTmD : ∀ {α β} → (Name α → Name β )→ (TmD α → TmD β )

renameTmD f (V x ) = V (f x )renameTmD f (t · u ) = renameTmD f t · renameTmD f u

renameTmD f ( ň t ) = ň (renameTmD (protect↑1 f ) t )

15

Building a renaming function

Derived from addN, cmpN, subtractN, and coerceN:

sucN↑ : ∀ {α} → Name α → Name (α ↑1 )predN? : ∀ {α} → Name (α ↑1 ) → Maybe (Name α)

Can we shift a function ?

protect↑1 : ∀ {α β} → (Name α → Name β )→ (Name (α ↑1 ) → Name (β ↑1 ) )

protect↑1 f = maybe (sucN↑ ◦ f ) zeroN ◦ predN?

We use protect↑1 to move under name-abstractions:

renameTmD : ∀ {α β} → (Name α → Name β )→ (TmD α → TmD β )

renameTmD f (V x ) = V (f x )renameTmD f (t · u ) = renameTmD f t · renameTmD f u

renameTmD f ( ň t ) = ň (renameTmD (protect↑1 f ) t )15

Derived operations and advanced examples

We can build a lot more: free-variables, comparison, NBE...

traverseTmD generalizes renameTmD in three ways !

Applying traverseTmD yields many functions...

... including shifting and substitution functions

All the details are in the paper !

16

Derived operations and advanced examples

We can build a lot more: free-variables, comparison, NBE...

traverseTmD generalizes renameTmD in three ways !

Applying traverseTmD yields many functions...

... including shifting and substitution functions

All the details are in the paper !

16

Derived operations and advanced examples

We can build a lot more: free-variables, comparison, NBE...

traverseTmD generalizes renameTmD in three ways !

Applying traverseTmD yields many functions...

... including shifting and substitution functions

All the details are in the paper !

16

Derived operations and advanced examples

We can build a lot more: free-variables, comparison, NBE...

traverseTmD generalizes renameTmD in three ways !

Applying traverseTmD yields many functions...

... including shifting and substitution functions

All the details are in the paper !

16

Derived operations and advanced examples

We can build a lot more: free-variables, comparison, NBE...

traverseTmD generalizes renameTmD in three ways !

Applying traverseTmD yields many functions...

... including shifting and substitution functions

All the details are in the paper !

16

Soundness properties

17

Logical relations save the day !

e : τ

-- for each program well-typed

J e K : J τ K e e-- one theorem for free

JNK x1 x2 = x1 ≡ x2 -- Relations indexed by types

-- Extensionality on functions

(Ar J→K Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br (f1 x1) (f2 x2)

-- Extends nicely to dependent types

( JΠK Ar Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br xr (f1 x1) (f2 x2)

JSetK A1 A2 = A1 → A2 → Set

18

Logical relations save the day !

e : τ -- for each program well-typed

J e K : J τ K e e-- one theorem for free

JNK x1 x2 = x1 ≡ x2 -- Relations indexed by types

-- Extensionality on functions

(Ar J→K Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br (f1 x1) (f2 x2)

-- Extends nicely to dependent types

( JΠK Ar Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br xr (f1 x1) (f2 x2)

JSetK A1 A2 = A1 → A2 → Set

18

Logical relations save the day !

e : τ -- for each program well-typed

J e K : J τ K e e

-- one theorem for free

JNK x1 x2 = x1 ≡ x2 -- Relations indexed by types

-- Extensionality on functions

(Ar J→K Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br (f1 x1) (f2 x2)

-- Extends nicely to dependent types

( JΠK Ar Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br xr (f1 x1) (f2 x2)

JSetK A1 A2 = A1 → A2 → Set

18

Logical relations save the day !

e : τ -- for each program well-typed

J e K : J τ K e e-- one theorem for free

JNK x1 x2 = x1 ≡ x2 -- Relations indexed by types

-- Extensionality on functions

(Ar J→K Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br (f1 x1) (f2 x2)

-- Extends nicely to dependent types

( JΠK Ar Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br xr (f1 x1) (f2 x2)

JSetK A1 A2 = A1 → A2 → Set

18

Logical relations save the day !

e : τ -- for each program well-typed

J e K : J τ K e e-- one theorem for free

JNK x1 x2 = x1 ≡ x2

-- Relations indexed by types

-- Extensionality on functions

(Ar J→K Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br (f1 x1) (f2 x2)

-- Extends nicely to dependent types

( JΠK Ar Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br xr (f1 x1) (f2 x2)

JSetK A1 A2 = A1 → A2 → Set

18

Logical relations save the day !

e : τ -- for each program well-typed

J e K : J τ K e e-- one theorem for free

JNK x1 x2 = x1 ≡ x2 -- Relations indexed by types

-- Extensionality on functions

(Ar J→K Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br (f1 x1) (f2 x2)

-- Extends nicely to dependent types

( JΠK Ar Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br xr (f1 x1) (f2 x2)

JSetK A1 A2 = A1 → A2 → Set

18

Logical relations save the day !

e : τ -- for each program well-typed

J e K : J τ K e e-- one theorem for free

JNK x1 x2 = x1 ≡ x2 -- Relations indexed by types

-- Extensionality on functions

(Ar J→K Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br (f1 x1) (f2 x2)

-- Extends nicely to dependent types

( JΠK Ar Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br xr (f1 x1) (f2 x2)

JSetK A1 A2 = A1 → A2 → Set

18

Logical relations save the day !

e : τ -- for each program well-typed

J e K : J τ K e e-- one theorem for free

JNK x1 x2 = x1 ≡ x2 -- Relations indexed by types

-- Extensionality on functions

(Ar J→K Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br (f1 x1) (f2 x2)

-- Extends nicely to dependent types

( JΠK Ar Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br xr (f1 x1) (f2 x2)

JSetK A1 A2 = A1 → A2 → Set

18

Logical relations save the day !

e : τ -- for each program well-typed

J e K : J τ K e e-- one theorem for free

JNK x1 x2 = x1 ≡ x2 -- Relations indexed by types

-- Extensionality on functions

(Ar J→K Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br (f1 x1) (f2 x2)

-- Extends nicely to dependent types

( JΠK Ar Br ) f1 f2 = ∀ {x1 x2} (xr : Ar x1 x2)→ Br xr (f1 x1) (f2 x2)

JSetK A1 A2 = A1 → A2 → Set

18

Free theorems for library clients

c : (lib : NomPa ) → τ

c : ∀ World Name _==N_ . . . → τ

JcK : J ∀ World Name _==N_ . . . → τ K c c

JcK : (∀〈 JWorldK : JSetK 〉J→K∀〈 JNameK : JWorldK J→K JSetK 〉J→K∀〈 _J==NK_ : . . . 〉J→K. . . J→K J τ K ) c c

JcK : ∀ {W1 W2} ( JWorldK : W1 → W2 → Set ){N1 N2} ( JNameK : . . . N1 N2){==1 ==2} (_J==NK_ : . . . ==1 ==2)

. . . → ( J τ K (c . . . ) (c . . . ) )

19

Free theorems for library clients

c : (lib : NomPa ) → τ

c : ∀ World Name _==N_ . . . → τ

JcK : J ∀ World Name _==N_ . . . → τ K c c

JcK : (∀〈 JWorldK : JSetK 〉J→K∀〈 JNameK : JWorldK J→K JSetK 〉J→K∀〈 _J==NK_ : . . . 〉J→K. . . J→K J τ K ) c c

JcK : ∀ {W1 W2} ( JWorldK : W1 → W2 → Set ){N1 N2} ( JNameK : . . . N1 N2){==1 ==2} (_J==NK_ : . . . ==1 ==2)

. . . → ( J τ K (c . . . ) (c . . . ) )

19

Free theorems for library clients

c : (lib : NomPa ) → τ

c : ∀ World Name _==N_ . . . → τ

JcK : J ∀ World Name _==N_ . . . → τ K c c

JcK : (∀〈 JWorldK : JSetK 〉J→K∀〈 JNameK : JWorldK J→K JSetK 〉J→K∀〈 _J==NK_ : . . . 〉J→K. . . J→K J τ K ) c c

JcK : ∀ {W1 W2} ( JWorldK : W1 → W2 → Set ){N1 N2} ( JNameK : . . . N1 N2){==1 ==2} (_J==NK_ : . . . ==1 ==2)

. . . → ( J τ K (c . . . ) (c . . . ) )

19

Free theorems for library clients

c : (lib : NomPa ) → τ

c : ∀ World Name _==N_ . . . → τ

JcK : J ∀ World Name _==N_ . . . → τ K c c

JcK : (∀〈 JWorldK : JSetK 〉J→K∀〈 JNameK : JWorldK J→K JSetK 〉J→K∀〈 _J==NK_ : . . . 〉J→K. . . J→K J τ K ) c c

JcK : ∀ {W1 W2} ( JWorldK : W1 → W2 → Set ){N1 N2} ( JNameK : . . . N1 N2){==1 ==2} (_J==NK_ : . . . ==1 ==2)

. . . → ( J τ K (c . . . ) (c . . . ) )

19

Free theorems for library clients

c : (lib : NomPa ) → τ

c : ∀ World Name _==N_ . . . → τ

JcK : J ∀ World Name _==N_ . . . → τ K c c

JcK : (∀〈 JWorldK : JSetK 〉J→K∀〈 JNameK : JWorldK J→K JSetK 〉J→K∀〈 _J==NK_ : . . . 〉J→K. . . J→K J τ K ) c c

JcK : ∀ {W1 W2} ( JWorldK : W1 → W2 → Set ){N1 N2} ( JNameK : . . . N1 N2){==1 ==2} (_J==NK_ : . . . ==1 ==2)

. . . → ( J τ K (c . . . ) (c . . . ) )

19

NaPa soundness, modularly

module JNomPaK where

record JWorldK (α1 α2 : World ) : Set1 where

constructor _,_

field R : Name α1 → Name α2 → Set

field R-pres-≡ : ∀ x1 y1 x2 y2 → R x1 x2 → R y1 y2

→ x1 ≡ y1 ↔ x2 ≡ y2

JNameK (R , _ ) x1 x2 = R x1 x2

JzeroNK : J ∀ {α} → Name (α ↑1 ) K zeroN zeroN

-- all our functions inhabit the logical relation

J==NK, JaddNK, ...

Wrong functions get rejected, though ! (isEven?, _≤_, ...)

20

NaPa soundness, modularly

module JNomPaK where

record JWorldK (α1 α2 : World ) : Set1 where

constructor _,_

field R : Name α1 → Name α2 → Set

field R-pres-≡ : ∀ x1 y1 x2 y2 → R x1 x2 → R y1 y2

→ x1 ≡ y1 ↔ x2 ≡ y2

JNameK (R , _ ) x1 x2 = R x1 x2

JzeroNK : J ∀ {α} → Name (α ↑1 ) K zeroN zeroN

-- all our functions inhabit the logical relation

J==NK, JaddNK, ...

Wrong functions get rejected, though ! (isEven?, _≤_, ...)

20

NaPa soundness, modularly

module JNomPaK where

record JWorldK (α1 α2 : World ) : Set1 where

constructor _,_

field R : Name α1 → Name α2 → Set

field R-pres-≡ : ∀ x1 y1 x2 y2 → R x1 x2 → R y1 y2

→ x1 ≡ y1 ↔ x2 ≡ y2

JNameK (R , _ ) x1 x2 = R x1 x2

JzeroNK : J ∀ {α} → Name (α ↑1 ) K zeroN zeroN

-- all our functions inhabit the logical relation

J==NK, JaddNK, ...

Wrong functions get rejected, though ! (isEven?, _≤_, ...)

20

NaPa soundness, modularly

module JNomPaK where

record JWorldK (α1 α2 : World ) : Set1 where

constructor _,_

field R : Name α1 → Name α2 → Set

field R-pres-≡ : ∀ x1 y1 x2 y2 → R x1 x2 → R y1 y2

→ x1 ≡ y1 ↔ x2 ≡ y2

JNameK (R , _ ) x1 x2 = R x1 x2

JzeroNK : J ∀ {α} → Name (α ↑1 ) K zeroN zeroN

-- all our functions inhabit the logical relation

J==NK, JaddNK, ...

Wrong functions get rejected, though ! (isEven?, _≤_, ...)

20

NaPa soundness, modularly

module JNomPaK where

record JWorldK (α1 α2 : World ) : Set1 where

constructor _,_

field R : Name α1 → Name α2 → Set

field R-pres-≡ : ∀ x1 y1 x2 y2 → R x1 x2 → R y1 y2

→ x1 ≡ y1 ↔ x2 ≡ y2

JNameK (R , _ ) x1 x2 = R x1 x2

JzeroNK : J ∀ {α} → Name (α ↑1 ) K zeroN zeroN

-- all our functions inhabit the logical relation

J==NK, JaddNK, ...

Wrong functions get rejected, though ! (isEven?, _≤_, ...)

20

Free theorems for library clients (cont.)

f : ∀ {α} → Name α → Bool

fr : (∀〈 αr : JWorldK 〉J→K JNameK αr J→K JBoolK ) f f

f-const : ∀ x1 x2 → f x1 ≡ f x2

Ren : (α β : World ) → Set

〈_〉 : ∀ {α β} → Ren α β → TmD α → TmD β

f : ∀ {α} → TmD α → TmD α

fr : (∀〈 αr : JWorldK 〉J→K JTmDK αr J→K JTmDK αr ) f f

f-comm-ren : ∀ {α β} ( Φ : Ren α β ) → 〈 Φ 〉 ◦ f $ f ◦ 〈 Φ 〉

21

Free theorems for library clients (cont.)

f : ∀ {α} → Name α → Bool

fr : (∀〈 αr : JWorldK 〉J→K JNameK αr J→K JBoolK ) f f

f-const : ∀ x1 x2 → f x1 ≡ f x2

Ren : (α β : World ) → Set

〈_〉 : ∀ {α β} → Ren α β → TmD α → TmD β

f : ∀ {α} → TmD α → TmD α

fr : (∀〈 αr : JWorldK 〉J→K JTmDK αr J→K JTmDK αr ) f f

f-comm-ren : ∀ {α β} ( Φ : Ren α β ) → 〈 Φ 〉 ◦ f $ f ◦ 〈 Φ 〉

21

Free theorems for library clients (cont.)

f : ∀ {α} → Name α → Bool

fr : (∀〈 αr : JWorldK 〉J→K JNameK αr J→K JBoolK ) f f

f-const : ∀ x1 x2 → f x1 ≡ f x2

Ren : (α β : World ) → Set

〈_〉 : ∀ {α β} → Ren α β → TmD α → TmD β

f : ∀ {α} → TmD α → TmD α

fr : (∀〈 αr : JWorldK 〉J→K JTmDK αr J→K JTmDK αr ) f f

f-comm-ren : ∀ {α β} ( Φ : Ren α β ) → 〈 Φ 〉 ◦ f $ f ◦ 〈 Φ 〉

21

Free theorems for library clients (cont.)

f : ∀ {α} → Name α → Bool

fr : (∀〈 αr : JWorldK 〉J→K JNameK αr J→K JBoolK ) f f

f-const : ∀ x1 x2 → f x1 ≡ f x2

Ren : (α β : World ) → Set

〈_〉 : ∀ {α β} → Ren α β → TmD α → TmD β

f : ∀ {α} → TmD α → TmD α

fr : (∀〈 αr : JWorldK 〉J→K JTmDK αr J→K JTmDK αr ) f f

f-comm-ren : ∀ {α β} ( Φ : Ren α β ) → 〈 Φ 〉 ◦ f $ f ◦ 〈 Φ 〉

21

Free theorems for library clients (cont.)

f : ∀ {α} → Name α → Bool

fr : (∀〈 αr : JWorldK 〉J→K JNameK αr J→K JBoolK ) f f

f-const : ∀ x1 x2 → f x1 ≡ f x2

Ren : (α β : World ) → Set

〈_〉 : ∀ {α β} → Ren α β → TmD α → TmD β

f : ∀ {α} → TmD α → TmD α

fr : (∀〈 αr : JWorldK 〉J→K JTmDK αr J→K JTmDK αr ) f f

f-comm-ren : ∀ {α β} ( Φ : Ren α β ) → 〈 Φ 〉 ◦ f $ f ◦ 〈 Φ 〉

21

Free theorems for library clients (cont.)

f : ∀ {α} → Name α → Bool

fr : (∀〈 αr : JWorldK 〉J→K JNameK αr J→K JBoolK ) f f

f-const : ∀ x1 x2 → f x1 ≡ f x2

Ren : (α β : World ) → Set

〈_〉 : ∀ {α β} → Ren α β → TmD α → TmD β

f : ∀ {α} → TmD α → TmD α

fr : (∀〈 αr : JWorldK 〉J→K JTmDK αr J→K JTmDK αr ) f f

f-comm-ren : ∀ {α β} ( Φ : Ren α β ) → 〈 Φ 〉 ◦ f $ f ◦ 〈 Φ 〉

21

Free theorems for library clients (cont.)

f : ∀ {α} → Name α → Bool

fr : (∀〈 αr : JWorldK 〉J→K JNameK αr J→K JBoolK ) f f

f-const : ∀ x1 x2 → f x1 ≡ f x2

Ren : (α β : World ) → Set

〈_〉 : ∀ {α β} → Ren α β → TmD α → TmD β

f : ∀ {α} → TmD α → TmD α

fr : (∀〈 αr : JWorldK 〉J→K JTmDK αr J→K JTmDK αr ) f f

f-comm-ren : ∀ {α β} ( Φ : Ren α β ) → 〈 Φ 〉 ◦ f $ f ◦ 〈 Φ 〉

21

NaPa is a subset of NomPa

The NomPa interface have a few more functions

. . . including a wide set of world inclusions witnesses

not only de Bruijn style binders

Nominal style binders

de Bruijn levels

Combinations of these different styles

Many generic operations and examples

Encoding of various other binding techniques

22

NaPa is a subset of NomPa

The NomPa interface have a few more functions

. . . including a wide set of world inclusions witnesses

not only de Bruijn style binders

Nominal style binders

de Bruijn levels

Combinations of these different styles

Many generic operations and examples

Encoding of various other binding techniques

22

NaPa is a subset of NomPa

The NomPa interface have a few more functions

. . . including a wide set of world inclusions witnesses

not only de Bruijn style binders

Nominal style binders

de Bruijn levels

Combinations of these different styles

Many generic operations and examples

Encoding of various other binding techniques

22

NaPa is a subset of NomPa

The NomPa interface have a few more functions

. . . including a wide set of world inclusions witnesses

not only de Bruijn style binders

Nominal style binders

de Bruijn levels

Combinations of these different styles

Many generic operations and examples

Encoding of various other binding techniques

22

NaPa is a subset of NomPa

The NomPa interface have a few more functions

. . . including a wide set of world inclusions witnesses

not only de Bruijn style binders

Nominal style binders

de Bruijn levels

Combinations of these different styles

Many generic operations and examples

Encoding of various other binding techniques

22

NaPa is a subset of NomPa

The NomPa interface have a few more functions

. . . including a wide set of world inclusions witnesses

not only de Bruijn style binders

Nominal style binders

de Bruijn levels

Combinations of these different styles

Many generic operations and examples

Encoding of various other binding techniques

22

NaPa is a subset of NomPa

The NomPa interface have a few more functions

. . . including a wide set of world inclusions witnesses

not only de Bruijn style binders

Nominal style binders

de Bruijn levels

Combinations of these different styles

Many generic operations and examples

Encoding of various other binding techniques

22

NaPa is a subset of NomPa

The NomPa interface have a few more functions

. . . including a wide set of world inclusions witnesses

not only de Bruijn style binders

Nominal style binders

de Bruijn levels

Combinations of these different styles

Many generic operations and examples

Encoding of various other binding techniques

22

Conclusion

Safety through abstract types on names

_+1 is a new operation on worlds. Fin was not enough !

Safe bulk operations (+k, ↑k)

All in Agda, code, formalization, and proofs

Free theorems available on-line

23

Conclusion

Safety through abstract types on names

_+1 is a new operation on worlds. Fin was not enough !

Safe bulk operations (+k, ↑k)

All in Agda, code, formalization, and proofs

Free theorems available on-line

23

Conclusion

Safety through abstract types on names

_+1 is a new operation on worlds. Fin was not enough !

Safe bulk operations (+k, ↑k)

All in Agda, code, formalization, and proofs

Free theorems available on-line

23

Conclusion

Safety through abstract types on names

_+1 is a new operation on worlds. Fin was not enough !

Safe bulk operations (+k, ↑k)

All in Agda, code, formalization, and proofs

Free theorems available on-line

23

Conclusion

Safety through abstract types on names

_+1 is a new operation on worlds. Fin was not enough !

Safe bulk operations (+k, ↑k)

All in Agda, code, formalization, and proofs

Free theorems available on-line

23

Bonus tracksBuilding world inclusion witnesses

Shifting versus adding example

Connecting approaches with type-isomorphisms

The Fin approach is too concrete

Traverse

Traverse (cont.)

Normalization by evaluation

Shifting is: renaming with an addition

Shifting a name

Renaming without protect↑

How dangerous this kind of programming is ?

Shifting gets a finer type

. . . and a faster implementation

How precise are worlds ? Singletons worlds !

24

Building world inclusion witnesses

_⊆_ : World → World → Set

⊆-refl : Reflexive _⊆_⊆-trans : Transitive _⊆_⊆-∅ : ∀ {α} → ∅ ⊆ α

⊆-∅+1 : ∅ +1 ⊆ ∅⊆-↑1-↑1 : ∀{α β}→ α ⊆ β ↔ α ↑1 ⊆ β ↑1⊆-+1-+1 : ∀{α β}→ α ⊆ β ↔ α +1 ⊆ β +1

⊆-+1-↑1 : ∀{α}→ α +1 ⊆ α ↑1

Back

25

Shifting versus adding example

•0 • 0

•1 • 1

•2 • 2

•3 • 3

αr

•0 • 0

•1 • 1

•2 • 2

•3 • 3

•4 • 4

αr J+1K

•0 • 0

•1 • 1

•2 • 2

•3 • 3

•4 • 4

αr J↑1KBack

26

Connecting approaches with type-isomorphisms

∀ ` → Maybe (Fin ` ) ⇔ Fin (suc ` )

∀ α → Maybe (Name α) ⇔ Name (α ↑1 )

∀ ` → Maybe^ ` ⊥ ⇔ Fin `. . . ⇔ Name (∅ ↑ ` )

∀ α → Name α ⇔ Name (α +1 )

∀ α → TmM (Name α) ⇔ TmD α

∀ ` → Tmf ` ⇔ TmM (Fin ` ). . . ⇔ TmM (Name (∅ ↑ ` ) ). . . ⇔ TmD (∅ ↑ ` )

Back

27

Connecting approaches with type-isomorphisms

∀ ` → Maybe (Fin ` ) ⇔ Fin (suc ` )

∀ α → Maybe (Name α) ⇔ Name (α ↑1 )

∀ ` → Maybe^ ` ⊥ ⇔ Fin `. . . ⇔ Name (∅ ↑ ` )

∀ α → Name α ⇔ Name (α +1 )

∀ α → TmM (Name α) ⇔ TmD α

∀ ` → Tmf ` ⇔ TmM (Fin ` ). . . ⇔ TmM (Name (∅ ↑ ` ) ). . . ⇔ TmD (∅ ↑ ` )

Back

27

Connecting approaches with type-isomorphisms

∀ ` → Maybe (Fin ` ) ⇔ Fin (suc ` )

∀ α → Maybe (Name α) ⇔ Name (α ↑1 )

∀ ` → Maybe^ ` ⊥ ⇔ Fin `. . . ⇔ Name (∅ ↑ ` )

∀ α → Name α ⇔ Name (α +1 )

∀ α → TmM (Name α) ⇔ TmD α

∀ ` → Tmf ` ⇔ TmM (Fin ` ). . . ⇔ TmM (Name (∅ ↑ ` ) ). . . ⇔ TmD (∅ ↑ ` )

Back

27

Connecting approaches with type-isomorphisms

∀ ` → Maybe (Fin ` ) ⇔ Fin (suc ` )

∀ α → Maybe (Name α) ⇔ Name (α ↑1 )

∀ ` → Maybe^ ` ⊥ ⇔ Fin `. . . ⇔ Name (∅ ↑ ` )

∀ α → Name α ⇔ Name (α +1 )

∀ α → TmM (Name α) ⇔ TmD α

∀ ` → Tmf ` ⇔ TmM (Fin ` ). . . ⇔ TmM (Name (∅ ↑ ` ) ). . . ⇔ TmD (∅ ↑ ` )

Back

27

Connecting approaches with type-isomorphisms

∀ ` → Maybe (Fin ` ) ⇔ Fin (suc ` )

∀ α → Maybe (Name α) ⇔ Name (α ↑1 )

∀ ` → Maybe^ ` ⊥ ⇔ Fin `. . . ⇔ Name (∅ ↑ ` )

∀ α → Name α ⇔ Name (α +1 )

∀ α → TmM (Name α) ⇔ TmD α

∀ ` → Tmf ` ⇔ TmM (Fin ` ). . . ⇔ TmM (Name (∅ ↑ ` ) ). . . ⇔ TmD (∅ ↑ ` )

Back

27

Connecting approaches with type-isomorphisms

∀ ` → Maybe (Fin ` ) ⇔ Fin (suc ` )

∀ α → Maybe (Name α) ⇔ Name (α ↑1 )

∀ ` → Maybe^ ` ⊥ ⇔ Fin `. . . ⇔ Name (∅ ↑ ` )

∀ α → Name α ⇔ Name (α +1 )

∀ α → TmM (Name α) ⇔ TmD α

∀ ` → Tmf ` ⇔ TmM (Fin ` ). . . ⇔ TmM (Name (∅ ↑ ` ) ). . . ⇔ TmD (∅ ↑ ` )

Back 27

The Fin approach is too concrete

A function can analyse its argument n:

ff : ∀ {n} → Tmf n → ...

Back

28

Traverse

module TraverseTmD

{E} (E-app : Applicative E ) {α β}(trName : ∀ ` → Name (α ↑ ` )

→ E (TmD (β ↑ ` ) ) )where

open Applicative E-app

tr : ∀ ` → TmD (α ↑ ` ) → E (TmD (β ↑ ` ) )tr ` (V x ) = trName ` x

tr ` (t · u ) = pure _ ·_ f tr ` t f tr ` u

tr ` ( ň t ) = pure ň f tr (suc ` ) t

trTmD : TmD α → E (TmD β )trTmD = tr 0

Back

29

Traverse (cont.)

traverseTmD :

∀ {E} (E-app : Applicative E ) {α β}(trName : ∀ ` → Name (α ↑ ` ) → E (TmD (β ↑ ` ) ) )TmD α → E (TmD β )

Traverse three main points:

Delegates all the name handling to trName

trName includes substitutions as well

trName can have any applicative effect

Back

30

Traverse (cont.)

traverseTmD :

∀ {E} (E-app : Applicative E ) {α β}(trName : ∀ ` → Name (α ↑ ` ) → E (TmD (β ↑ ` ) ) )TmD α → E (TmD β )

Traverse three main points:

Delegates all the name handling to trName

trName includes substitutions as well

trName can have any applicative effect

Back

30

Traverse (cont.)

traverseTmD :

∀ {E} (E-app : Applicative E ) {α β}(trName : ∀ ` → Name (α ↑ ` ) → E (TmD (β ↑ ` ) ) )TmD α → E (TmD β )

Traverse three main points:

Delegates all the name handling to trName

trName includes substitutions as well

trName can have any applicative effect

Back

30

Traverse (cont.)

traverseTmD :

∀ {E} (E-app : Applicative E ) {α β}(trName : ∀ ` → Name (α ↑ ` ) → E (TmD (β ↑ ` ) ) )TmD α → E (TmD β )

Traverse three main points:

Delegates all the name handling to trName

trName includes substitutions as well

trName can have any applicative effect

Back

30

Normalization by evaluation

module M (Abs : (World → Set ) → World → Set ) where

data T α : Set where

V : Name α → T αň : Abs T α → T α_ ·_ : T α → T α → T α

Back

31

Normalization by evaluation

SynAbsN : (World → Set ) → World → Set

SynAbsN F α = ∃[ b ](F (b / α) )

open M SynAbsN renaming (T to Term )

SemAbs : (World → Set ) → World → Set

SemAbs F α = ∀ {β} → α ⊆ β → F β → F β

open M SemAbs renaming (T to Sem )

Back

31

Normalization by evaluation

coerceSem : ∀ {α β} → α ⊆ β → Sem α → Sem βcoerceSem pf (V a ) = V (coerceN pf a )coerceSem pf ( ň f ) = ň (λ pf′ v → f (⊆-trans pf pf′ ) v )coerceSem pf (t · u ) = coerceSem pf t · coerceSem pf u

EvalEnv : (α β : World ) → Set

EvalEnv α β = Name α → Sem β-- α is the inner world

-- β is the outer world

_,_ 7→_ : ∀ {α β} ( Γ : EvalEnv α β ) b → Sem β → EvalEnv (b / α) β_,_ 7→_ Γ b v = exportWith v Γ-- b 7→ v

-- x 7→ Γ x

Back

31

Normalization by evaluation

coerceEnv : ∀ {α β1 β2} → β1 ⊆ β2 → EvalEnv α β1 → EvalEnv α β2

coerceEnv pf Γ = coerceSem pf ◦ Γ

eval : ∀ {α β} → EvalEnv α β → Term α → Sem βeval Γ ( ň (a , t ) ) = ň (λ pf v → eval (coerceEnv pf Γ , a 7→ v ) t )eval Γ (V x ) = Γ x

eval Γ (t · u ) = app (eval Γ t ) (eval Γ u ) where

app : ∀ {α} → Sem α → Sem α → Sem αapp ( ň f ) v = f ⊆-refl v

app n v = n · v

Back

31

Normalization by evaluation

reify : ∀ {α} → Supply α → Sem α → Term αreify s (V a ) = V a

reify s (n · v ) = reify s n · reify s v

reify (sB , s# ) ( ň f ) =

ň (sB , reify (sucs (sB , s# ) ) (f (⊆-# s# ) (V (nameB sB) ) ) )

nf : ∀ {α} → Supply α → Term α → Term αnf supply = reify supply ◦ eval V

Back

31

Shifting is: renaming with an addition

The traditional shifting can be expressed:

shiftTmD↑ : ∀ {α} k → TmD α → TmD (α ↑ k )shiftTmD↑ = renameTmD ◦ addN↑

Is it the complexity we want for shiftTmD↑ ?

This piles up a chain of predecessor/successor...

Back

32

Shifting is: renaming with an addition

The traditional shifting can be expressed:

shiftTmD↑ : ∀ {α} k → TmD α → TmD (α ↑ k )shiftTmD↑ = renameTmD ◦ addN↑

Is it the complexity we want for shiftTmD↑ ?

This piles up a chain of predecessor/successor...

Back

32

Shifting is: renaming with an addition

The traditional shifting can be expressed:

shiftTmD↑ : ∀ {α} k → TmD α → TmD (α ↑ k )shiftTmD↑ = renameTmD ◦ addN↑

Is it the complexity we want for shiftTmD↑ ?

This piles up a chain of predecessor/successor...

Back

32

Shifting a name

... amounts to a protected addition:

shiftN↑ : ∀ {α} k `→ Name (α ↑ ` )→ Name (α ↑ k ↑ ` )

shiftN↑ = protect↑ ◦ addN↑

The function has the following graph:

•0 • 0

•1 • 1

•2 • 2

•...• ...

•`́ 1 • `́ 1

•` ••1+` ••2+` • k+`

•...• 1+k+`

• 2+k+`

• ...

Back

33

Shifting a name

... amounts to a protected addition:

shiftN↑ : ∀ {α} k `→ Name (α ↑ ` )→ Name (α ↑ k ↑ ` )

shiftN↑ = protect↑ ◦ addN↑

The function has the following graph:

•0 • 0

•1 • 1

•2 • 2

•...• ...

•`́ 1 • `́ 1

•` ••1+` ••2+` • k+`

•...• 1+k+`

• 2+k+`

• ...

Back

33

Renaming without protect↑Here, ` is use to count crossed binders:

renameTmD↑ : ∀ {α β} → (∀ ` → Name (α ↑ ` ) → Name (β ↑ ` ) )→ (TmD α → TmD β )

renameTmD↑ {α} {β} f = go 0 where

go : ∀ ` → TmD (α ↑ ` ) → TmD (β ↑ ` )go ` (V x ) = V (f ` x )go ` (t · u ) = go ` t · go ` u

go ` ( ň t ) = ň (go (suc ` ) t )

shiftTmD↑′ : ∀ {α} k → TmD α → TmD (α ↑ k )shiftTmD↑′ = renameTmD↑ ◦ shiftN↑

Back

34

Renaming without protect↑Here, ` is use to count crossed binders:

renameTmD↑ : ∀ {α β} → (∀ ` → Name (α ↑ ` ) → Name (β ↑ ` ) )→ (TmD α → TmD β )

renameTmD↑ {α} {β} f = go 0 where

go : ∀ ` → TmD (α ↑ ` ) → TmD (β ↑ ` )go ` (V x ) = V (f ` x )go ` (t · u ) = go ` t · go ` u

go ` ( ň t ) = ň (go (suc ` ) t )

shiftTmD↑′ : ∀ {α} k → TmD α → TmD (α ↑ k )shiftTmD↑′ = renameTmD↑ ◦ shiftN↑

Back

34

How dangerous this kind of programming is ?Sadly the unprotected addition can becoerced to this type:

unprotectedAddN↑ :

∀ {α} k `→ Name (α ↑ ` )→ Name (α ↑ k ↑ ` )

unprotectedAddN↑ k ` =

{! coercion omitted !}◦ addN↑ k

-- this is ok since

-- (α ↑ k ) ↑ ` ≡ (α ↑ ` ) ↑ k •0 • 0

•1 • ...

•2 • k

•...• 1+k

•`́ 1 • 2+k

•` • ...

•1+` • k+`́ 1

•2+` • k+`

•...• 1+k+`

• 2+k+`

• ...

Back

35

Shifting gets a finer type

shiftN : ∀ {α} k ` → Name (α ↑ ` ) → Name (α +W k ↑ ` )shiftN = protect↑ ◦ addN

•0 • 0

•1 • 1

•2 • 2

•...• ...

•`́ 1 • `́ 1

•`

•1+`

•2+` • k+`

•...• 1+k+`

• 2+k+`

• ...

Ruling out any unprotected attempt !

Back

36

Shifting gets a finer type

shiftN : ∀ {α} k ` → Name (α ↑ ` ) → Name (α +W k ↑ ` )shiftN = protect↑ ◦ addN

•0 • 0

•1 • 1

•2 • 2

•...• ...

•`́ 1 • `́ 1

•`

•1+`

•2+` • k+`

•...• 1+k+`

• 2+k+`

• ...

Ruling out any unprotected attempt !

Back

36

Shifting gets a finer type

shiftN : ∀ {α} k ` → Name (α ↑ ` ) → Name (α +W k ↑ ` )shiftN = protect↑ ◦ addN

•0 • 0

•1 • 1

•2 • 2

•...• ...

•`́ 1 • `́ 1

•`

•1+`

•2+` • k+`

•...• 1+k+`

• 2+k+`

• ...

Ruling out any unprotected attempt !

Back

36

. . . and a faster implementation

shiftN : ∀ {α} k ` → Name (α ↑ ` ) → Name (α +W k ↑ ` )shiftN k ` x

with subtractN ` x

... | inj1 x′ = x′ -- coercion omitted

... | inj2 x′ = addN k n′ -- coercion omitted

Back

37

How precise are worlds ? Singletons worlds !

Worlds : N → World

Worlds n = ∅ ↑1 +W n

Names : N → Set

Names = Name ◦ Worlds

_Ns : ∀ n → Names n

_Ns n = zeroN +N n

adds : ∀ {n} k → Names n → Names (k +N n )adds {n} k x = addN k x 〈-because ⊆-assoc-+ ⊆-refl n k -〉

subtracts : ∀ {n} k → Names (k +N n ) → Names n

subtracts {n} k x = subtractN k x

〈-because ⊆-assoc-+′ ⊆-refl n k -〉

Back

38