@@ -249,10 +249,12 @@ standard library.
249
249
250
250
Functions over booleans can be defined in the same way as above :
251
251
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
+
256
258
> andb : (b1 : Bool) -> (b2 : Bool) -> Bool
257
259
> andb True b2 = b2
258
260
> andb False b2 = False
@@ -286,20 +288,22 @@ We can also introduce some familiar syntax for the boolean operations we have
286
288
just defined . The \idr{syntax} command defines a new symbolic notation for an
287
289
existing definition , and \idr{infixl} specifies left -associative fixity .
288
290
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
298
302
> testOrb5 = Refl
299
303
>
300
304
301
305
302
- === Exercise: 1 star (nandb)
306
+ ==== Exercise: 1 star (nandb)
303
307
304
308
Fill in the hole \idr{?nandb_rhs} and complete the following function; then make
305
309
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}.
325
329
$\square$
326
330
327
331
328
- === Exercise: 1 star (andb3)
332
+ ==== Exercise: 1 star (andb3)
329
333
330
334
Do the same for the \idr{andb3} function below . This function should return
331
335
\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.
355
359
The \idr{:type} (or \idr{:t}) REPL command asks Idris to print the type of an
356
360
expression.
357
361
358
- For example , the type of \idr{negb True } is \idr{Bool}.
362
+ For example , the type of \idr{not True } is \idr{Bool}.
359
363
360
364
```idris
361
365
λΠ> :type True
362
366
True : Bool
363
- λΠ> :t negb True
364
- negb True : Bool
367
+ λΠ> :t not True
368
+ not True : Bool
365
369
```
366
370
367
371
\todo[inline]{Confirm the "function types " wording.}
368
372
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
370
374
\idr{False}. Their types are called \glspl{function type }, and they are written
371
375
with arrows .
372
376
373
377
```idris
374
- λΠ> :t negb
375
- negb : Bool -> Bool
378
+ λΠ> :t not
379
+ not : Bool -> Bool
376
380
```
377
381
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}
379
383
arrow \idr{Bool}," can be read, "Given an input of type \idr{Bool}, this
380
384
function produces an output of type \idr{Bool}." Similarly, the type of
381
385
\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:
499
503
> ||| Determine whether a number is odd .
500
504
> ||| @n a number
501
505
> oddb : (n : Nat) -> Bool
502
- > oddb n = negb (evenb n )
506
+ > oddb n = not (evenb n )
503
507
>
504
508
> testOddb1 : oddb 1 = True
505
509
> testOddb1 = Refl
@@ -576,7 +580,7 @@ right-hand side. This avoids the need to invent a bogus variable name.
576
580
>
577
581
578
582
579
- === Exercise: 1 star (factorial)
583
+ ==== Exercise: 1 star (factorial)
580
584
581
585
Recall the standard mathematical factorial function :
582
586
@@ -623,38 +627,43 @@ simply instructions to the Idris parser to accept \idr{x + y} in place of
623
627
\idr{plus x y} and, conversely, to the Idris pretty -printer to display \idr{plus
624
628
x y } as \idr{x + y}.
625
629
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 }
628
631
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
+ ```
636
643
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
638
645
its second argument, yielding a boolean.
639
646
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
648
657
>
649
- > testLeb2 : leb 2 4 = True
650
- > testLeb2 = Refl
658
+ > testLte2 : lte 2 4 = True
659
+ > testLte2 = Refl
651
660
>
652
- > testLeb3 : leb 4 2 = False
653
- > testLeb3 = Refl
661
+ > testLte3 : lte 4 2 = False
662
+ > testLte3 = Refl
654
663
>
655
664
656
665
657
- === Exercise: 1 star (blt_nat)
666
+ ==== Exercise: 1 star (blt_nat)
658
667
659
668
The \idr{blt_nat} function tests \idr{Nat}ural numbers for
660
669
\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."
760
769
As before , we need to be able to reason by assuming the existence of some
761
770
numbers \idr{n} and \idr{m}. We also need to assume the hypothesis \idr{n = m}.
762
771
763
- \todo[inline]{Edit.}
772
+ \todo[inline]{Edit, mention the "generate initial pattern match " editor command }
773
+
764
774
The \idr{intros} tactic will serve to move all three of these from the goal into
765
775
assumptions in the current context.
766
776
@@ -780,7 +790,7 @@ tells Idris to rewrite the current goal (\idr{n + n = m + m}) by replacing the
780
790
left side of the equality hypothesis \idr{prf} with the right side .
781
791
782
792
783
- === Exercise: 1 star (plus_id_exercise)
793
+ ==== Exercise: 1 star (plus_id_exercise)
784
794
785
795
Fill in the proof .
786
796
@@ -816,7 +826,7 @@ Unlike in Coq, we don't need to perform such a rewrite for \idr{mult_0_plus} in
816
826
Idris and can just use \idr{Refl} instead.
817
827
818
828
819
- === Exercise: 2 starts (mult_S_1)
829
+ ==== Exercise: 2 starts (mult_S_1)
820
830
821
831
> mult_S_1 : (n, m : Nat) -> (m = S n ) -> m * (1 + n) = m * m
822
832
> 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
833
843
using the \idr{Refl} tactic as above, we get stuck.
834
844
835
845
```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
837
847
plus_1_neq_0_firsttry n = Refl -- does nothing !
838
848
```
839
849
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{+}
841
851
begin by performing a \idr{match} on their first argument . But here , the first
842
852
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 .
844
854
845
855
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
848
858
\idr{k}, then, although we don't know exactly what number \idr{n + 1} yields, we
849
859
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}.
851
861
852
862
To tell Idris to consider, separately, the cases where \idr{n = Z} and where
853
863
\idr{n = S k }, simply case split on \idr{n}.
854
864
855
865
\todo[inline]{Mention case splitting interactively in Emacs , Atom, etc.}
856
866
857
- > plus_1_neq_0 : (n : Nat) -> beq_nat (n + 1) 0 = False
867
+ > plus_1_neq_0 : (n : Nat) -> (n + 1) == 0 = False
858
868
> plus_1_neq_0 Z = Refl
859
869
> plus_1_neq_0 (S k ) = Refl
860
870
>
@@ -864,8 +874,8 @@ separately, in order to get Idris to accept the theorem.
864
874
865
875
In this example, each of the holes is easily filled by a single use of
866
876
\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
869
879
matching.
870
880
871
881
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 --
884
894
i.e., that negation is its own inverse .
885
895
886
896
> ||| 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
890
900
>
891
901
892
902
Note that the case splitting here doesn't introduce any variables because none
@@ -896,7 +906,7 @@ any names.
896
906
It is sometimes useful to case split on more than one parameter , generating yet
897
907
more proof obligations. For example :
898
908
899
- > andb_commutative : (b, c : Bool) -> andb b c = andb c b
909
+ > andb_commutative : (b, c : Bool) -> b && c = c && b
900
910
> andb_commutative True True = Refl
901
911
> andb_commutative True False = Refl
902
912
> andb_commutative False True = Refl
@@ -906,34 +916,34 @@ more proof obligations. For example:
906
916
In more complex proofs , it is often better to lift subgoals to lemmas:
907
917
908
918
909
- > andb_commutative'_rhs_1 : (c : Bool) -> c = andb c True
919
+ > andb_commutative'_rhs_1 : (c : Bool) -> c = c && True
910
920
> andb_commutative'_rhs_1 True = Refl
911
921
> andb_commutative'_rhs_1 False = Refl
912
922
>
913
- > andb_commutative'_rhs_2 : (c : Bool) -> False = andb c False
923
+ > andb_commutative'_rhs_2 : (c : Bool) -> False = c && False
914
924
> andb_commutative'_rhs_2 True = Refl
915
925
> andb_commutative'_rhs_2 False = Refl
916
926
>
917
- > andb_commutative' : (b, c : Bool) -> andb b c = andb c b
927
+ > andb_commutative' : (b, c : Bool) -> b && c = c && b
918
928
> andb_commutative' True = andb_commutative'_rhs_1
919
929
> andb_commutative' False = andb_commutative'_rhs_2
920
930
>
921
931
922
932
923
- === Exercise: 2 stars (andb_true_elim2)
933
+ ==== Exercise: 2 stars (andb_true_elim2)
924
934
925
935
Prove the following claim , lift cases (and subcases ) to lemmas when case split.
926
936
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
928
938
> andb_true_elim_2 b c prf = ?andb_true_elim_2_rhs
929
939
>
930
940
931
941
$\square$
932
942
933
943
934
- === Exercise: 1 star (zero_nbeq_plus_1)
944
+ ==== Exercise: 1 star (zero_nbeq_plus_1)
935
945
936
- > zero_nbeq_plus_1 : (n : Nat) -> beq_nat 0 (n + 1) = False
946
+ > zero_nbeq_plus_1 : (n : Nat) -> 0 == (n + 1) = False
937
947
> zero_nbeq_plus_1 n = ?zero_nbeq_plus_1_rhs
938
948
>
939
949
@@ -973,7 +983,8 @@ unnatural ways.
973
983
974
984
== More Exercises
975
985
976
- === Exercise: 2 stars (boolean_functions)
986
+
987
+ ==== Exercise: 2 stars (boolean_functions)
977
988
978
989
Use the tactics you have learned so far to prove the following theorem about
979
990
boolean functions .
@@ -985,7 +996,7 @@ boolean functions.
985
996
986
997
Now state and prove a theorem \idr{negation_fn_applied_twice} similar to the
987
998
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 }.
989
1000
990
1001
>
991
1002
> -- FILL IN HERE
@@ -994,19 +1005,19 @@ the property that \idr{f x = negb x}.
994
1005
$\square$
995
1006
996
1007
997
- === Exercise: 2 start (andb_eq_orb)
1008
+ ==== Exercise: 2 start (andb_eq_orb)
998
1009
999
1010
Prove the following theorem . (You may want to first prove a subsidiary lemma or
1000
1011
two. Alternatively, remember that you do not have to introduce all hypotheses at
1001
1012
the same time.)
1002
1013
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
1004
1015
> andb_eq_orb b c prf = ?andb_eq_orb_rhs
1005
1016
1006
1017
$\square$
1007
1018
1008
1019
1009
- === Exercise: 3 stars (binary)
1020
+ ==== Exercise: 3 stars (binary)
1010
1021
1011
1022
Consider a different, more efficient representation of natural numbers using a
1012
1023
binary rather than unary system. That is , instead of saying that each natural
0 commit comments