Skip to content

Commit 14a5458

Browse files
committed
Exercises
1 parent 21524b6 commit 14a5458

File tree

1 file changed

+121
-146
lines changed

1 file changed

+121
-146
lines changed

src/Smallstep.lidr

Lines changed: 121 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -989,174 +989,151 @@ _Proof sketch_: By induction on terms. There are two cases to
989989
> lemma_deconstruct : Value v -> (n : Nat ** v = C n)
990990
> lemma_deconstruct v@(V_const n) = (n ** Refl)
991991
992-
> {-
993992
994-
(* ================================================================= *)
995-
(** ** Equivalence of Big-Step and Small-Step *)
993+
=== Equivalence of Big-Step and Small-Step
996994
997-
(** Having defined the operational semantics of our tiny programming
995+
Having defined the operational semantics of our tiny programming
998996
language in two different ways (big-step and small-step), it makes
999997
sense to ask whether these definitions actually define the same
1000998
thing! They do, though it takes a little work to show it. The
1001-
details are left as an exercise. *)
999+
details are left as an exercise.
10021000
1003-
(** **** Exercise: 3 stars (eval__multistep) *)
1001+
==== Exercise: 3 stars (eval__multistep)
10041002
1005-
> eval__multistep : {t: Tm} -> {n: Nat} -> t # n -> t ->>* C n
1006-
> eval__multistep hyp =
1007-
> case hyp of
1008-
> E_Const => Multi_refl
1009-
> E_Plus l r =>
1010-
> let hypl = multistep_congr_1 (eval__multistep l)
1011-
> hypr = multistep_congr_2 {v = V_const _}(eval__multistep r)
1012-
> in multi_trans (multi_trans hypl hypr)(Multi_step ST_PlusConstConst Multi_refl)
1013-
1014-
(** The key ideas in the proof can be seen in the following picture:
1015-
1016-
P t1 t2 ->> (by ST_Plus1)
1017-
P t1' t2 ->> (by ST_Plus1)
1018-
P t1'' t2 ->> (by ST_Plus1)
1019-
...
1020-
P (C n1) t2 ->> (by ST_Plus2)
1021-
P (C n1) t2' ->> (by ST_Plus2)
1022-
P (C n1) t2'' ->> (by ST_Plus2)
1023-
...
1024-
P (C n1) (C n2) ->> (by ST_PlusConstConst)
1025-
C (n1 + n2)
1026-
1027-
That is, the multistep reduction of a term of the form [P t1 t2]
1028-
proceeds in three phases:
1029-
- First, we use [ST_Plus1] some number of times to reduce [t1]
1030-
to a normal form, which must (by [nf_same_as_value]) be a
1031-
term of the form [C n1] for some [n1].
1032-
- Next, we use [ST_Plus2] some number of times to reduce [t2]
1033-
to a normal form, which must again be a term of the form [C
1034-
n2] for some [n2].
1035-
- Finally, we use [ST_PlusConstConst] one time to reduce [P (C
1036-
n1) (C n2)] to [C (n1 + n2)]. *)
1037-
1038-
(** To formalize this intuition, you'll need to use the congruence
1003+
> eval__multistep: {t: Tm} -> {n: Nat} -> t >>> n -> t ->>* C n
1004+
> eval__multistep hyp = ?eval__multistep_rhs
1005+
1006+
The key ideas in the proof can be seen in the following picture:
1007+
1008+
```
1009+
P t1 t2 ->> (by ST_Plus1)
1010+
P t1' t2 ->> (by ST_Plus1)
1011+
P t1'' t2 ->> (by ST_Plus1)
1012+
...
1013+
P (C n1) t2 ->> (by ST_Plus2)
1014+
P (C n1) t2' ->> (by ST_Plus2)
1015+
P (C n1) t2'' ->> (by ST_Plus2)
1016+
...
1017+
P (C n1) (C n2) ->> (by ST_PlusConstConst)
1018+
C (n1 + n2)
1019+
```
1020+
1021+
That is, the multistep reduction of a term of the form [P t1 t2]
1022+
proceeds in three phases:
1023+
1024+
- First, we use [ST_Plus1] some number of times to reduce [t1]
1025+
to a normal form, which must (by [nf_same_as_value]) be a
1026+
term of the form [C n1] for some [n1].
1027+
- Next, we use [ST_Plus2] some number of times to reduce [t2]
1028+
to a normal form, which must again be a term of the form [C
1029+
n2] for some [n2].
1030+
- Finally, we use [ST_PlusConstConst] one time to reduce [P (C
1031+
n1) (C n2)] to [C (n1 + n2)].
1032+
1033+
To formalize this intuition, you'll need to use the congruence
10391034
lemmas from above (you might want to review them now, so that
10401035
you'll be able to recognize when they are useful), plus some basic
10411036
properties of [->>*]: that it is reflexive, transitive, and
1042-
includes [->>]. *)
1037+
includes [->>].
10431038
1044-
Proof.
1045-
(* FILL IN HERE *) Admitted.
1046-
(** [] *)
10471039
1048-
(** **** Exercise: 3 stars, advanced (eval__multistep_inf) *)
1049-
(** Write a detailed informal version of the proof of [eval__multistep].
1040+
==== Exercise: 3 stars, advanced (eval__multistep_inf)
1041+
1042+
Write a detailed informal version of the proof of [eval__multistep]
10501043
10511044
(* FILL IN HERE *)
1052-
*)
1053-
(** [] *)
10541045
1055-
(** For the other direction, we need one lemma, which establishes a
1056-
relation between single-step reduction and big-step evaluation. *)
1046+
For the other direction, we need one lemma, which establishes a
1047+
relation between single-step reduction and big-step evaluation.
10571048
1058-
(** **** Exercise: 3 stars (step__eval) *)
1059-
Lemma step__eval : forall t t' n,
1060-
t ->> t' ->
1061-
t' \\ n ->
1062-
t \\ n.
1063-
Proof.
1064-
intros t t' n Hs. generalize dependent n.
1065-
(* FILL IN HERE *) Admitted.
1066-
(** [] *)
1049+
==== Exercise: 3 stars (step__eval)
10671050
1068-
(** The fact that small-step reduction implies big-step evaluation is
1051+
> step__eval : {t, t': Tm} -> {n: Nat} ->
1052+
> t ->> t' ->
1053+
> t' >>> n ->
1054+
> t >>> n
1055+
> step__eval h1 h2 = ?step__eval_rhs
1056+
1057+
The fact that small-step reduction implies big-step evaluation is
10691058
now straightforward to prove, once it is stated correctly.
10701059
1071-
The proof proceeds by induction on the multi-step reduction
1072-
sequence that is buried in the hypothesis [normal_form_of t t']. *)
1060+
The proof proceeds by induction on the multi-step reduction
1061+
sequence that is buried in the hypothesis [normal_form_of t t'].
10731062
1074-
(** Make sure you understand the statement before you start to
1075-
work on the proof. *)
1063+
Make sure you understand the statement before you start to
1064+
work on the proof.
10761065
1077-
(** **** Exercise: 3 stars (multistep__eval) *)
1078-
Theorem multistep__eval : forall t t',
1079-
normal_form_of t t' -> exists n, t' = C n /\ t \\ n.
1080-
Proof.
1081-
(* FILL IN HERE *) Admitted.
1082-
(** [] *)
1066+
==== Exercise: 3 stars (multistep__eval)
1067+
1068+
> multistep__eval : {t, t': Tm} ->
1069+
> normal_form_of t t' -> (n : Nat ** (t' = C n, t >>> n))
1070+
> multistep__eval hyp = ?multistep__eval_rhs
10831071
1084-
(* ================================================================= *)
1085-
(** ** Additional Exercises *)
10861072
1087-
(** **** Exercise: 3 stars, optional (interp_tm) *)
1088-
(** Remember that we also defined big-step evaluation of terms as a
1089-
function [evalF]. Prove that it is equivalent to the existing
1090-
semantics. (Hint: we just proved that [eval] and [multistep] are
1073+
=== Additional Exercises
1074+
1075+
==== Exercise: 3 stars, optional (interp_tm)
1076+
1077+
Remember that we also defined big-step evaluation of terms as a
1078+
function `evalF`. Prove that it is equivalent to the existing
1079+
semantics. (Hint: we just proved that `eval` and `multistep` are
10911080
equivalent, so logically it doesn't matter which you choose.
1092-
One will be easier than the other, though!) *)
1081+
One will be easier than the other, though!)
10931082
1094-
Theorem evalF_eval : forall t n,
1095-
evalF t = n <-> t \\ n.
1096-
Proof.
1097-
(* FILL IN HERE *) Admitted.
1098-
(** [] *)
1083+
> evalF_eval : {t: Tm} -> {n: Nat} -> ((evalF t = n) <-> (t >>> n))
1084+
1085+
==== Exercise: 4 stars (combined_properties)
1086+
1087+
We've considered arithmetic and conditional expressions
1088+
separately. This exercise explores how the two interact.
1089+
1090+
1091+
> data TmC : Type where
1092+
> CC : Nat -> TmC
1093+
> PC : TmC -> TmC -> TmC
1094+
> TtrueC : TmC
1095+
> TfalseC : TmC
1096+
> TifC : TmC -> TmC -> TmC -> TmC
1097+
1098+
> data ValueC : TmC -> Type where
1099+
> V_constC : {n: Nat} -> ValueC (CC n)
1100+
> V_trueC : ValueC TtrueC
1101+
> V_falseC : ValueC TfalseC
1102+
1103+
1104+
> mutual
1105+
> infixl 6 >>->
1106+
> (>>->) : TmC -> TmC -> Type
1107+
> (>>->) = StepC
1108+
>
1109+
> data StepC : TmC -> TmC -> Type where
1110+
> ST_PlusConstConstC : PC (CC n1) (CC n2) >>-> CC (n1 + n2)
1111+
> ST_Plus1C : t1 >>-> t1' -> PC t1 t2 >>-> PC t1' t2
1112+
> ST_Plus2C : ValueC v1 -> t2 >>-> t2' -> PC v1 t2 >>-> PC v1 t2'
1113+
> ST_IfTrueC : TifC TtrueC t1 t2 >>-> t1
1114+
> ST_IfFalseC : TifC TfalseC t1 t2 >>-> t2
1115+
> ST_IfC : t1 >>-> t1' -> TifC t1 t2 t3 >>-> TifC t1' t2 t3
1116+
1117+
1118+
Earlier, we separately proved for both plus- and if-expressions...
1119+
1120+
- that the step relation was deterministic, and
1121+
1122+
- a strong progress lemma, stating that every term is either a
1123+
value or can take a step.
10991124
1100-
(** **** Exercise: 4 stars (combined_properties) *)
1101-
(** We've considered arithmetic and conditional expressions
1102-
separately. This exercise explores how the two interact. *)
1103-
1104-
Module Combined.
1105-
1106-
Inductive tm : Type :=
1107-
| C : nat -> tm
1108-
| P : tm -> tm -> tm
1109-
| ttrue : tm
1110-
| tfalse : tm
1111-
| tif : tm -> tm -> tm -> tm.
1112-
1113-
Inductive value : tm -> Prop :=
1114-
| v_const : forall n, value (C n)
1115-
| v_true : value ttrue
1116-
| v_false : value tfalse.
1117-
1118-
Reserved Notation " t '->>' t' " (at level 40).
1119-
1120-
Inductive step : tm -> tm -> Prop :=
1121-
| ST_PlusConstConst : forall n1 n2,
1122-
P (C n1) (C n2) ->> C (n1 + n2)
1123-
| ST_Plus1 : forall t1 t1' t2,
1124-
t1 ->> t1' ->
1125-
P t1 t2 ->> P t1' t2
1126-
| ST_Plus2 : forall v1 t2 t2',
1127-
value v1 ->
1128-
t2 ->> t2' ->
1129-
P v1 t2 ->> P v1 t2'
1130-
| ST_IfTrue : forall t1 t2,
1131-
tif ttrue t1 t2 ->> t1
1132-
| ST_IfFalse : forall t1 t2,
1133-
tif tfalse t1 t2 ->> t2
1134-
| ST_If : forall t1 t1' t2 t3,
1135-
t1 ->> t1' ->
1136-
tif t1 t2 t3 ->> tif t1' t2 t3
1137-
1138-
where " t '->>' t' " := (step t t').
1139-
1140-
(** Earlier, we separately proved for both plus- and if-expressions...
1141-
1142-
- that the step relation was deterministic, and
1143-
1144-
- a strong progress lemma, stating that every term is either a
1145-
value or can take a step.
1146-
1147-
Formally prove or disprove these two properties for the combined
1148-
language. (That is, state a theorem saying that the property
1149-
holds or does not hold, and prove your theorem.) *)
1125+
Formally prove or disprove these two properties for the combined
1126+
language. (That is, state a theorem saying that the property
1127+
holds or does not hold, and prove your theorem.)
11501128
11511129
(* FILL IN HERE *)
11521130
1153-
End Combined.
1154-
(** [] *)
1131+
<!--
11551132
1156-
<!--
11571133
(* ################################################################# *)
11581134
(** * Small-Step Imp *)
11591135
1136+
11601137
(** Now for a more serious example: a small-step version of the Imp
11611138
operational semantics. *)
11621139
@@ -1174,6 +1151,7 @@ Inductive aval : aexp -> Prop :=
11741151
below (why?), though they might be if our language were a bit
11751152
larger (why?). *)
11761153
1154+
11771155
Reserved Notation " t '/' st '->>a' t' "
11781156
(at level 40, st at level 39).
11791157
@@ -1286,7 +1264,7 @@ Inductive cstep : (com * state) -> (com * state) -> Prop :=
12861264
a / st ->>a a' ->
12871265
(i ::= a) / st ->> (i ::= a') / st
12881266
| CS_Ass : forall st i n,
1289-
(i ::= (ANum n)) / st ->> SKIP / (st & { i --> n })
1267+
(i ::= (ANum n)) / st ->> SKIP / (st & { i ==> n })
12901268
| CS_SeqStep : forall st c1 c1' st' c2,
12911269
c1 / st ->> c1' / st' ->
12921270
(c1 ;; c2) / st ->> (c1' ;; c2) / st'
@@ -1346,7 +1324,7 @@ Inductive cstep : (com * state) -> (com * state) -> Prop :=
13461324
a / st ->>a a' ->
13471325
(i ::= a) / st ->> (i ::= a') / st
13481326
| CS_Ass : forall st i n,
1349-
(i ::= (ANum n)) / st ->> SKIP / st & { i --> n }
1327+
(i ::= (ANum n)) / st ->> SKIP / st & { i ==> n }
13501328
| CS_SeqStep : forall st c1 c1' st' c2,
13511329
c1 / st ->> c1' / st' ->
13521330
(c1 ;; c2) / st ->> (c1' ;; c2) / st'
@@ -1397,7 +1375,7 @@ Definition par_loop : com :=
13971375
13981376
Example par_loop_example_0:
13991377
exists st',
1400-
par_loop / { --> 0 } ->>* SKIP / st'
1378+
par_loop / { ==> 0 } ->>* SKIP / st'
14011379
/\ st' X = 0.
14021380
Proof.
14031381
eapply ex_intro. split.
@@ -1418,7 +1396,7 @@ Proof.
14181396
14191397
Example par_loop_example_2:
14201398
exists st',
1421-
par_loop / { --> 0 } ->>* SKIP / st'
1399+
par_loop / { ==> 0 } ->>* SKIP / st'
14221400
/\ st' X = 2.
14231401
Proof.
14241402
eapply ex_intro. split.
@@ -1466,7 +1444,7 @@ Proof.
14661444
(** **** Exercise: 3 stars, optional (par_body_n__Sn) *)
14671445
Lemma par_body_n__Sn : forall n st,
14681446
st X = n /\ st Y = 0 ->
1469-
par_loop / st ->>* par_loop / st & { X --> S n}.
1447+
par_loop / st ->>* par_loop / st & { X ==> S n}.
14701448
Proof.
14711449
(* FILL IN HERE *) Admitted.
14721450
(** [] *)
@@ -1485,16 +1463,16 @@ Proof.
14851463
14861464
Theorem par_loop_any_X:
14871465
forall n, exists st',
1488-
par_loop / { --> 0 } ->>* SKIP / st'
1466+
par_loop / { ==> 0 } ->>* SKIP / st'
14891467
/\ st' X = n.
14901468
Proof.
14911469
intros n.
1492-
destruct (par_body_n n { --> 0 }).
1470+
destruct (par_body_n n { ==> 0 }).
14931471
split; unfold t_update; reflexivity.
14941472
14951473
rename x into st.
14961474
inversion H as [H' [HX HY]]; clear H.
1497-
exists (st & { Y --> 1 }). split.
1475+
exists (st & { Y ==> 1 }). split.
14981476
eapply multi_trans with (par_loop,st). apply H'.
14991477
eapply multi_step. apply CS_Par1. apply CS_Ass.
15001478
eapply multi_step. apply CS_Par2. apply CS_While.
@@ -1557,9 +1535,6 @@ Proof.
15571535
(* FILL IN HERE *) Admitted.
15581536
(** [] *)
15591537
1560-
15611538
(** $Date$ *)
15621539
1563-
> -}
1564-
15651540
-->

0 commit comments

Comments
 (0)