Tableaux.Prelude.LocallyNamelessClasses
From Tableaux Require Import Init.
From Tableaux Require Import Sets.
From Tableaux Require Import Atoms.
This file mainly defines the different classes (and also notations) for manipulating
variables in a locally nameless representation. In particular, it defines a typeclass
for:
- variable opening (i.e., instantiating a variable by a term),
- getting the bound variables of a term,
- substitution in a locally nameless environment
Variable opening: replacing a bound variable with an atom
Class Opening (A B : Type) :=
varOpening : nat -> A -> B -> B.
Arguments varOpening {_ _ _} _ _ _.
Notation "t { n \to x }" := (varOpening n x t) (at level 3).
varOpening : nat -> A -> B -> B.
Arguments varOpening {_ _ _} _ _ _.
Notation "t { n \to x }" := (varOpening n x t) (at level 3).
Section Substitution.
Context `{set_nat : set nat}.
Class BV (A : Type) :=
bv : A -> set_nat.
Arguments bv {_ _}.
Definition isLocallyClosed {A : Type} `{BV A} (x : A) :=
is_empty (bv x).
Class Substitution (X : Type) `{isAtom X} (A : Type) `{BV A} :=
{ subst :> X -> A
; isSubst : forall (x : X), isLocallyClosed (subst x) }.
Class Subst {X : Type} `{isAtom X} (A B : Type) `{BV B} :=
substitute : A -> Substitution X B -> A.
Arguments substitute {_ _ _ _ _} _ _.
End Substitution.
Notation "x @[ sigma ]" := (substitute x sigma) (at level 3).
Context `{set_nat : set nat}.
Class BV (A : Type) :=
bv : A -> set_nat.
Arguments bv {_ _}.
Definition isLocallyClosed {A : Type} `{BV A} (x : A) :=
is_empty (bv x).
Class Substitution (X : Type) `{isAtom X} (A : Type) `{BV A} :=
{ subst :> X -> A
; isSubst : forall (x : X), isLocallyClosed (subst x) }.
Class Subst {X : Type} `{isAtom X} (A B : Type) `{BV B} :=
substitute : A -> Substitution X B -> A.
Arguments substitute {_ _ _ _ _} _ _.
End Substitution.
Notation "x @[ sigma ]" := (substitute x sigma) (at level 3).
Further free instances of BV.
Section BVInstances.
Context `{set_nat : set nat}.
#[global] Instance bv_list {A : Type} `{H : @BV set_nat A} : @BV set_nat (list A) :=
fix F (l : list A) : set_nat :=
match l with
| [] => empty_set
| h :: t => (bv h) \union F t
end.
End BVInstances.
Context `{set_nat : set nat}.
#[global] Instance bv_list {A : Type} `{H : @BV set_nat A} : @BV set_nat (list A) :=
fix F (l : list A) : set_nat :=
match l with
| [] => empty_set
| h :: t => (bv h) \union F t
end.
End BVInstances.
Further free instances of Subst.
Section SubstInstances.
Context `{set_nat : set nat}.
#[global] Instance subst_list {X : Type} `{isAtom X} {A B : Type} `{H : BV B} `{Subst X A B} :
Subst (list A) B :=
fun xs sigma =>
(fix F (xs : list A) : list A :=
match xs with
| [] => []
| x :: xs => x@[sigma] :: F xs
end) xs.
End SubstInstances.
Context `{set_nat : set nat}.
#[global] Instance subst_list {X : Type} `{isAtom X} {A B : Type} `{H : BV B} `{Subst X A B} :
Subst (list A) B :=
fun xs sigma =>
(fix F (xs : list A) : list A :=
match xs with
| [] => []
| x :: xs => x@[sigma] :: F xs
end) xs.
End SubstInstances.
Section FreeVariables.
Context {var : Type} `{isAtom var}.
Let set_var := set_atom var.
Class FV (A : Type) :=
fv : A -> set_var.
Definition isClosed {A : Type} `{FV A} (x : A) :=
is_empty (fv x).
End FreeVariables.
Context {var : Type} `{isAtom var}.
Let set_var := set_atom var.
Class FV (A : Type) :=
fv : A -> set_var.
Definition isClosed {A : Type} `{FV A} (x : A) :=
is_empty (fv x).
End FreeVariables.
Further free instances of FV.
Section FVInstances.
Context {var : Type} `{isAtom var}.
Let set_var := set_atom var.
#[global] Instance fv_list {A : Type} `{!FV A} : FV (list A) :=
fix F (xs : list A) : set_var :=
match xs with
| [] => empty_set
| x :: xs => (fv x) \union (F xs)
end.
Lemma fv_list_in :
forall {A : Type} `{!FV A} (x : A) (l : list A),
List.In x l -> fv l = fv (x :: l).
Proof using Type.
intros ???? hin; induction l as [|y ys IHys]; inversion hin.
- subst. cbn. rewrite -union_assoc union_idemp //.
- cbn. rewrite -union_assoc.
symmetry; etransitivity. { refine (f_equal (fun s => s \union fv ys) _). apply union_comm. }
rewrite union_assoc. cbn in IHys. rewrite -IHys; auto.
Qed.
End FVInstances.
Context {var : Type} `{isAtom var}.
Let set_var := set_atom var.
#[global] Instance fv_list {A : Type} `{!FV A} : FV (list A) :=
fix F (xs : list A) : set_var :=
match xs with
| [] => empty_set
| x :: xs => (fv x) \union (F xs)
end.
Lemma fv_list_in :
forall {A : Type} `{!FV A} (x : A) (l : list A),
List.In x l -> fv l = fv (x :: l).
Proof using Type.
intros ???? hin; induction l as [|y ys IHys]; inversion hin.
- subst. cbn. rewrite -union_assoc union_idemp //.
- cbn. rewrite -union_assoc.
symmetry; etransitivity. { refine (f_equal (fun s => s \union fv ys) _). apply union_comm. }
rewrite union_assoc. cbn in IHys. rewrite -IHys; auto.
Qed.
End FVInstances.