Library Int_typ
Require
Import
Eqdep_dec
.
Require
Omega
.
Require
Export
Class
.
Inductive
Int_K
: Type
:=
| iK
: forall
s
, Can
s
-> Int_K
| iT
: Int_K
.
Definition
intP
:= nat
-> Int_K
.
Definition
nil_intP
: intP
:= fun
_
=> iT
.
Definition
class_of_ik
ik
:=
match
ik
with
| iK
s
_
=> Knd
s
| iT
=> Typ
PROP
end
.
Definition
def_ik
cl
:=
match
cl
with
Knd
s
=> iK
s
(default_can
s
)
| _
=> iT
end
.
Definition
cls_of_int
(ip
: intP
) : cls
:= fun
i
=> class_of_ik
(ip
i
).
Inductive
ik_eq_can
: Int_K
-> Int_K
-> Prop
:=
| eqic_K
:
forall
s
(X
Y
: Can
s
), eq_can
_
X
Y
-> ik_eq_can
(iK
s
X
) (iK
s
Y
)
| eqic_T
: ik_eq_can
iT
iT
.
Hint
Constructors
ik_eq_can
: coc
.
Lemma
ik_eq_can_sym
: forall
i1
i2
, ik_eq_can
i1
i2
-> ik_eq_can
i2
i1
.
Proof
.
destruct
1; constructor
; apply
eq_can_sym
; trivial
.
Qed
.
Definition
int_eq_can
(ip1
ip2
: intP
) : Prop
:=
forall
i
, ik_eq_can
(ip1
i
) (ip2
i
).
Hint
Unfold
int_eq_can
: coc
.
Lemma
int_eq_can_right
:
forall
ip1
ip2
, int_eq_can
ip1
ip2
-> int_eq_can
ip2
ip2
.
Proof
.
unfold
int_eq_can
; intros
.
generalize
(H
i
); intro
.
destruct
H0
; trivial
with
coc
.
constructor
.
prolog
[eq_can_right
] 2.
Qed
.
Lemma
tail_int_eq_can
: forall
i1
i2
ip1
ip2
,
int_eq_can
(cons_map
i1
ip1
) (cons_map
i2
ip2
) ->
int_eq_can
ip1
ip2
.
Proof
.
unfold
int_eq_can
; intros
; exact
(H
(S
i
)).
Qed
.
Lemma
cons_int_eq_can
: forall
i1
i2
ip1
ip2
,
ik_eq_can
i1
i2
->
int_eq_can
ip1
ip2
->
int_eq_can
(cons_map
i1
ip1
) (cons_map
i2
ip2
).
Proof
.
unfold
int_eq_can
.
destruct
i
; simpl
; auto
with
coc
.
Qed
.
Lemma
del_int_eq_can
: forall
ip1
ip2
n
k
,
int_eq_can
ip1
ip2
-> int_eq_can
(del_map
n
k
ip1
) (del_map
n
k
ip2
).
Proof
.
red
; intros
.
unfold
del_map
.
case
(le_gt_dec
k
i
); auto
with
coc
.
Qed
.
Lemma
ins_int_eq_can
: forall
i1
i2
ip1
ip2
k
,
int_eq_can
ip1
ip2
->
ik_eq_can
i1
i2
->
int_eq_can
(ins_map
k
i1
ip1
) (ins_map
k
i2
ip2
).
Proof
.
red
; intros
.
unfold
ins_map
.
case
(lt_eq_lt_dec
k
i
); auto
with
coc
.
destruct
s
; auto
with
coc
.
Qed
.
Lemma
ins_int_eq_can_inv
: forall
k
i1
i2
ip1
ip2
,
int_eq_can
(ins_map
k
i1
ip1
) (ins_map
k
i2
ip2
) ->
int_eq_can
ip1
ip2
.
Proof
.
red
; intros
.
generalize
(H
i
) (H
(S
i
)).
unfold
ins_map
.
generalize
(lt_eq_lt_dec
k
i
); intros
[[cmp
|cmp]|cmp]; auto
.
generalize
(lt_eq_lt_dec
k
(S
i
)); intros
[[cmp2
|cmp2]|cmp2];
try
(apply
False_ind
; omega
); auto
.
generalize
(lt_eq_lt_dec
k
(S
i
)); intros
[[cmp2
|cmp2]|cmp2];
try
(apply
False_ind
; omega
); auto
.
Qed
.
Lemma
int_eq_can_cons_del
: forall
i
i'
ip
ip'
n
k
,
ik_eq_can
i
i'
->
int_eq_can
ip
(del_map
n
k
ip'
) ->
int_eq_can
(cons_map
i
ip
) (del_map
n
(S
k
) (cons_map
i'
ip'
)).
Proof
.
red
in
|- *; intros
.
rewrite
del_cons_map
.
generalize
i0
.
apply
cons_int_eq_can
; trivial
.
Qed
.
Lemma
int_eq_can_cons_ins
: forall
i
i'
j
ip
ip'
k
,
ik_eq_can
i
i'
->
int_eq_can
ip
(ins_map
k
j
ip'
) ->
int_eq_can
(cons_map
i
ip
) (ins_map
(S
k
) j
(cons_map
i'
ip'
)).
Proof
.
red
in
|- *; intros
.
rewrite
ins_cons_map
.
generalize
i0
.
apply
cons_int_eq_can
; trivial
.
Qed
.
Lemma
int_eq_can_class
:
forall
ip
ip'
,
int_eq_can
ip
ip'
->
eq_map
(cls_of_int
ip
) (cls_of_int
ip'
).
Proof
.
red
; unfold
int_eq_can
, cls_of_int
in
|- *; intros
.
elim
H
with
i
; reflexivity
.
Qed
.
Lemma
int_eq_can_cons_class
:
forall
i
ip
ip'
,
eq_map
(cons_map
(class_of_ik
i
) (cls_of_int
ip
)) ip'
->
eq_map
(cls_of_int
(cons_map
i
ip
)) ip'
.
Proof
.
intros
; apply
trans_eq_map
with
(2:=H).
red
; unfold
cls_of_int
in
|- *; destruct
i0
; simpl
in
|- *; auto
with
coc
.
Qed
.
Hint
Resolve
cons_int_eq_can
ins_int_eq_can
del_int_eq_can
int_eq_can_cons_del
int_eq_can_cons_ins
int_eq_can_class
int_eq_can_cons_class
: coc
.
Inductive
can_interp
: Int_K
-> Prop
:=
| ca_K
: forall
s
C
, is_can
_
C
-> can_interp
(iK
s
C
)
| ca_T
: can_interp
iT
.
Hint
Resolve
ca_K
ca_T
: coc
.
Lemma
def_ik_can
: forall
cl
, can_interp
(def_ik
cl
).
Proof
.
unfold
def_ik
in
|- *; destruct
cl
; auto
with
coc
.
Qed
.
Hint
Resolve
def_ik_can
: coc
.
Definition
can_adapt
(ip
: intP
) : Prop
:= forall
i
, can_interp
(ip
i
).
Hint
Unfold
can_adapt
: coc
.
Lemma
cons_can_adapt
:
forall
i
ip
, can_interp
i
-> can_adapt
ip
-> can_adapt
(cons_map
i
ip
).
Proof
.
unfold
can_adapt
.
destruct
i0
; simpl
; auto
with
coc
.
Qed
.
Lemma
adapt_int_eq_can
: forall
ip
, can_adapt
ip
-> int_eq_can
ip
ip
.
Proof
.
unfold
can_adapt
, int_eq_can
.
intros
.
elim
(H
i
); auto
10 with
coc
.
Qed
.
Hint
Resolve
cons_can_adapt
adapt_int_eq_can
: coc
.
Definition
coerce_CR
(s
: skel
) (i
: Int_K
) : Can
s
:=
match
i
with
| iK
si
Ci
=>
match
EQ_skel
si
s
with
| left
y
=>
match
y
in
(_
=s) return
(Can
s
) with
| refl_equal
=> Ci
end
| right
_
=> default_can
s
end
| _
=> default_can
s
end
.
Lemma
coerce_refl
: forall
s
C
, coerce_CR
s
(iK
s
C
) = C
.
Proof
.
intros
.
unfold
coerce_CR
.
elim
(EQ_skel
s
s
); intros
.
elim
a
using
K_dec
; trivial
.
intros
. elim
(EQ_skel
x
y
); auto
.
elim
b
; trivial
.
Qed
.
Lemma
eq_can_coerce
:
forall
s
i1
i2
,
ik_eq_can
i1
i2
-> eq_can
_
(coerce_CR
s
i1
) (coerce_CR
s
i2
).
Proof
.
destruct
1; simpl
; auto
with
coc
.
elim
(EQ_skel
s0
s
); simpl
; auto
with
coc
.
intro
a
; case
a
; trivial
.
Qed
.
Hint
Resolve
eq_can_coerce
: coc
.
Lemma
is_can_coerce
: forall
i
s
, can_interp
i
-> is_can
s
(coerce_CR
s
i
).
destruct
1; simpl
; intros
; auto
with
coc
.
elim
(EQ_skel
s0
s
); auto
with
coc
.
intro
a
; case
a
; auto
with
coc
.
Qed
.
Hint
Resolve
is_can_coerce
: coc
.
Lemma
ik_proj_right
: forall
s
X
Y
,
existT
(fun
s
=> Can
s
) s
X
= existT
(fun
s
=> Can
s
) s
Y
-> X
=Y.
Proof
.
intros
.
set
(ex2ik
:= fun
(e
:sigT(fun s
=> Can
s
)) =>
let
(s'
,C) := e
in
coerce_CR
s
(iK
s'
C
)).
rewrite
<- (coerce_refl
s
X
); rewrite
<- (coerce_refl
s
Y
).
change
(ex2ik
(existT
(fun
s
=> Can
s
) s
X
) =ex2ik
(existT
(fun
s
=> Can
s
) s
Y
)).
rewrite
H
; trivial
.
Qed
.
Lemma
ik_eq_can_trans
: forall
i1
i2
i3
,
ik_eq_can
i1
i2
-> ik_eq_can
i2
i3
-> ik_eq_can
i1
i3
.
destruct
1; intros
.
inversion
H0
.
constructor
.
apply
eq_can_trans
with
Y
; trivial
.
rewrite
<- ik_proj_right
with
(1:=H3); trivial
.
trivial
.
Qed
.
Definition
ik_app
i1
i2
:=
match
i1
, i2
with
iK
s
F
, iK
_
_
=>
match
s
return
Can
s
-> Int_K
with
PROD
s1
s2
=> fun
F
=> iK
s2
(F
(coerce_CR
s1
i2
))
| _
=> fun
_
=> i1
end
F
| _
, _
=> i1
end
.
Lemma
ik_app_ext
:
forall
U1
U2
V1
V2
,
ik_eq_can
U1
U2
->
ik_eq_can
V1
V2
->
ik_eq_can
(ik_app
U1
V1
) (ik_app
U2
V2
).
Proof
.
intros
.
unfold
ik_app
in
|- *.
elim
H
; intros
; auto
with
coc
.
elim
H0
; intros
; auto
with
coc
.
destruct
s
; intros
; auto
with
coc
.
simpl
in
H1
; auto
with
coc
.
Qed
.
Lemma
ik_app_can
:
forall
U
V
, can_interp
U
-> can_interp
V
-> can_interp
(ik_app
U
V
).
Proof
.
destruct
1; simpl
in
|- *; auto
with
coc
.
destruct
1; auto
with
coc
.
destruct
s
; auto
with
coc
.
simpl
in
H
.
destruct
H
; auto
with
coc
.
Qed
.
Definition
ik_lam
cl1
cl2
F
:=
match
cl2
, cl1
with
| Typ
s2
, Knd
s1
=>
iK
(PROD
s1
s2
) (fun
C
=> coerce_CR
s2
(F
(iK
_
C
)))
| Typ
_
, Typ
PROP
=> F
iT
| _
, _
=> iT
end
.
Definition
ik_eq_fun
cl
F1
F2
:=
forall
i1
i2
,
ik_eq_can
i1
i2
-> class_of_ik
i1
= cl
-> ik_eq_can
(F1
i1
) (F2
i2
).
Hint
Unfold
ik_eq_fun
: coc
.
Lemma
ik_lam_ext
:
forall
clA1
clA2
clM1
clM2
F1
F2
,
clA1
= clA2
->
(clA1
= clA2
-> clM1
= clM2
) ->
ik_eq_fun
clA1
F1
F2
->
ik_eq_can
(ik_lam
clA1
clM1
F1
) (ik_lam
clA2
clM2
F2
).
Proof
.
unfold
ik_lam
, ik_eq_fun
; fold
Can
.
intros
.
elim
H
; elim
H0
; trivial
.
destruct
clM1
; auto
with
coc
.
destruct
clA1
; eauto
10 with
coc
.
destruct
s0
; auto
10 with
coc
.
Qed
.
Lemma
ik_lam_can
:
forall
cl1
cl2
F
,
(forall
X
, can_interp
X
-> can_interp
(F
X
)) ->
ik_eq_fun
cl1
F
F
->
can_interp
(ik_lam
cl1
cl2
F
).
Proof
.
unfold
ik_lam
, ik_eq_fun
; fold
Can
.
destruct
cl2
; auto
with
coc
.
destruct
cl1
; auto
with
coc
.
destruct
s0
; auto
with
coc
.
constructor
; split
; auto
with
coc
.
Qed
.
Definition
ik_pi
cl
i
F
:=
let
X
:= coerce_CR
PROP
i
in
match
cl
with
Knd
s
=> iK
PROP
(Pi
s
X
(fun
C
=> coerce_CR
PROP
(F
(iK
_
C
))))
| _
=> iK
PROP
(Pi
PROP
X
(fun
_
=> coerce_CR
PROP
(F
iT
)))
end
.
Lemma
ik_pi_ext
:
forall
cl1
cl2
A1
A2
B1
B2
,
cl1
= cl2
->
ik_eq_can
A1
A2
->
((forall
s
, cl1
<> Knd
s
) -> ik_eq_can
(B1
iT
) (B2
iT
)) ->
(forall
s
X
Y
,
cl1
= Knd
s
->
eq_can
s
X
Y
->
ik_eq_can
(B1
(iK
_
X
)) (B2
(iK
_
Y
))) ->
ik_eq_can
(ik_pi
cl1
A1
B1
) (ik_pi
cl2
A2
B2
).
Proof
.
intros
.
subst
cl2
.
unfold
ik_pi
in
|- *; fold
Can
in
|- *.
destruct
cl1
; constructor
; apply
eq_can_Pi
; eauto
with
coc
.
apply
eq_can_prod
; intros
; apply
eq_can_coerce
; apply
H1
; intros
;
discriminate
.
apply
eq_can_prod
; intros
; apply
eq_can_coerce
; apply
H1
; intros
;
discriminate
.
Qed
.
Lemma
ik_pi_can
:
forall
cl
X
F
,
can_interp
X
->
(forall
i
, can_interp
i
-> can_interp
(F
i
)) ->
can_interp
(ik_pi
cl
X
F
).
Proof
.
unfold
ik_pi
in
|- *; fold
Can
in
|- *.
destruct
cl
; intros
; constructor
; simpl
in
|- *; apply
is_can_Pi
;
auto
10 with
coc
.
Qed
.
Lemma
ik_beta_redex
:
forall
cl1
cl2
F
i
,
typ_cls
cl2
(class_of_ik
(F
i
)) ->
class_of_ik
i
= cl1
->
ik_app
(ik_lam
cl1
cl2
F
) i
= F
i
.
Proof
.
intros
cl1
cl2
F
i
H
.
inversion
H
.
simpl
in
|- *; intros
; destruct
(F
i
); try
discriminate
; reflexivity
.
unfold
ik_lam
in
|- *; fold
Can
in
|- *.
destruct
i
; simpl
in
|- *; destruct
1; unfold
ik_app
in
|- *.
rewrite
coerce_refl
.
destruct
(F
(iK
s0
c
)); intros
; try
discriminate
.
injection
H2
; intro
; subst
s1
.
rewrite
coerce_refl
; reflexivity
.
case
(F
iT
); reflexivity
.
Qed
.
Lemma
ik_pi_elim
:
forall
cl
X
F
i
t
u
,
coerce_CR
PROP
(ik_pi
cl
X
F
) t
->
coerce_CR
PROP
X
u
->
can_interp
i
->
class_of_ik
i
= cl
->
coerce_CR
PROP
(F
i
) (App
t
u
).
Proof
.
unfold
ik_pi
in
|- *; fold
Can
in
|- *.
intros
cl
X
F
i
t
u
.
destruct
cl
; repeat
rewrite
coerce_refl
; simpl
in
|- *; intros
; red
in
H
.
destruct
i
; try
discriminate
H2
.
destruct
i
; try
discriminate
H2
.
eauto
with
coc
.
generalize
H2
; clear
H2
.
destruct
H1
; simpl
in
|- *; intro
; try
discriminate
.
injection
H2
; intro
; subst
s
.
eauto
with
coc
.
Qed
.
Lemma
ik_pi_intro
:
forall
cl
X
F
A
t
,
can_interp
X
->
(forall
i
, can_interp
i
-> can_interp
(F
i
)) ->
ik_eq_fun
cl
F
F
->
(forall
u
i
,
can_interp
i
->
class_of_ik
i
= cl
->
coerce_CR
PROP
X
u
->
coerce_CR
PROP
(F
i
) (subst
u
t
)) ->
sn
A
->
match
cl
with
Knd
_
=> True
| Typ
PROP
=> True
| _
=> False
end
->
coerce_CR
PROP
(ik_pi
cl
X
F
) (Abs
A
t
).
Proof
.
intros
.
unfold
ik_pi
in
|- *; fold
Can
in
|- *.
destruct
cl
as
[| [| s1
s2
]| s
]; destruct
H4
; try
rewrite
coerce_refl
;
apply
Abs_sound
; intros
; auto
10 with
coc
.
split
; simpl
in
|- *; intros
; auto
with
coc
.
split
; simpl
in
|- *; intros
; auto
with
coc
.
fold
(eq_can
PROP
) in
|- *; auto
with
coc
.
Qed
.
Fixpoint
int_typ
(T
: term
) (ip
: intP
) {struct
T
} : Int_K
:=
match
T
with
| Srt
_
=> iK
_
(default_can
PROP
)
| Ref
n
=> ip
n
| Abs
A
t
=>
let
clA
:= cl_term
A
(cls_of_int
ip
) in
let
clt
:= cl_term
t
(cons_map
clA
(cls_of_int
ip
)) in
ik_lam
clA
clt
(fun
i
=> int_typ
t
(cons_map
i
ip
))
| App
u
v
=>
ik_app
(int_typ
u
ip
) (int_typ
v
ip
)
| Prod
A
B
=>
let
clA
:= cl_term
A
(cls_of_int
ip
) in
ik_pi
clA
(int_typ
A
ip
) (fun
i
=> int_typ
B
(cons_map
i
ip
))
end
.
Fixpoint
proj_fw
(T
:term) (ip
: cls
) {struct
T
} : term
:=
match
T
with
| Abs
A
t
=>
let
clA
:= cl_term
A
ip
in
match
cl_term
t
(cons_map
clA
ip
), clA
with
| Typ
_
, Typ
_
=> proj_fw
t
(cons_map
clA
ip
)
| _
, _
=> Abs
(proj_fw
A
ip
) (proj_fw
t
(cons_map
clA
ip
))
end
| App
u
v
=>
match
cl_term
u
ip
, cl_term
v
ip
with
| Typ
_
, Trm
=> proj_fw
u
ip
| _
, _
=> App
(proj_fw
u
ip
) (proj_fw
v
ip
)
end
| Prod
A
B
=>
let
clA
:= cl_term
A
ip
in
match
cl_term
B
(cons_map
clA
ip
), clA
with
Knd
_
, Typ
_
=> proj_fw
B
(cons_map
clA
ip
)
| _
, _
=> Prod
(proj_fw
A
ip
) (proj_fw
B
(cons_map
clA
ip
))
end
| _
=> T
end
.