Lecture notes 20210329 Small Step Semantics 2
Remark. Some material in this lecture is from << Software Foundation >>
volume 1 and volume 2.
Require Import Coq.micromega.Psatz.
Require Import PL.Imp.
Require Import PL.ImpExt.
Require Import PL.RTClosure.
Import Assertion_D.
Import Abstract_Pretty_Printing.
Local Open Scope imp.
Require Import PL.Imp.
Require Import PL.ImpExt.
Require Import PL.RTClosure.
Import Assertion_D.
Import Abstract_Pretty_Printing.
Local Open Scope imp.
Review: Small Step
Simulation for Program Equivalence
Associativity of Sequential Composition
( c1 ;; (c2 ;; c3), st1 ) ( (c1 ;; c2) ;; c3, st1 )
| |
| |
v v
( c1' ;; (c2 ;; c3), st1' ) ( (c1' ;; c2) ;; c3, st1' )
| |
[...] [...]
| |
v v
( Skip ;; (c2 ;; c3), st2 ) ( (Skip ;; c2) ;; c3, st2 )
| |
| |
v v
------> ( c2 ;; c3, st2 ) <-------
|
|
v
( c2' ;; c3, st2' )
|
...
|
v
( Skip ;; c3, st3 )
|
|
v
( c3 , st3 )
|
|
v
( c3' , st3' )
|
...
|
v
( Skip, st4 )
| |
| |
v v
( c1' ;; (c2 ;; c3), st1' ) ( (c1' ;; c2) ;; c3, st1' )
| |
[...] [...]
| |
v v
( Skip ;; (c2 ;; c3), st2 ) ( (Skip ;; c2) ;; c3, st2 )
| |
| |
v v
------> ( c2 ;; c3, st2 ) <-------
|
|
v
( c2' ;; c3, st2' )
|
...
|
v
( Skip ;; c3, st3 )
|
|
v
( c3 , st3 )
|
|
v
( c3' , st3' )
|
...
|
v
( Skip, st4 )
Module SeqAssoc.
Inductive match_com: com -> com -> Prop :=
| MatSeqAssoc: ∀c1 c2 c3,
match_com (c1 ;; (c2 ;; c3)) ((c1 ;; c2);; c3)
| MatRefl: ∀c,
match_com c c.
Inductive match_com: com -> com -> Prop :=
| MatSeqAssoc: ∀c1 c2 c3,
match_com (c1 ;; (c2 ;; c3)) ((c1 ;; c2);; c3)
| MatRefl: ∀c,
match_com c c.
And we can proof the simulation between such two programs. Here, simulation
mean: whenever one side takes a step, the other side can take a
corresponding step.
step
A --------> B
| .
match | . match
| .
v v
A' - - - - > B' (∃)
step
A --------> B
| .
match | . match
| .
v v
A' - - - - > B' (∃)
step
Lemma L_simulate_R: ∀c1 c1' c2' st1 st2,
match_com c1 c1' ->
cstep (c1', st1) (c2', st2) ->
∃c2,
match_com c2 c2' ∧ cstep (c1, st1) (c2, st2).
match_com c1 c1' ->
cstep (c1', st1) (c2', st2) ->
∃c2,
match_com c2 c2' ∧ cstep (c1, st1) (c2, st2).
The proof is straightforward. We can prove it by a case analysis over
Case 1: MatRefl case, i.e. c1 = c2. The conclusion is obviously true.
Case 2: MatSeqAssoc case, i.e. c1 = c1_1 ;; (c1_2 ;; c1_3)
Case 2-1: cstep (c1_1, st1) (c2_1, st2). New simulation is still based on
MatSeqAssoc.
Case 2-1: c1_1 = CSkip. New simulation is based MatRefl.
match_com c1 c2.
Proof.
intros.
inversion H as [c1_1 c1_2 c1_3 |]; subst.
2: { ∃c2'; split; [constructor | exact H0]. }
inversion H0; subst.
inversion H2 as [| | ? ? c2_1 | | | | |]; subst; clear H0 H2.
+ ∃(c2_1 ;; (c1_2 ;; c1_3)).
split.
- apply MatSeqAssoc.
- constructor.
apply H1.
+ rename c1' into c1_2.
∃(c1_2 ;; c1_3).
split.
- apply MatRefl.
- constructor.
Qed.
intros.
inversion H as [c1_1 c1_2 c1_3 |]; subst.
2: { ∃c2'; split; [constructor | exact H0]. }
inversion H0; subst.
inversion H2 as [| | ? ? c2_1 | | | | |]; subst; clear H0 H2.
+ ∃(c2_1 ;; (c1_2 ;; c1_3)).
split.
- apply MatSeqAssoc.
- constructor.
apply H1.
+ rename c1' into c1_2.
∃(c1_2 ;; c1_3).
split.
- apply MatRefl.
- constructor.
Qed.
The other direction is simular.
Lemma R_simulate_L: ∀c1 c2 c1' st st',
match_com c1 c2 ->
cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧ cstep (c2, st) (c2', st').
End SeqAssoc.
match_com c1 c2 ->
cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧ cstep (c2, st) (c2', st').
Proof.
intros.
inversion H; subst.
2: { ∃c1'; split; [constructor | exact H0]. }
inversion H0; subst.
+ ∃((c1'0 ;; c3) ;; c4).
split.
- apply MatSeqAssoc.
- constructor.
constructor.
apply H2.
+ ∃(c3 ;; c4).
split.
- apply MatRefl.
- constructor.
constructor.
Qed.
intros.
inversion H; subst.
2: { ∃c1'; split; [constructor | exact H0]. }
inversion H0; subst.
+ ∃((c1'0 ;; c3) ;; c4).
split.
- apply MatSeqAssoc.
- constructor.
constructor.
apply H2.
+ ∃(c3 ;; c4).
split.
- apply MatRefl.
- constructor.
constructor.
Qed.
End SeqAssoc.
Removing Skips On the Left
Fixpoint remove_skip (c: com): com :=
match c with
| CSkip ⇒
CSkip
| CAss X E ⇒
CAss X E
| CSeq c1 c2 ⇒
match remove_skip c1 with
| CSkip ⇒ remove_skip c2
| _ ⇒ CSeq (remove_skip c1) (remove_skip c2)
end
| CIf b c1 c2 ⇒
CIf b (remove_skip c1) (remove_skip c2)
| CWhile b c1 ⇒
CWhile b (remove_skip c1)
end.
Example remove_skip_example_1:
remove_skip (Skip ;; (Skip ;; While BTrue Do Skip EndWhile)) =
While BTrue Do Skip EndWhile.
Proof. reflexivity. Qed.
Example remove_skip_example_2:
remove_skip ((Skip ;; Skip) ;; While BTrue Do Skip EndWhile) =
While BTrue Do Skip EndWhile.
Proof. reflexivity. Qed.
Example remove_skip_example_3: ∀(X: var),
remove_skip (Skip ;; X ::= 0 ;; Skip) =
(X ::= 0 ;; Skip).
Proof. intros. reflexivity. Qed.
match c with
| CSkip ⇒
CSkip
| CAss X E ⇒
CAss X E
| CSeq c1 c2 ⇒
match remove_skip c1 with
| CSkip ⇒ remove_skip c2
| _ ⇒ CSeq (remove_skip c1) (remove_skip c2)
end
| CIf b c1 c2 ⇒
CIf b (remove_skip c1) (remove_skip c2)
| CWhile b c1 ⇒
CWhile b (remove_skip c1)
end.
Example remove_skip_example_1:
remove_skip (Skip ;; (Skip ;; While BTrue Do Skip EndWhile)) =
While BTrue Do Skip EndWhile.
Proof. reflexivity. Qed.
Example remove_skip_example_2:
remove_skip ((Skip ;; Skip) ;; While BTrue Do Skip EndWhile) =
While BTrue Do Skip EndWhile.
Proof. reflexivity. Qed.
Example remove_skip_example_3: ∀(X: var),
remove_skip (Skip ;; X ::= 0 ;; Skip) =
(X ::= 0 ;; Skip).
Proof. intros. reflexivity. Qed.
It is easy to prove that c and remove_skip c always have the same
denotation. But we can prove stronger claims based on small step semantics.
That is, the steps of executing c will be simulated by the steps of
executing remove_skip c, though some redundant skip-step can be removed.
This conclusion can be formally stated as follows.
Definition cstep_or_not (X Y: com * state): Prop :=
X = Y ∨ cstep X Y.
Definition SimulationStatement_01 (match_com: com -> com -> Prop): Prop :=
∀c1 c2 c1' st st',
match_com c1 c2 ->
cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧ cstep_or_not (c2, st) (c2', st').
X = Y ∨ cstep X Y.
Definition SimulationStatement_01 (match_com: com -> com -> Prop): Prop :=
∀c1 c2 c1' st st',
match_com c1 c2 ->
cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧ cstep_or_not (c2, st) (c2', st').
Let's start with an naive definition of match_com.
Module RemoveSkip_First_Attempt.
Definition match_com (c1 c2: com): Prop := c2 = remove_skip c1.
Definition match_com (c1 c2: com): Prop := c2 = remove_skip c1.
The following statement says: when c takes one step, remove_skip c
will take zero step or one corresponding step.
Lemma R_simulate_L: ∀c1 c2 c1' st st',
match_com c1 c2 ->
cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧
((c2, st) = (c2', st') ∨ cstep (c2, st) (c2', st')).
match_com c1 c2 ->
cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧
((c2, st) = (c2', st') ∨ cstep (c2, st) (c2', st')).
Unfortunately, this statement is not true! Consider the execution of
According to small step semantics, it takes three steps.
But remove_skip (Skip;; Y ::= 0) = (Y ::= 0). Thus, the first step above
does not have a correspondence when the remove_skip transformation is
taken. You can find where a Coq proof attempt will fail in the following
scripts.
X ::= 1;; Y ::= 0.
X ::= 1;; Y ::= 0 -->
Skip;; Y ::= 0 -->
Y ::= 0 -->
Skip
Skip;; Y ::= 0 -->
Y ::= 0 -->
Skip
Proof.
intros.
unfold match_com in *.
subst c2.
∃(remove_skip c1').
split; [reflexivity |].
induction_cstep H0; simpl; intros.
+ simpl.
right.
constructor; tauto.
+ simpl.
right.
constructor; tauto.
+
Abort.
End RemoveSkip_First_Attempt.
Module RemoveSkip.
intros.
unfold match_com in *.
subst c2.
∃(remove_skip c1').
split; [reflexivity |].
induction_cstep H0; simpl; intros.
+ simpl.
right.
constructor; tauto.
+ simpl.
right.
constructor; tauto.
+
Abort.
End RemoveSkip_First_Attempt.
Module RemoveSkip.
In order to establish a simulation relation for remove_skip, we define
a weaker version of match_com. The main idea is to reserve some left-side
skips.
Fixpoint match_com (c1 c2: com): Prop :=
match c1 with
| c1_1 ;; c1_2 ⇒
remove_skip c1_1 = CSkip ∧ c2 = remove_skip c1_2 ∨
∃c2_1, match_com c1_1 c2_1 ∧ c2 = (c2_1 ;; remove_skip c1_2)
| CIf b c1_1 c1_2 ⇒
∃c2_1, match_com c1_1 c2_1 ∧ c2 = CIf b c2_1 (remove_skip c1_2)
| _ ⇒
c2 = remove_skip c1
end.
match c1 with
| c1_1 ;; c1_2 ⇒
remove_skip c1_1 = CSkip ∧ c2 = remove_skip c1_2 ∨
∃c2_1, match_com c1_1 c2_1 ∧ c2 = (c2_1 ;; remove_skip c1_2)
| CIf b c1_1 c1_2 ⇒
∃c2_1, match_com c1_1 c2_1 ∧ c2 = CIf b c2_1 (remove_skip c1_2)
| _ ⇒
c2 = remove_skip c1
end.
For example, consider X ::= 1;; (Skip;; Y ::= 2), which will be transfered
to X ::= 1;; Y ::=2 by remove_skip.
This new definition of match_com allows Skip;; (Skip;; Y ::= 2) to match
Skip;; Y ::= 2, but not only restricted to Y ::= 2.
Here we prove this match_com relation is indeed a weaker one comparing to
remove_skip.
X ::= 1;; (Skip;; Y ::= 2) X ::= 1;; Y ::= 2
| |
| |
v v
Skip;; (Skip;; Y ::= 2) Skip;; Y ::= 2
| | |
| | | (no step)
v | |
Skip;; Y ::= 2 Skip;; Y ::= 2
| |
| |
v v
Y ::= 2 Y ::= 2
| |
| |
v v
Skip Skip
| |
| |
v v
Skip;; (Skip;; Y ::= 2) Skip;; Y ::= 2
| | |
| | | (no step)
v | |
Skip;; Y ::= 2 Skip;; Y ::= 2
| |
| |
v v
Y ::= 2 Y ::= 2
| |
| |
v v
Skip Skip
Lemma match_com_remove_skip: ∀c, match_com c (remove_skip c).
Proof.
intros.
induction c; simpl; try tauto.
+ destruct (remove_skip c1); try eauto.
+ eauto.
Qed.
Proof.
intros.
induction c; simpl; try tauto.
+ destruct (remove_skip c1); try eauto.
+ eauto.
Qed.
Our proof strategy for simulation (defined as follows)
is based on an induction over its assumption
Corresponding to cstep's definition, our inductive proof includes 8 cases.
For example, the proof step for the CS_AssStep case is to prove:
which will be proved later (Lemma R_simulate_L_CS_AssStep).
Among all 8 cases, the most intersting case is the CS_SeqStep case, and we
need two auxiliary lemmas for establishing the proof.
The following lemma remove_skip_skip_step says, if c1 can be transformed
to Skip by remove_skip (i.e. it is a sequential composition of many
skips), then taking one step from c1 results in another command c2 s.t.
remove_skip c2 = Skip as well. The main proof idea is to apply an
induction over c1's structure.
∀c1 c2 c1' st st',
match_com c1 c2 ->
cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧
cstep_or_not (c2, st) (c2', st')
match_com c1 c2 ->
cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧
cstep_or_not (c2, st) (c2', st')
cstep (c1, st) (c1', st').
astep st a a' ->
match_com (CAss X a) c2 ->
∃c2',
match_com (CAss X a') c2' ∧
cstep_or_not (c2, st) (c2', st)
match_com (CAss X a) c2 ->
∃c2',
match_com (CAss X a') c2' ∧
cstep_or_not (c2, st) (c2', st)
Lemma remove_skip_skip_step: ∀c1 c2 st1 st2,
remove_skip c1 = CSkip ->
cstep (c1, st1) (c2, st2) ->
st1 = st2 ∧ remove_skip c2 = CSkip.
remove_skip c1 = CSkip ->
cstep (c1, st1) (c2, st2) ->
st1 = st2 ∧ remove_skip c2 = CSkip.
Proof.
intros.
revert st1 c2 st2 H0.
induction c1; try solve [inversion H]; intros.
+ inversion H0.
+ simpl in H.
destruct (remove_skip c1_1) eqn:?H; try solve [inversion H].
specialize (IHc1_1 eq_refl).
inversion H0; subst.
- specialize (IHc1_1 _ _ _ H3).
destruct IHc1_1.
split; [auto | simpl].
rewrite H4, H.
reflexivity.
- auto.
Qed.
intros.
revert st1 c2 st2 H0.
induction c1; try solve [inversion H]; intros.
+ inversion H0.
+ simpl in H.
destruct (remove_skip c1_1) eqn:?H; try solve [inversion H].
specialize (IHc1_1 eq_refl).
inversion H0; subst.
- specialize (IHc1_1 _ _ _ H3).
destruct IHc1_1.
split; [auto | simpl].
rewrite H4, H.
reflexivity.
- auto.
Qed.
The following lemma says, if one or zero step takes (c1, st) to (c1',
st') , then one or zero step can also take (c1;; c2, st) to (c1';;c2,
st') . Its proof is straightforward.
Lemma cstep_or_not_congr_CSeq: ∀c1 st c1' st' c2,
cstep_or_not (c1, st) (c1', st') ->
cstep_or_not (c1;; c2, st) (c1';; c2, st').
cstep_or_not (c1, st) (c1', st') ->
cstep_or_not (c1;; c2, st) (c1';; c2, st').
Proof.
intros.
destruct H; [left | right].
+ injection H as ? ?; subst; reflexivity.
+ apply CS_SeqStep, H.
Qed.
intros.
destruct H; [left | right].
+ injection H as ? ?; subst; reflexivity.
+ apply CS_SeqStep, H.
Qed.
The following lemma states the induction step of CS_SeqStep. Since
either c2 has a form of c2_1 ;; c2_2 s.t.
or c2 = remove_skip c1_2 and remove_skip c1_1 = CSkip. We prove the
following lemma by such a case analysis.
match_com (c1_1;; c1_2) c2,
- match_com c1_1 c2_1;
- remove_skip c1_2 = c2_2;
Lemma R_simulate_L_CS_SeqStep: ∀c1_1 c1_2 st c1_1' st' c2
(IH:
∀c2_1,
match_com c1_1 c2_1 ->
∃c2_1',
match_com c1_1' c2_1' ∧
cstep_or_not (c2_1, st) (c2_1', st')),
cstep (c1_1, st) (c1_1', st') ->
match_com (c1_1;; c1_2) c2 ->
∃c2',
match_com (c1_1';; c1_2) c2' ∧
cstep_or_not (c2, st) (c2', st').
Proof.
intros.
simpl.
simpl in H0.
destruct H0 as [[? ?] | [c2_1 [? ?]]].
+ pose proof remove_skip_skip_step _ _ _ _ H0 H as [? ?].
subst st'.
∃c2.
split; [| left; reflexivity].
subst c2; simpl; rewrite H3.
auto.
+ specialize (IH _ H0) as [c2_1' [? ?]].
∃(c2_1' ;; remove_skip c1_2).
split; [right; eauto |].
subst c2.
apply cstep_or_not_congr_CSeq, H3.
Qed.
(IH:
∀c2_1,
match_com c1_1 c2_1 ->
∃c2_1',
match_com c1_1' c2_1' ∧
cstep_or_not (c2_1, st) (c2_1', st')),
cstep (c1_1, st) (c1_1', st') ->
match_com (c1_1;; c1_2) c2 ->
∃c2',
match_com (c1_1';; c1_2) c2' ∧
cstep_or_not (c2, st) (c2', st').
Proof.
intros.
simpl.
simpl in H0.
destruct H0 as [[? ?] | [c2_1 [? ?]]].
+ pose proof remove_skip_skip_step _ _ _ _ H0 H as [? ?].
subst st'.
∃c2.
split; [| left; reflexivity].
subst c2; simpl; rewrite H3.
auto.
+ specialize (IH _ H0) as [c2_1' [? ?]].
∃(c2_1' ;; remove_skip c1_2).
split; [right; eauto |].
subst c2.
apply cstep_or_not_congr_CSeq, H3.
Qed.
The following lemma proves the CS_Seq case. Its assumption
also means two possibilities:
match_com (CSkip;; c1_2) c2
- c2 = CSkip;; remove_skip c1_2;
- c2 = remove_skip c1_2.
Lemma R_simulate_L_CS_Seq: ∀c1_2 c2 st,
match_com (CSkip;; c1_2) c2 ->
∃c2',
match_com c1_2 c2' ∧
cstep_or_not (c2, st) (c2', st).
Proof.
intros.
destruct H as [[? ?] | [c2_1 [? ?]]].
+ clear H.
subst c2.
∃(remove_skip c1_2).
split; [apply match_com_remove_skip | left; reflexivity].
+ inversion H; subst.
clear H.
simpl (remove_skip Skip).
∃(remove_skip c1_2).
split; [apply match_com_remove_skip |].
right; apply CS_Seq.
Qed.
match_com (CSkip;; c1_2) c2 ->
∃c2',
match_com c1_2 c2' ∧
cstep_or_not (c2, st) (c2', st).
Proof.
intros.
destruct H as [[? ?] | [c2_1 [? ?]]].
+ clear H.
subst c2.
∃(remove_skip c1_2).
split; [apply match_com_remove_skip | left; reflexivity].
+ inversion H; subst.
clear H.
simpl (remove_skip Skip).
∃(remove_skip c1_2).
split; [apply match_com_remove_skip |].
right; apply CS_Seq.
Qed.
We then list other proof steps for building R_simulate_L.
Lemma R_simulate_L_CS_AssStep: ∀X a a' c2 st,
astep st a a' ->
match_com (CAss X a) c2 ->
∃c2',
match_com (CAss X a') c2' ∧
cstep_or_not (c2, st) (c2', st).
Lemma R_simulate_L_CS_Ass: ∀X n c2 st1 st2,
st2 X = n ->
(∀Y : var, X ≠ Y -> st1 Y = st2 Y) ->
match_com (CAss X (ANum n)) c2 ->
∃c2',
match_com CSkip c2' ∧
cstep_or_not (c2, st1) (c2', st2).
Lemma R_simulate_L_CS_IfStep: ∀b b' c1_1 c1_2 c2 st,
bstep st b b' ->
match_com (If b Then c1_1 Else c1_2 EndIf) c2 ->
∃c2',
match_com (If b' Then c1_1 Else c1_2 EndIf) c2' ∧
cstep_or_not (c2, st) (c2', st).
Lemma R_simulate_L_CS_IfTrue: ∀c1_1 c1_2 c2 st,
match_com (If BTrue Then c1_1 Else c1_2 EndIf) c2 ->
∃c2',
match_com c1_1 c2' ∧
cstep_or_not (c2, st) (c2', st).
Lemma R_simulate_L_CS_IfFalse: ∀c1_1 c1_2 c2 st,
match_com (If BFalse Then c1_1 Else c1_2 EndIf) c2 ->
∃c2',
match_com c1_2 c2' ∧
cstep_or_not (c2, st) (c2', st).
Lemma R_simulate_L_CS_While: ∀b c1_1 c2 st,
match_com (While b Do c1_1 EndWhile) c2 ->
∃c2',
match_com (If b Then c1_1;; While b Do c1_1 EndWhile Else Skip EndIf) c2' ∧
cstep_or_not (c2, st) (c2', st).
astep st a a' ->
match_com (CAss X a) c2 ->
∃c2',
match_com (CAss X a') c2' ∧
cstep_or_not (c2, st) (c2', st).
Proof.
intros.
inversion H0; subst; clear H0.
∃(X ::= a').
split; [constructor |].
right; constructor; tauto.
Qed.
intros.
inversion H0; subst; clear H0.
∃(X ::= a').
split; [constructor |].
right; constructor; tauto.
Qed.
Lemma R_simulate_L_CS_Ass: ∀X n c2 st1 st2,
st2 X = n ->
(∀Y : var, X ≠ Y -> st1 Y = st2 Y) ->
match_com (CAss X (ANum n)) c2 ->
∃c2',
match_com CSkip c2' ∧
cstep_or_not (c2, st1) (c2', st2).
Proof.
intros.
inversion H1; subst; clear H1.
∃CSkip.
split; [constructor |].
right; apply CS_Ass; tauto.
Qed.
intros.
inversion H1; subst; clear H1.
∃CSkip.
split; [constructor |].
right; apply CS_Ass; tauto.
Qed.
Lemma R_simulate_L_CS_IfStep: ∀b b' c1_1 c1_2 c2 st,
bstep st b b' ->
match_com (If b Then c1_1 Else c1_2 EndIf) c2 ->
∃c2',
match_com (If b' Then c1_1 Else c1_2 EndIf) c2' ∧
cstep_or_not (c2, st) (c2', st).
Proof.
intros.
simpl.
simpl in H0.
destruct H0 as [c2_1 [? ?]].
subst c2.
∃(If b' Then c2_1 Else (remove_skip c1_2) EndIf).
split; [eauto |].
right; apply CS_IfStep, H.
Qed.
intros.
simpl.
simpl in H0.
destruct H0 as [c2_1 [? ?]].
subst c2.
∃(If b' Then c2_1 Else (remove_skip c1_2) EndIf).
split; [eauto |].
right; apply CS_IfStep, H.
Qed.
Lemma R_simulate_L_CS_IfTrue: ∀c1_1 c1_2 c2 st,
match_com (If BTrue Then c1_1 Else c1_2 EndIf) c2 ->
∃c2',
match_com c1_1 c2' ∧
cstep_or_not (c2, st) (c2', st).
Proof.
intros.
simpl.
simpl in H.
destruct H as [c2_1 [? ?]].
subst c2.
∃c2_1.
split; [exact H |].
right; apply CS_IfTrue.
Qed.
intros.
simpl.
simpl in H.
destruct H as [c2_1 [? ?]].
subst c2.
∃c2_1.
split; [exact H |].
right; apply CS_IfTrue.
Qed.
Lemma R_simulate_L_CS_IfFalse: ∀c1_1 c1_2 c2 st,
match_com (If BFalse Then c1_1 Else c1_2 EndIf) c2 ->
∃c2',
match_com c1_2 c2' ∧
cstep_or_not (c2, st) (c2', st).
Proof.
intros.
simpl.
simpl in H.
destruct H as [c2_1 [? ?]].
subst c2.
∃(remove_skip c1_2).
split; [apply match_com_remove_skip |].
right; apply CS_IfFalse.
Qed.
intros.
simpl.
simpl in H.
destruct H as [c2_1 [? ?]].
subst c2.
∃(remove_skip c1_2).
split; [apply match_com_remove_skip |].
right; apply CS_IfFalse.
Qed.
Lemma R_simulate_L_CS_While: ∀b c1_1 c2 st,
match_com (While b Do c1_1 EndWhile) c2 ->
∃c2',
match_com (If b Then c1_1;; While b Do c1_1 EndWhile Else Skip EndIf) c2' ∧
cstep_or_not (c2, st) (c2', st).
Proof.
intros.
simpl in H.
subst c2.
∃(CIf b (remove_skip c1_1;; CWhile b (remove_skip c1_1)) Skip).
split.
+ ∃(remove_skip c1_1;; CWhile b (remove_skip c1_1)).
split.
- right.
∃(remove_skip c1_1).
split; [apply match_com_remove_skip | reflexivity].
- reflexivity.
+ right.
apply CS_While.
Qed.
intros.
simpl in H.
subst c2.
∃(CIf b (remove_skip c1_1;; CWhile b (remove_skip c1_1)) Skip).
split.
+ ∃(remove_skip c1_1;; CWhile b (remove_skip c1_1)).
split.
- right.
∃(remove_skip c1_1).
split; [apply match_com_remove_skip | reflexivity].
- reflexivity.
+ right.
apply CS_While.
Qed.
Adding these proof steps together, we can prove the simulation.
Theorem R_simulate_L: SimulationStatement_01 match_com.
∀c1 c2 c1' st st',
match_com c1 c2 ->
cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧ cstep_or_not (c2, st) (c2', st').
match_com c1 c2 ->
cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧ cstep_or_not (c2, st) (c2', st').
Proof.
unfold SimulationStatement_01.
intros.
revert c2 H; induction_cstep H0; intros.
+ eapply R_simulate_L_CS_AssStep; eassumption.
+ eapply R_simulate_L_CS_Ass; eassumption.
+ eapply R_simulate_L_CS_SeqStep; eassumption.
+ eapply R_simulate_L_CS_Seq; eassumption.
+ eapply R_simulate_L_CS_IfStep; eassumption.
+ eapply R_simulate_L_CS_IfTrue; eassumption.
+ eapply R_simulate_L_CS_IfFalse; eassumption.
+ eapply R_simulate_L_CS_While; eassumption.
Qed.
End RemoveSkip.
unfold SimulationStatement_01.
intros.
revert c2 H; induction_cstep H0; intros.
+ eapply R_simulate_L_CS_AssStep; eassumption.
+ eapply R_simulate_L_CS_Ass; eassumption.
+ eapply R_simulate_L_CS_SeqStep; eassumption.
+ eapply R_simulate_L_CS_Seq; eassumption.
+ eapply R_simulate_L_CS_IfStep; eassumption.
+ eapply R_simulate_L_CS_IfTrue; eassumption.
+ eapply R_simulate_L_CS_IfFalse; eassumption.
+ eapply R_simulate_L_CS_While; eassumption.
Qed.
End RemoveSkip.
Properties of Simulation Relations
Definition SimulationStatement_1 (match_com: com -> com -> Prop): Prop :=
∀c1 c2 c1' st st',
match_com c1 c2 ->
cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧ cstep (c2, st) (c2', st').
Lemma multi_cstep_Simulation_1: ∀match_com,
SimulationStatement_1 match_com ->
∀c1 c2 c1' st st',
match_com c1 c2 ->
multi_cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧ multi_cstep (c2, st) (c2', st').
Proof.
intros.
revert c2 H0; induction_1n H1; intros.
+ ∃c2.
split; [exact H0 | reflexivity].
+ pose proof H _ _ _ _ _ H2 H0.
destruct H3 as [c' [? ?]].
specialize (IHrt c' H3).
destruct IHrt as [c2' [? ?]].
∃c2'.
split; [exact H5 |].
etransitivity_1n; [exact H4 | exact H6].
Qed.
∀c1 c2 c1' st st',
match_com c1 c2 ->
cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧ cstep (c2, st) (c2', st').
Lemma multi_cstep_Simulation_1: ∀match_com,
SimulationStatement_1 match_com ->
∀c1 c2 c1' st st',
match_com c1 c2 ->
multi_cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧ multi_cstep (c2, st) (c2', st').
Proof.
intros.
revert c2 H0; induction_1n H1; intros.
+ ∃c2.
split; [exact H0 | reflexivity].
+ pose proof H _ _ _ _ _ H2 H0.
destruct H3 as [c' [? ?]].
specialize (IHrt c' H3).
destruct IHrt as [c2' [? ?]].
∃c2'.
split; [exact H5 |].
etransitivity_1n; [exact H4 | exact H6].
Qed.
The following lemma says, such properties about multi-step relation also
holds for SimulationStatement_01.
Lemma multi_cstep_Simulation_01: ∀match_com,
SimulationStatement_01 match_com ->
∀c1 c2 c1' st st',
match_com c1 c2 ->
multi_cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧ multi_cstep (c2, st) (c2', st').
Proof.
intros.
revert c2 H0; induction_1n H1; intros.
+ ∃c2.
split; [exact H0 | reflexivity].
+ pose proof H _ _ _ _ _ H2 H0.
destruct H3 as [c' [? ?]].
specialize (IHrt c' H3).
destruct IHrt as [c2' [? ?]].
∃c2'.
split; [exact H5 |].
destruct H4.
- injection H4 as ? ?; subst.
exact H6.
- etransitivity_1n; [exact H4 | exact H6].
Qed.
SimulationStatement_01 match_com ->
∀c1 c2 c1' st st',
match_com c1 c2 ->
multi_cstep (c1, st) (c1', st') ->
∃c2',
match_com c1' c2' ∧ multi_cstep (c2, st) (c2', st').
Proof.
intros.
revert c2 H0; induction_1n H1; intros.
+ ∃c2.
split; [exact H0 | reflexivity].
+ pose proof H _ _ _ _ _ H2 H0.
destruct H3 as [c' [? ?]].
specialize (IHrt c' H3).
destruct IHrt as [c2' [? ?]].
∃c2'.
split; [exact H5 |].
destruct H4.
- injection H4 as ? ?; subst.
exact H6.
- etransitivity_1n; [exact H4 | exact H6].
Qed.
More Reading: Unused Assignments
X ::= 1;; Y ::= 2;; X ::= 3
Y ::= 2;; X ::= 3
X ::= 1;; Y ::= 2;; X ::= 3 (State Match) Y ::= 2;; X ::= 3
| | |
| | | (no step)
v | |
Skip;; Y ::= 2;; X ::= 3 (State Mismatch) Y ::= 2;; X ::= 3
| | |
| | | (no step)
v | |
Y ::= 2;; X ::= 3 (State Mismatch) Y ::= 2;; X ::= 3
| |
| |
v v
Skip;; X ::= 3 (State Mismatch) Skip;; X ::= 3
| |
| |
v v
X ::= 3 (State Mismatch) X ::= 3
| |
| |
v v
Skip (State Match) Skip
| | |
| | | (no step)
v | |
Skip;; Y ::= 2;; X ::= 3 (State Mismatch) Y ::= 2;; X ::= 3
| | |
| | | (no step)
v | |
Y ::= 2;; X ::= 3 (State Mismatch) Y ::= 2;; X ::= 3
| |
| |
v v
Skip;; X ::= 3 (State Mismatch) Skip;; X ::= 3
| |
| |
v v
X ::= 3 (State Mismatch) X ::= 3
| |
| |
v v
Skip (State Match) Skip
Definition SimulatationStatement_01'
(match_com_state: com * state -> com * state -> Prop) :=
∀cst1 cst2 cst1',
match_com_state cst1 cst2 ->
cstep cst1 cst1' ->
∃cst2',
match_com_state cst1' cst2' ∧
cstep_or_not cst2 cst2'.
(* 2021-03-29 18:49 *)
(match_com_state: com * state -> com * state -> Prop) :=
∀cst1 cst2 cst1',
match_com_state cst1 cst2 ->
cstep cst1 cst1' ->
∃cst2',
match_com_state cst1' cst2' ∧
cstep_or_not cst2 cst2'.
(* 2021-03-29 18:49 *)