@@ -323,24 +323,24 @@ _Proof_: By induction on `a`. Most cases follow directly from the `IH`. The
323
323
remaining cases are as follows:
324
324
325
325
- Suppose `a = ANum n` for some `n`. We must show
326
- ```
326
+ ```
327
327
aeval (optimize_0plus (ANum n)) = aeval (ANum n).
328
- ```
328
+ ```
329
329
This is immediate from the definition of `optimize_0plus`.
330
330
331
331
- Suppose `a = APlus a1 a2` for some `a1` and `a2`. We must show
332
- ```
332
+ ```
333
333
aeval (optimize_0plus (APlus a1 a2)) = aeval (APlus a1 a2).
334
334
```
335
-
335
+
336
336
Consider the possible forms of `a1`. For most of them, `optimize_0plus`
337
337
simply calls itself recursively for the subexpressions and rebuilds a new
338
338
expression of the same form as `a1`; in these cases, the result follows
339
339
directly from the `IH`. The interesting case is when `a1 = ANum n` for some
340
340
`n`. If `n = ANum 0`, then
341
- ```
341
+ ```
342
342
optimize_0plus (APlus a1 a2) = optimize_0plus a2
343
- ```
343
+ ```
344
344
and the `IH` for `a2` is exactly what we need. On the other hand, if `n = S
345
345
n'` for some `n'`, then again `optimize_0plus` simply calls itself
346
346
recursively, and the result follows from the `IH`. $\square$
@@ -571,13 +571,13 @@ data AEvalR : AExp0 -> Nat -> Type where
571
571
AEvalR e1 n1 ->
572
572
AEvalR e2 n2 ->
573
573
AEvalR (AMult0 e1 e2) (n1 * n2)
574
- ```
574
+ ```
575
575
576
576
\todo[inline]{Edit}
577
577
578
578
It will be convenient to have an infix notation for \idr{AEvalR}. We'll write
579
579
\idr{e |/ n} to mean that arithmetic expression \idr{e} evaluates to value
580
- \idr{n}.
580
+ \idr{n}.
581
581
582
582
In fact, Idris provides a way to use this notation in the definition of
583
583
\idr{AevalR} itself. This reduces confusion by avoiding situations where we're
@@ -1304,9 +1304,9 @@ definitions. This section explores some examples.
1304
1304
1305
1305
\todo[inline]{Edit}
1306
1306
1307
- Inverting Heval essentially forces Idris to expand one step of the ceval
1308
- computation — in this case revealing that st' must be st extended with the new
1309
- value of X , since plus2 is an assignment
1307
+ Inverting ` Heval` essentially forces Idris to expand one step of the `CEval`
1308
+ computation — in this case revealing that ` st'` must be st extended with the new
1309
+ value of `X` , since ` plus2` is an assignment
1310
1310
1311
1311
> plus2_spec prf (E_Ass aev) = rewrite sym aev in rewrite prf in Refl
1312
1312
@@ -1323,12 +1323,16 @@ $\square$
1323
1323
==== Exercise: 3 stars, recommended (loop_never_stops)
1324
1324
1325
1325
> loop_never_stops : Not (Imp.loop / st |/ st')
1326
- > loop_never_stops = ?loop_never_stops_rhs
1326
+ > loop_never_stops contra = ?loop_never_stops_rhs
1327
1327
1328
+ \todo[inline]{Edit}
1329
+
1330
+ ```coq
1328
1331
Proof.
1329
1332
intros st st' contra. unfold loop in contra.
1330
1333
remember (WHILE BTrue DO SKIP END) as loopdef
1331
1334
eqn:Heqloopdef.
1335
+ ```
1332
1336
1333
1337
Proceed by induction on the assumed derivation showing that loopdef terminates.
1334
1338
Most of the cases are immediately contradictory (and so can be solved in one
@@ -1526,18 +1530,12 @@ with an additional case.
1526
1530
> CIfB : BExp -> ComB -> ComB -> ComB
1527
1531
> CWhileB : BExp -> ComB -> ComB
1528
1532
1529
- Notation "'SKIP'" :=
1530
- CSkip.
1531
- Notation "'BREAK'" :=
1532
- CBreak.
1533
- Notation "x '::=' a" :=
1534
- (CAss x a) (at level 60).
1535
- Notation "c1 ;; c2" :=
1536
- (CSeq c1 c2) (at level 80, right associativity).
1537
- Notation "'WHILE' b 'DO' c 'END'" :=
1538
- (CWhile b c) (at level 80, right associativity).
1539
- Notation "'IFB' c1 'THEN' c2 'ELSE' c3 'FI'" :=
1540
- (CIf c1 c2 c3) (at level 80, right associativity).
1533
+ > syntax SKIP' = CSkipB
1534
+ > syntax BREAK' = CBreakB
1535
+ > syntax [x] "::='" [a] = CAssB x a
1536
+ > syntax [c1] ";;'" [c2] = CSeqB c1 c2
1537
+ > syntax WHILE' [b] DO [c] END = CWhileB b c
1538
+ > syntax IFB' [c1] THEN [c2] ELSE [c3] FI = CIfB c1 c2 c3
1541
1539
1542
1540
Next, we need to define the behavior of \idr{BREAK}. Informally, whenever
1543
1541
\idr{BREAK} is executed in a sequence of commands, it stops the execution of
@@ -1550,7 +1548,7 @@ One important point is what to do when there are multiple loops enclosing a
1550
1548
given \idr{BREAK}. In those cases, \idr{BREAK} should only terminate the
1551
1549
_innermost_ loop. Thus, after executing the following...
1552
1550
1553
- ```idris
1551
+ ```
1554
1552
X ::= 0;;
1555
1553
Y ::= 1;;
1556
1554
WHILE 0 ≠ Y DO
@@ -1572,18 +1570,15 @@ evaluation relation that specifies whether evaluation of a command executes a
1572
1570
> SContinue : Result
1573
1571
> SBreak : Result
1574
1572
1575
- Reserved Notation "c1 '/' st '||//' s '/' st'"
1576
- (at level 40, st, s at level 39).
1577
-
1578
- Intuitively, `c / st ||// s / st'` means that, if \idr{c} is started in state
1573
+ Intuitively, \idr{c // st |/ s / st'} means that, if \idr{c} is started in state
1579
1574
\idr{st}, then it terminates in state \idr{st'} and either signals that the
1580
1575
innermost surrounding loop (or the whole program) should exit immediately
1581
1576
(\idr{s = SBreak}) or that execution should continue normally (\idr{s =
1582
1577
SContinue}).
1583
1578
1584
- The definition of the "` c / st ||// s / st'` " relation is very similar to the
1585
- one we gave above for the regular evaluation relation (` c / st ||// st'` ) — we
1586
- just need to handle the termination signals appropriately:
1579
+ The definition of the "\idr{ c // st |/ s / st'} " relation is very similar to the
1580
+ one we gave above for the regular evaluation relation (\idr{ c / st |/ st'} ) —
1581
+ we just need to handle the termination signals appropriately:
1587
1582
1588
1583
- If the command is \idr{SKIP}, then the state doesn't change and execution of
1589
1584
any enclosing loop can continue normally.
@@ -1622,37 +1617,38 @@ relation.
1622
1617
> E_SkipB : CEvalB CSkipB st SContinue st
1623
1618
> -- FILL IN HERE
1624
1619
1625
- where "c1 '/' st '||//' s '/' st'" := (ceval c1 st s st').
1620
+ > syntax [c1] "//" [st] "|/" [s] "/" [ st'] = CEvalB c1 st s st'
1626
1621
1627
1622
Now prove the following properties of your definition of \idr{CEvalB}:
1628
1623
1629
- > break_ignore : CEvalB (CSeqB CBreakB c) st s st' -> st = st'
1624
+ > break_ignore : (((BREAK') ;;' (c)) // st |/ s / st') -> st = st'
1630
1625
> break_ignore x = ?break_ignore_rhs
1631
1626
1632
- > while_continue : CEvalB (CWhileB b c) st s st' -> s = SContinue
1627
+ > while_continue : ((WHILE' b DO c END) // st |/ s / st') -> s = SContinue
1633
1628
> while_continue x = ?while_continue_rhs
1634
1629
1635
- > while_stops_on_break : beval st b = True -> CEvalB c st SBreak st' ->
1636
- > CEvalB (CWhileB b c) st SContinue st'
1630
+ > while_stops_on_break : beval st b = True ->
1631
+ > (c // st |/ SBreak / st') ->
1632
+ > ((WHILE' b DO c END) // st |/ SContinue / st')
1637
1633
> while_stops_on_break prf x = ?while_stops_on_break_rhs
1638
1634
1639
1635
$\square$
1640
1636
1641
1637
1642
1638
==== Exercise: 3 stars, advanced, optional (while_break_true)
1643
1639
1644
- > while_break_true : CEvalB (CWhileB b c) st SContinue st' ->
1640
+ > while_break_true : ((WHILE' b DO c END) // st |/ SContinue / st') ->
1645
1641
> beval st' b = True ->
1646
- > (st'' ** CEvalB c st'' SBreak st')
1642
+ > (st'' ** c // st'' |/ SBreak / st')
1647
1643
> while_break_true x prf = ?while_break_true_rhs
1648
1644
1649
1645
$\square$
1650
1646
1651
1647
1652
1648
==== Exercise: 4 stars, advanced, optional (cevalB_deterministic)
1653
1649
1654
- > cevalB_deterministic : CEvalB c st s1 st1 ->
1655
- > CEvalB c st s2 st2 ->
1650
+ > cevalB_deterministic : (c // st |/ s1 / st1) ->
1651
+ > (c // st |/ s2 / st2) ->
1656
1652
> (st1 = st2, s1 = s2)
1657
1653
> cevalB_deterministic x y = ?cevalB_deterministic_rhs
1658
1654
0 commit comments