Skip to content

Commit 182e492

Browse files
committed
Basics.lean: More Exercises
1 parent 7d8994a commit 182e492

File tree

1 file changed

+217
-0
lines changed

1 file changed

+217
-0
lines changed

SoftwareFoundationsVol1/Basics.lean

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,3 +429,220 @@ theorem zero_nbeq_add_one : ∀ n : Nat, 0 =? n + 1 = false := by
429429
/- FILL IN HERE -/ sorry
430430

431431
-- # More Exercises
432+
433+
-- ## Warmups
434+
435+
-- ### Exercise: 1 star, standard (identity_fn_applied_twice)
436+
theorem identity_fn_applied_twice :
437+
∀ (f : Bool → Bool),
438+
(∀ (x : Bool), f x = x) →
439+
∀ (b : Bool), f (f b) = b := by
440+
/- FILL IN HERE -/ sorry
441+
442+
-- ### Exercise: 1 star, standard (negation_fn_applied_twice)
443+
/- FILL IN HERE -/
444+
445+
-- ### Exercise: 3 stars, standard, optional (and_eq_or)
446+
theorem and_eq_or :
447+
∀ (b c : Bool),
448+
(and b c = or b c) →
449+
b = c := by
450+
/- FILL IN HERE -/ sorry
451+
452+
-- ## Course Late Policies, Formalized
453+
namespace LateDays
454+
inductive Letter : Type where
455+
| a | b | c | d | f
456+
457+
inductive Modifier : Type where
458+
| plus | natural | minus
459+
460+
inductive Grade : Type where
461+
| grade (l : Letter) (m : Modifier)
462+
463+
inductive Comparison : Type where
464+
| eq -- equal
465+
| lt -- less than
466+
| gt -- greater than
467+
468+
def letter_comparison (l1 l2 : Letter) : Comparison :=
469+
match l1, l2 with
470+
| .a, .a => .eq
471+
| .a, _ => .gt
472+
| .b, .a => .lt
473+
| .b, .b => .eq
474+
| .b, _ => .gt
475+
| .c, .a | .c, .b => .lt
476+
| .c, .c => .eq
477+
| .c, _ => .gt
478+
| .d, .a | .d, .b | .d, .c => .lt
479+
| .d, .d => .eq
480+
| .d, _ => .gt
481+
| .f, .a | .f, .b | .f, .c | .f, .d => .lt
482+
| .f, .f => .eq
483+
484+
#eval letter_comparison .b .a -- .lt
485+
#eval letter_comparison .d .d -- .eq
486+
#eval letter_comparison .b .f -- .gt
487+
488+
-- ### Exercise: 1 star, standard (letter_comparison)
489+
def letter_comparison_eq :
490+
∀ l, letter_comparison l l = .eq := by
491+
/- FILL IN HERE -/ sorry
492+
493+
def modifier_comparison (m1 m2 : Modifier) : Comparison :=
494+
match m1, m2 with
495+
| .plus, .plus => .eq
496+
| .plus, _ => .gt
497+
| .natural, .plus => .lt
498+
| .natural, .natural => .eq
499+
| .natural, _ => .gt
500+
| .minus, .plus | .minus, .natural => .lt
501+
| .minus, _ => .eq
502+
503+
-- ### Exercise: 2 stars, standard (grade_comparison)
504+
def grade_comparison (g1 g2 : Grade) : Comparison :=
505+
/- REPLACE THIS LINE WITH YOUR DEFINITION -/ sorry
506+
507+
example : grade_comparison (.grade .a .minus) (.grade .b .plus) = .gt :=
508+
/- FILL IN HERE -/ sorry
509+
510+
example : grade_comparison (.grade .a .minus) (.grade .a .plus) = .lt :=
511+
/- FILL IN HERE -/ sorry
512+
513+
example : grade_comparison (.grade .f .plus) (.grade .f .plus) = .eq :=
514+
/- FILL IN HERE -/ sorry
515+
516+
example : grade_comparison (.grade .b .minus) (.grade .c .plus) = .gt :=
517+
/- FILL IN HERE -/ sorry
518+
519+
def lower_letter (l : Letter) : Letter :=
520+
match l with
521+
| .a => .b
522+
| .b => .c
523+
| .c => .d
524+
| .d => .f
525+
| .f => .f -- Can't go lower than F!
526+
527+
theorem lower_letter_lowers_wrong :
528+
∀ (l : Letter), letter_comparison (lower_letter l) l = .lt := by
529+
intro l
530+
cases l
531+
. rfl -- a -> b
532+
. rfl -- b -> c
533+
. rfl -- c -> d
534+
. rfl -- d -> f
535+
. sorry -- We get stuck here
536+
537+
theorem lower_letter_f_is_f : lower_letter .f = .f := by
538+
rfl
539+
540+
-- ### Exercise: 2 stars, standard (lower_letter_lowers)
541+
theorem lower_letter_lowers :
542+
∀ (l : Letter),
543+
letter_comparison .f l = .lt →
544+
letter_comparison (lower_letter l) l = .lt := by
545+
/- FILL IN HERE -/ sorry
546+
547+
-- ### Exercise: 2 stars, standard (lower_grade)
548+
def lower_grade (g : Grade) : Grade :=
549+
/- REPLACE THIS LINE WITH YOUR DEFINITION -/ sorry
550+
551+
example : lower_grade (.grade .a .plus) = (.grade .a .natural) :=
552+
/- FILL IN HERE -/ sorry
553+
554+
example : lower_grade (.grade .a .natural) = (.grade .a .minus) :=
555+
/- FILL IN HERE -/ sorry
556+
557+
example : lower_grade (.grade .a .minus) = (.grade .b .plus) :=
558+
/- FILL IN HERE -/ sorry
559+
560+
example : lower_grade (.grade .b .plus) = (.grade .b .natural) :=
561+
/- FILL IN HERE -/ sorry
562+
563+
example : lower_grade (.grade .f .natural) = (.grade .f .minus) :=
564+
/- FILL IN HERE -/ sorry
565+
566+
example : lower_grade (lower_grade (.grade .b .minus)) = (.grade .c .natural) :=
567+
/- FILL IN HERE -/ sorry
568+
569+
example : lower_grade (lower_grade (lower_grade (.grade .b .minus))) = (.grade .c .minus) :=
570+
/- FILL IN HERE -/ sorry
571+
572+
theorem lower_grade_f_minus : lower_grade (.grade .f .minus) = (.grade .f .minus) := by
573+
/- FILL IN HERE -/ sorry
574+
575+
-- ### Exercise: 3 stars, standard (lower_grade_lowers)
576+
theorem lower_grade_lowers :
577+
∀ (g : Grade),
578+
grade_comparison (.grade .f .minus) g = .lt →
579+
grade_comparison (lower_grade g) g = .lt := by
580+
/- FILL IN HERE -/ sorry
581+
582+
def apply_late_policy (late_days : Nat) (g : Grade) : Grade :=
583+
if late_days <? 9 then g
584+
else if late_days <? 17 then lower_grade g
585+
else if late_days <? 21 then lower_grade (lower_grade g)
586+
else lower_grade (lower_grade (lower_grade g))
587+
588+
theorem apply_late_policy_unfold :
589+
∀ (late_days : Nat) (g : Grade), apply_late_policy late_days g
590+
=
591+
if late_days <? 9 then g
592+
else if late_days <? 17 then lower_grade g
593+
else if late_days <? 21 then lower_grade (lower_grade g)
594+
else lower_grade (lower_grade (lower_grade g))
595+
:= by
596+
intros
597+
rfl
598+
599+
-- ### Exercise: 2 stars, standard (no_penalty_for_mostly_on_time)
600+
theorem no_penalty_for_mostly_on_time :
601+
∀ (late_days : Nat) (g : Grade), late_days <? 9 = true
602+
603+
apply_late_policy late_days g = g
604+
:= by
605+
/- FILL IN HERE -/ sorry
606+
607+
-- ### Exercise: 2 stars, standard (graded_lowered_once)
608+
theorem grade_lowered_once :
609+
∀ (late_days : Nat) (g : Grade),
610+
late_days <? 9 = false →
611+
late_days <? 17 = true →
612+
apply_late_policy late_days g = lower_grade g
613+
:= by
614+
/- FILL IN HERE -/ sorry
615+
end LateDays
616+
617+
-- ## Binary Numerals
618+
619+
-- ### Exercise: 3 stars, standard (binary)
620+
inductive Bin : Type where
621+
| z
622+
| b0 (n : Bin)
623+
| b1 (n : Bin)
624+
625+
-- ### Exercise: 3 stars, standard (binary)
626+
def incr (m : Bin) : Bin :=
627+
/- REPLACE THIS LINE WITH YOUR DEFINITION -/ sorry
628+
629+
def bin_to_nat (m : Bin) : Nat :=
630+
/- REPLACE THIS LINE WITH YOUR DEFINITION -/ sorry
631+
632+
example : (incr (.b1 .z)) = .b0 (.b1 .z) :=
633+
/- FILL IN HERE -/ sorry
634+
635+
example : (incr (.b0 (.b1 .z))) = .b1 (.b1 .z) :=
636+
/- FILL IN HERE -/ sorry
637+
638+
example : (incr (.b1 (.b1 .z))) = .b0 (.b0 (.b1 .z)) :=
639+
/- FILL IN HERE -/ sorry
640+
641+
example : bin_to_nat (.b0 (.b1 .z)) = 2 :=
642+
/- FILL IN HERE -/ sorry
643+
644+
example : bin_to_nat (incr (.b1 .z)) = 1 + bin_to_nat (.b1 .z) :=
645+
/- FILL IN HERE -/ sorry
646+
647+
example : bin_to_nat (incr (incr (.b1 .z))) = 2 + bin_to_nat (.b1 .z) :=
648+
/- FILL IN HERE -/ sorry

0 commit comments

Comments
 (0)