Skip to content

Commit 2ae7861

Browse files
author
Alex Gryzlov
committed
Logic: fix some exercises
1 parent 47f6440 commit 2ae7861

File tree

1 file changed

+50
-38
lines changed

1 file changed

+50
-38
lines changed

src/Logic.lidr

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,10 @@ their arguments.
9494
For instance, here's a (polymorphic) property defining the familiar notion of an
9595
_injective function_.
9696

97-
> injective : (f : a -> b) -> Type
98-
> injective {a} {b} f = (x, y : a) -> f x = f y -> x = y
97+
> Injective : (f : a -> b) -> Type
98+
> Injective {a} {b} f = (x, y : a) -> f x = f y -> x = y
9999

100-
> succ_inj : injective S
100+
> succ_inj : Injective S
101101
> succ_inj x x Refl = Refl
102102

103103
The equality operator \idr{=} is also a function that returns a \idr{Type}.
@@ -545,9 +545,9 @@ $\square$
545545

546546
Prove that existential quantification distributes over disjunction.
547547

548-
> dist_exists_or : (p, q : a -> Type) -> (x ** (p x `Either` q x)) <->
548+
> dist_exists_or : {p, q : a -> Type} -> (x ** (p x `Either` q x)) <->
549549
> ((x ** p x) `Either` (x ** q x))
550-
> dist_exists_or p q = ?dist_exists_or_rhs
550+
> dist_exists_or = ?dist_exists_or_rhs
551551

552552
$\square$
553553

@@ -634,9 +634,8 @@ definition should _not_ just restate the left-hand side of \idr{All_In}.)
634634
> All : (p : t -> Type) -> (l : List t) -> Type
635635
> All p l = ?All_rhs
636636

637-
> All_In : (p : t -> Type) -> (l : List t) ->
638-
> ((x:t) -> In x l -> p x) <-> (All p l)
639-
> All_In P l = ?All_In_rhs
637+
> All_In : ((x:t) -> In x l -> p x) <-> (All p l)
638+
> All_In = ?All_In_rhs
640639

641640
$\square$
642641

@@ -653,23 +652,23 @@ n} when \idr{n} is odd and equivalent to \idr{peven n} otherwise.
653652

654653
To test your definition, prove the following facts:
655654

656-
> combine_odd_even_intro : (podd, peven : Nat -> Type) -> (n : Nat) ->
655+
> combine_odd_even_intro : (n : Nat) ->
657656
> (oddb n = True -> podd n) ->
658657
> (oddb n = False -> peven n) ->
659658
> combine_odd_even podd peven n
660-
> combine_odd_even_intro podd peven n oddp evenp = ?combine_odd_even_intro_rhs
659+
> combine_odd_even_intro n oddp evenp = ?combine_odd_even_intro_rhs
661660

662-
> combine_odd_even_elim_odd : (podd, peven : Nat -> Type) -> (n : Nat) ->
661+
> combine_odd_even_elim_odd : (n : Nat) ->
663662
> combine_odd_even podd peven n ->
664663
> oddb n = True ->
665664
> podd n
666-
> combine_odd_even_elim_odd podd peven n x prf = ?combine_odd_even_elim_odd_rhs
665+
> combine_odd_even_elim_odd n x prf = ?combine_odd_even_elim_odd_rhs
667666

668-
> combine_odd_even_elim_even : (podd, peven : Nat -> Type) -> (n : Nat) ->
667+
> combine_odd_even_elim_even : (n : Nat) ->
669668
> combine_odd_even podd peven n ->
670669
> oddb n = False ->
671670
> peven n
672-
> combine_odd_even_elim_even podd peven n x prf = ?combine_odd_even_elim_even_rhs
671+
> combine_odd_even_elim_even n x prf = ?combine_odd_even_elim_even_rhs
673672

674673
$\square$
675674

@@ -719,8 +718,8 @@ wanted to prove the following result:
719718
\todo[inline]{Edit, we already have done this before}
720719

721720
It appears at first sight that we ought to be able to prove this by rewriting
722-
with \idr{plusCommutative} twice to make the two sides match. The problem, however, is that
723-
the second \idr{rewrite} will undo the effect of the first.
721+
with \idr{plusCommutative} twice to make the two sides match. The problem,
722+
however, is that the second \idr{rewrite} will undo the effect of the first.
724723

