@@ -210,7 +210,6 @@ $\square$
210
210
211
211
=== Disjunction
212
212
213
- \ todo[inline]{Make syntax synonym? }
214
213
215
214
Another important connective is the _disjunction_, or _logical or_ of two
216
215
propositions : \idr{a `Either ` b} is true when either \idr{a} or \idr{b} is. The
@@ -270,27 +269,22 @@ from the previous chapter; it asserts that, if we assume a contradiction, then
270
269
any other proposition can be derived. Following this intuition, we could define
271
270
\ idr{Not p} as \ idr{q -> (p -> q)}. Idris actually makes a slightly different
272
271
choice, defining \ idr{Not p} as \ idr{p -> Void }, where \ idr{Void } is a
273
- _particular_ contradictory proposition defined in the standard library.
274
-
275
- \ todo[inline]{Edit }
276
-
277
- Module MyNot .
278
-
279
- Definition not (P : Type ) := P -> Void.
280
-
281
- Notation " ¬ x" := (not x) : type_scope.
272
+ _particular_ contradictory proposition defined in the standard library as a
273
+ data type with no constructors.
282
274
283
275
```idris
284
- λΠ> : t Not
276
+ data Void : Type where
277
+
285
278
Not : Type -> Type
279
+ Not a = a -> Void
286
280
`` `
287
281
288
282
Since \ idr{Void } is a contradictory proposition, the principle of explosion also
289
283
applies to it. If we get \ idr{Void } into the proof context, we can call
290
- \ idr{absurd} on it to complete any goal :
284
+ \ idr{void} or \ idr{ absurd} on it to complete any goal :
291
285
292
286
> ex_falso_quodlibet : Void -> p
293
- > ex_falso_quodlibet = absurd
287
+ > ex_falso_quodlibet = void
294
288
295
289
The Latin _ex falso quodlibet_ means, literally, " from falsehood follows
296
290
whatever you like" ; this is another common name for the principle of explosion.
@@ -446,7 +440,6 @@ $\square$
446
440
447
441
$\ square$
448
442
449
- \ todo[inline]{Edit , what to do wth Setoids ? }
450
443
451
444
Some of Idris's tactics treat iff statements specially, avoiding the need for
452
445
some low- level proof- state manipulation. In particular, rewrite and reflexivity
@@ -483,23 +476,28 @@ We can now use these facts with rewrite and reflexivity to give smooth proofs of
483
476
statements involving equivalences. Here is a ternary version of the previous
484
477
mult_0 result :
485
478
486
- > mult_0_3 : (n * m * p = 0) <->
487
- > ((n = 0) `Either ` ((m = 0) `Either ` (p = 0)))
488
-
489
- Proof .
490
- intros n m p.
491
- rewrite mult_0. rewrite mult_0. rewrite or_assoc.
492
- reflexivity.
493
- Qed .
494
-
495
- The apply tactic can also be used with ↔. When given an equivalence as its
479
+ > mult_0_3 : (n * m * p = Z) <->
480
+ > ((n = Z) `Either ` ((m = Z) `Either ` (p = Z)))
481
+ > mult_0_3 = (to, fro)
482
+ > where
483
+ > to : (n * m * p = Z) -> ((n = Z) `Either ` ((m = Z) `Either ` (p = Z)))
484
+ > to {n} {m} {p} prf = let
485
+ > (nm_p_to, _ ) = mult_0 {n= (n* m)} {m= p}
486
+ > (n_m_to, _ ) = mult_0 {n} {m}
487
+ > (_ , or_a_fro) = or_assoc {p= (n= Z )} {q= (m= Z )} {r= (p= Z )}
488
+ > in or_a_fro $ case nm_p_to prf of
489
+ > Left prf => Left $ n_m_to prf
490
+ > Right prf => Right prf
491
+ > fro : ((n = Z) `Either ` ((m = Z) `Either ` (p = Z))) -> (n * m * p = Z)
492
+ > fro (Left Refl ) = Refl
493
+ > fro {n} (Right (Left Refl )) = rewrite multZeroRightZero n in Refl
494
+ > fro {n} {m} (Right (Right Refl )) = rewrite multZeroRightZero (n* m) in Refl
495
+
496
+ The apply tactic can also be used with <->. When given an equivalence as its
496
497
argument, apply tries to guess which side of the equivalence to use.
497
498
498
- > apply_iff_example : (n, m : Nat ) -> n * m = 0 -> ((n = 0) `Either ` (m = 0))
499
-
500
- Proof .
501
- intros n m H . apply mult_0. apply H .
502
- Qed .
499
+ > apply_iff_example : (n, m : Nat ) -> n * m = Z -> ((n = Z) `Either ` (m = Z))
500
+ > apply_iff_example n m = fst $ mult_0 {n} {m}
503
501
504
502
505
503
=== Existential Quantification
@@ -510,8 +508,6 @@ there is some \idr{x} of type \idr{t} such that some property \idr{p} holds of
510
508
omitted if Idris is able to infer from the context what the type of \ idr{x}
511
509
should be.
512
510
513
- \ todo[inline]{Edit }
514
-
515
511
To prove a statement of the form \ idr{(x ** p)}, we must show that \ idr{p} holds
516
512
for some specific choice of value for \ idr{x}, known as the _witness_ of the
517
513
existential. This is done in two steps : First, we explicitly tell Idris which
@@ -715,7 +711,7 @@ wanted to prove the following result:
715
711
716
712
> plus_comm3 : (n, m, p : Nat ) -> n + (m + p) = (p + m) + n
717
713
718
- \ todo[inline]{Edit , we already have done this before }
714
+ \ todo[inline]{Edit , we have already done this in previous chapters }
719
715
720
716
It appears at first sight that we ought to be able to prove this by rewriting
721
717
with \ idr{plusCommutative} twice to make the two sides match. The problem,
@@ -770,7 +766,7 @@ We will see many more examples of the idioms from this section in later chapters
770
766
771
767
== Idris vs. Set Theory
772
768
773
- \ todo[inline]{Edit }
769
+ \ todo[inline]{Edit , Idris' core is likely some variant of MLTT }
774
770
775
771
Idris's logical core, the Calculus of Inductive Constructions , differs in some
776
772
important ways from other formal systems that are used by mathematicians for
@@ -804,6 +800,8 @@ we can write propositions claiming that two _functions_ are equal to each other:
804
800
805
801
In common mathematical practice, two functions `f` and `g` are considered equal
806
802
if they produce the same outputs :
803
+
804
+ \ todo[inline]{Use proper TeX here? }
807
805
808
806
`(∀x, f x = g x) -> f = g`
809
807
@@ -822,39 +820,34 @@ function_equality_ex2 : (\x => plus x 1) = (\x => plus 1 x)
822
820
function_equality_ex2 = ? stuck
823
821
`` `
824
822
825
- \ todo[inline]{Edit , use \ idr{really_believe_me}? }
823
+ \ todo[inline]{Explain \ idr{believe_me} vs \ idr{really_believe_me}? }
826
824
827
825
However , we can add functional extensionality to Idris's core logic using the
828
- Axiom command.
826
+ \ idr{really_believe_me} command.
829
827
830
- Axiom functional_extensionality : ∀{X Y: Type }
831
- {f g : X -> Y},
832
- (∀(x : X), f x = g x) -> f = g.
828
+ > functional_extensionality : ((x :a) -> f x = g x) -> f = g
829
+ > functional_extensionality = really_believe_me
833
830
834
- Using Axiom has the same effect as stating a theorem and skipping its proof
835
- using Admitted , but it alerts the reader that this isn't just something we're
836
- going to come back and fill in later!
831
+ Using \ idr{really_believe_me} has the same effect as stating a theorem and
837
832
838
833
We can now invoke functional extensionality in proofs :
839
834
840
- Example function_equality_ex2 :
841
- (fun x ⇒ plus x 1 ) = (fun x ⇒ plus 1 x).
842
- Proof .
843
- apply functional_extensionality. intros x.
844
- apply plus_comm.
845
- Qed .
835
+ > function_equality_ex2 : (\x => plus x 1) = (\x => plus 1 x)
836
+ > function_equality_ex2 = functional_extensionality $ \ x => plusCommutative x 1
846
837
847
838
Naturally , we must be careful when adding new axioms into Idris's logic, as they
848
- may render it inconsistent -- that is, they may make it possible to prove every
849
- proposition, including Void !
839
+ may render it _inconsistent_ -- that is, they may make it possible to prove
840
+ every proposition, including \ idr{ Void } !
850
841
851
842
Unfortunately , there is no simple way of telling whether an axiom is safe to
852
843
add : hard work is generally required to establish the consistency of any
853
844
particular combination of axioms.
854
845
855
- However , it is known that adding functional extensionality, in particular, is
846
+ However , it is known that adding functional extensionality, in particular, _is_
856
847
consistent.
857
848
849
+ \ todo[inline]{Is there such a command in Idris ? }
850
+
858
851
To check whether a particular proof relies on any additional axioms, use the
859
852
Print Assumptions command.
860
853
@@ -1035,12 +1028,8 @@ What is interesting is that, since the two notions are equivalent, we can use
1035
1028
the boolean formulation to prove the other one without mentioning the value 500
1036
1029
explicitly :
1037
1030
1038
- \ todo[inline]{Finish with \ idr{even_bool_prop}}
1039
-
1040
1031
> even_1000'' : (k ** 1000 = double k)
1041
- > even_1000'' = ?even_1000' _rhs
1042
-
1043
- Proof . apply even_bool_prop. reflexivity. Qed .
1032
+ > even_1000'' = (fst $ even_bool_prop {n=1000}) Refl
1044
1033
1045
1034
Although we haven' t gained much in terms of proof size in this case , larger
1046
1035
proofs can often be made considerably simpler by the use of reflection. As an
@@ -1092,6 +1081,7 @@ function below. To make sure that your definition is correct, prove the lemma
1092
1081
> beq_list_true_iff : (beq : a -> a -> Bool ) ->
1093
1082
> ((a1, a2 : a) -> (beq a1 a2 = True) <-> (a1 = a2)) ->
1094
1083
> ((l1, l2 : List a) -> (beq_list beq l1 l2 = True) <-> (l1 = l2))
1084
+ > beq_list_true_iff beq f l1 l2 = ? beq_list_true_iff_rhs
1095
1085
1096
1086
$\ square$
1097
1087
@@ -1147,10 +1137,8 @@ the value of \idr{b}.
1147
1137
\ todo[inline]{Remove when a release with
1148
1138
https : //github.com/idris-lang/Idris-dev/pull/3925 happens}
1149
1139
1150
- > Uninhabited (False = True ) where
1151
- > uninhabited Refl impossible
1152
-
1153
- \ todo[inline]{Explain `uninhabited` }
1140
+ Uninhabited (False = True ) where
1141
+ uninhabited Refl impossible
1154
1142
1155
1143
> restricted_excluded_middle : (p <-> b = True) -> p `Either ` Not p
1156
1144
> restricted_excluded_middle {b = True } (_ , bp) = Left $ bp Refl
@@ -1162,7 +1150,8 @@ natural numbers \idr{n} and \idr{m}.
1162
1150
\ todo[inline]{Is there a simpler way to write this? Maybe with setoids? }
1163
1151
1164
1152
> restricted_excluded_middle_eq : (n, m : Nat ) -> (n = m) `Either ` Not (n = m)
1165
- > restricted_excluded_middle_eq n m = restricted_excluded_middle (to n m, fro n m)
1153
+ > restricted_excluded_middle_eq n m =
1154
+ > restricted_excluded_middle (to n m, fro n m)
1166
1155
> where
1167
1156
> to : (n, m : Nat ) -> (n=m) -> (n==m)=True
1168
1157
> to Z Z prf = Refl
@@ -1194,7 +1183,10 @@ hold for arbitrary propositions, are referred to as _classical_.
1194
1183
The following example illustrates why assuming the excluded middle may lead to
1195
1184
non- constructive proofs :
1196
1185
1197
- _Claim_ : There exist irrational numbers `a` and `b` such that `a ^ b` is rational.
1186
+ \ todo[inline]{Use proper TeX ? }
1187
+
1188
+ _Claim_ : There exist irrational numbers `a` and `b` such that `a ^ b` is
1189
+ rational.
1198
1190
1199
1191
_Proof_ : It is not difficult to show that `sqrt 2` is irrational. If `sqrt 2 ^
1200
1192
sqrt 2 ` is rational, it suffices to take `a = b = sqrt 2 ` and we are done.
@@ -1252,20 +1244,23 @@ $\square$
1252
1244
1253
1245
==== Exercise : 3 stars, advanced (not_exists_dist)
1254
1246
1255
- It is a theorem of classical logic that the following two assertions are equivalent :
1247
+ It is a theorem of classical logic that the following two assertions are
1248
+ equivalent :
1256
1249
1257
1250
`` `idris
1258
- Not (x : a ** Not p x)
1259
- (x : a) -> p x
1251
+ Not (x : a ** Not p x)
1252
+ (x : a) -> p x
1260
1253
`` `
1261
1254
1262
1255
The \ idr{dist_not_exists} theorem above proves one side of this equivalence.
1263
1256
Interestingly , the other direction cannot be proved in constructive logic. Your
1264
1257
job is to show that it is implied by the excluded middle.
1265
1258
1266
- \ todo[inline]{Use \ idr{really_believe_me}? }
1267
-
1268
- not_exists_dist : excluded_middle -> Not (x ** Not $ P x) -> ((x :a) -> P x)
1259
+ > not_exists_dist : {p : a -> Type } -> Not (x ** Not $ p x) -> ((x : a) -> p x)
1260
+ > not_exists_dist prf x = ? not_exists_dist_rhs
1261
+ > where
1262
+ > excluded_middle : (a : Type ) -> a `Either ` (Not a)
1263
+ > excluded_middle p = really_believe_me p
1269
1264
1270
1265
$\ square$
1271
1266
0 commit comments