Require
Export
Nominal.
Module Type
STLC.
Datatypes. |
Parameter
tmvar : AtomT.
Definition
tmvarP := mkAtomPset tmvar.
Inductive
ty : Set :=
| unit : ty
| arrow : ty -> ty -> ty.
Definition
tyP : PsetT tmvar ty := mkIdPset tmvar ty.
Parameter
tm : Set.
Parameter
tmP : PsetT tmvar tm.
Parameter
dot : tm.
Parameter
var : tmvar -> tm.
Parameter
app : tm -> tm -> tm.
Parameter
lam : tmvar -> ty -> tm -> tm.
Constructor distinctness. |
Section
Distinctness.
Variables
a b : tmvar.
Variables
T : ty.
Variables
s t q r : tm.
Axiom
distinctness_dot_var : dot <> var a.
Axiom
distinctness_dot_app : dot <> app s t.
Axiom
distinctness_dot_lam : dot <> lam a T s.
Axiom
distinctness_var_dot : var a <> dot.
Axiom
distinctness_var_app : var a <> app s t.
Axiom
distinctness_var_lam : var a <> lam b T s.
Axiom
distinctness_app_dot : app s t <> dot.
Axiom
distinctness_app_var : app s t <> var a.
Axiom
distinctness_app_lam : app s t <> lam a T q.
Axiom
distinctness_lam_dot : lam a T s <> dot.
Axiom
distinctness_lam_var : lam a T s <> var b.
Axiom
distinctness_lam_app : lam a T s <> app q r.
End
Distinctness.
Ltac
stlc_discriminate :=
match goal with
| [H : (var _ = dot) |- _] =>
pose (distinctness_var_dot _ H); intuition; fail
| [H : (app _ _ = dot) |- _] =>
pose (distinctness_app_dot _ _ H); intuition; fail
| [H : (lam _ _ _ = dot) |- _] =>
pose (distinctness_lam_dot _ _ _ H); intuition; fail
| [H : (dot = var _) |- _] =>
pose (distinctness_dot_var _ H); intuition; fail
| [H : (app _ _ = var _) |- _] =>
pose (distinctness_app_var _ _ _ H); intuition; fail
| [H : (lam _ _ _ = var _) |- _] =>
pose (distinctness_lam_var _ _ _ _ H); intuition; fail
| [H : (dot = app _ _) |- _] =>
pose (distinctness_dot_app _ _ H); intuition fail
| [H : (var _ = app _ _) |- _] =>
pose (distinctness_var_app _ _ _ H); intuition; fail
| [H : (lam _ _ _ = app _ _) |- _] =>
pose (distinctness_lam_app _ _ _ _ _ H); intuition; fail
| [H : (dot = lam _ _ _) |- _] =>
pose (distinctness_dot_lam _ _ _ H); intuition; fail
| [H : (var _ = lam _ _ _) |- _] =>
pose (distinctness_var_lam _ _ _ _ H); intuition; fail
| [H : (app _ _ = lam _ _ _) |- _] =>
pose (distinctness_app_lam _ _ _ _ _ H); intuition; fail
end.
Permutation on terms. |
Section
STLCPermutations.
Variable
p : permt tmvar.
Variable
c : tmvar.
Variable
T : ty.
Variables
s t : tm.
Axiom
perm_dot : perm tmP p dot = dot.
Axiom
perm_var : perm tmP p (var c) = var (perm tmvarP p c).
Axiom
perm_app :
perm tmP p (app s t) = app (perm tmP p s) (perm tmP p t).
Axiom
perm_lam :
perm tmP p (lam c T s) = lam (perm tmvarP p c) T (perm tmP p s).
End
STLCPermutations.
Free variables. |
Section
FreeVariables.
Variables
a : tmvar.
Variables
T : ty.
Variables
s t : tm.
Parameter
fvar : tm -> aset tmvar.
Axiom
fvar_dot : fvar dot = empty.
Axiom
fvar_var : fvar (var a) = singleton a.
Axiom
fvar_app : fvar (app s t) = union (fvar s) (fvar t).
Axiom
fvar_lam : fvar (lam a T s) = remove a (fvar s).
End
FreeVariables.
Alpha-Equality. |
Axiom
eq_lam :
forall (a b : tmvar) (T : ty) (t : tm),
~ In b (fvar t) ->
lam a T t = lam b T (perm tmP [(a, b)] t).
Injectivity for constructors. |
Section
Injectivity.
Variables
a a' : tmvar.
Variables
T T' : ty.
Variables
s s' t t' : tm.
Axiom
injection_var : var a = var a' -> a = a'.
Axiom
injection_app_fun : app s t = app s' t' -> s = s'.
Axiom
injection_app_arg : app s t = app s' t' -> t = t'.
Axiom
injection_lam_ty : lam a T s = lam a' T' s' -> T = T'.
Axiom
injection_lam_body :
lam a T s = lam a' T' s' ->
(a = a' /\ s = s') \/
(a <> a' /\ ~ In a (fvar s') /\ s = perm tmP [(a, a')] s').
End
Injectivity.
Ltac
stlc_injection :=
match goal with
| [H : (var _ = var _) |- _] =>
pose (injection_var _ _ H)
| [H : (app _ _ = app _ _) |- _] =>
pose (injection_app_fun _ _ _ _ H);
pose (injection_app_arg _ _ _ _ H)
| [H : (lam _ _ _ = lam _ _ _) |- _] =>
pose (injection_lam_ty _ _ _ _ _ _ H);
pose (injection_lam_body _ _ _ _ _ _ H)
end.
Structural induction. |
Axiom
tm_induction_weak :
forall (P : tm -> Type),
(P dot) ->
(forall a, P (var a)) ->
(forall s, P s -> forall t, P t -> P (app s t)) ->
(forall a T s, P s -> P (lam a T s)) ->
forall x : tm, P x.
Primitive recursion. |
Parameter
tm_rec
: forall R : Set,
R ->
(tmvar -> R) ->
(tm -> R -> tm -> R -> R) ->
(tmvar -> ty -> tm -> R -> R) -> aset tmvar -> tm -> R.
Axiom
tm_rec_dot
: forall (R : Set) (f_dot : R) (f_var : tmvar -> R)
(f_app : tm -> R -> tm -> R -> R)
(f_lam : tmvar -> ty -> tm -> R -> R) (F : aset tmvar),
tm_rec R f_dot f_var f_app f_lam F dot = f_dot.
Axiom
tm_rec_var
: forall (R : Set) (f_dot : R) (f_var : tmvar -> R)
(f_app : tm -> R -> tm -> R -> R)
(f_lam : tmvar -> ty -> tm -> R -> R) (F : aset tmvar) (a : tmvar),
tm_rec R f_dot f_var f_app f_lam F (var a) = f_var a.
Axiom
tm_rec_app
: forall (R : Set) (f_dot : R) (f_var : tmvar -> R)
(f_app : tm -> R -> tm -> R -> R)
(f_lam : tmvar -> ty -> tm -> R -> R) (F : aset tmvar) (s t : tm),
tm_rec R f_dot f_var f_app f_lam F (app s t) =
f_app s (tm_rec R f_dot f_var f_app f_lam F s) t
(tm_rec R f_dot f_var f_app f_lam F t).
Axiom
tm_rec_lam
: forall (R : Set) (RP : PsetT tmvar R) (f_dot : R) (f_var : tmvar -> R)
(f_app : tm -> R -> tm -> R -> R)
(f_lam : tmvar -> ty -> tm -> R -> R) (F : aset tmvar),
supports RP F f_dot ->
supports (tmvarP ^-> RP) F f_var ->
supports (tmP ^-> RP ^-> tmP ^-> RP ^-> RP) F f_app ->
supports (tmvarP ^-> tyP ^-> tmP ^-> RP ^-> RP) F f_lam ->
(exists b : tmvar,
~ In (e:=asetR tmvar) b F /\
(forall (x : ty) (y : tm) (z : R), freshP RP b (f_lam b x y z))) ->
forall (a : tmvar) (T : ty) (s : tm),
~ In (e:=asetR tmvar) a F ->
tm_rec R f_dot f_var f_app f_lam F (lam a T s) =
f_lam a T s (tm_rec R f_dot f_var f_app f_lam F s).
Axiom
tm_rec_supp
: forall (R : Set) (RP : PsetT tmvar R) (f_dot : R) (f_var : tmvar -> R)
(f_app : tm -> R -> tm -> R -> R)
(f_lam : tmvar -> ty -> tm -> R -> R) (F : aset tmvar),
supports RP F f_dot ->
supports (tmvarP ^-> RP) F f_var ->
supports (tmP ^-> RP ^-> tmP ^-> RP ^-> RP) F f_app ->
supports (tmvarP ^-> tyP ^-> tmP ^-> RP ^-> RP) F f_lam ->
(exists b : tmvar,
~ In (e:=asetR tmvar) b F /\
(forall (x : ty) (y : tm) (z : R), freshP RP b (f_lam b x y z))) ->
supports (tmP ^-> RP) F (tm_rec R f_dot f_var f_app f_lam F).
Automation hints. |
Hint
Resolve distinctness_dot_var : stlc.
Hint
Resolve distinctness_dot_app : stlc.
Hint
Resolve distinctness_dot_lam : stlc.
Hint
Resolve distinctness_var_dot : stlc.
Hint
Resolve distinctness_var_app : stlc.
Hint
Resolve distinctness_var_lam : stlc.
Hint
Resolve distinctness_app_dot : stlc.
Hint
Resolve distinctness_app_var : stlc.
Hint
Resolve distinctness_app_lam : stlc.
Hint
Resolve distinctness_lam_dot : stlc.
Hint
Resolve distinctness_lam_var : stlc.
Hint
Resolve distinctness_lam_app : stlc.
Hint
Resolve perm_dot : stlc.
Hint
Resolve perm_var : stlc.
Hint
Resolve perm_app : stlc.
Hint
Resolve perm_lam : stlc.
Hint
Rewrite perm_dot : stlc.
Hint
Rewrite perm_var : stlc.
Hint
Rewrite perm_app : stlc.
Hint
Rewrite perm_lam : stlc.
Hint
Resolve fvar_dot : stlc.
Hint
Resolve fvar_var : stlc.
Hint
Resolve fvar_app : stlc.
Hint
Resolve fvar_lam : stlc.
Hint
Rewrite fvar_dot : stlc.
Hint
Rewrite fvar_var : stlc.
Hint
Rewrite fvar_app : stlc.
Hint
Rewrite fvar_lam : stlc.
Hint
Immediate
injection_var : stlc.
Hint
Immediate
injection_app_fun : stlc.
Hint
Immediate
injection_app_arg : stlc.
Hint
Immediate
injection_lam_ty : stlc.
Hint
Immediate
injection_lam_body : stlc.
Hint
Resolve tm_rec_dot tm_rec_var tm_rec_app : stlc.
Hint
Rewrite tm_rec_dot tm_rec_var tm_rec_app : stlc.
Hint
Immediate
tm_rec_lam : stlc.
Hint
Rewrite tm_rec_lam using (auto with stlc nominal; fail) : stlc.
End
STLC.