725724
Proof.
726725
intros n m p.
@@ -761,8 +760,10 @@ in the proof below.
761760
> lemma_application_ex : (n : Nat) -> (ns : List Nat) ->
762761
> In n (map (\m => m * 0) ns) -> n = 0
763762
> lemma_application_ex _ [] prf = absurd prf
764-
> lemma_application_ex _ (y :: _) (Left prf) = rewrite sym $ multZeroRightZero y in sym prf
765-
> lemma_application_ex n (_ :: xs) (Right prf) = lemma_application_ex n xs prf
763+
> lemma_application_ex _ (y :: _) (Left prf) =
764+
> rewrite sym $ multZeroRightZero y in sym prf
765+
> lemma_application_ex n (_ :: xs) (Right prf) =
766+
> lemma_application_ex n xs prf
766767

767768
We will see many more examples of the idioms from this section in later chapters.
768769

@@ -893,7 +894,7 @@ to execute \idr{++} after the recursive call); a decent compiler will generate
893894
very efficient code in this case. Prove that the two definitions are indeed
894895
equivalent.
895896

896-
> tr_rev_correct : tr_rev x = rev x
897+
> tr_rev_correct : (x : List a) -> tr_rev x = rev x
897898
> tr_rev_correct = ?tr_rev_correct_rhs
898899

899900
$\square$
@@ -932,33 +933,44 @@ We often say that the boolean \idr{evenb n} _reflects_ the proposition \idr{(k
932933

933934
$\square$
934935

935-
\todo[inline]{Finish, use \idr{really_believe_me} for \idr{evenb_double_conv}?}
936-
937936
> even_bool_prop : (evenb n = True) <-> (k ** n = double k)
938-
> even_bool_prop = ?even_bool_prop_rhs
937+
> even_bool_prop = (to, fro)
938+
> where
939+
> to : evenb n = True -> (k ** n = double k)
940+
> to {n} prf = let
941+
> (k ** p) = evenb_double_conv {n}
942+
> in
939943

940-
Proof.
941-
intros n. split.
942-
- intros H. destruct (evenb_double_conv n) as [k Hk].
943-
rewrite Hk. rewrite H. ∃k. reflexivity.
944-
- intros [k Hk]. rewrite Hk. apply evenb_double.
945-
Qed.
944+
\todo[inline]{Is there a shorter way?}
945+
946+
> (k ** replace prf p {P = \x => n = if x then double k else S (double k)})
947+
> fro : (k ** n = double k) -> evenb n = True
948+
> fro {n} (k**prf) = rewrite prf in evenb_double {k}
946949

947950
Similarly, to state that two numbers \idr{n} and \idr{m} are equal, we can say
948951
either (1) that \idr{beq_nat n m} returns \idr{True} or (2) that \idr{n = m}.
949952
These two notions are equivalent.
950953

951-
\todo[inline]{Finish, implement \idr{beq_nat_true} and \idr{beq_nat_refl} from
952-
`Tactics`}
954+
\todo[inline]{Copy these 2 here for now}
953955

954-
> beq_nat_true_iff : (n1, n2 : Nat) -> (beq_nat n1 n2 = True) <-> (n1 = n2)
955-
> beq_nat_true_iff n1 n2 = ?beq_nat_true_iff_rhs
956-
957-
Proof.
958-
intros n1 n2. split.
959-
- apply beq_nat_true.
960-
- intros H. rewrite H. rewrite ← beq_nat_refl. reflexivity.
961-
Qed.
956+
> beq_nat_true : beq_nat n m = True -> n = m
957+
> beq_nat_true {n=Z} {m=Z} _ = Refl
958+
> beq_nat_true {n=(S _)} {m=Z} Refl impossible
959+
> beq_nat_true {n=Z} {m=(S _)} Refl impossible
960+
> beq_nat_true {n=(S n')} {m=(S m')} eq =
961+
> rewrite beq_nat_true {n=n'} {m=m'} eq in Refl
962+
963+
> beq_nat_refl : (n : Nat) -> True = beq_nat n n
964+
> beq_nat_refl Z = Refl
965+
> beq_nat_refl (S k) = beq_nat_refl k
966+
967+
> beq_nat_true_iff : (n1, n2 : Nat) -> (beq_nat n1 n2 = True) <-> (n1 = n2)
968+
> beq_nat_true_iff n1 n2 = (to, fro n1 n2)
969+
> where
970+
> to : (beq_nat n1 n2 = True) -> (n1 = n2)
971+
> to = beq_nat_true {n=n1} {m=n2}
972+
> fro : (n1, n2 : Nat) -> (n1 = n2) -> (beq_nat n1 n2 = True)
973+
> fro n1 n1 Refl = sym $ beq_nat_refl n1
962974

963975
However, while the boolean and propositional formulations of a claim are
964976
equivalent from a purely logical perspective, they need not be equivalent

0 commit comments

Comments
 (0)