From Coq Require Import Classical List Setoid.
Require Import semantics.
Traces
Definition trace:
Type :=
list term.
Definition cons_right (
t:
trace) (
a:
term) :=
t ++ (
a ::
nil).
Notation "
a @@
b" := (
cons_right a b) (
at level 55,
right associativity).
Lemma cons_right_app:
forall a b c, (
a ++
b) @@
c =
a ++ (
b @@
c).
Proof.
Definition trace_app_l (
t:
trace) (
b:
term) :
trace :=
List.map (
fun a =>
App a b)
t.
Definition trace_app_r (
a:
term) (
t:
trace) :
trace :=
List.map (
fun b =>
App a b)
t.
CoInductive traceinf:
Type :=
|
Tcons:
term ->
traceinf ->
traceinf.
Infix ":::" :=
Tcons (
at level 60,
right associativity).
Fixpoint append_trace_traceinf (
t1:
trace) (
t2:
traceinf) {
struct t1}:
traceinf :=
match t1 with
|
nil =>
t2
|
ev ::
t =>
ev :::
append_trace_traceinf t t2
end.
Notation "
a +++
b" := (
append_trace_traceinf a b) (
at level 55,
right associativity).
Lemma append_assoc:
forall t1 t2 t3, (
t1 ++
t2) +++
t3 =
t1 +++ (
t2 +++
t3).
Proof.
induction t1; simpl; intros. auto. rewrite IHt1. auto.
Qed.
Lemma decompose_traceinf:
forall t,
t =
match t with Tcons e t' =>
Tcons e t'
end.
Proof.
intro. destruct t; auto.
Qed.
Ltac dec x :=
rewrite (
decompose_traceinf x);
simpl.
CoFixpoint traceinf_app_l (
t:
traceinf) (
b:
term) :
traceinf :=
match t with
|
a :::
t' =>
App a b :::
traceinf_app_l t'
b
end.
CoFixpoint traceinf_app_r (
a:
term) (
t:
traceinf) :
traceinf :=
match t with
|
b :::
t' =>
App a b :::
traceinf_app_r a t'
end.
CoInductive traceinf_sim:
traceinf ->
traceinf ->
Prop :=
|
traceinf_sim_intro:
forall a t1 t2,
traceinf_sim t1 t2 ->
traceinf_sim (
a :::
t1) (
a :::
t2).
Notation "
x ==
y" := (
traceinf_sim x y) (
at level 70,
no associativity).
Lemma traceinf_sim_refl:
forall x,
x ==
x.
Proof.
cofix COINDHYP; intro. destruct x. constructor. apply COINDHYP.
Qed.
Lemma traceinf_sim_sym:
forall x y,
x ==
y ->
y ==
x.
Proof.
cofix COINDHYP; intros. inversion H. constructor. apply COINDHYP; auto.
Qed.
Lemma traceinf_sim_trans:
forall x y z,
x ==
y ->
y ==
z ->
x ==
z.
Proof.
cofix COINDHYP; intros. inversion H; subst. inversion H0; subst. constructor. apply COINDHYP with t2; auto.
Qed.
Add Relation traceinf traceinf_sim
reflexivity proved by traceinf_sim_refl
symmetry proved by traceinf_sim_sym
transitivity proved by traceinf_sim_trans
as traceinf_sim_Rel.
Add Morphism traces.Tcons
with signature eq ==>
traceinf_sim ==>
traceinf_sim
as Tcons_M.
Proof.
intros. constructor; auto.
Qed.
Add Morphism append_trace_traceinf
with signature eq ==>
traceinf_sim ==>
traceinf_sim
as append_trace_traceinf_M.
Proof.
induction y; intros; simpl. auto. constructor; auto.
Qed.
Add Morphism traceinf_app_l
with signature traceinf_sim ==>
eq ==>
traceinf_sim
as traceinf_app_l_M.
Proof.
cofix COINDHYP;
intros.
inversion H.
dec (
traceinf_app_l (
a :::
t1)
y0).
dec (
traceinf_app_l (
a :::
t2)
y0).
constructor.
apply COINDHYP;
assumption.
Qed.
Add Morphism traceinf_app_r
with signature eq ==>
traceinf_sim ==>
traceinf_sim
as traceinf_app_r_M.
Proof.
cofix COINDHYP;
intros.
inversion H.
dec (
traceinf_app_r y (
a :::
t1)).
dec (
traceinf_app_r y (
a :::
t2)).
constructor.
apply COINDHYP;
assumption.
Qed.
Big-step semantics with traces
Inductive teval:
term ->
trace ->
term ->
Prop :=
|
teval_const:
forall c,
teval (
Const c)
nil (
Const c)
|
teval_fun:
forall x a,
teval (
Fun x a)
nil (
Fun x a)
|
teval_app:
forall a b x c vb v t1 t2 t3,
teval a t1 (
Fun x c) ->
teval b t2 vb ->
teval (
subst x vb c)
t3 v ->
teval (
App a b) (
trace_app_l t1 b ++
trace_app_r (
Fun x c)
t2 ++
App (
Fun x c)
vb ::
t3)
v.
Lemma teval_isvalue:
forall a t b,
teval a t b ->
isvalue b.
Proof.
induction 1; intros.
constructor.
constructor.
auto.
Qed.
Lemma teval_deterministic:
forall a t v,
teval a t v ->
forall t'
v',
teval a t'
v' ->
v' =
v /\
t' =
t.
Proof.
induction 1; intros.
inversion H; auto.
inversion H; auto.
inversion H2. subst.
destruct (IHteval1 _ _ H5) as [EQ1 EQ2].
subst t1. inversion EQ1; subst.
destruct (IHteval2 _ _ H6) as [EQ3 EQ4]. subst.
destruct (IHteval3 _ _ H9) as [EQ5 EQ6]. subst.
auto.
Qed.
Definition vx:
var := 0.
Definition delta :=
Fun vx (
App (
Var vx) (
Var vx)).
Definition omega :=
App delta delta.
Lemma not_eval_omega:
forall t v, ~(
teval omega t v).
Proof.
assert (
forall a t v,
teval a t v ->
a <>
omega).
induction 1;
unfold omega.
congruence.
congruence.
red;
intro.
injection H2;
intros;
subst a;
subst b.
clear H2.
unfold delta in H.
inversion H.
subst x;
subst c.
clear H.
unfold delta in H0.
inversion H0.
subst vb;
clear H0.
simpl in IHteval3.
fold delta in IHteval3.
fold omega in IHteval3.
congruence.
intros;
red;
intros.
elim (
H _ _ _ H0).
auto.
Qed.
CoInductive tevalinf:
term ->
traceinf ->
Prop :=
|
tevalinf_app_l:
forall a b t1 t,
tevalinf a t1 ->
t ==
traceinf_app_l t1 b ->
tevalinf (
App a b)
t
|
tevalinf_app_r:
forall a b va t1 t2 t,
teval a t1 va ->
tevalinf b t2 ->
t ==
trace_app_l t1 b +++
traceinf_app_r va t2 ->
tevalinf (
App a b)
t
|
tevalinf_app_f:
forall a b x c vb t1 t2 t3 t,
teval a t1 (
Fun x c) ->
teval b t2 vb ->
tevalinf (
subst x vb c)
t3 ->
t ==
trace_app_l t1 b +++
trace_app_r (
Fun x c)
t2 +++
(
App (
Fun x c)
vb :::
t3) ->
tevalinf (
App a b)
t.
CoFixpoint omegatrace :
traceinf :=
omega :::
omegatrace.
Lemma tevalinf_omega:
tevalinf omega omegatrace.
Proof.
Small-step semantics
Inductive tred:
term ->
trace ->
term ->
Prop :=
|
tred_refl:
forall a,
tred a nil a
|
tred_step:
forall a b c t,
red1 a b ->
tred b t c ->
tred a (
a ::
t)
c.
Lemma tred_one:
forall a b,
red1 a b ->
tred a (
a ::
nil)
b.
Proof.
Lemma tred_trans:
forall a t1 b t2 c,
tred a t1 b ->
tred b t2 c ->
tred a (
t1 ++
t2)
c.
Proof.
induction 1;
intros.
simpl.
auto.
simpl.
apply tred_step with b;
auto.
Qed.
CoInductive tredinf:
term ->
traceinf ->
Prop :=
|
tredinf_intro:
forall a b t,
red1 a b ->
tredinf b t ->
tredinf a (
a :::
t).
Lemma tredinf_deterministic:
forall a t1 t2,
tredinf a t1 ->
tredinf a t2 ->
t1 ==
t2.
Proof.
cofix COINDHYP;
intros.
inversion H;
subst.
inversion H0;
subst.
assert (
b =
b0).
eapply red1_deterministic;
eauto.
subst b0.
constructor.
apply COINDHYP with b;
assumption.
Qed.
CoInductive tredinf':
term ->
traceinf ->
Prop :=
|
tredinf'
_intro:
forall a b t1 t,
red1 a b ->
tredinf'
b t1 ->
t ==
a :::
t1 ->
tredinf'
a t.
Lemma tredinf'
_tredinf:
forall a t,
tredinf'
a t ->
tredinf a t.
Proof.
cofix COINDHYP;
intros.
inversion H;
subst.
inversion H2;
subst.
apply tredinf_intro with b.
assumption.
apply COINDHYP.
inversion H1;
subst.
apply tredinf'
_intro with b0 t2;
auto.
transitivity t1.
auto.
auto.
Qed.
Lemma tredinf_decompose:
forall a b t,
tred a t b ->
forall T,
tredinf a T ->
exists T',
tredinf b T' /\
T =
t +++
T'.
Proof.
induction 1;
intros.
exists T;
split;
auto.
inversion H1.
subst.
assert (
b =
b0).
eapply red1_deterministic;
eauto.
subst b0.
destruct (
IHtred t0 H3)
as [
T' [
A B]].
exists T';
split;
auto.
simpl.
rewrite B;
auto.
Qed.
Connections between the reduction semantics with and without traces
Lemma tred_red:
forall a t b,
tred a t b ->
red a b.
Proof.
induction 1; econstructor; eauto.
Qed.
Lemma red_tred:
forall a b,
red a b ->
exists t,
tred a t b.
Proof.
induction 1.
exists (@
nil term);
constructor.
destruct IHred as [
t R2].
exists (
a ::
t);
econstructor;
eauto.
Qed.
Lemma tred_or_redinf:
forall a,
(
exists b,
exists t,
tred a t b /\
notred b) \/
redinf a.
Proof.
intro.
elim (
red_or_redinf a).
intros [
b [
R NR]].
destruct (
red_tred _ _ R)
as [
t TR].
left;
exists b;
exists t;
split.
auto.
auto.
intro RI.
right;
auto.
Qed.
Lemma isvalue_dec:
forall a, {
isvalue a} + {~
isvalue a}.
Proof.
destruct a.
right; red; intro; inversion H.
left; constructor.
left; constructor.
right; red; intro; inversion H.
Qed.
Fixpoint reduce1 (
a:
term):
option term :=
match a with
|
Var _ =>
None
|
Const c =>
None
|
Fun x b =>
None
|
App (
Fun x b)
c =>
if isvalue_dec c
then Some (
subst x c b)
else match reduce1 c with
|
Some c' =>
Some (
App (
Fun x b)
c')
|
None =>
None
end
|
App b c =>
match reduce1 b with
|
Some b' =>
Some(
App b'
c)
|
None =>
if isvalue_dec b then
match reduce1 c with
|
Some c' =>
Some(
App b c')
|
None =>
None
end
else None
end
end.
Lemma isvalue_reduce1:
forall v,
isvalue v ->
reduce1 v =
None.
Proof.
intros. inversion H; reflexivity.
Qed.
Lemma red1_reduce1:
forall a b,
red1 a b ->
reduce1 a =
Some b.
Proof.
induction 1;
simpl.
destruct (
isvalue_dec v).
auto.
contradiction.
rewrite IHred1.
destruct a1;
auto.
inversion H.
repeat rewrite (
isvalue_reduce1 _ H).
destruct (
isvalue_dec v); [
idtac |
contradiction].
rewrite IHred1.
destruct v;
auto.
destruct (
isvalue_dec b1).
generalize (
isvalue_reduce1 _ i0).
congruence.
auto.
Qed.
CoFixpoint traceinf_for (
a:
term) :
traceinf :=
match reduce1 a with
|
Some b =>
a :::
traceinf_for b
|
None =>
a :::
traceinf_for a
end.
Lemma redinf_tredinf_aux:
forall a,
redinf a ->
tredinf a (
traceinf_for a).
Proof.
Lemma tred_or_tredinf:
forall a,
(
exists b,
exists t,
tred a t b /\
notred b) \/
(
exists t,
tredinf a t).
Proof.
Connections between big-step and small-step semantics
Lemma tred_app_l:
forall a1 t a2 b,
tred a1 t a2 ->
tred (
App a1 b) (
trace_app_l t b) (
App a2 b).
Proof.
Lemma tred_app_r:
forall v a1 t a2 ,
isvalue v ->
tred a1 t a2 ->
tred (
App v a1) (
trace_app_r v t) (
App v a2).
Proof.
Lemma teval_tred:
forall a t v,
teval a t v ->
tred a t v.
Proof.
Lemma teval_value:
forall v,
isvalue v ->
teval v nil v.
Proof.
Lemma tred1_teval:
forall a b,
red1 a b ->
forall t v,
teval b t v ->
teval a (
a ::
t)
v.
Proof.
Lemma tred_teval:
forall a t v,
tred a t v ->
isvalue v ->
teval a t v.
Proof.
Lemma tevalinf_tred1:
forall a t,
tevalinf a t ->
exists b,
exists t',
red1 a b /\
tevalinf b t' /\
t ==
a :::
t'.
Proof.
Lemma tevalinf_tredinf':
forall a t,
tevalinf a t ->
tredinf'
a t.
Proof.
cofix COINDHYP.
intros.
destruct (
tevalinf_tred1 _ _ H)
as [
b [
t1 [
R1 [
RI EQ]]]].
apply tredinf'
_intro with b t1.
auto.
apply COINDHYP.
auto.
auto.
Qed.
Lemma tevalinf_tredinf:
forall a t,
tevalinf a t ->
tredinf a t.
Proof.
intros. apply tredinf'_tredinf. apply tevalinf_tredinf'. auto.
Qed.
Lemma tredinf_app_l_1:
forall a t a'
b t',
tred a t a' ->
tredinf (
App a b)
t' ->
exists t'',
tredinf (
App a'
b)
t'' /\
t' =
trace_app_l t b +++
t''.
Proof.
Lemma tredinf_app_r_1:
forall b t b'
a t',
tred b t b' ->
isvalue a ->
tredinf (
App a b)
t' ->
exists t'',
tredinf (
App a b')
t'' /\
t' =
trace_app_r a t +++
t''.
Proof.
Lemma tredinf_app_l:
forall a b t,
tredinf a t ->
tredinf (
App a b) (
traceinf_app_l t b).
Proof.
cofix COINDHYP;
intros.
inversion H.
subst.
dec (
traceinf_app_l (
a :::
t0)
b).
apply tredinf_intro with (
App b0 b).
constructor.
auto.
apply COINDHYP.
assumption.
Qed.
Lemma tredinf_app_r:
forall a b t,
isvalue a ->
tredinf b t ->
tredinf (
App a b) (
traceinf_app_r a t).
Proof.
cofix COINDHYP;
intros.
inversion H0.
subst.
dec (
traceinf_app_r a (
b :::
t0)).
apply tredinf_intro with (
App a b0).
constructor.
auto.
auto.
apply COINDHYP.
assumption.
assumption.
Qed.
Lemma tredinf_app_l_2:
forall a b t ta,
tredinf (
App a b)
t ->
tredinf a ta ->
t ==
traceinf_app_l ta b.
Proof.
Lemma tredinf_app_r_2:
forall a b t tb,
tredinf (
App a b)
t ->
isvalue a ->
tredinf b tb ->
t ==
traceinf_app_r a tb.
Proof.
Lemma redinf_evalinf:
forall a t,
tredinf a t ->
tevalinf a t.
Proof.
cofix COINDHYP.
intros.
destruct a;
try (
inversion H;
inversion H0;
fail).
elim (
tred_or_tredinf a1).
intros [
n1 [
t1 [
REDM1 NOTRED1]]].
destruct (
tredinf_app_l_1 _ _ _ _ _ REDM1 H)
as [
t1' [
REDINF1 EQ1]].
assert (
ISVAL1:
isvalue n1).
inversion REDINF1.
inversion H0.
constructor.
elim (
NOTRED1 _ H7).
assumption.
elim (
tred_or_tredinf a2).
intros [
n2 [
t2 [
REDM2 NOTRED2]]].
destruct (
tredinf_app_r_1 _ _ _ _ _ REDM2 ISVAL1 REDINF1)
as [
t2' [
REDINF2 EQ2]].
assert (
exists x,
exists c,
exists t3,
n1 =
Fun x c /\
isvalue n2 /\
tredinf (
subst x n2 c)
t3 /\
t2' =
App n1 n2 :::
t3).
inversion REDINF2;
subst.
inversion H0;
subst.
exists x;
exists a;
exists t0.
tauto.
elim (
NOTRED1 _ H5).
elim (
NOTRED2 _ H6).
destruct H0 as [
x [
c [
t3 [
A [
B [
C D]]]]]].
subst n1.
rewrite EQ1;
rewrite EQ2;
rewrite D.
eapply tevalinf_app_f.
apply tred_teval;
eassumption.
apply tred_teval;
eassumption.
apply COINDHYP.
eassumption.
reflexivity.
intros [
t2'
TREDINF2].
assert (
t1' ==
traceinf_app_r n1 t2').
apply tredinf_app_r_2 with a2;
auto.
eapply tevalinf_app_r.
apply tred_teval;
eassumption.
apply COINDHYP.
eassumption.
rewrite EQ1.
rewrite H0.
reflexivity.
intros [
t1'
REDINF1].
assert (
t ==
traceinf_app_l t1'
a2).
apply tredinf_app_l_2 with a1;
auto.
apply tevalinf_app_l with t1'.
apply COINDHYP.
assumption.
assumption.
Qed.
Lemma tevalinf_deterministic:
forall a t1 t2,
tevalinf a t1 ->
tevalinf a t2 ->
t1 ==
t2.
Proof.