Skip to content

Commit 07fe0df

Browse files
author
Alex Gryzlov
committed
finish Logic
1 parent 9bbbc88 commit 07fe0df

File tree

1 file changed

+62
-67
lines changed

1 file changed

+62
-67
lines changed

src/Logic.lidr

Lines changed: 62 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,6 @@ $\square$
210210

211211
=== Disjunction
212212

213-
\todo[inline]{Make syntax synonym?}
214213

215214
Another important connective is the _disjunction_, or _logical or_ of two
216215
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
270269
any other proposition can be derived. Following this intuition, we could define
271270
\idr{Not p} as \idr{q -> (p -> q)}. Idris actually makes a slightly different
272271
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.
282274

283275
```idris
284-
λΠ> :t Not
276+
data Void : Type where
277+
285278
Not : Type -> Type
279+
Not a = a -> Void
286280
```
287281

288282
Since \idr{Void} is a contradictory proposition, the principle of explosion also
289283
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:
291285

292286
> ex_falso_quodlibet : Void -> p
293-
> ex_falso_quodlibet = absurd
287+
> ex_falso_quodlibet = void
294288

295289
The Latin _ex falso quodlibet_ means, literally, "from falsehood follows
296290
whatever you like"; this is another common name for the principle of explosion.
@@ -446,7 +440,6 @@ $\square$
446440

447441
$\square$
448442

449-
\todo[inline]{Edit, what to do wth Setoids?}
450443

451444
Some of Idris's tactics treat iff statements specially, avoiding the need for
452445
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
483476
statements involving equivalences. Here is a ternary version of the previous
484477
mult_0 result:
485478

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
496497
argument, apply tries to guess which side of the equivalence to use.
497498

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}
503501

504502

505503
=== Existential Quantification
@@ -510,8 +508,6 @@ there is some \idr{x} of type \idr{t} such that some property \idr{p} holds of
510508
omitted if Idris is able to infer from the context what the type of \idr{x}
511509
should be.
512510

513-
\todo[inline]{Edit}
514-
515511
To prove a statement of the form \idr{(x ** p)}, we must show that \idr{p} holds
516512
for some specific choice of value for \idr{x}, known as the _witness_ of the
517513
existential. This is done in two steps: First, we explicitly tell Idris which
@@ -715,7 +711,7 @@ wanted to prove the following result:
715711

716712
> plus_comm3 : (n, m, p : Nat) -> n + (m + p) = (p + m) + n
717713

718-
\todo[inline]{Edit, we already have done this before}
714+
\todo[inline]{Edit, we have already done this in previous chapters}
719715

720716
It appears at first sight that we ought to be able to prove this by rewriting
721717
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
770766

771767
== Idris vs. Set Theory
772768

773-
\todo[inline]{Edit}
769+
\todo[inline]{Edit, Idris' core is likely some variant of MLTT}
774770

775771
Idris's logical core, the Calculus of Inductive Constructions, differs in some
776772
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:
804800

805801
In common mathematical practice, two functions `f` and `g` are considered equal
806802
if they produce the same outputs:
803+
804+
\todo[inline]{Use proper TeX here?}
807805

808806
`(∀x, f x = g x) -> f = g`
809807

@@ -822,39 +820,34 @@ function_equality_ex2 : (\x => plus x 1) = (\x => plus 1 x)
822820
function_equality_ex2 = ?stuck
823821
```
824822

825-
\todo[inline]{Edit, use \idr{really_believe_me}?}
823+
\todo[inline]{Explain \idr{believe_me} vs \idr{really_believe_me}?}
826824

827825
However, we can add functional extensionality to Idris's core logic using the
828-
Axiom command.
826+
\idr{really_believe_me} command.
829827

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
833830

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
837832

838833
We can now invoke functional extensionality in proofs:
839834

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
846837

847838
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}!
850841

851842
Unfortunately, there is no simple way of telling whether an axiom is safe to
852843
add: hard work is generally required to establish the consistency of any
853844
particular combination of axioms.
854845

855-
However, it is known that adding functional extensionality, in particular, is
846+
However, it is known that adding functional extensionality, in particular, _is_
856847
consistent.
857848

849+
\todo[inline]{Is there such a command in Idris?}
850+
858851
To check whether a particular proof relies on any additional axioms, use the
859852
Print Assumptions command.
860853

@@ -1035,12 +1028,8 @@ What is interesting is that, since the two notions are equivalent, we can use
10351028
the boolean formulation to prove the other one without mentioning the value 500
10361029
explicitly:
10371030

1038-
\todo[inline]{Finish with \idr{even_bool_prop}}
1039-
10401031
> 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
10441033
10451034
Although we haven't gained much in terms of proof size in this case, larger
10461035
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
10921081
> beq_list_true_iff : (beq : a -> a -> Bool) ->
10931082
> ((a1, a2 : a) -> (beq a1 a2 = True) <-> (a1 = a2)) ->
10941083
> ((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
10951085

10961086
$\square$
10971087

@@ -1147,10 +1137,8 @@ the value of \idr{b}.
11471137
\todo[inline]{Remove when a release with
11481138
https://github.com/idris-lang/Idris-dev/pull/3925 happens}
11491139

1150-
> Uninhabited (False = True) where
1151-
> uninhabited Refl impossible
1152-
1153-
\todo[inline]{Explain `uninhabited`}
1140+
Uninhabited (False = True) where
1141+
uninhabited Refl impossible
11541142

11551143
> restricted_excluded_middle : (p <-> b = True) -> p `Either` Not p
11561144
> restricted_excluded_middle {b = True} (_, bp) = Left $ bp Refl
@@ -1162,7 +1150,8 @@ natural numbers \idr{n} and \idr{m}.
11621150
\todo[inline]{Is there a simpler way to write this? Maybe with setoids?}
11631151

11641152
> 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)
11661155
> where
11671156
> to : (n, m : Nat) -> (n=m) -> (n==m)=True
11681157
> to Z Z prf = Refl
@@ -1194,7 +1183,10 @@ hold for arbitrary propositions, are referred to as _classical_.
11941183
The following example illustrates why assuming the excluded middle may lead to
11951184
non-constructive proofs:
11961185

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.
11981190

11991191
_Proof_: It is not difficult to show that `sqrt 2` is irrational. If `sqrt 2 ^
12001192
sqrt 2` is rational, it suffices to take `a = b = sqrt 2` and we are done.
@@ -1252,20 +1244,23 @@ $\square$
12521244

12531245
==== Exercise: 3 stars, advanced (not_exists_dist)
12541246

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:
12561249

12571250
```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
12601253
```
12611254

12621255
The \idr{dist_not_exists} theorem above proves one side of this equivalence.
12631256
Interestingly, the other direction cannot be proved in constructive logic. Your
12641257
job is to show that it is implied by the excluded middle.
12651258

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
12691264

12701265
$\square$
12711266

0 commit comments

Comments
 (0)