Reputation: 3218
I'm working in a simple library containing definitions and properties about substitutions for simple types. I'm using the following encoding for types:
data Ty (n : Nat) : Set where
var : Fin n -> Ty n
con : Ty n
app : Ty n -> Ty n -> Ty n
so, since variables are represented as finite sets, substitutions are just vectors:
Subst : Nat -> Nat -> Set
Subst n m = Vec (Ty m) n
The complete development is in the following paste: http://lpaste.net/107751
Using this encoding, I have defined several lemmas about such substitutions, but I do not know how to define a theorem that specifies that substitutions are idempotent. I believe that I must use some property like weakening in order to express this, but I can't figure out how.
Could someone give any directions or clues?
Thanks in advance.
Upvotes: 0
Views: 121
Reputation: 309
Substitutions that produce expressions over fresh variables are indeed idempotent. But in order to express this theorem, you have to consider your substitution Subst n m
as one operating on the joint variable set Subst (n + m) (n + m)
. Here is a variant that uses arbitrary variable sets A
and B
instead of Fin n
and Fin m
.
open import Relation.Binary.PropositionalEquality using (_≡_; refl)
-- Disjoint union.
data _+_ (A B : Set) : Set where
left : A → A + B
right : B → A + B
-- A set of variable names can be any type.
Names = Set
-- Simple expressions over a set of names.
data Tm (A : Names) : Set where
var : A → Tm A
app : Tm A → Tm A → Tm A
-- Substitute all variables from set A by terms over a name set B.
Subst : Names → Names → Set
Subst A B = A → Tm B
subst : ∀{A B} → Subst A B → Tm A → Tm B
subst σ (var x) = σ x
subst σ (app t u) = app (subst σ t) (subst σ u)
-- Rename all variables from set A to names from set B.
Rename : Names → Names → Set
Rename A B = A → B
rename : ∀{A B} → Rename A B → Tm A → Tm B
rename σ (var x) = var (σ x)
rename σ (app t u) = app (rename σ t) (rename σ u)
-- In order to speak about idempotency of substitutions whose domain A
-- is disjoint from the variable set B used in the range, we have to promote
-- them to work on the union A+B of variable sets.
-- The promoted substitution is the identity on B,
-- and the original substitution on A, but with the result transferred from B to A + B.
promote : ∀{A B} → Subst A B → Subst (A + B) (A + B)
promote σ (left x) = rename right (σ x)
promote σ (right x) = var (right x)
module _ {A B : Set} (σ₀ : Subst A B) where
-- Now assume a promoted substitution.
σ = promote σ₀
-- A promoted substitution has no effect on terms with variables only in B.
lemma : ∀ t → subst σ (rename right t) ≡ rename right t
lemma (var x) = refl
lemma (app t u) rewrite lemma t | lemma u = refl
-- Hence, it is idempotent.
idempotency : ∀ x → subst σ (σ x) ≡ σ x
idempotency (right x) = refl
idempotency (left x) = lemma (σ₀ x)
Upvotes: 1