Library Class
Require
Export
Can
.
Require
Export
Types
.
Require
Export
IntMap
.
Inductive
class
: Set
:=
| Trm
: class
| Typ
: skel
-> class
| Knd
: skel
-> class
.
Definition
cls
:= nat
-> class
.
Definition
nil_cls
: cls
:= fun
_
=> Typ
PROP
.
Definition
Knd_1
c
:= match
c
with
| Knd
s
=> s
| _
=> PROP
end
.
Definition
Typ_1
c
:= match
c
with
| Typ
s
=> s
| _
=> PROP
end
.
Lemma
commut_case
:
forall
(A
B
: Type
) (f
: A
-> B
) c
bt
bT
bK
,
f
match
c
with
| Trm
=> bt
| Typ
s
=> bT
s
| Knd
s
=> bK
s
end
=
match
c
with
| Trm
=> f
bt
| Typ
_
=> f
(bT
(Typ_1
c
))
| Knd
_
=> f
(bK
(Knd_1
c
))
end
.
simple
destruct
c
; auto
.
Qed
.
Fixpoint
cl_term
(t
: term
) (i
: cls
) {struct
t
} : class
:=
match
t
with
| Srt
_
=> Knd
PROP
| Ref
n
=> match
i
n
with
| Knd
s
=> Typ
s
| _
=> Trm
end
| Abs
A
B
=>
let
clA
:= cl_term
A
i
in
match
cl_term
B
(cons_map
clA
i
), clA
with
| Typ
s2
, Knd
s1
=> Typ
(PROD
s1
s2
)
| Typ
s
, _
=> Typ
s
| Knd
_
, _
=> Knd
PROP
| Trm
, _
=> Trm
end
| App
u
v
=>
match
cl_term
u
i
, cl_term
v
i
with
| Typ
(PROD
s1
s2
), Typ
s
=> Typ
s2
| Typ
s
, _
=> Typ
s
| Knd
_
, _
=> Knd
PROP
| Trm
, _
=> Trm
end
| Prod
T
U
=>
let
clT
:= cl_term
T
i
in
match
cl_term
U
(cons_map
clT
i
), clT
with
| Knd
s2
, Knd
s1
=> Knd
(PROD
s1
s2
)
| Knd
s
, _
=> Knd
s
| Typ
s
, _
=> Typ
s
| c1
, _
=> c1
end
end
.
Fixpoint
class_env
(e
: env
) : cls
:=
match
e
with
| nil
=> nil_cls
| t
:: f
=> cons_map
(cl_term
t
(class_env
f
)) (class_env
f
)
end
.
Lemma
cl_term_ext
: forall
t
f
g
, eq_map
f
g
-> cl_term
t
f
= cl_term
t
g
.
Proof
.
induction
t
; simpl
; intros
; auto
.
rewrite
H
; trivial
.
rewrite
IHt1
with
(g
:=g); trivial
.
rewrite
IHt2
with
(g
:=cons_map (cl_term
t1
g
) g
); auto
; intros
.
rewrite
IHt1
with
(g
:=g); trivial
.
rewrite
IHt2
with
(g
:=g); trivial
.
rewrite
IHt1
with
(g
:=g); trivial
.
rewrite
IHt2
with
(g
:=cons_map (cl_term
t1
g
) g
); auto
; intros
.
Qed
.
Hint
Resolve
cl_term_ext
: coc
.
Lemma
nth_class_env
:
forall
t
e
n
,
item
t
(e
:env) n
->
class_env
e
n
= cl_term
t
(del_map
(S
n
) 0 (class_env
e
)).
Proof
.
simple
induction
1; simpl
in
|- *; intros
; auto
.
apply
cl_term_ext
; red
; auto
with
coc
.
Qed
.
Lemma
nth_class_env'
:
forall
t
e
f
n
,
item
t
(e
:env) n
->
trunc
(S
n
) e
(f
:env) ->
class_env
e
n
= cl_term
t
(class_env
f
).
Proof
.
simple
induction
1; simpl
in
|- *; intros
.
inversion_clear
H0
.
inversion_clear
H1
; auto
.
apply
H1
.
inversion_clear
H2
; auto
.
Qed
.
Lemma
class_knd
:
forall
e
t
T
,
typ
e
t
T
->
T
= Srt
kind
->
cl_term
t
(class_env
e
) = Knd
(Knd_1
(cl_term
t
(class_env
e
))).
Proof
.
simple
induction
1; intros
.
simpl
in
|- *; auto
with
coc
.
elim
H1
; intros
.
elim
item_trunc
with
term
v
e0
x
; auto
with
coc
; intros
.
elim
wf_sort
with
v
e0
x0
x
; auto
with
coc
; intros
.
elim
inv_typ_kind
with
e0
(Srt
x1
).
elim
H2
.
rewrite
H3
.
replace
(Srt
x1
) with
(lift
(S
v
) (Srt
x1
)); auto
with
coc
.
apply
thinning_n
with
x0
; auto
with
coc
.
discriminate
H6
.
elim
type_case
with
(1 := H2
); intros
.
inversion_clear
H5
.
apply
inv_typ_prod
with
(1 := H6
); intros
.
elim
inv_typ_kind
with
e0
(Srt
s2
); auto
with
coc
.
elim
H4
.
replace
(Srt
s2
) with
(subst
v
(Srt
s2
)); auto
with
coc
.
apply
substitution
with
V
; auto
with
coc
.
discriminate
H5
.
simpl
in
H3
.
simpl
in
|- *.
rewrite
H3
; auto
with
coc
.
elim
(cl_term
T0
(class_env
e0
)); auto
with
coc
.
elim
inv_typ_kind
with
e0
(Srt
s
); auto
with
coc
.
elim
H5
; auto
with
coc
.
Qed
.
Lemma
class_typ
:
forall
e
t
T
,
typ
e
t
T
->
typ
e
T
(Srt
kind
) ->
cl_term
t
(class_env
e
) = Typ
(Typ_1
(cl_term
t
(class_env
e
))).
Proof
.
simple
induction
1; intros
.
elim
inv_typ_kind
with
e0
(Srt
kind
); trivial
.
elim
H1
; intros
.
simpl
in
|- *.
elim
item_trunc
with
term
v
e0
x
; auto
with
coc
; intros
.
rewrite
nth_class_env'
with
x
e0
x0
v
; auto
with
coc
.
rewrite
(class_knd
x0
x
(Srt
kind
)); trivial
.
elim
wf_sort
with
(1 := H5
) (3 := H4
); trivial
.
simple
destruct
x1
; trivial
; intros
.
absurd
(kind
= prop
).
discriminate
.
apply
conv_sort
.
apply
typ_unique
with
(1 := H2
).
rewrite
H3
.
fold
(lift_rec
(S
v
) (Srt
prop
) 0) (lift
(S
v
) (Srt
prop
)) in
|- *.
apply
thinning_n
with
(2 := H6
); trivial
.
simpl
in
|- *.
simpl
in
H5
.
rewrite
H5
.
elim
(cl_term
T0
(class_env
e0
)); intros
; auto
with
coc
.
apply
inv_typ_prod
with
(1 := H6
); intros
.
elim
conv_sort
with
s3
kind
; auto
with
coc
.
simpl
in
|- *.
elim
type_case
with
(1 := H2
); intros
.
inversion_clear
H5
.
rewrite
H3
.
case
(Typ_1
(cl_term
u
(class_env
e0
))); auto
with
coc
.
elim
(cl_term
v
(class_env
e0
)); auto
with
coc
.
apply
inv_typ_prod
with
(1 := H6
); intros
.
apply
type_prod
with
s1
; auto
with
coc
.
elim
conv_sort
with
s2
kind
; auto
with
coc
.
apply
typ_unique
with
e0
(subst
v
Ur
); auto
with
coc
.
replace
(Srt
s2
) with
(subst
v
(Srt
s2
)); auto
with
coc
.
apply
substitution
with
V
; auto
with
coc
.
discriminate
H5
.
simpl
in
|- *.
simpl
in
H3
.
rewrite
H3
; auto
with
coc
.
replace
(Srt
s2
) with
(lift
1 (Srt
s2
)); auto
with
coc
.
replace
(Srt
kind
) with
(lift
1 (Srt
kind
)); auto
with
coc
.
apply
thinning
; auto
with
coc
.
apply
wf_var
with
s1
; auto
with
coc
.
apply
H1
.
elim
type_case
with
(1 := H0
); intros
.
inversion_clear
H6
.
elim
conv_sort
with
x
kind
; auto
with
coc
.
apply
typ_conv_conv
with
e0
U
V
; auto
with
coc
.
elim
inv_typ_conv_kind
with
e0
V
(Srt
kind
); auto
with
coc
.
elim
H6
; auto
with
coc
.
Qed
.
Lemma
class_trm
:
forall
e
t
T
,
typ
e
t
T
-> typ
e
T
(Srt
prop
) -> cl_term
t
(class_env
e
) = Trm
.
Proof
.
simple
induction
1; intros
.
elim
inv_typ_kind
with
e0
(Srt
prop
); auto
with
coc
.
elim
H1
; intros
.
elim
item_trunc
with
term
v
e0
x
; auto
with
coc
; intros
.
elim
wf_sort
with
(1 := H5
) (3 := H4
); trivial
.
simple
destruct
x1
; intros
.
absurd
(kind
= prop
).
discriminate
.
apply
conv_sort
.
apply
typ_unique
with
(2 := H2
).
rewrite
H3
.
fold
(lift_rec
(S
v
) (Srt
kind
) 0) (lift
(S
v
) (Srt
kind
)) in
|- *.
apply
thinning_n
with
(2 := H6
); trivial
.
simpl
in
|- *.
rewrite
nth_class_env'
with
x
e0
x0
v
; auto
with
coc
.
rewrite
(class_typ
x0
x
(Srt
prop
)); trivial
.
constructor
; prolog
[ typ_wf
] 5.
simpl
in
|- *.
simpl
in
H5
.
rewrite
H5
; auto
with
coc
.
apply
inv_typ_prod
with
e0
T0
U
(Srt
prop
); intros
; auto
with
coc
.
elim
conv_sort
with
s3
prop
; auto
with
coc
.
simpl
in
|- *.
elim
type_case
with
e0
u
(Prod
V
Ur
); auto
with
coc
; intros
.
inversion_clear
H5
.
rewrite
H3
; auto
with
coc
.
apply
inv_typ_prod
with
e0
V
Ur
(Srt
x
); intros
; auto
with
coc
.
apply
type_prod
with
s1
; auto
with
coc
.
elim
conv_sort
with
s2
prop
; auto
with
coc
.
apply
typ_unique
with
e0
(subst
v
Ur
); auto
with
coc
.
replace
(Srt
s2
) with
(subst
v
(Srt
s2
)); auto
with
coc
.
apply
substitution
with
V
; auto
with
coc
.
discriminate
H5
.
simpl
in
|- *.
simpl
in
H3
.
rewrite
H3
; auto
with
coc
.
replace
(Srt
s2
) with
(lift
1 (Srt
s2
)); auto
with
coc
.
replace
(Srt
prop
) with
(lift
1 (Srt
prop
)); auto
with
coc
.
apply
thinning
; auto
with
coc
.
apply
wf_var
with
s1
; auto
with
coc
.
apply
H1
.
elim
type_case
with
e0
t0
U
; auto
with
coc
; intros
.
inversion_clear
H6
.
elim
conv_sort
with
x
prop
; auto
with
coc
.
apply
typ_conv_conv
with
e0
U
V
; auto
with
coc
.
elim
inv_typ_conv_kind
with
e0
V
(Srt
prop
); auto
with
coc
.
elim
H6
; auto
with
coc
.
Qed
.
Inductive
adj_cls
: class
-> class
-> Prop
:=
| adj_t
: forall
s
, adj_cls
Trm
(Typ
s
)
| adj_T
: forall
s1
s2
, adj_cls
(Typ
s1
) (Knd
s2
).
Hint
Constructors
adj_cls
: coc
.
Lemma
cl_term_sound
:
forall
e
t
T
K
,
typ
e
t
T
->
typ
e
T
K
-> adj_cls
(cl_term
t
(class_env
e
)) (cl_term
T
(class_env
e
)).
Proof
.
intros
.
elim
type_case
with
(1 := H
); intros
; auto
with
coc
.
elim
H1
.
simple
destruct
x
; intros
.
rewrite
(class_knd
e
T
(Srt
kind
)); auto
with
coc
.
rewrite
(class_typ
e
t
T
); auto
with
coc
.
rewrite
(class_typ
e
T
(Srt
prop
)); auto
with
coc
.
rewrite
(class_trm
e
t
T
); auto
with
coc
.
apply
type_prop
.
apply
typ_wf
with
t
T
; auto
with
coc
.
elim
inv_typ_kind
with
e
K
; auto
with
coc
.
elim
H1
; auto
with
coc
.
Qed
.
Lemma
class_lift
:
forall
n
t
k
f
, cl_term
(lift_rec
n
t
k
) f
= cl_term
t
(del_map
n
k
f
).
simple
induction
t
; intros
.
simpl
in
|- *; auto
.
simpl
in
|- *.
unfold
del_map
.
elim
(le_gt_dec
k
n0
); simpl
in
|- *; trivial
.
simpl
in
|- *.
rewrite
H
; rewrite
H0
.
rewrite
cl_term_ext
with
(g
:=cons_map (cl_term
t0
(del_map
n
k
f
)) (del_map
n
k
f
)).
2:apply del_cons_map
.
trivial
.
simpl
in
|- *.
rewrite
H
; rewrite
H0
.
trivial
.
simpl
in
*.
rewrite
H
; rewrite
H0
.
rewrite
cl_term_ext
with
(g
:=cons_map (cl_term
t0
(del_map
n
k
f
)) (del_map
n
k
f
)).
2:apply del_cons_map
.
trivial
.
Qed
.
Inductive
typ_cls
: class
-> class
-> Prop
:=
| tc_t
: typ_cls
Trm
(Typ
PROP
)
| tc_T
: forall
s
, typ_cls
(Typ
s
) (Knd
s
).
Hint
Constructors
typ_cls
: coc
.
Lemma
class_subst
:
forall
a
x
t
k
E
,
typ_cls
(cl_term
x
(del_map
k
0 E
)) a
->
cl_term
(subst_rec
x
t
k
) E
= cl_term
t
(ins_map
k
a
E
).
simple
induction
t
; simpl
in
|- *; intros
; auto
with
coc
.
unfold
ins_map
.
elim
(lt_eq_lt_dec
k
n
); simpl
in
|- *; intros
; auto
.
elim
a0
; intros
; auto
.
unfold
lift
; rewrite
class_lift
.
elim
H
; trivial
.
rewrite
H
with
(1:=H1).
rewrite
H0
with
(S
k
) (cons_map
(cl_term
t0
(ins_map
k
a
E
)) E
).
rewrite
cl_term_ext
with
(g
:=cons_map (cl_term
t0
(ins_map
k
a
E
)) (ins_map
k
a
E
)).
trivial
.
apply
ins_cons_map
.
exact
H1
.
rewrite
H
with
(1:=H1).
rewrite
H0
with
(1:=H1).
trivial
.
rewrite
H
with
(1:=H1).
rewrite
H0
with
(S
k
) (cons_map
(cl_term
t0
(ins_map
k
a
E
)) E
).
rewrite
cl_term_ext
with
(g
:=cons_map (cl_term
t0
(ins_map
k
a
E
)) (ins_map
k
a
E
)).
trivial
.
apply
ins_cons_map
.
exact
H1
.
Qed
.
Inductive
loose_eqc
: class
-> class
-> Prop
:=
| leqc_trm
: loose_eqc
Trm
Trm
| leqc_typ
: forall
s1
s2
, loose_eqc
(Typ
s1
) (Typ
s2
)
| leqc_ord
: forall
s
, loose_eqc
(Knd
s
) (Knd
s
).
Hint
Constructors
loose_eqc
: coc
.
Lemma
refl_loose_eqc
: forall
c
, loose_eqc
c
c
.
Proof
.
simple
destruct
c
; constructor
.
Qed
.
Hint
Resolve
refl_loose_eqc
: coc
.
Lemma
loose_eqc_trans
:
forall
c1
c2
,
loose_eqc
c1
c2
-> forall
c3
, loose_eqc
c2
c3
-> loose_eqc
c1
c3
.
Proof
.
simple
destruct
1; intros
; inversion_clear
H0
; auto
with
coc
.
Qed
.
Lemma
loose_eqc_stable
:
forall
t
cl1
cl2
,
(forall
n
, loose_eqc
(cl1
n
) (cl2
n
)) ->
loose_eqc
(cl_term
t
cl1
) (cl_term
t
cl2
).
Proof
.
simple
induction
t
; simpl
in
|- *; intros
; auto
with
coc
.
elim
(H
n
); auto
with
coc
.
case
H0
with
(cons_map
(cl_term
t0
cl1
) cl1
) (cons_map
(cl_term
t0
cl2
) cl2
);
auto
with
coc
.
destruct
n
; simpl
; auto
.
case
H
with
(1 := H1
); auto
with
coc
; intros
.
case
H
with
(1 := H1
); auto
with
coc
; intros
.
case
s1
; case
s2
; case
H0
with
(1 := H1
); auto
with
coc
; intros
.
case
H0
with
(cons_map
(cl_term
t0
cl1
) cl1
) (cons_map
(cl_term
t0
cl2
) cl2
);
auto
with
coc
.
destruct
n
; simpl
; auto
.
case
H
with
(1 := H1
); auto
with
coc
; intros
.
Qed
.
Hint
Resolve
loose_eqc_stable
: coc
.
Lemma
cl_term_subst
:
forall
a
x
t
k
E
,
adj_cls
(cl_term
x
(del_map
k
0 E
)) a
->
loose_eqc
(cl_term
t
(ins_map
k
a
E
)) (cl_term
(subst_rec
x
t
k
) E
).
Proof
.
simple
induction
t
; simpl
in
|- *; intros
; auto
with
coc
.
unfold
ins_map
.
generalize
(lt_eq_lt_dec
k
n
); intros
[[H0
|H0]|H0]; simpl
in
|- *; auto
with
coc
.
unfold
lift
; rewrite
class_lift
.
elim
H
; auto
with
coc
.
assert
(loose_eqc
(cl_term
t0
(ins_map
k
a
E
)) (cl_term
(subst_rec
x
t0
k
) E
)); intros
;
auto
with
coc
.
assert
(loose_eqc
(cl_term
t1
(cons_map
(cl_term
t0
(ins_map
k
a
E
)) (ins_map
k
a
E
)))
(cl_term
(subst_rec
x
t1
(S
k
)) (cons_map
(cl_term
(subst_rec
x
t0
k
) E
) E
)));
intros
.
apply
loose_eqc_trans
with
(cl_term
t1
(cons_map
(cl_term
(subst_rec
x
t0
k
) E
) (ins_map
k
a
E
)));
auto
with
coc
.
apply
loose_eqc_stable
.
destruct
n
; simpl
; auto
with
coc
.
rewrite
<- cl_term_ext
with
(f
:=ins_map (S
k
) a
(cons_map
(cl_term
(subst_rec
x
t0
k
) E
) E
)).
auto
with
coc
.
apply
ins_cons_map
.
elim
H3
; auto
with
coc
; intros
.
elim
H2
; auto
with
coc
.
elim
H
with
k
E
; auto
with
coc
; intros
.
elim
s1
; elim
s2
; elim
H0
with
k
E
; auto
with
coc
.
assert
(loose_eqc
(cl_term
t0
(ins_map
k
a
E
)) (cl_term
(subst_rec
x
t0
k
) E
)); intros
;
auto
with
coc
.
assert
(loose_eqc
(cl_term
t1
(cons_map
(cl_term
t0
(ins_map
k
a
E
)) (ins_map
k
a
E
)))
(cl_term
(subst_rec
x
t1
(S
k
)) (cons_map
(cl_term
(subst_rec
x
t0
k
) E
) E
)));
intros
.
apply
loose_eqc_trans
with
(cl_term
t1
(cons_map
(cl_term
(subst_rec
x
t0
k
) E
) (ins_map
k
a
E
)));
auto
with
coc
.
apply
loose_eqc_stable
.
destruct
n
; simpl
; auto
with
coc
.
rewrite
<- cl_term_ext
with
(f
:=ins_map (S
k
) a
(cons_map
(cl_term
(subst_rec
x
t0
k
) E
) E
)).
auto
with
coc
.
apply
ins_cons_map
.
elim
H3
; auto
with
coc
; intros
.
elim
H2
; auto
with
coc
.
Qed
.
Lemma
cl_term_subst0
:
forall
a
x
t
E
,
adj_cls
(cl_term
x
E
) a
->
loose_eqc
(cl_term
t
(cons_map
a
E
)) (cl_term
(subst
x
t
) E
).
Proof
.
intros
.
rewrite
cl_term_ext
with
(g
:=ins_map 0 a
E
).
unfold
subst
.
apply
cl_term_subst
.
rewrite
cl_term_ext
with
(g
:=E); try
red
; auto
with
coc
.
red
; destruct
i
; auto
with
coc
.
Qed
.
Lemma
cl_term_red1
:
forall
e
A
T
,
typ
e
A
T
->
forall
B
,
red1
A
B
-> loose_eqc
(cl_term
A
(class_env
e
)) (cl_term
B
(class_env
e
)).
simple
induction
1; intros
; auto
with
coc
.
inversion_clear
H1
.
inversion_clear
H2
.
inversion_clear
H6
.
simpl
in
|- *.
elim
loose_eqc_stable
with
M
(cons_map
(cl_term
T0
(class_env
e0
)) (class_env
e0
))
(cons_map
(cl_term
M'
(class_env
e0
)) (class_env
e0
));
auto
with
coc
.
elim
H1
with
M'
; auto
with
coc
.
destruct
n
; simpl
; auto
with
coc
.
simpl
.
change
(cons_map
(cl_term
T0
(class_env
e0
)) (class_env
e0
)) with
(class_env
(T0
:: e0
)).
elim
H5
with
M'
; auto
with
coc
.
elim
(cl_term
T0
(class_env
e0
)); auto
with
coc
.
generalize
H2
H3
; clear
H2
H3
.
inversion_clear
H4
; intros
.
elim
type_case
with
(1 := H2
); intros
.
inversion_clear
H4
.
apply
inv_typ_prod
with
(1 := H5
); intros
.
apply
inv_typ_abs
with
(1 := H2
); intros
.
simpl
in
|- *.
apply
loose_eqc_trans
with
(cl_term
M
(class_env
(T0
:: e0
))).
unfold
class_env
in
|- *; fold
(class_env
(T0
:: e0
)) class_env
in
|- *;
auto
with
coc
.
elim
cl_term_sound
with
(1 := H9
) (2 := H10
); intros
; auto
with
coc
.
elim
(cl_term
T0
(class_env
e0
)); intros
.
elim
s4
; elim
(cl_term
v
(class_env
e0
)); auto
with
coc
.
elim
s4
; elim
(cl_term
v
(class_env
e0
)); auto
with
coc
.
elim
(cl_term
v
(class_env
e0
)); auto
with
coc
.
simpl
.
apply
cl_term_subst0
.
apply
cl_term_sound
with
(Srt
s0
); auto
with
coc
.
apply
type_conv
with
V
s0
; auto
with
coc
.
apply
inv_conv_prod_l
with
Ur
T1
; auto
with
coc
.
discriminate
.
simpl
in
|- *.
elim
H4
with
N1
; intros
; auto
with
coc
.
case
s1
; case
s2
; elim
(cl_term
v
(class_env
e0
)); auto
with
coc
.
simpl
in
|- *.
elim
(cl_term
u
(class_env
e0
)); intros
; auto
with
coc
.
case
s
; elim
H1
with
N2
; auto
with
coc
.
inversion_clear
H4
.
simpl
in
|- *.
elim
loose_eqc_stable
with
U
(cons_map
(cl_term
T0
(class_env
e0
)) (class_env
e0
))
(cons_map
(cl_term
N1
(class_env
e0
)) (class_env
e0
));
auto
with
coc
.
elim
H1
with
N1
; auto
with
coc
.
destruct
n
; simpl
; auto
with
coc
.
simpl
in
|- *.
unfold
class_env
in
|- *; fold
(class_env
(T0
:: e0
)) class_env
in
|- *;
auto
with
coc
.
elim
H3
with
N2
; auto
with
coc
.
Qed
.
Lemma
cl_term_red
:
forall
T
U
,
red
T
U
->
forall
e
K
,
typ
e
T
K
-> loose_eqc
(cl_term
T
(class_env
e
)) (cl_term
U
(class_env
e
)).
Proof
.
simple
induction
1; intros
; auto
with
coc
.
apply
loose_eqc_trans
with
(cl_term
P
(class_env
e
)); auto
with
coc
.
apply
H1
with
K
; auto
with
coc
.
apply
cl_term_red1
with
K
; auto
with
coc
.
apply
subject_reduction
with
T
; auto
with
coc
.
Qed
.
Lemma
cl_term_conv
:
forall
e
T
U
K1
K2
,
typ
e
T
K1
->
typ
e
U
K2
->
conv
T
U
-> loose_eqc
(cl_term
T
(class_env
e
)) (cl_term
U
(class_env
e
)).
Proof
.
intros
.
elim
church_rosser
with
(1 := H1
); intros
.
apply
loose_eqc_trans
with
(cl_term
x
(class_env
e
)).
apply
cl_term_red
with
K1
; auto
with
coc
.
elim
cl_term_red
with
U
x
e
K2
; auto
with
coc
.
Qed
.
Lemma
skel_sound
:
forall
e
t
T
,
typ
e
t
T
->
Knd_1
(cl_term
T
(class_env
e
)) = Typ_1
(cl_term
t
(class_env
e
)).
Proof
.
simple
induction
1; intros
; auto
with
coc
.
inversion_clear
H1
.
subst
t0
.
unfold
lift
.
rewrite
class_lift
.
unfold
del_map
.
simpl
.
elim
H3
; simpl
in
|- *; intros
; auto
.
rewrite
cl_term_ext
with
(g
:=class_env l
); try
red
; auto
.
case
(cl_term
x
(class_env
l
)); simpl
; auto
.
simpl
in
|- *.
unfold
class_env
in
|- *; fold
(class_env
(T0
:: e0
)) class_env
in
|- *;
auto
with
coc
.
rewrite
(commut_case
_
_
Knd_1
(cl_term
U
(class_env
(T0
:: e0
)))
(cl_term
U
(class_env
(T0
:: e0
))) (fun
s
=> Typ
s
)
(fun
s
=>
match
cl_term
T0
(class_env
e0
) with
| Trm
=> Knd
s
| Typ
_
=> Knd
s
| Knd
s0
=> Knd
(PROD
s0
s
)
end
)).
rewrite
(commut_case
_
_
Typ_1
(cl_term
M
(class_env
(T0
:: e0
))) Trm
(fun
s
=>
match
cl_term
T0
(class_env
e0
) with
| Trm
=> Typ
s
| Typ
_
=> Typ
s
| Knd
s0
=> Typ
(PROD
s0
s
)
end
) (fun
_
=> Knd
PROP
)).
pattern
(cl_term
M
(class_env
(T0
:: e0
))) at
1,
(cl_term
U
(class_env
(T0
:: e0
))) at
1 in
|- *.
elim
cl_term_sound
with
(1 := H4
) (2 := H2
); intros
; auto
with
coc
.
rewrite
(commut_case
_
_
Knd_1
(cl_term
T0
(class_env
e0
))
(Knd
(Knd_1
(cl_term
U
(class_env
(T0
:: e0
)))))
(fun
_
=> Knd
(Knd_1
(cl_term
U
(class_env
(T0
:: e0
)))))
(fun
s4
=> Knd
(PROD
s4
(Knd_1
(cl_term
U
(class_env
(T0
:: e0
)))))))
.
elim
(cl_term
T0
(class_env
e0
)); simpl
in
|- *; auto
with
coc
.
unfold
class_env
in
|- *; fold
(class_env
(T0
:: e0
)) class_env
in
|- *;
auto
with
coc
.
elim
H5
; auto
with
coc
.
elim
type_case
with
(1 := H2
); intros
.
inversion_clear
H4
.
apply
inv_typ_prod
with
(1 := H5
); intros
.
assert
(adj_cls
(cl_term
u
(class_env
e0
)) (cl_term
(Prod
V
Ur
) (class_env
e0
))).
apply
cl_term_sound
with
(Srt
x
); auto
with
coc
.
generalize
H3
H8
; clear
H3
H8
.
simpl
in
|- *.
elim
cl_term_subst0
with
(cl_term
V
(class_env
e0
)) v
Ur
(class_env
e0
);
simpl
in
|- *; auto
with
coc
.
intros
.
inversion_clear
H8
.
intros
.
inversion_clear
H8
.
auto
with
coc
.
elim
cl_term_sound
with
e0
v
V
(Srt
s1
); simpl
in
|- *; intros
; auto
with
coc
.
rewrite
H3
.
inversion_clear
H8
; auto
with
coc
.
case
s3
; auto
with
coc
.
generalize
H3
.
inversion_clear
H8
; intros
; auto
with
coc
.
simpl
in
H8
.
elim
H8
; auto
with
coc
.
apply
cl_term_sound
with
(Srt
s1
); auto
with
coc
.
discriminate
H4
.
simpl
in
|- *.
simpl
in
H3
.
simpl
in
H1
.
rewrite
(commut_case
_
_
Typ_1
(cl_term
U
(cons_map
(cl_term
T0
(class_env
e0
)) (class_env
e0
)))
(cl_term
U
(cons_map
(cl_term
T0
(class_env
e0
)) (class_env
e0
)))
(fun
s
=> Typ
s
)
(fun
s
=>
match
cl_term
T0
(class_env
e0
) with
| Trm
=> Knd
s
| Typ
_
=> Knd
s
| Knd
s0
=> Knd
(PROD
s0
s
)
end
)).
simpl
in
|- *.
elim
H3
.
elim
(cl_term
U
(cons_map
(cl_term
T0
(class_env
e0
)) (class_env
e0
)));
auto
with
coc
.
elim
(cl_term
T0
(class_env
e0
)); auto
with
coc
.
elim
H1
.
elim
cl_term_conv
with
e0
U
V
(Srt
s
) (Srt
s
); auto
with
coc
.
elim
type_case
with
e0
t0
U
; auto
with
coc
; intros
.
inversion_clear
H5
.
elim
conv_sort
with
x
s
; auto
with
coc
.
apply
typ_conv_conv
with
e0
U
V
; auto
with
coc
.
elim
inv_typ_conv_kind
with
e0
V
(Srt
s
); auto
with
coc
.
elim
H5
; auto
with
coc
.
Qed
.
Lemma
class_red
:
forall
e
T
U
K
,
typ
e
T
K
-> red
T
U
-> cl_term
T
(class_env
e
) = cl_term
U
(class_env
e
).
Proof
.
intros
.
cut
(Typ_1
(cl_term
T
(class_env
e
)) = Typ_1
(cl_term
U
(class_env
e
))).
elim
cl_term_red
with
T
U
e
K
; simpl
in
|- *; intros
; auto
with
coc
.
elim
H1
; auto
with
coc
.
elim
skel_sound
with
(1 := H
); auto
with
coc
.
apply
skel_sound
; auto
with
coc
.
apply
subject_reduction
with
T
; auto
with
coc
.
Qed
.
Lemma
class_sound
:
forall
e
t
T
K
,
typ
e
t
T
->
typ
e
T
K
-> typ_cls
(cl_term
t
(class_env
e
)) (cl_term
T
(class_env
e
)).
Proof
.
intros
.
elim
type_case
with
(1 := H
); intros
.
elim
H1
.
simple
destruct
x
; intros
.
rewrite
(class_knd
e
T
(Srt
kind
)); trivial
.
rewrite
(class_typ
e
t
T
); trivial
.
elim
skel_sound
with
(1 := H
); auto
with
coc
.
rewrite
(class_typ
e
T
(Srt
prop
)); trivial
.
rewrite
(class_trm
e
t
T
); trivial
.
elim
skel_sound
with
(1 := H2
); simpl
in
|- *; auto
with
coc
.
apply
type_prop
.
apply
typ_wf
with
t
T
; auto
with
coc
.
elim
inv_typ_kind
with
e
K
.
elim
H1
; auto
with
coc
.
Qed
.
Lemma
class_type
: forall
e
t
s
(P
:class->Prop),
typ
e
t
(Srt
s
) ->
(cl_term
t
(class_env
e
) = Typ
PROP
-> P
(Typ
PROP
)) ->
(forall
s
, cl_term
t
(class_env
e
) = Knd
s
-> P
(Knd
s
)) ->
P
(cl_term
t
(class_env
e
)).
Proof
.
destruct
s
; intros
.
generalize
H1
.
rewrite
class_knd
with
(1:= H
); auto
.
generalize
H0
.
rewrite
class_typ
with
(1:=H); trivial
.
assert
(Knd_1
(cl_term
(Srt
prop
) (class_env
e
)) = PROP
). reflexivity
.
generalize
H2
; clear
H2
.
elim
class_sound
with
(1:=H) (K
:=Srt kind
); simpl
; intros
; auto
.
subst
s
; auto
.
constructor
; eapply
typ_wf
; eauto
.
constructor
; eapply
typ_wf
; eauto
.
Qed
.
Lemma
class_term
: forall
e
t
T
s
(P
:class->class->Prop),
typ
e
t
T
->
typ
e
T
(Srt
s
) ->
(cl_term
t
(class_env
e
) = Trm
->
cl_term
T
(class_env
e
) = Typ
PROP
->
P
Trm
(Typ
PROP
)) ->
(forall
s
, cl_term
t
(class_env
e
) = Typ
s
->
cl_term
T
(class_env
e
) = Knd
s
->
P
(Typ
s
) (Knd
s
)) ->
P
(cl_term
t
(class_env
e
)) (cl_term
T
(class_env
e
)).
Proof
.
intros
.
specialize
class_sound
with
(1:=H) (2:=H0).
apply
class_type
with
(1:=H0); intros
.
generalize
H1
.
inversion_clear
H4
; auto
.
generalize
H2
.
inversion_clear
H4
; auto
.
Qed
.