Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Andrew Hirsch
Pirouette Coq Code
Commits
2203b568
Commit
2203b568
authored
Sep 21, 2021
by
Andrew Hirsch
Browse files
Comments for local languages.
parent
867f7f59
Changes
3
Hide whitespace changes
Inline
Side-by-side
LocalLang.v
View file @
2203b568
(
*
Module
type
for
the
local
language
.
We
can
instantiate
this
module
type
with
any
number
of
languages
,
as
we
can
see
in
the
examples
.
We
can
instantiate
this
module
type
with
any
number
of
languages
,
as
we
can
see
in
the
examples
.
*
)
Module
Type
LocalLang
.
(
*
The
local
language
is
an
expression
-
based
language
.
We
assume
that
expressions
have
decidable
syntactic
equality
.
This
is
a
pretty
weak
assumption
for
syntax
.
The
local
language
is
an
expression
-
based
language
.
We
assume
that
expressions
have
decidable
syntactic
equality
.
This
is
a
pretty
weak
assumption
for
syntax
.
*
)
Parameter
Expr
:
Set
.
Parameter
ExprEqDec
:
forall
e1
e2
:
Expr
,
{
e1
=
e2
}
+
{
e1
<>
e2
}
.
(
*
Since
we
use
de
Bruijn
indices
,
we
represent
variables
as
natural
numbers
.
We
don
'
t
require
any
sort
of
binders
in
the
local
language
,
so
these
don
'
t
necessarily
count
to
the
relevant
binder
.
However
,
in
our
examples
they
do
.
*
)
(
*
Since
we
use
de
Bruijn
indices
,
we
represent
variables
as
natural
numbers
.
We
don
'
t
require
any
sort
of
binders
in
the
local
language
,
so
these
don
'
t
necessarily
count
to
the
relevant
binder
.
However
,
in
our
examples
they
do
.
*
)
Parameter
ExprVar
:
nat
->
Expr
.
(
*
An
expression
is
closed
above
`n
`
if
variables
above
`n
`
do
not
appear
free
in
the
expression
.
Clearly
,
if
an
expression
is
closed
above
`0
`
,
then
it
contains
no
free
variables
.
(
*
An
expression
is
closed
above
`n
`
if
variables
above
`n
`
do
not
appear
free
in
the
expression
.
Clearly
,
if
an
expression
is
closed
above
`0
`
,
then
it
contains
no
free
variables
.
The
property
of
being
closed
above
is
monotonic
.
Moreover
,
variables
are
always
closed
above
anything
greater
than
themselves
.
The
property
of
being
closed
above
is
monotonic
.
Moreover
,
variables
are
always
closed
above
anything
greater
than
themselves
.
*
)
Parameter
ExprClosedAbove
:
nat
->
Expr
->
Prop
.
Definition
ExprClosed
:=
ExprClosedAbove
0.
...
...
@@ -36,22 +35,19 @@ Module Type LocalLang.
Parameter
ExprVarClosed
:
forall
n
m
,
ExprClosedAbove
n
(
ExprVar
m
)
<->
m
<
n
.
(
*
Values
are
a
subset
of
expressions
(
here
represented
as
a
property
of
expressions
.
These
are
always
closed
.
This
restriction
is
necessary
for
communication
to
typecheck
in
Pirouette
.
Values
are
a
subset
of
expressions
(
here
represented
as
a
property
of
expressions
.
These
are
always
closed
.
This
restriction
is
necessary
for
communication
to
typecheck
in
Pirouette
.
*
)
Parameter
ExprVal
:
Expr
->
Prop
.
Parameter
ExprValuesClosed
:
forall
v
:
Expr
,
ExprVal
v
->
ExprClosed
v
.
(
*
Local
languages
need
to
define
a
(
n
infinite
)
substitution
operator
.
This
replaces
all
variables
in
the
expression
with
new
subexpressions
.
We
also
consider
a
renaming
operation
,
which
allows
us
to
substitute
variables
more
easily
with
other
variables
.
This
can
be
defined
via
the
"specification"
equation
below
,
but
it
is
often
better
to
define
it
seperately
.
Local
languages
need
to
define
a
(
n
infinite
)
substitution
operator
.
This
replaces
all
variables
in
the
expression
with
new
subexpressions
.
We
also
consider
a
renaming
operation
,
which
allows
us
to
substitute
variables
more
easily
with
other
variables
.
This
can
be
defined
via
the
"specification"
equation
below
,
but
it
is
often
better
to
define
it
seperately
.
*
)
Parameter
ExprSubst
:
Expr
->
(
nat
->
Expr
)
->
Expr
.
Parameter
ExprRename
:
Expr
->
(
nat
->
nat
)
->
Expr
.
...
...
@@ -60,8 +56,9 @@ Module Type LocalLang.
Parameter
ExprRenameSpec
:
forall
(
e
:
Expr
)
(
ξ
:
nat
->
nat
),
e
⟨
e
|
ξ⟩
=
e
[
e
|
fun
n
=>
ExprVar
(
ξ
n
)].
(
*
Substitution
must
correctly
replace
a
variable
.
This
allows
us
to
show
that
renaming
must
do
the
same
thing
.
(
*
Substitution
must
correctly
replace
a
variable
.
This
allows
us
to
show
that
renaming
must
do
the
same
thing
.
*
)
Parameter
ExprSubstVar
:
forall
n
σ
,
(
ExprVar
n
)
[
e
|
σ
]
=
σ
n
.
Lemma
ExprRenameVar
:
forall
n
ξ
,
(
ExprVar
n
)
⟨
e
|
ξ
⟩
=
ExprVar
(
ξ
n
).
...
...
@@ -71,20 +68,17 @@ Module Type LocalLang.
Qed
.
(
*
Renaming
in
an
expression
twice
should
behave
compositionally
.
For
technical
reasons
,
we
need
this
to
prove
an
important
property
of
Pirouette
.
*
)
(
*
Renaming
in
an
expression
twice
should
behave
compositionally
.
For
technical
reasons
,
we
need
this
to
prove
an
important
property
of
Pirouette
.
*
)
Parameter
ExprRenameFusion
:
forall
(
e
:
Expr
)
(
ξ
1
ξ
2
:
nat
->
nat
),
(
e
⟨
e
|
ξ
1
⟩
)
⟨
e
|
ξ
2
⟩
=
e
⟨
e
|
fun
n
=>
ξ
2
(
ξ
1
n
)
⟩
.
(
*
Parameter
ExprSubstFusion
:
forall
(
e
:
Expr
)
(
σ
1
σ
2
:
nat
->
Expr
),
*
)
(
*
(
e
[
e
|
σ
1
])
[
e
|
σ
2
]
=
e
[
e
|
fun
n
=>
σ
1
n
[
e
|
σ
2
]].
*
)
(
*
Substitution
must
be
_
extensional_
in
the
sense
that
it
does
not
rely
on
the
implementation
of
the
substitution
functions
.
This
allows
us
to
show
that
renaming
is
also
extensional
.
Substitution
must
be
_
extensional_
in
the
sense
that
it
does
not
rely
on
the
implementation
of
the
substitution
functions
.
This
allows
us
to
show
that
renaming
is
also
extensional
.
*
)
Parameter
ExprSubstExt
:
forall
(
e
:
Expr
)
(
σ
1
σ
2
:
nat
->
Expr
),
(
forall
n
,
σ
1
n
=
σ
2
n
)
->
e
[
e
|
σ
1
]
=
e
[
e
|
σ
2
].
...
...
@@ -97,10 +91,8 @@ Module Type LocalLang.
Qed
.
(
*
We
define
identity
substitution
and
renamings
.
We
require
that
the
substitution
behave
as
an
identity
.
From
that
,
we
can
show
that
the
renaming
also
behaves
as
an
identity
.
We
define
identity
substitution
and
renamings
.
We
require
that
the
substitution
behave
as
an
identity
.
From
that
,
we
can
show
that
the
renaming
also
behaves
as
an
identity
.
*
)
Definition
ExprIdSubst
:
nat
->
Expr
:=
fun
n
=>
ExprVar
n
.
Parameter
ExprIdentitySubstSpec
:
forall
(
e
:
Expr
),
e
[
e
|
ExprIdSubst
]
=
e
.
...
...
@@ -110,19 +102,15 @@ Module Type LocalLang.
intros
e
;
rewrite
ExprRenameSpec
;
unfold
ExprIdRenaming
;
cbn
.
apply
ExprIdentitySubstSpec
.
Qed
.
(
*
Substitution
with
de
Bruijn
indices
usually
relies
on
`up
`
constructions
on
substitutions
.
These
are
used
when
going
past
a
constructor
to
ensure
that
counting
is
done
correctly
.
Since
we
don
'
t
define
substitution
explicitly
here
,
nor
do
we
have
binders
,
these
aren
'
t
used
here
.
However
,
we
define
them
for
convenience
'
s
sake
.
We
also
prove
that
they
do
not
affect
the
identity
substitution
and
renaming
.
Substitution
with
de
Bruijn
indices
usually
relies
on
`up
`
constructions
on
substitutions
.
These
are
used
when
going
past
a
constructor
to
ensure
that
counting
is
done
correctly
.
Since
we
don
'
t
define
substitution
explicitly
here
,
nor
do
we
have
binders
,
these
aren
'
t
used
here
.
However
,
we
define
them
for
convenience
'
s
sake
.
We
also
prove
that
they
do
not
affect
the
identity
substitution
and
renaming
.
*
)
Definition
ExprUpSubst
:
(
nat
->
Expr
)
->
nat
->
Expr
:=
fun
σ
n
=>
...
...
@@ -161,29 +149,26 @@ Module Type LocalLang.
Qed
.
(
*
We
require
separate
boolean
expressions
`true
`
and
`false
`
.
These
must
be
separate
expressions
,
and
both
be
values
.
We
require
separate
boolean
expressions
`true
`
and
`false
`
.
These
must
be
separate
expressions
,
and
both
be
values
.
*
)
Parameter
tt
ff
:
Expr
.
Parameter
ttValue
:
ExprVal
tt
.
Parameter
ffValue
:
ExprVal
ff
.
Parameter
boolSeperation
:
tt
<>
ff
.
(
*
ExprStep
is
the
small
-
step
semantics
for
the
local
language
.
We
require
that
values
not
be
able
to
take
a
step
,
which
reflects
the
fact
that
we
are
using
_
small_
-
step
semantics
.
ExprStep
is
the
small
-
step
semantics
for
the
local
language
.
We
require
that
values
not
be
able
to
take
a
step
,
which
reflects
the
fact
that
we
are
using
_
small_
-
step
semantics
.
*
)
Parameter
ExprStep
:
Expr
->
Expr
->
Prop
.
Parameter
NoExprStepFromVal
:
forall
v
,
ExprVal
v
->
forall
e
,
~
ExprStep
v
e
.
(
*
Substitution
,
renaming
,
and
stepping
should
not
change
the
fact
that
expressions
are
closed
above
some
level
.
Substitution
,
renaming
,
and
stepping
should
not
change
the
fact
that
expressions
are
closed
above
some
level
.
*
)
Parameter
ExprRenameClosedAbove
:
forall
e
n
ξ
m
,
(
forall
k
,
k
<
n
->
ξ
k
<
m
)
->
...
...
SoundlyTypedLocalLang.v
View file @
2203b568
Require
Export
LocalLang
.
Require
Export
TypedLocalLang
.
Module
Type
SoundlyTypedLocalLang
(
E
:
LocalLang
)
(
TE
:
TypedLocalLang
E
).
Import
E
.
Import
TE
.
Module
Type
SoundlyTypedLocalLang
(
Import
LL
:
LocalLang
)
(
Import
TLL
:
TypedLocalLang
LL
).
(
*
A
soundly
-
typed
local
language
does
not
allow
boolean
values
other
than
true
and
false
.
This
is
important
in
order
to
know
that
if
expressions
in
Pirouette
don
'
t
go
wrong
.
If
we
didn
'
t
have
this
,
we
could
have
a
boolean
expression
which
can
'
t
reduce
,
yet
is
neither
true
nor
false
.
*
)
Parameter
BoolInversion
:
forall
(
Γ
:
nat
->
ExprTyp
)
(
v
:
Expr
),
Γ
⊢
e
v
:::
bool
->
ExprVal
v
->
{
v
=
tt
}
+
{
v
=
ff
}
.
(
*
Progress
and
preservation
for
the
local
language
is
standard
.
*
)
Parameter
ExprPreservation
:
forall
(
Γ
:
nat
->
ExprTyp
)
(
e1
e2
:
Expr
)
(
τ
:
ExprTyp
),
Γ
⊢
e
e1
:::
τ
->
ExprStep
e1
e2
->
Γ
⊢
e
e2
:::
τ
.
Parameter
ExprProgress
:
forall
(
Γ
:
nat
->
ExprTyp
)
(
e1
:
Expr
)
(
τ
:
ExprTyp
),
...
...
TypedLocalLang.v
View file @
2203b568
Require
Export
LocalLang
.
Module
Type
TypedLocalLang
(
E
:
LocalLang
).
Import
E
.
(
*
Assumptions
for
a
type
system
for
local
languages
.
Again
,
this
is
given
as
a
module
type
.
See
STLC
.
v
and
TypedNatLang
.
v
for
instantiations
.
*
)
Module
Type
TypedLocalLang
(
Import
E
:
LocalLang
).
(
*
Types
are
a
Set
with
decidable
equality
.
*
)
Parameter
ExprTyp
:
Set
.
Parameter
ExprTypEqDec
:
forall
tau
sigma
:
ExprTyp
,
{
tau
=
sigma
}
+
{
tau
<>
sigma
}
.
(
*
We
require
a
typing
judgment
of
the
form
Γ
⊢
e
:
τ
.
We
represent
a
context
Γ
as
a
function
from
natural
numbers
(
which
represent
variables
)
to
types
.
This
judgment
is
a
proposition
(
probably
given
as
an
inductive
type
,
but
we
do
not
bake
that
in
).
*
)
Parameter
ExprTyping
:
(
nat
->
ExprTyp
)
->
Expr
->
ExprTyp
->
Prop
.
Notation
"Gamma ⊢e e ::: tau"
:=
(
ExprTyping
Gamma
e
tau
)
(
at
level
30
).
(
*
Variables
are
given
the
type
they
are
assigned
in
the
context
.
*
)
Parameter
ExprVarTyping
:
forall
(
Γ
:
nat
->
ExprTyp
)
(
n
:
nat
),
Γ
⊢
e
(
ExprVar
n
)
:::
(
Γ
n
).
(
*
Typing
is
extensional
in
the
since
that
it
does
not
look
at
the
internal
definition
of
its
context
;
it
only
cares
about
what
type
the
context
associates
with
what
variable
.
*
)
Parameter
ExprTypingExt
:
forall
(
Γ
Δ
:
nat
->
ExprTyp
)
(
e
:
Expr
)
(
τ
:
ExprTyp
),
(
forall
n
,
Γ
n
=
Δ
n
)
->
Γ
⊢
e
e
:::
τ
->
Δ
⊢
e
e
:::
τ
.
(
*
We
require
that
each
expression
have
a
unique
type
within
a
given
context
.
This
is
probably
the
most
burdensome
requirement
of
this
module
type
.
However
,
it
is
necessary
for
equivalence
of
choreographies
to
be
type
preserving
.
*
)
Parameter
ExprTypingUnique
:
forall
(
Γ
:
nat
->
ExprTyp
)
(
e
:
Expr
)
(
τ
σ
:
ExprTyp
),
Γ
⊢
e
e
:::
τ
->
Γ
⊢
e
e
:::
σ
->
τ
=
σ
.
Parameter
ExprWeakening
:
forall
(
Γ
Δ
:
nat
->
ExprTyp
)
(
ξ
:
nat
->
nat
)
(
e
:
Expr
)
(
τ
:
ExprTyp
),
(
forall
n
,
Γ
n
=
Δ
(
ξ
n
))
->
Γ
⊢
e
e
:::
τ
->
Δ
⊢
e
e
⟨
e
|
ξ⟩
:::
τ
.
(
*
The
type
system
should
not
take
the
values
assigned
by
the
context
to
variables
not
free
in
the
expression
.
Thus
,
if
an
expression
e
is
closed
above
n
,
the
values
of
the
context
above
n
should
not
matter
.
This
is
enough
to
allow
us
to
prove
that
the
context
does
not
matter
at
all
when
typing
closed
programs
.
Since
we
insist
that
all
values
are
closed
,
it
does
not
matter
when
typing
values
.
*
)
Parameter
ExprClosedAboveTyping
:
forall
(
Γ
Δ
:
nat
->
ExprTyp
)
(
e
:
Expr
)
(
τ
:
ExprTyp
)
(
n
:
nat
),
ExprClosedAbove
n
e
->
(
forall
m
,
m
<
n
->
Γ
m
=
Δ
m
)
->
Γ
⊢
e
e
:::
τ
->
Δ
⊢
e
e
:::
τ
.
Lemma
ExprClosedTyping
:
forall
(
Γ
Δ
:
nat
->
ExprTyp
)
(
e
:
Expr
)
(
τ
:
ExprTyp
),
...
...
@@ -43,56 +72,89 @@ Module Type TypedLocalLang (E : LocalLang).
apply
ExprValuesClosed
;
auto
.
Qed
.
(
*
We
represent
weakening
by
allowing
renaming
,
changing
the
context
to
match
.
This
represents
exchange
as
well
as
the
classical
definition
of
weakening
.
To
see
why
this
represents
weakening
,
consider
an
expression
e
which
is
closed
above
n
,
but
which
does
contain
the
variable
n
.
If
we
type
e
in
some
context
Γ
,
we
can
think
of
the
"real"
finite
context
as
Γ
up
through
n
.
Then
imagine
renaming
with
the
function
ξ
i
=
if
i
=
n
+
1
then
0
else
i
+
1
Clearly
,
the
resulting
expression
is
only
closed
above
n
+
1.
Thus
,
the
new
real
context
contains
some
variables
not
in
the
original
context
.
*
)
Parameter
ExprWeakening
:
forall
(
Γ
Δ
:
nat
->
ExprTyp
)
(
ξ
:
nat
->
nat
)
(
e
:
Expr
)
(
τ
:
ExprTyp
),
(
forall
n
,
Γ
n
=
Δ
(
ξ
n
))
->
Γ
⊢
e
e
:::
τ
->
Δ
⊢
e
e
⟨
e
|
ξ⟩
:::
τ
.
(
*
We
require
a
type
of
booleans
,
and
require
that
true
and
false
are
of
boolean
type
.
*
)
Parameter
bool
:
ExprTyp
.
Parameter
TrueTyping
:
forall
(
Γ
:
nat
->
ExprTyp
),
Γ
⊢
e
tt
:::
bool
.
Parameter
FalseTyping
:
forall
(
Γ
:
nat
->
ExprTyp
),
Γ
⊢
e
ff
:::
bool
.
(
*
Substitutions
replace
every
variable
with
a
new
expression
.
These
expressions
can
themselves
contain
variables
.
If
Γ
is
a
context
,
and
σ
assigns
every
variable
x
an
expression
that
(
under
a
new
context
Δ
)
has
the
type
Γ
gives
x
,
then
we
say
that
σ
changes
Γ
to
Δ
,
which
we
write
Γ
⊢
σ
⊣
Δ
.
*
)
Definition
ExprSubstTyping
:
(
nat
->
ExprTyp
)
->
(
nat
->
Expr
)
->
(
nat
->
ExprTyp
)
->
Prop
:=
fun
Γ
σ
Δ
=>
forall
n
:
nat
,
Δ
⊢
e
(
σ
n
)
:::
(
Γ
n
).
Notation
"Gamma ⊢es sigma ⊣ Delta"
:=
(
ExprSubstTyping
Gamma
sigma
Delta
)
(
at
level
30
).
(
*
We
then
require
that
,
if
σ
changes
Γ
to
Δ
and
e
hastype
τ
under
Γ
,
then
e
[
e
|
σ
]
has
type
τ
under
Δ
.
*
)
Parameter
ExprSubstType
:
forall
(
Γ
Δ
:
nat
->
ExprTyp
)
(
sigma
:
nat
->
Expr
)
(
e
:
Expr
)
(
τ
:
ExprTyp
),
Γ
⊢
es
sigma
⊣
Δ
->
Γ
⊢
e
e
:::
τ
->
Δ
⊢
e
e
[
e
|
sigma
]
:::
τ
.
forall
(
Γ
Δ
:
nat
->
ExprTyp
)
(
σ
:
nat
->
Expr
)
(
e
:
Expr
)
(
τ
:
ExprTyp
),
Γ
⊢
es
σ
⊣
Δ
->
Γ
⊢
e
e
:::
τ
->
Δ
⊢
e
e
[
e
|
σ
]
:::
τ
.
(
*
Clearly
,
the
identity
substitution
changes
Γ
to
itself
.
*
)
Lemma
ExprIdSubstTyping
:
forall
(
Γ
:
nat
->
ExprTyp
),
Γ
⊢
es
ExprIdSubst
⊣
Γ
.
Proof
.
unfold
ExprSubstTyping
.
intros
Γ
n
.
unfold
ExprIdSubst
.
apply
ExprVarTyping
.
unfold
ExprSubstTyping
;
intros
Γ
n
;
unfold
ExprIdSubst
;
apply
ExprVarTyping
.
Qed
.
Lemma
ExprSubstLWeakening
:
forall
(
Γ
Δ
1
Δ
2
:
nat
->
ExprTyp
)
(
σ
:
nat
->
Expr
)
(
ξ
:
nat
->
nat
),
(
forall
n
,
Δ
1
n
=
Δ
2
(
ξ
n
))
->
Γ
⊢
es
σ
⊣
Δ
1
->
Γ
⊢
es
fun
n
=>
(
σ
n
)
⟨
e
|
ξ⟩
⊣
Δ
2.
Proof
.
intros
Γ
Δ
1
Δ
2
σ
ξ
sub
Δ
typing
.
unfold
ExprSubstTyping
in
*
;
intro
n
.
eapply
ExprWeakening
;
eauto
.
Qed
.
(
*
Lemma
ExprSubstLWeakening
:
forall
(
Γ
Δ
1
Δ
2
:
nat
->
ExprTyp
)
(
σ
:
nat
->
Expr
)
(
ξ
:
nat
->
nat
),
*
)
(
*
(
forall
n
,
Δ
1
n
=
Δ
2
(
ξ
n
))
->
*
)
(
*
Γ
⊢
es
σ
⊣
Δ
1
->
*
)
(
*
Γ
⊢
es
fun
n
=>
(
σ
n
)
⟨
e
|
ξ⟩
⊣
Δ
2.
*
)
(
*
Proof
.
*
)
(
*
intros
Γ
Δ
1
Δ
2
σ
ξ
sub
Δ
typing
.
*
)
(
*
unfold
ExprSubstTyping
in
*
;
intro
n
.
*
)
(
*
eapply
ExprWeakening
;
eauto
.
*
)
(
*
Qed
.
*
)
Lemma
ExprSubstRWeakening
:
forall
(
Γ
1
Γ
2
Δ
:
nat
->
ExprTyp
)
(
σ
:
nat
->
Expr
)
(
ξ
:
nat
->
nat
),
(
forall
n
,
Γ
1
(
ξ
n
)
=
Γ
2
n
)
->
Γ
1
⊢
es
σ
⊣
Δ
->
Γ
2
⊢
es
fun
n
=>
σ
(
ξ
n
)
⊣
Δ
.
Proof
.
intros
Γ
1
Γ
2
Δ
σ
ξ
sub
Γ
typing
.
unfold
ExprSubstTyping
in
*
;
intro
n
.
rewrite
<-
sub
Γ
.
apply
typing
.
Qed
.
(
*
Lemma
ExprSubstRWeakening
:
forall
(
Γ
1
Γ
2
Δ
:
nat
->
ExprTyp
)
(
σ
:
nat
->
Expr
)
(
ξ
:
nat
->
nat
),
*
)
(
*
(
forall
n
,
Γ
1
(
ξ
n
)
=
Γ
2
n
)
->
*
)
(
*
Γ
1
⊢
es
σ
⊣
Δ
->
*
)
(
*
Γ
2
⊢
es
fun
n
=>
σ
(
ξ
n
)
⊣
Δ
.
*
)
(
*
Proof
.
*
)
(
*
intros
Γ
1
Γ
2
Δ
σ
ξ
sub
Γ
typing
.
*
)
(
*
unfold
ExprSubstTyping
in
*
;
intro
n
.
*
)
(
*
rewrite
<-
sub
Γ
.
apply
typing
.
*
)
(
*
Qed
.
*
)
Lemma
ExprSubstTypeExpand
:
forall
(
Γ
Δ
:
nat
->
ExprTyp
)
(
σ
:
nat
->
Expr
),
Γ
⊢
es
σ
⊣
Δ
->
forall
τ
:
ExprTyp
,
ExprSubstTyping
(
fun
n
=>
match
n
with
|
0
=>
τ
|
S
n
=>
Γ
n
end
)
(
ExprUpSubst
σ
)
(
fun
n
=>
match
n
with
|
0
=>
τ
|
S
n
=>
Δ
n
end
).
Proof
.
intros
Γ
Δ
σ
typing
τ
.
unfold
ExprUpSubst
.
unfold
ExprSubstTyping
in
*
.
intro
m
.
unfold
ExprUpSubst
.
destruct
m
;
simpl
.
apply
ExprVarTyping
.
apply
ExprWeakening
with
(
Γ
:=
Δ
);
auto
.
Qed
.
(
*
Lemma
ExprSubstTypeExpand
:
forall
(
Γ
Δ
:
nat
->
ExprTyp
)
(
σ
:
nat
->
Expr
),
*
)
(
*
Γ
⊢
es
σ
⊣
Δ
->
*
)
(
*
forall
τ
:
ExprTyp
,
ExprSubstTyping
(
fun
n
=>
match
n
with
|
0
=>
τ
|
S
n
=>
Γ
n
end
)
*
)
(
*
(
ExprUpSubst
σ
)
*
)
(
*
(
fun
n
=>
match
n
with
|
0
=>
τ
|
S
n
=>
Δ
n
end
).
*
)
(
*
Proof
.
*
)
(
*
intros
Γ
Δ
σ
typing
τ
.
*
)
(
*
unfold
ExprUpSubst
.
*
)
(
*
unfold
ExprSubstTyping
in
*
.
*
)
(
*
intro
m
.
*
)
(
*
unfold
ExprUpSubst
.
destruct
m
;
simpl
.
*
)
(
*
apply
ExprVarTyping
.
*
)
(
*
apply
ExprWeakening
with
(
Γ
:=
Δ
);
auto
.
*
)
(
*
Qed
.
*
)
End
TypedLocalLang
.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment