Skip to content

Commit 700fad3

Browse files
committed
Merge branch 'first_part_cleanup' into develop
2 parents 67310bd + 944bc3c commit 700fad3

File tree

8 files changed

+856
-921
lines changed

8 files changed

+856
-921
lines changed

src/Basics.lidr

Lines changed: 86 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -249,10 +249,12 @@ standard library.
249249

250250
Functions over booleans can be defined in the same way as above:
251251

252-
> negb : (b : Bool) -> Bool
253-
> negb True = False
254-
> negb False = True
255-
>
252+
```idris
253+
not : (b : Bool) -> Bool
254+
not True = False
255+
not False = True
256+
```
257+
256258
> andb : (b1 : Bool) -> (b2 : Bool) -> Bool
257259
> andb True b2 = b2
258260
> andb False b2 = False
@@ -286,20 +288,22 @@ We can also introduce some familiar syntax for the boolean operations we have
286288
just defined. The \idr{syntax} command defines a new symbolic notation for an
287289
existing definition, and \idr{infixl} specifies left-associative fixity.
288290

289-
> infixl 4 /\, \/
290-
>
291-
> (/\) : Bool -> Bool -> Bool
292-
> (/\) = andb
293-
>
294-
> (\/) : Bool -> Bool -> Bool
295-
> (\/) = orb
296-
>
297-
> testOrb5 : False \/ False \/ True = True
291+
```idris
292+
infixl 4 &&, ||
293+
294+
(&&) : Bool -> Bool -> Bool
295+
(&&) = andb
296+
297+
(||) : Bool -> Bool -> Bool
298+
(||) = orb
299+
```
300+
301+
> testOrb5 : False || False || True = True
298302
> testOrb5 = Refl
299303
>
300304

301305

302-
=== Exercise: 1 star (nandb)
306+
==== Exercise: 1 star (nandb)
303307

