Set Implicit Arguments.
Require Import Coq.Relations.Relations.
Require Import MyTactics.
Require Import DeBruijn.
Require Import Coercions.
Require Import Store.
Require Import Layers.
Require Import Programs.
Require Import ValueLists.
Require Import RawPrograms.
-------------------------------------------------------------------------
The type erasure function.
Fixpoint erase_value (
v :
value) :
raw_value :=
match v with
|
VVar x =>
RawVVar x
|
VAbs t =>
RawVAbs (
erase_term t)
|
VPair Physical Physical w1 w2 =>
RawVPair (
erase_value w1) (
erase_value w2)
|
VPair Logical Physical w1 w2 =>
erase_value w2
|
VPair Physical Logical w1 w2 =>
erase_value w1
|
VPair Logical Logical w1 w2 =>
RawVErased
|
VPhyUnit =>
RawVUnit
|
VLoc l _ =>
RawVLoc l
|
VTyAbs v
|
VPack v
|
VCoApp _ v
|
VBang v
|
VInhabitant v =>
erase_value v
|
VRegionCap _
|
VRegionCapPunched _
|
VLogUnit =>
capabilities are erased
RawVErased
end
with erase_term (
t :
term) :
raw_term :=
match t with
|
TVal v =>
RawTVal (
erase_value v)
|
TApp v t =>
RawTApp (
erase_value v) (
erase_term t)
|
TMixPair t1 v2 =>
erase_term t1
|
TTyAbs t =>
erase_term t
|
TCoApp _ t =>
erase_term t
|
TLetBang v t
|
TLetUnpack v t
|
THide v t =>
subst_raw_term (
erase_value v) 0 (
erase_term t)
|
TLetPair Physical Physical v t =>
RawTLetPair (
erase_value v) (
erase_term t)
|
TLetPair Physical Logical v t =>
subst_raw_term (
erase_value v) 0 (
subst_raw_term RawVErased 0 (
erase_term t))
the second variable bound by TLetMixedPair should appear in t only at
logical positions, so whatever we substitute for it will disappear, if
the term is well-layered; RawVErased is the most natural choice
|
TLetPair Logical Physical v t =>
subst_raw_term RawVErased 0 (
subst_raw_term (
lift_raw_value 0 (
erase_value v)) 0 (
erase_term t))
|
TLetPair Logical Logical v t =>
subst_raw_term RawVErased 0 (
subst_raw_term RawVErased 0 (
erase_term t))
|
TPrimApp (
PDefocusDuplicable _)
v
|
TPrimApp (
PFocus _)
v
|
TPrimApp PNewGroup v
|
TPrimApp PAdopt v
|
TPrimApp PFocusGroup v =>
RawTVal (
erase_value v)
|
TPrimApp PNewAffine v
|
TPrimApp PNewCap v =>
RawTNew (
erase_value v)
|
TPrimApp PReadCap v =>
RawTRead (
erase_value v)
|
TPrimApp PWriteCap v =>
RawTWrite (
erase_value v)
|
TPrimApp PReadAffine v =>
The primitive operation PReadAffine returns a pair of the value that has been
read and the reference. We implement this behavior explicitly.
RawTLet (
RawTRead (
erase_value v)) (
RawTVal (
RawVPair (
RawVVar 0) (
lift_raw_value 0 (
erase_value v))))
|
TPrimApp PWriteAffine v =>
RawTLet (
RawTWrite (
erase_value v)) (
RawTFirst (
lift_raw_value 0 (
erase_value v)))
end.
Definition erase_store (
s :
store) :
raw_store :=
match s with
|
Store limit m =>
Store limit (
transform erase_value m)
end.
-------------------------------------------------------------------------
Erasure commutes with lifting and substitution.
Hint Extern 1 =>
match goal with eq:
forall k,
_ =
_ |-
_ =>
rewrite eq end :
erase_lift.
Hint Extern 1 =>
rewrite raw_lift_lift_value :
erase_lift.
Hint Extern 1 =>
rewrite raw_lift_subst_2_term :
erase_lift.
Lemma erase_lift:
(
forall v k,
erase_value (
lift_value k v) =
lift_raw_value k (
erase_value v)) /\
(
forall vs :
values,
True) /\
(
forall t k,
erase_term (
lift_term k t) =
lift_raw_term k (
erase_term t)).
Proof.
apply value_term_ind;
simpl;
intros;
layers;
try prim;
eauto 7
with erase_lift.
Qed.
Hint Extern 1 =>
rewrite (
pi1 erase_lift).
Hint Extern 1 =>
rewrite (
pi3 erase_lift).
Hint Extern 1 =>
repeat match goal with eq:
forall v k,
_ =
_ |-
_ =>
rewrite eq end :
erase_subst.
Hint Extern 1 =>
rewrite <-
raw_lift_subst_1_value :
erase_subst.
The following tactic looks for an outer substitution for an index s which
is non-zero -- so s is the variable k that we are substituting for, or
perhaps S k, etc. -- and pushes this substitution inwards.
Ltac push_subst :=
match goal with |-
context[
subst_raw_term _ ?
s (
subst_raw_term _ ?
k _)] =>
match s with
| 0 =>
fail 1
|
_ =>
rewrite raw_subst_subst_term with (
s1 :=
s);
simpl;
eauto
end
end.
Hint Extern 1 =>
push_subst :
erase_subst.
Lemma erase_subst:
(
forall w v k,
erase_value (
subst_value v k w) =
subst_raw_value (
erase_value v)
k (
erase_value w)) /\
(
forall vs :
values,
True) /\
(
forall t v k,
erase_term (
subst_term v k t) =
subst_raw_term (
erase_value v)
k (
erase_term t)).
Proof.
apply value_term_ind;
simpl;
intros;
layers;
try prim;
try solve [
eauto 7
with erase_subst ].
VVar
intros;
unfold subst_var;
inspect_cases;
auto.
Qed.
Hint Extern 1 =>
rewrite (
pi3 erase_subst);
simpl.
Hint Extern 1 =>
rewrite (
proj2 raw_pun_1).
Hint Extern 1 =>
rewrite (
proj2 raw_pun_2).
-------------------------------------------------------------------------
Pointwise equality of lists of values up to erasure.
Inductive pwe :
values ->
values ->
Prop :=
|
PweNil:
pwe VNil VNil
|
PweCons:
forall v1 v2 vs1 vs2,
erase_value v1 =
erase_value v2 ->
pwe vs1 vs2 ->
pwe (
VCons v1 vs1) (
VCons v2 vs2).
Hint Constructors pwe.
Lemma pwe_reflexive:
forall vs,
pwe vs vs.
Proof.
induction vs; eauto.
Qed.
Lemma pwe_some:
forall (
P :
value ->
Prop),
(
forall v w,
erase_value v =
erase_value w ->
P v ->
P w) ->
forall vs1 vs2,
pwe vs1 vs2 ->
some P vs1 ->
some P vs2.
Proof.
introv hp. induction 1; simpl. tauto. intros [ ? | ? ]; eauto.
Qed.
Lemma pwe_count:
forall vs1 vs2,
pwe vs1 vs2 ->
count vs1 =
count vs2.
Proof.
induction 1; simpl; congruence.
Qed.
Lemma pwe_vmap_coapp:
forall c vs,
pwe vs (
vmap (
VCoApp c)
vs).
Proof.
induction vs; simpl; auto.
Qed.
Lemma pwe_vmap_vtyabs:
forall vs,
pwe vs (
vmap VTyAbs vs).
Proof.
induction vs; simpl; auto.
Qed.