Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
C
cpdt
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
research
cpdt
Commits
22c2f4b7
Commit
22c2f4b7
authored
Dec 11, 2009
by
Adam Chlipala
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Proved preservation for LocallyNameless
parent
4faa155a
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
253 additions
and
119 deletions
+253
-119
Firstorder.v
src/Firstorder.v
+253
-119
No files found.
src/Firstorder.v
View file @
22c2f4b7
...
...
@@ -628,14 +628,14 @@ Module LocallyNameless.
end
.
End
open
.
Inductive
notFreeIn
(
x
:
free_var
)
:
exp
->
Prop
:=
|
NfConst
:
forall
c
,
notFreeIn
x
(
Const
c
)
|
NfFreeVar
:
forall
y
,
y
<>
x
->
notFreeIn
x
(
FreeVar
y
)
|
NfBoundVar
:
forall
y
,
notFreeIn
x
(
BoundVar
y
)
|
NfApp
:
forall
e1
e2
,
notFreeIn
x
e1
->
notFreeIn
x
e2
->
notFreeIn
x
(
App
e1
e2
)
|
NfAbs
:
forall
e1
,
(
forall
y
,
y
<>
x
->
notFreeIn
x
(
open
y
O
e1
))
->
notFreeIn
x
(
Abs
e1
)
.
Hint
Constructors
notFreeIn
.
Fixpoint
freeVars
(
e
:
exp
)
:
list
free_var
:=
match
e
with
|
Const
_
=>
nil
|
FreeVar
x
=>
x
::
nil
|
BoundVar
_
=>
nil
|
App
e1
e2
=>
freeVars
e1
++
freeVars
e2
|
Abs
e1
=>
freeVars
e1
end
.
Inductive
hasType
:
ctx
->
exp
->
type
->
Prop
:=
|
TConst
:
forall
G
b
,
...
...
@@ -647,38 +647,133 @@ Module LocallyNameless.
G
|-
e
e1
:
dom
-->
ran
->
G
|-
e
e2
:
dom
->
G
|-
e
App
e1
e2
:
ran
|
TAbs
:
forall
G
e
'
dom
ran
,
(
forall
x
,
notFreeIn
x
e
'
->
(
x
,
dom
)
::
G
|-
e
open
x
O
e
'
:
ran
)
|
TAbs
:
forall
G
e
'
dom
ran
L
,
(
forall
x
,
~
In
x
L
->
(
x
,
dom
)
::
G
|-
e
open
x
O
e
'
:
ran
)
->
G
|-
e
Abs
e
'
:
dom
-->
ran
where
"G |-e e : t"
:=
(
hasType
G
e
t
)
.
Hint
Constructors
hasType
.
(
**
We
prove
roughly
the
same
weakening
theorems
as
before
.
*
)
Lemma
lookup_push
:
forall
G
G
'
x
t
x
'
t
'
,
(
forall
x
t
,
G
|-
v
x
:
t
->
G
'
|-
v
x
:
t
)
->
(
x
,
t
)
::
G
|-
v
x
'
:
t
'
->
(
x
,
t
)
::
G
'
|-
v
x
'
:
t
'
.
inversion
2
;
crush
.
Qed
.
Lemma
weaken_lookup
:
forall
G
'
v
t
G
,
G
|-
v
v
:
t
->
G
++
G
'
|-
v
v
:
t
.
Hint
Resolve
lookup_push
.
Theorem
weaken_hasType
:
forall
G
e
t
,
G
|-
e
e
:
t
->
forall
G
'
,
(
forall
x
t
,
G
|-
v
x
:
t
->
G
'
|-
v
x
:
t
)
->
G
'
|-
e
e
:
t
.
induction
1
;
crush
;
eauto
.
Qed
.
Hint
Resolve
weaken_hasType
.
Inductive
lclosed
:
nat
->
exp
->
Prop
:=
|
CConst
:
forall
n
b
,
lclosed
n
(
Const
b
)
|
CFreeVar
:
forall
n
v
,
lclosed
n
(
FreeVar
v
)
|
CBoundVar
:
forall
n
v
,
v
<
n
->
lclosed
n
(
BoundVar
v
)
|
CApp
:
forall
n
e1
e2
,
lclosed
n
e1
->
lclosed
n
e2
->
lclosed
n
(
App
e1
e2
)
|
CAbs
:
forall
n
e1
,
lclosed
(
S
n
)
e1
->
lclosed
n
(
Abs
e1
)
.
Hint
Constructors
lclosed
.
Lemma
lclosed_S
:
forall
x
e
n
,
lclosed
n
(
open
x
n
e
)
->
lclosed
(
S
n
)
e
.
induction
e
;
inversion
1
;
crush
;
repeat
(
match
goal
with
|
[
_
:
context
[
if
?
E
then
_
else
_
]
|-
_
]
=>
destruct
E
end
;
crush
)
.
Qed
.
Hint
Resolve
lclosed_S
.
Lemma
lclosed_weaken
:
forall
n
e
,
lclosed
n
e
->
forall
n
'
,
n
'
>=
n
->
lclosed
n
'
e
.
induction
1
;
crush
.
Qed
.
Hint
Resolve
weaken_lookup
.
Hint
Resolve
lclosed_weaken
.
Hint
Extern
1
(
_
>=
_
)
=>
omega
.
Theorem
weaken_hasType
'
:
forall
G
'
G
e
t
,
Open
Scope
string_scope
.
Fixpoint
primes
(
n
:
nat
)
:
string
:=
match
n
with
|
O
=>
"x"
|
S
n
'
=>
primes
n
'
++
"'"
end
.
Check
fold_left
.
Fixpoint
sumLengths
(
L
:
list
free_var
)
:
nat
:=
match
L
with
|
nil
=>
O
|
x
::
L
'
=>
String
.
length
x
+
sumLengths
L
'
end
.
Definition
fresh
(
L
:
list
free_var
)
:=
primes
(
sumLengths
L
)
.
Theorem
freshOk
'
:
forall
x
L
,
String
.
length
x
>
sumLengths
L
->
~
In
x
L
.
induction
L
;
crush
.
Qed
.
Lemma
length_app
:
forall
s2
s1
,
String
.
length
(
s1
++
s2
)
=
String
.
length
s1
+
String
.
length
s2
.
induction
s1
;
crush
.
Qed
.
Hint
Rewrite
length_app
:
cpdt
.
Lemma
length_primes
:
forall
n
,
String
.
length
(
primes
n
)
=
S
n
.
induction
n
;
crush
.
Qed
.
Hint
Rewrite
length_primes
:
cpdt
.
Theorem
freshOk
:
forall
L
,
~
In
(
fresh
L
)
L
.
intros
;
apply
freshOk
'
;
unfold
fresh
;
crush
.
Qed
.
Hint
Resolve
freshOk
.
Lemma
hasType_lclosed
:
forall
G
e
t
,
G
|-
e
e
:
t
->
G
++
G
'
|-
e
e
:
t
.
induction
1
;
crush
;
eauto
.
->
lclosed
O
e
.
induction
1
;
eauto
.
Qed
.
Theorem
weaken_hasType
:
forall
e
t
,
nil
|-
e
e
:
t
->
forall
G
'
,
G
'
|-
e
e
:
t
.
intros
;
change
G
'
with
(
nil
++
G
'
)
;
eapply
weaken_hasType
'
;
eauto
.
Lemma
lclosed_open
:
forall
n
e
,
lclosed
n
e
->
forall
x
,
open
x
n
e
=
e
.
induction
1
;
crush
;
repeat
(
match
goal
with
|
[
|-
context
[
if
?
E
then
_
else
_
]
]
=>
destruct
E
end
;
crush
)
.
Qed
.
Hint
Resolve
weaken_hasType
.
Hint
Resolve
lclosed_open
hasType_lclosed
.
Open
Scope
list_scope
.
Lemma
In_app1
:
forall
T
(
x
:
T
)
ls2
ls1
,
In
x
ls1
->
In
x
(
ls1
++
ls2
)
.
induction
ls1
;
crush
.
Qed
.
Lemma
In_app2
:
forall
T
(
x
:
T
)
ls2
ls1
,
In
x
ls2
->
In
x
(
ls1
++
ls2
)
.
induction
ls1
;
crush
.
Qed
.
Hint
Resolve
In_app1
In_app2
.
Section
subst
.
Variable
x
:
free_var
.
...
...
@@ -692,125 +787,140 @@ Module LocallyNameless.
|
App
e1
e2
=>
App
(
subst
e1
)
(
subst
e2
)
|
Abs
e
'
=>
Abs
(
subst
e
'
)
end
.
End
subst
.
Notation
"[ x ~> e1 ] e2"
:=
(
subst
x
e1
e2
)
(
no
associativity
,
at
level
80
)
.
Inductive
val
:
exp
->
Prop
:=
|
VConst
:
forall
b
,
val
(
Const
b
)
|
VAbs
:
forall
e
,
val
(
Abs
e
)
.
Hint
Constructors
val
.
Variable
xt
:
type
.
Reserved
Notation
"e1 ==> e2"
(
no
associativity
,
at
level
90
)
.
Definition
disj
x
(
G
:
ctx
)
:=
In
x
(
map
(
@
fst
_
_
)
G
)
->
False
.
Infix
"#"
:=
disj
(
no
associativity
,
at
level
90
)
.
Inductive
step
:
exp
->
exp
->
Prop
:=
|
Beta
:
forall
x
e1
e2
,
val
e2
->
notFreeIn
x
e1
->
App
(
Abs
e1
)
e2
==>
[
x
~>
e2
]
(
open
x
O
e1
)
|
Cong1
:
forall
e1
e2
e1
'
,
e1
==>
e1
'
->
App
e1
e2
==>
App
e1
'
e2
|
Cong2
:
forall
e1
e2
e2
'
,
val
e1
->
e2
==>
e2
'
->
App
e1
e2
==>
App
e1
e2
'
Lemma
lookup_disj
'
:
forall
t
G1
,
G1
|-
v
x
:
t
->
forall
G
,
x
#
G
->
G1
=
G
++
(
x
,
xt
)
::
nil
->
t
=
xt
.
unfold
disj
;
induction
1
;
crush
;
match
goal
with
|
[
_
:
_
::
_
=
?
G0
++
_
|-
_
]
=>
destruct
G0
end
;
crush
;
eauto
.
Qed
.
where
"e1 ==> e2"
:=
(
step
e1
e2
)
.
Lemma
lookup_disj
:
forall
t
G
,
x
#
G
->
G
++
(
x
,
xt
)
::
nil
|-
v
x
:
t
->
t
=
xt
.
intros
;
eapply
lookup_disj
'
;
eauto
.
Qed
.
Hint
Constructors
step
.
Lemma
lookup_ne
'
:
forall
G1
v
t
,
G1
|-
v
v
:
t
->
forall
G
,
G1
=
G
++
(
x
,
xt
)
::
nil
->
v
<>
x
->
G
|-
v
v
:
t
.
induction
1
;
crush
;
match
goal
with
|
[
_
:
_
::
_
=
?
G0
++
_
|-
_
]
=>
destruct
G0
end
;
crush
.
Qed
.
Open
Scope
string_scope
.
Lemma
lookup_ne
:
forall
G
v
t
,
G
++
(
x
,
xt
)
::
nil
|-
v
v
:
t
->
v
<>
x
->
G
|-
v
v
:
t
.
intros
;
eapply
lookup_ne
'
;
eauto
.
Qed
.
Fixpoint
vlen
(
e
:
exp
)
:
nat
:=
match
e
with
|
Const
_
=>
0
|
FreeVar
x
=>
String
.
length
x
|
BoundVar
_
=>
0
|
App
e1
e2
=>
vlen
e1
+
vlen
e2
|
Abs
e1
=>
vlen
e1
Hint
Extern
1
(
_
|-
e
_
:
_
)
=>
match
goal
with
|
[
H1
:
_
,
H2
:
_
|-
_
]
=>
rewrite
(
lookup_disj
H1
H2
)
end
.
Opaque
le_lt_dec
.
Hint
Resolve
lookup_ne
.
Hint
Extern
1
(
@
eq
exp
_
_
)
=>
f_equal
.
Lemma
open_comm
:
forall
x1
x2
e
n1
n2
,
open
x1
n1
(
open
x2
(
S
n2
+
n1
)
e
)
=
open
x2
(
n2
+
n1
)
(
open
x1
n1
e
)
.
induction
e
;
crush
;
Lemma
open_subst
:
forall
x0
e
'
n
,
lclosed
n
e1
->
x
<>
x0
->
open
x0
n
(
subst
e
'
)
=
subst
(
open
x0
n
e
'
)
.
induction
e
'
;
crush
;
repeat
(
match
goal
with
|
[
|-
context
[
if
?
E
then
_
else
_
]
]
=>
destruct
E
end
;
crush
)
.
replace
(
S
(
n2
+
n1
))
with
(
n2
+
S
n1
)
;
auto
.
end
;
crush
)
;
eauto
6.
Qed
.
Hint
Rewrite
plus_0_r
:
cpdt
.
Hint
Rewrite
open_subst
:
cpdt
.
Lemma
open_comm0
:
forall
x1
x2
e
n
,
open
x1
0
(
open
x2
(
S
n
)
e
)
=
open
x2
n
(
open
x1
0
e
)
.
intros
;
generalize
(
open_comm
x1
x2
e
0
n
)
;
crush
.
Lemma
disj_push
:
forall
x0
(
t
:
type
)
G
,
x
#
G
->
x
<>
x0
->
x
#
(
x0
,
t
)
::
G
.
unfold
disj
;
crush
.
Qed
.
Hint
Extern
1
(
notFreeIn
_
(
open
_
0
(
open
_
(
S
_
)
_
)))
=>
rewrite
open_comm0
.
Hint
Immediate
disj_push
.
Lemma
notFreeIn_open
:
forall
x
y
,
x
<>
y
->
forall
e
,
notFreeIn
x
e
->
forall
n
,
notFreeIn
x
(
open
y
n
e
)
.
induction
2
;
crush
;
repeat
(
match
goal
with
|
[
|-
context
[
if
?
E
then
_
else
_
]
]
=>
destruct
E
end
;
crush
)
.
Lemma
lookup_cons
:
forall
x0
dom
G
x1
t
,
G
|-
v
x1
:
t
->
x0
#
G
->
(
x0
,
dom
)
::
G
|-
v
x1
:
t
.
unfold
disj
;
induction
1
;
crush
;
match
goal
with
|
[
H
:
_
|-
v
_
:
_
|-
_
]
=>
inversion
H
end
;
crush
.
Qed
.
Hint
Resolve
notFreeIn_open
.
Hint
Resolve
lookup_cons
.
Hint
Unfold
disj
.
Lemma
infVar
:
forall
x
y
,
String
.
length
x
>
String
.
length
y
->
y
<>
x
.
intros
;
destruct
(
string_dec
x
y
)
;
intros
;
subst
;
crush
.
Qed
.
Lemma
hasType_subst
'
:
forall
G1
e
t
,
G1
|-
e
e
:
t
->
forall
G
,
G1
=
G
++
(
x
,
xt
)
::
nil
->
x
#
G
->
G
|-
e
e1
:
xt
->
G
|-
e
subst
e
:
t
.
induction
1
;
crush
;
eauto
.
Hint
Resolve
infVar
.
destruct
(
string_dec
v
x
)
;
crush
.
Lemma
inf
'
:
forall
x
e
,
String
.
length
x
>
vlen
e
->
notFreeIn
x
e
.
induction
e
;
crush
;
eauto
.
apply
TAbs
with
(
x
::
L
++
map
(
@
fst
_
_
)
G0
)
;
crush
;
eauto
7
.
apply
H0
;
eauto
6
.
Qed
.
Fixpoint
primes
(
n
:
nat
)
:
string
:=
match
n
with
|
O
=>
"x"
|
S
n
'
=>
primes
n
'
++
"'"
end
.
Lemma
length_app
:
forall
s2
s1
,
String
.
length
(
s1
++
s2
)
=
String
.
length
s1
+
String
.
length
s2
.
induction
s1
;
crush
.
Theorem
hasType_subst
:
forall
e
t
,
(
x
,
xt
)
::
nil
|-
e
e
:
t
->
nil
|-
e
e1
:
xt
->
nil
|-
e
subst
e
:
t
.
intros
;
eapply
hasType_subst
'
;
eauto
.
Qed
.
End
subst
.
Hint
Re
write
length_app
:
cpd
t
.
Hint
Re
solve
hasType_subs
t
.
Lemma
length_primes
:
forall
n
,
String
.
length
(
primes
n
)
=
S
n
.
induction
n
;
crush
.
Qed
.
Notation
"[ x ~> e1 ] e2"
:=
(
subst
x
e1
e2
)
(
no
associativity
,
at
level
60
)
.
Hint
Rewrite
length_primes
:
cpdt
.
Inductive
val
:
exp
->
Prop
:=
|
VConst
:
forall
b
,
val
(
Const
b
)
|
VAbs
:
forall
e
,
val
(
Abs
e
)
.
Lemma
inf
:
forall
e
,
exists
x
,
notFreeIn
x
e
.
intro
;
exists
(
primes
(
vlen
e
))
;
apply
inf
'
;
crush
.
Qed
.
Hint
Constructors
val
.
Reserved
Notation
"e1 ==> e2"
(
no
associativity
,
at
level
90
)
.
Lemma
progress_Abs
:
forall
e1
e2
,
Inductive
step
:
exp
->
exp
->
Prop
:=
|
Beta
:
forall
e1
e2
x
,
val
e2
->
exists
e
'
,
App
(
Abs
e1
)
e2
==>
e
'
.
intros
;
destruct
(
inf
e1
)
;
eauto
.
Qed
.
->
~
In
x
(
freeVars
e1
)
->
App
(
Abs
e1
)
e2
==>
[
x
~>
e2
]
(
open
x
O
e1
)
|
Cong1
:
forall
e1
e2
e1
'
,
e1
==>
e1
'
->
App
e1
e2
==>
App
e1
'
e2
|
Cong2
:
forall
e1
e2
e2
'
,
val
e1
->
e2
==>
e2
'
->
App
e1
e2
==>
App
e1
e2
'
Hint
Resolve
progress_Abs
.
where
"e1 ==> e2"
:=
(
step
e1
e2
)
.
Hint
Constructors
step
.
Lemma
progress
'
:
forall
G
e
t
,
G
|-
e
e
:
t
->
G
=
nil
...
...
@@ -829,7 +939,29 @@ Module LocallyNameless.
intros
;
eapply
progress
'
;
eauto
.
Qed
.
(
*
Lemma
preservation
'
:
forall
G
e
t
,
G
|-
e
e
:
t
Lemma
alpha_open
:
forall
x1
x2
e1
e2
n
,
~
In
x1
(
freeVars
e2
)
->
~
In
x2
(
freeVars
e2
)
->
[
x1
~>
e1
](
open
x1
n
e2
)
=
[
x2
~>
e1
](
open
x2
n
e2
)
.
induction
e2
;
crush
;
repeat
(
match
goal
with
|
[
|-
context
[
if
?
E
then
_
else
_
]
]
=>
destruct
E
end
;
crush
)
.
Qed
.
Lemma
freshOk_app1
:
forall
L1
L2
,
~
In
(
fresh
(
L1
++
L2
))
L1
.
intros
;
generalize
(
freshOk
(
L1
++
L2
))
;
crush
.
Qed
.
Lemma
freshOk_app2
:
forall
L1
L2
,
~
In
(
fresh
(
L1
++
L2
))
L2
.
intros
;
generalize
(
freshOk
(
L1
++
L2
))
;
crush
.
Qed
.
Hint
Resolve
freshOk_app1
freshOk_app2
.
Lemma
preservation
'
:
forall
G
e
t
,
G
|-
e
e
:
t
->
G
=
nil
->
forall
e
'
,
e
==>
e
'
->
nil
|-
e
e
'
:
t
.
...
...
@@ -837,12 +969,14 @@ Module LocallyNameless.
match
goal
with
|
[
H
:
_
|-
e
Abs
_
:
_
|-
_
]
=>
inversion
H
end
;
eauto
.
rewrite
(
alpha_open
x
(
fresh
(
L
++
freeVars
e0
)))
;
eauto
.
Qed
.
Theorem
preservation
:
forall
e
t
,
nil
|-
e
e
:
t
->
forall
e
'
,
e
==>
e
'
->
nil
|-
e
e
'
:
t
.
intros
;
eapply
preservation
'
;
eauto
.
Qed
.
*
)
Qed
.
End
LocallyNameless
.
Write
Preview
Markdown
is supported
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