304308
Fill in the hole \idr{?nandb_rhs} and complete the following function; then make
305309
sure that the assertions below can each be verified by Idris. (Fill in each of
@@ -325,7 +329,7 @@ should return \idr{True} if either or both of its inputs are \idr{False}.
325329
$\square$
326330

327331

328-
=== Exercise: 1 star (andb3)
332+
==== Exercise: 1 star (andb3)
329333

330334
Do the same for the \idr{andb3} function below. This function should return
331335
\idr{True} when all of its inputs are \idr{True}, and \idr{False} otherwise.
@@ -355,27 +359,27 @@ Every expression in Idris has a type, describing what sort of thing it computes.
355359
The \idr{:type} (or \idr{:t}) REPL command asks Idris to print the type of an
356360
expression.
357361

358-
For example, the type of \idr{negb True} is \idr{Bool}.
362+
For example, the type of \idr{not True} is \idr{Bool}.
359363

360364
```idris
361365
λΠ> :type True
362366
True : Bool
363-
λΠ> :t negb True
364-
negb True : Bool
367+
λΠ> :t not True
368+
not True : Bool
365369
```
366370

367371
\todo[inline]{Confirm the "function types" wording.}
368372

369-
Functions like \idr{negb} itself are also data values, just like \idr{True} and
373+
Functions like \idr{not} itself are also data values, just like \idr{True} and
370374
\idr{False}. Their types are called \glspl{function type}, and they are written
371375
with arrows.
372376

373377
```idris
374-
λΠ> :t negb
375-
negb : Bool -> Bool
378+
λΠ> :t not
379+
not : Bool -> Bool
376380
```
377381

378-
The type of \idr{negb}, written \idr{Bool -> Bool} and pronounced "\idr{Bool}
382+
The type of \idr{not}, written \idr{Bool -> Bool} and pronounced "\idr{Bool}
379383
arrow \idr{Bool}," can be read, "Given an input of type \idr{Bool}, this
380384
function produces an output of type \idr{Bool}." Similarly, the type of
381385
\idr{andb}, written \idr{Bool -> Bool -> Bool}, can be read, "Given two inputs,
@@ -499,7 +503,7 @@ simpler definition that is a bit easier to work with:
499503
> ||| Determine whether a number is odd.
500504
> ||| @n a number
501505
> oddb : (n : Nat) -> Bool
502-
> oddb n = negb (evenb n)
506+
> oddb n = not (evenb n)
503507
>
504508
> testOddb1 : oddb 1 = True
505509
> testOddb1 = Refl
@@ -576,7 +580,7 @@ right-hand side. This avoids the need to invent a bogus variable name.
576580
>
577581

578582

579-
=== Exercise: 1 star (factorial)
583+
==== Exercise: 1 star (factorial)
580584

581585
Recall the standard mathematical factorial function:
582586

@@ -623,38 +627,43 @@ simply instructions to the Idris parser to accept \idr{x + y} in place of
623627
\idr{plus x y} and, conversely, to the Idris pretty-printer to display \idr{plus
624628
x y} as \idr{x + y}.
625629

626-
The \idr{beq_nat} function tests \idr{Nat}ural numbers for \idr{eq}uality,
627-
yielding a \idr{b}oolean.
630+
\todo[inline]{Mention interfaces here? Say this is infix}
628631

629-
> ||| Test natural numbers for equality.
630-
> beq_nat : (n, m : Nat) -> Bool
631-
> beq_nat Z Z = True
632-
> beq_nat Z (S j) = False
633-
> beq_nat (S k) Z = False
634-
> beq_nat (S k) (S j) = beq_nat k j
635-
>
632+
The \idr{(==)} function tests \idr{Nat}ural numbers for equality, yielding a
633+
\idr{Bool}ean.
634+
635+
```idris
636+
||| Test natural numbers for equality.
637+
(==) : (n, m : Nat) -> Bool
638+
(==) Z Z = True
639+
(==) Z (S j) = False
640+
(==) (S k) Z = False
641+
(==) (S k) (S j) = (==) k j
642+
```
636643

637-
The \idr{leb} function tests whether its first argument is less than or equal to
644+
The \idr{lte} function tests whether its first argument is less than or equal to
638645
its second argument, yielding a boolean.
639646

640-
> ||| Test whether a number is less than or equal to another.
641-
> leb : (n, m : Nat) -> Bool
642-
> leb Z m = True
643-
> leb (S k) Z = False
644-
> leb (S k) (S j) = leb k j
645-
>
646-
> testLeb1 : leb 2 2 = True
647-
> testLeb1 = Refl
647+
```idris
648+
||| Test whether a number is less than or equal to another.
649+
lte : (n, m : Nat) -> Bool
650+
lte Z m = True
651+
lte n Z = False
652+
lte (S k) (S j) = lte k j
653+
```
654+
655+
> testLte1 : lte 2 2 = True
656+
> testLte1 = Refl
648657
>
649-
> testLeb2 : leb 2 4 = True
650-
> testLeb2 = Refl
658+
> testLte2 : lte 2 4 = True
659+
> testLte2 = Refl
651660
>
652-
> testLeb3 : leb 4 2 = False
653-
> testLeb3 = Refl
661+
> testLte3 : lte 4 2 = False
662+
> testLte3 = Refl
654663
>
655664

656665

657-
=== Exercise: 1 star (blt_nat)
666+
==== Exercise: 1 star (blt_nat)
658667

659668
The \idr{blt_nat} function tests \idr{Nat}ural numbers for
660669
\idr{l}ess-\idr{t}han, yielding a \idr{b}oolean. Instead of making up a new
@@ -760,7 +769,8 @@ arrow symbol is pronounced "implies."
760769
As before, we need to be able to reason by assuming the existence of some
761770
numbers \idr{n} and \idr{m}. We also need to assume the hypothesis \idr{n = m}.
762771

763-
\todo[inline]{Edit.}
772+
\todo[inline]{Edit, mention the "generate initial pattern match" editor command}
773+
764774
The \idr{intros} tactic will serve to move all three of these from the goal into
765775
assumptions in the current context.
766776

@@ -780,7 +790,7 @@ tells Idris to rewrite the current goal (\idr{n + n = m + m}) by replacing the
780790
left side of the equality hypothesis \idr{prf} with the right side.
781791

782792

783-
=== Exercise: 1 star (plus_id_exercise)
793+
==== Exercise: 1 star (plus_id_exercise)
784794

785795
Fill in the proof.
786796

@@ -816,7 +826,7 @@ Unlike in Coq, we don't need to perform such a rewrite for \idr{mult_0_plus} in
816826
Idris and can just use \idr{Refl} instead.
817827

818828

819-
=== Exercise: 2 starts (mult_S_1)
829+
==== Exercise: 2 starts (mult_S_1)
820830

821831
> mult_S_1 : (n, m : Nat) -> (m = S n) -> m * (1 + n) = m * m
822832
> mult_S_1 n m prf = ?mult_S_1_rhs
@@ -833,28 +843,28 @@ can block simplification. For example, if we try to prove the following fact
833843
using the \idr{Refl} tactic as above, we get stuck.
834844

835845
```idris
836-
plus_1_neq_0_firsttry : (n : Nat) -> beq_nat (n + 1) 0 = False
846+
plus_1_neq_0_firsttry : (n : Nat) -> (n + 1) == 0 = False
837847
plus_1_neq_0_firsttry n = Refl -- does nothing!
838848
```
839849

840-
The reason for this is that the definitions of both \idr{beq_nat} and \idr{+}
850+
The reason for this is that the definitions of both \idr{(==)} and \idr{+}
841851
begin by performing a \idr{match} on their first argument. But here, the first
842852
argument to \idr{+} is the unknown number \idr{n} and the argument to
843-
\idr{beq_nat} is the compound expression \idr{n + 1}; neither can be simplified.
853+
\idr{(==)} is the compound expression \idr{n + 1}; neither can be simplified.
844854

845855
To make progress, we need to consider the possible forms of \idr{n} separately.
846-
If \idr{n} is \idr{Z}, then we can calculate the final result of \idr{beq_nat (n
847-
+ 1) 0} and check that it is, indeed, \idr{False}. And if \idr{n = S k} for some
856+
If \idr{n} is \idr{Z}, then we can calculate the final result of \idr{(n + 1) ==
857+
0} and check that it is, indeed, \idr{False}. And if \idr{n = S k} for some
848858
\idr{k}, then, although we don't know exactly what number \idr{n + 1} yields, we
849859
can calculate that, at least, it will begin with one \idr{S}, and this is enough
850-
to calculate that, again, \idr{beq_nat (n + 1) 0} will yield \idr{False}.
860+
to calculate that, again, \idr{(n + 1) == 0} will yield \idr{False}.
851861

852862
To tell Idris to consider, separately, the cases where \idr{n = Z} and where
853863
\idr{n = S k}, simply case split on \idr{n}.
854864

855865
\todo[inline]{Mention case splitting interactively in Emacs, Atom, etc.}
856866

857-
> plus_1_neq_0 : (n : Nat) -> beq_nat (n + 1) 0 = False
867+
> plus_1_neq_0 : (n : Nat) -> (n + 1) == 0 = False
858868
> plus_1_neq_0 Z = Refl
859869
> plus_1_neq_0 (S k) = Refl
860870
>
@@ -864,8 +874,8 @@ separately, in order to get Idris to accept the theorem.
864874

865875
In this example, each of the holes is easily filled by a single use of
866876
\idr{Refl}, which itself performs some simplification -- e.g., the first one
867-
simplifies \idr{beq_nat (S k + 1) 0} to \idr{False} by first rewriting \idr{(S k
868-
+ 1)} to \idr{S (k + 1)}, then unfolding \idr{beq_nat}, simplifying its pattern
877+
simplifies \idr{(S k + 1) == 0} to \idr{False} by first rewriting \idr{(S k +
878+
1)} to \idr{S (k + 1)}, then unfolding \idr{(==)}, simplifying its pattern
869879
matching.
870880

871881
There are no hard and fast rules for how proofs should be formatted in Idris.
@@ -884,9 +894,9 @@ For example, we use it next to prove that boolean negation is involutive --
884894
i.e., that negation is its own inverse.
885895

886896
> ||| A proof that boolean negation is involutive.
887-
> negb_involutive : (b : Bool) -> negb (negb b) = b
888-
> negb_involutive True = Refl
889-
> negb_involutive False = Refl
897+
> not_involutive : (b : Bool) -> not (not b) = b
898+
> not_involutive True = Refl
899+
> not_involutive False = Refl
890900
>
891901

892902
Note that the case splitting here doesn't introduce any variables because none
@@ -896,7 +906,7 @@ any names.
896906
It is sometimes useful to case split on more than one parameter, generating yet
897907
more proof obligations. For example:
898908

899-
> andb_commutative : (b, c : Bool) -> andb b c = andb c b
909+
> andb_commutative : (b, c : Bool) -> b && c = c && b
900910
> andb_commutative True True = Refl
901911
> andb_commutative True False = Refl
902912
> andb_commutative False True = Refl
@@ -906,34 +916,34 @@ more proof obligations. For example:
906916
In more complex proofs, it is often better to lift subgoals to lemmas:
907917

908918

909-
> andb_commutative'_rhs_1 : (c : Bool) -> c = andb c True
919+
> andb_commutative'_rhs_1 : (c : Bool) -> c = c && True
910920
> andb_commutative'_rhs_1 True = Refl
911921
> andb_commutative'_rhs_1 False = Refl
912922
>
913-
> andb_commutative'_rhs_2 : (c : Bool) -> False = andb c False
923+
> andb_commutative'_rhs_2 : (c : Bool) -> False = c && False
914924
> andb_commutative'_rhs_2 True = Refl
915925
> andb_commutative'_rhs_2 False = Refl
916926
>
917-
> andb_commutative' : (b, c : Bool) -> andb b c = andb c b
927+
> andb_commutative' : (b, c : Bool) -> b && c = c && b
918928
> andb_commutative' True = andb_commutative'_rhs_1
919929
> andb_commutative' False = andb_commutative'_rhs_2
920930
>
921931

922932

923-
=== Exercise: 2 stars (andb_true_elim2)
933+
==== Exercise: 2 stars (andb_true_elim2)
924934

925935
Prove the following claim, lift cases (and subcases) to lemmas when case split.
926936

927-
> andb_true_elim_2 : (b, c : Bool) -> (andb b c = True) -> c = True
937+
> andb_true_elim_2 : (b, c : Bool) -> (b && c = True) -> c = True
928938
> andb_true_elim_2 b c prf = ?andb_true_elim_2_rhs
929939
>
930940

931941
$\square$
932942

933943

934-
=== Exercise: 1 star (zero_nbeq_plus_1)
944+
==== Exercise: 1 star (zero_nbeq_plus_1)
935945

936-
> zero_nbeq_plus_1 : (n : Nat) -> beq_nat 0 (n + 1) = False
946+
> zero_nbeq_plus_1 : (n : Nat) -> 0 == (n + 1) = False
937947
> zero_nbeq_plus_1 n = ?zero_nbeq_plus_1_rhs
938948
>
939949

@@ -973,7 +983,8 @@ unnatural ways.
973983

974984
== More Exercises
975985

976-
=== Exercise: 2 stars (boolean_functions)
986+
987+
==== Exercise: 2 stars (boolean_functions)
977988

978989
Use the tactics you have learned so far to prove the following theorem about
979990
boolean functions.
@@ -985,7 +996,7 @@ boolean functions.
985996

986997
Now state and prove a theorem \idr{negation_fn_applied_twice} similar to the
987998
previous one but where the second hypothesis says that the function \idr{f} has
988-
the property that \idr{f x = negb x}.
999+
the property that \idr{f x = not x}.
9891000

9901001
>
9911002
> -- FILL IN HERE
@@ -994,19 +1005,19 @@ the property that \idr{f x = negb x}.
9941005
$\square$
9951006

9961007

997-
=== Exercise: 2 start (andb_eq_orb)
1008+
==== Exercise: 2 start (andb_eq_orb)
9981009

9991010
Prove the following theorem. (You may want to first prove a subsidiary lemma or
10001011
two. Alternatively, remember that you do not have to introduce all hypotheses at
10011012
the same time.)
10021013

1003-
> andb_eq_orb : (b, c : Bool) -> (andb b c = orb b c) -> b = c
1014+
> andb_eq_orb : (b, c : Bool) -> (b && c = b || c) -> b = c
10041015
> andb_eq_orb b c prf = ?andb_eq_orb_rhs
10051016

10061017
$\square$
10071018

10081019

1009-
=== Exercise: 3 stars (binary)
1020+
==== Exercise: 3 stars (binary)
10101021

10111022
Consider a different, more efficient representation of natural numbers using a
10121023
binary rather than unary system. That is, instead of saying that each natural

0 commit comments

Comments
 (0)