').addClass('code').append(spoiler[0].childNodes));
84 | }
85 | }
86 |
87 | if (location.search !== '?jscoq=no') {
88 | window.addEventListener('DOMContentLoaded', () => {
89 | jsCoqInject();
90 | jsCoqLoad();
91 | });
92 | }
93 |
--------------------------------------------------------------------------------
/textbook/lf/IndPrinciplesTest.v:
--------------------------------------------------------------------------------
1 | Set Warnings "-notation-overridden,-parsing".
2 | From Coq Require Export String.
3 | From LF Require Import IndPrinciples.
4 |
5 | Parameter MISSING: Type.
6 |
7 | Module Check.
8 |
9 | Ltac check_type A B :=
10 | match type of A with
11 | | context[MISSING] => idtac "Missing:" A
12 | | ?T => first [unify T B; idtac "Type: ok" | idtac "Type: wrong - should be (" B ")"]
13 | end.
14 |
15 | Ltac print_manual_grade A :=
16 | match eval compute in A with
17 | | Some (_ ?S ?C) =>
18 | idtac "Score:" S;
19 | match eval compute in C with
20 | | ""%string => idtac "Comment: None"
21 | | _ => idtac "Comment:" C
22 | end
23 | | None =>
24 | idtac "Score: Ungraded";
25 | idtac "Comment: None"
26 | end.
27 |
28 | End Check.
29 |
30 | From LF Require Import IndPrinciples.
31 | Import Check.
32 |
33 | Goal True.
34 |
35 | idtac "------------------- plus_one_r' --------------------".
36 | idtac " ".
37 |
38 | idtac "#> plus_one_r'".
39 | idtac "Possible points: 2".
40 | check_type @plus_one_r' ((forall n : nat, n + 1 = S n)).
41 | idtac "Assumptions:".
42 | Abort.
43 | Print Assumptions plus_one_r'.
44 | Goal True.
45 | idtac " ".
46 |
47 | idtac "------------------- booltree_ind --------------------".
48 | idtac " ".
49 |
50 | idtac "#> booltree_ind_type_correct".
51 | idtac "Possible points: 2".
52 | check_type @booltree_ind_type_correct (booltree_ind_type).
53 | idtac "Assumptions:".
54 | Abort.
55 | Print Assumptions booltree_ind_type_correct.
56 | Goal True.
57 | idtac " ".
58 |
59 | idtac "------------------- toy_ind --------------------".
60 | idtac " ".
61 |
62 | idtac "#> Toy_correct".
63 | idtac "Possible points: 2".
64 | check_type @Toy_correct (
65 | (exists (f : bool -> Toy) (g : nat -> Toy -> Toy),
66 | forall P : Toy -> Prop,
67 | (forall b : bool, P (f b)) ->
68 | (forall (n : nat) (t : Toy), P t -> P (g n t)) -> forall t : Toy, P t)).
69 | idtac "Assumptions:".
70 | Abort.
71 | Print Assumptions Toy_correct.
72 | Goal True.
73 | idtac " ".
74 |
75 | idtac " ".
76 |
77 | idtac "Max points - standard: 6".
78 | idtac "Max points - advanced: 6".
79 | idtac "".
80 | idtac "Allowed Axioms:".
81 | idtac "functional_extensionality".
82 | idtac "FunctionalExtensionality.functional_extensionality_dep".
83 | idtac "plus_le".
84 | idtac "le_trans".
85 | idtac "le_plus_l".
86 | idtac "add_le_cases".
87 | idtac "Sn_le_Sm__n_le_m".
88 | idtac "O_le_n".
89 | idtac "".
90 | idtac "".
91 | idtac "********** Summary **********".
92 | idtac "".
93 | idtac "Below is a summary of the automatically graded exercises that are incomplete.".
94 | idtac "".
95 | idtac "The output for each exercise can be any of the following:".
96 | idtac " - 'Closed under the global context', if it is complete".
97 | idtac " - 'MANUAL', if it is manually graded".
98 | idtac " - A list of pending axioms, containing unproven assumptions. In this case".
99 | idtac " the exercise is considered complete, if the axioms are all allowed.".
100 | idtac "".
101 | idtac "********** Standard **********".
102 | idtac "---------- plus_one_r' ---------".
103 | Print Assumptions plus_one_r'.
104 | idtac "---------- booltree_ind_type_correct ---------".
105 | Print Assumptions booltree_ind_type_correct.
106 | idtac "---------- Toy_correct ---------".
107 | Print Assumptions Toy_correct.
108 | idtac "".
109 | idtac "********** Advanced **********".
110 | Abort.
111 |
112 | (* 2022-06-16 11:18 *)
113 |
114 | (* 2022-06-16 11:18 *)
115 |
--------------------------------------------------------------------------------
/notes/lf/Postscript.v:
--------------------------------------------------------------------------------
1 | (** * Postscript *)
2 |
3 | (** Congratulations: We've made it to the end of _Logical
4 | Foundations_! *)
5 |
6 | (* ################################################################# *)
7 | (** * Looking Back *)
8 |
9 | (** We've covered quite a bit of ground so far. Here's a quick review...
10 |
11 | - _Functional programming_:
12 | - "declarative" programming style (recursion over immutable
13 | data structures, rather than looping over mutable arrays
14 | or pointer structures)
15 | - higher-order functions
16 | - polymorphism *)
17 |
18 | (**
19 | - _Logic_, the mathematical basis for software engineering:
20 |
21 | logic calculus
22 | -------------------- ~ ----------------------------
23 | software engineering mechanical/civil engineering
24 |
25 | - inductively defined sets and relations
26 | - inductive proofs
27 | - proof objects *)
28 |
29 | (**
30 | - _Coq_, an industrial-strength proof assistant
31 | - functional core language
32 | - core tactics
33 | - automation
34 | *)
35 |
36 | (* ################################################################# *)
37 | (** * Looking Forward *)
38 |
39 | (** If what you've seen so far has whetted your interest, you have
40 | several choices for further reading in later volumes of the
41 | _Software Foundations_ series. Some of these are intended to be
42 | accessible to readers immediately after finishing _Logical
43 | Foundations_; others require a few chapters from Volume 2,
44 | _Programming Language Foundations_. The Preface chapter in each
45 | volume gives details about prerequisites. *)
46 |
47 | (* ################################################################# *)
48 | (** * Resources *)
49 |
50 | (** Here are some other good places to learn more...
51 |
52 | - This book includes some optional chapters covering topics
53 | that you may find useful. Take a look at the table of contents and the chapter dependency diagram to find
54 | them.
55 |
56 | - For questions about Coq, the [#coq] area of Stack
57 | Overflow ({https://stackoverflow.com/questions/tagged/coq})
58 | is an excellent community resource.
59 |
60 | - Here are some great books on functional programming
61 | - Learn You a Haskell for Great Good, by Miran Lipovaca
62 | [Lipovaca 2011] (in Bib.v).
63 | - Real World Haskell, by Bryan O'Sullivan, John Goerzen,
64 | and Don Stewart [O'Sullivan 2008] (in Bib.v)
65 | - ...and many other excellent books on Haskell, OCaml,
66 | Scheme, Racket, Scala, F sharp, etc., etc.
67 |
68 | - And some further resources for Coq:
69 | - Certified Programming with Dependent Types, by Adam
70 | Chlipala [Chlipala 2013] (in Bib.v).
71 | - Interactive Theorem Proving and Program Development:
72 | Coq'Art: The Calculus of Inductive Constructions, by Yves
73 | Bertot and Pierre Casteran [Bertot 2004] (in Bib.v).
74 |
75 | - If you're interested in real-world applications of formal
76 | verification to critical software, see the Postscript chapter
77 | of _Programming Language Foundations_.
78 |
79 | - For applications of Coq in building verified systems, the
80 | lectures and course materials for the 2017 DeepSpec Summer
81 | School are a great resource.
82 | {https://deepspec.org/event/dsss17/index.html}
83 | *)
84 |
--------------------------------------------------------------------------------
/textbook/lf/Postscript.v:
--------------------------------------------------------------------------------
1 | (** * Postscript *)
2 |
3 | (** Congratulations: We've made it to the end of _Logical
4 | Foundations_! *)
5 |
6 | (* ################################################################# *)
7 | (** * Looking Back *)
8 |
9 | (** We've covered quite a bit of ground so far. Here's a quick review...
10 |
11 | - _Functional programming_:
12 | - "declarative" programming style (recursion over immutable
13 | data structures, rather than looping over mutable arrays
14 | or pointer structures)
15 | - higher-order functions
16 | - polymorphism *)
17 |
18 | (**
19 | - _Logic_, the mathematical basis for software engineering:
20 |
21 | logic calculus
22 | -------------------- ~ ----------------------------
23 | software engineering mechanical/civil engineering
24 |
25 | - inductively defined sets and relations
26 | - inductive proofs
27 | - proof objects *)
28 |
29 | (**
30 | - _Coq_, an industrial-strength proof assistant
31 | - functional core language
32 | - core tactics
33 | - automation
34 | *)
35 |
36 | (* ################################################################# *)
37 | (** * Looking Forward *)
38 |
39 | (** If what you've seen so far has whetted your interest, you have
40 | several choices for further reading in later volumes of the
41 | _Software Foundations_ series. Some of these are intended to be
42 | accessible to readers immediately after finishing _Logical
43 | Foundations_; others require a few chapters from Volume 2,
44 | _Programming Language Foundations_. The Preface chapter in each
45 | volume gives details about prerequisites. *)
46 |
47 | (* ################################################################# *)
48 | (** * Resources *)
49 |
50 | (** Here are some other good places to learn more...
51 |
52 | - This book includes some optional chapters covering topics
53 | that you may find useful. Take a look at the table of contents and the chapter dependency diagram to find
54 | them.
55 |
56 | - For questions about Coq, the [#coq] area of Stack
57 | Overflow ({https://stackoverflow.com/questions/tagged/coq})
58 | is an excellent community resource.
59 |
60 | - Here are some great books on functional programming
61 | - Learn You a Haskell for Great Good, by Miran Lipovaca
62 | [Lipovaca 2011] (in Bib.v).
63 | - Real World Haskell, by Bryan O'Sullivan, John Goerzen,
64 | and Don Stewart [O'Sullivan 2008] (in Bib.v)
65 | - ...and many other excellent books on Haskell, OCaml,
66 | Scheme, Racket, Scala, F sharp, etc., etc.
67 |
68 | - And some further resources for Coq:
69 | - Certified Programming with Dependent Types, by Adam
70 | Chlipala [Chlipala 2013] (in Bib.v).
71 | - Interactive Theorem Proving and Program Development:
72 | Coq'Art: The Calculus of Inductive Constructions, by Yves
73 | Bertot and Pierre Casteran [Bertot 2004] (in Bib.v).
74 |
75 | - If you're interested in real-world applications of formal
76 | verification to critical software, see the Postscript chapter
77 | of _Programming Language Foundations_.
78 |
79 | - For applications of Coq in building verified systems, the
80 | lectures and course materials for the 2017 DeepSpec Summer
81 | School are a great resource.
82 | {https://deepspec.org/event/dsss17/index.html}
83 | *)
84 |
85 | (* 2022-06-16 11:18 *)
86 |
--------------------------------------------------------------------------------
/textbook/lf/common/css/jscoq.css:
--------------------------------------------------------------------------------
1 | body {
2 | overscroll-behavior-y: none;
3 | }
4 |
5 | @media (max-width: 1564px) { /* 860 / 0.55 */
6 |
7 | /* this is a hack that's needed because changing padding causes reflow */
8 | /* and loses the current scroll position */
9 | .terse#ide-wrapper #main {
10 | padding-right: 10px;
11 | padding-left: 10px;
12 | }
13 | .terse#ide-wrapper #page {
14 | padding-left: 80px;
15 | transition: padding 0.1s ease;
16 | transition-delay: 0.5s;
17 | }
18 | .terse#ide-wrapper:not(.toggled) #page {
19 | padding-left: 0;
20 | }
21 | #ide-wrapper #main {
22 | transition: padding 0.1s ease;
23 | transition-delay: 0.3s;
24 | }
25 | .full#ide-wrapper:not(.toggled) #main {
26 | padding-right: 10px;
27 | transition: padding 0.1s ease;
28 | }
29 | #ide-wrapper:not(.toggled) #page {
30 | transition-delay: 0s;
31 | }
32 | .terse#ide-wrapper #panel-wrapper {
33 | transition-delay: 0.1s;
34 | }
35 |
36 | }
37 |
38 | #ide-wrapper.layout-flex #panel-wrapper {
39 | max-width: 38em !important; /* jsCoq's default is 48em */
40 | }
41 |
42 | .doc div.code {
43 | display: block;
44 | overflow-x: auto;
45 | }
46 |
47 | *:focus {
48 | outline: none;
49 | }
50 |
51 | #jscoq-plug {
52 | position: absolute;
53 | height: 32px;
54 | right: 0;
55 | top: 40px;
56 | width: 40px !important;
57 | background: url(../../../../node_modules/wacoq/ui-images/jscoq-splash.png);
58 | background-size: cover;
59 | cursor: pointer;
60 | /*transition: visibility 0s linear 1s, width 0.2s ease; */
61 | transition: width 0.2s ease;
62 | }
63 |
64 | #jscoq-plug:hover {
65 | width: 60px !important;
66 | }
67 |
68 | body.goals-active #jscoq-plug {
69 | width: 0 !important;
70 | }
71 |
72 | #panel-wrapper #hide-panel {
73 | display: none; /* sorry, this clashes with the SF page design */
74 | }
75 |
76 | #panel-wrapper button.close {
77 | position: absolute;
78 | padding: 0;
79 | border: none;
80 | top: 0; left: 0;
81 | width: 15px; height: 15px;
82 | font-size: 16px; line-height: 10px;
83 | }
84 |
85 | #panel-wrapper button.close:hover {
86 | background: #ccc;
87 | }
88 |
89 | #panel-wrapper #toolbar > *:first-child {
90 | margin-left: 15px; /* cannot use padding on `#toolbar` */
91 | } /* because an element with padding cannot have zero width */
92 |
93 | /*
94 | * Larger fonts in presentation mode
95 | */
96 |
97 | body.terse #panel-wrapper .flex-panel {
98 | font-size: 125%;
99 | }
100 | body.terse #panel-wrapper .exits.right {
101 | display: none;
102 | }
103 |
104 | body.terse .CodeMirror.jscoq {
105 | font-size: 22px;
106 | line-height: 34px;
107 | }
108 |
109 | body.terse #goal-panel div.contextual-info {
110 | font-size: 100%; /* overrides jsCoq's style */
111 | }
112 |
113 | body.terse #query-panel .Error,
114 | body.terse #query-panel .Warning,
115 | body.terse #query-panel .Notice,
116 | body.terse #query-panel .Info,
117 | body.terse #query-panel .Debug {
118 | background-size: 18px;
119 | background-position-y: 3px;
120 | padding-left: 22px;
121 | }
122 |
123 | #footer hr {
124 | border-top: 1px solid black;
125 | opacity: 0.2;
126 | }
127 |
128 | /*
129 | * Proof script toggle stuff
130 | */
131 |
132 | div.togglescript {
133 | font-size: 22px;
134 | line-height: calc(60% + 6px); /* per `.show` */
135 | padding-left: 1em;
136 | }
137 |
138 | div.togglescript.hidden {
139 | display: block;
140 | }
141 | div.togglescript.hidden > .show {
142 | background: #888;
143 | color: #ccc
144 | }
145 | div.togglescript.hidden > .show::before {
146 | content: '-';
147 | }
148 |
149 | div.proofscript > .code-tight {
150 | margin-top: .1em;
151 | }
152 |
153 | div.proofscript.hidden {
154 | display: block; /* needed because CodeMirror does not like being initialized when hidden */
155 | visibility: hidden;
156 | }
157 |
158 |
--------------------------------------------------------------------------------
/textbook/lf/Bib.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
Bib: Bibliography
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
29 |
30 |
31 |
32 |
BibBibliography
33 |
34 |
35 |
36 |
37 |
38 |
39 |
Resources cited in this volume
40 |
41 |
42 |
43 |
44 |
45 |
46 |
[Bertot 2004] Interactive Theorem Proving and Program Development:
47 | Coq'Art: The Calculus of Inductive Constructions, by Yves Bertot and
48 | Pierre Casteran. Springer-Verlag, 2004.
49 |
https://tinyurl.com/z3o7nqu
50 |
51 |
52 |
53 |
[Chlipala 2013] Certified Programming with Dependent Types, by
54 | Adam Chlipala. MIT Press. 2013.
https://tinyurl.com/zqdnyg2
55 |
56 |
57 |
58 |
[Lipovaca 2011] Learn You a Haskell for Great Good! A Beginner's
59 | Guide, by Miran Lipovaca, No Starch Press, April 2011.
60 |
http://learnyouahaskell.com
61 |
62 |
63 |
64 |
[O'Sullivan 2008] Bryan O'Sullivan, John Goerzen, and Don Stewart:
65 | Real world Haskell - code you can believe in. O'Reilly
66 | 2008.
http://book.realworldhaskell.org
67 |
68 |
69 |
70 |
[Pugh 1991] Pugh, William. "The Omega test: a fast and practical
71 | integer programming algorithm for dependence analysis." Proceedings
72 | of the 1991 ACM/IEEE conference on Supercomputing. ACM, 1991.
73 |
https://dl.acm.org/citation.cfm?id=125848
74 |
75 |
76 |
77 |
[Wadler 2015] Philip Wadler. "Propositions as types."
78 | Communications of the ACM 58, no. 12 (2015): 75-84.
79 |
https://dl.acm.org/citation.cfm?id=2699407
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/textbook/lf/common/slides.js:
--------------------------------------------------------------------------------
1 | /* Presentation mode for SF HTML
2 | *
3 | * This file implements simple slide functionality for the SF HTML
4 | * files. When loaded in a page, it will tag some of the page elements
5 | * as slide boundaries, giving each an id of the form
6 | * "#slide-XX". Pressing left or right should trigger "slide mode",
7 | * focusing the screen on the current slide, and then navigate between
8 | * slides. Pressing escape brings the page back to normal. */
9 |
10 | /* Which DOM elements to mark as slide boundaries */
11 | var slideSelector = 'h1.libtitle, h1.section, h2.section, h3.section, .quiz';
12 |
13 | /* Whether or not we are in slide mode */
14 | var slideMode = false;
15 |
16 | /* Keyboard navigation */
17 | var KEYS = {
18 | next: 39, // Right arrow
19 | prev: 37, // Left arrow
20 | exit: 27 // Escape
21 | };
22 |
23 | /* Navigates between slides, using the current location hash to find
24 | * the next slide to go to */
25 | function slideNavigate(direction) {
26 |
27 | function slideNumber(s) {
28 | if (!s) return null;
29 | var match = s.match(/slide-(.*)/);
30 | if (match && match.length != 0) {
31 | return parseInt(match[1]);
32 | }
33 | return null;
34 | }
35 |
36 | var curSlide = slideNumber(location.hash);
37 | var lastSlide = slideNumber($('.slide').last().attr('id'));
38 | var nextSlide;
39 |
40 | /* We change the id of each slide element when the page loads, and
41 | * then switch between slides based on the current hash. This is
42 | * not entirely optimal, and can probably be made better.
43 | * http://www.appelsiini.net/projects/viewport seems to be a nice choice.
44 | */
45 |
46 | if (direction == 'left') {
47 | if (curSlide != null) {
48 | if (curSlide > 0) {
49 | nextSlide = curSlide - 1;
50 | } else {
51 | nextSlide = lastSlide;
52 | }
53 | } else {
54 | nextSlide = 0;
55 | }
56 | } else if (direction == 'right') {
57 | if (curSlide != null && curSlide < lastSlide) {
58 | nextSlide = curSlide + 1;
59 | } else {
60 | nextSlide = 0;
61 | }
62 | }
63 |
64 | location.hash = '#slide-' + nextSlide;
65 |
66 | return false;
67 | };
68 |
69 | /* Force the browser to scroll back to the hash location */
70 | function refreshHash() {
71 | var t = location.hash;
72 | location.hash = '';
73 | location.hash = t;
74 | }
75 |
76 | /* Activate slide mode. Inserts the right amount of spacing between
77 | * slide boundaries, ensuring that only one slide appears on the
78 | * screen at a time */
79 | function slideActivate() {
80 | $('.slide').each(function (i, elt) {
81 | if (i > 0) $(elt).css('margin-top', $(window).height());
82 | $(elt).css('height', '20px');
83 | });
84 | $('#main').css('padding-bottom', $(window).height());
85 | slideMode = true;
86 | if (location.hash) {
87 | refreshHash();
88 | } else {
89 | location.hash = '#slide-0';
90 | }
91 | }
92 |
93 | /* Deactivate slide mode. Removes the extra spacing between slides */
94 | function slideDeactivate() {
95 | $('.slide').each(function (i, elt) {
96 | $(elt).css('margin-top', 0);
97 | $(elt).css('height', 0);
98 | });
99 | $('#main').css('padding-bottom', 0);
100 | refreshHash();
101 | slideMode = false;
102 | }
103 |
104 | /* Set up appropriate input handlers */
105 | $(document).keydown(function (event) {
106 | if (slideMode) {
107 | if (event.keyCode == KEYS.prev) {
108 | slideNavigate('left');
109 | event.preventDefault();
110 | } else if (event.keyCode == KEYS.next) {
111 | slideNavigate('right');
112 | event.preventDefault();
113 | } else if (event.keyCode == KEYS.exit) {
114 | slideDeactivate();
115 | event.preventDefault();
116 | } else return true;
117 | } else {
118 | if (event.keyCode == KEYS.prev || event.keyCode == KEYS.next) {
119 | slideActivate();
120 | event.preventDefault();
121 | return false;
122 | } else {
123 | return true;
124 | }
125 | }
126 | });
127 |
128 | /* Find slide boundaries and tag them */
129 | $(document).ready(function () {
130 | $(slideSelector).each(function (i, elt) {
131 | var mark = '
';
132 | $(mark).insertBefore($(elt));
133 | });
134 | if (location.hash) {
135 | slideActivate();
136 | }
137 | });
138 |
--------------------------------------------------------------------------------
/textbook/lf/Extraction.v:
--------------------------------------------------------------------------------
1 | (** * Extraction: Extracting OCaml from Coq *)
2 |
3 | (* ################################################################# *)
4 | (** * Basic Extraction *)
5 |
6 | (** In its simplest form, extracting an efficient program from one
7 | written in Coq is completely straightforward.
8 |
9 | First we say what language we want to extract into. Options are
10 | OCaml (the most mature), Haskell (mostly works), and Scheme (a bit
11 | out of date). *)
12 |
13 | Require Coq.extraction.Extraction.
14 | Extraction Language OCaml.
15 |
16 | (** Now we load up the Coq environment with some definitions, either
17 | directly or by importing them from other modules. *)
18 |
19 | From Coq Require Import Arith.Arith.
20 | From Coq Require Import Init.Nat.
21 | From Coq Require Import Arith.EqNat.
22 | From LF Require Import ImpCEvalFun.
23 |
24 | (** Finally, we tell Coq the name of a definition to extract and the
25 | name of a file to put the extracted code into. *)
26 |
27 | Extraction "imp1.ml" ceval_step.
28 |
29 | (** When Coq processes this command, it generates a file [imp1.ml]
30 | containing an extracted version of [ceval_step], together with
31 | everything that it recursively depends on. Compile the present
32 | [.v] file and have a look at [imp1.ml] now. *)
33 |
34 | (* ################################################################# *)
35 | (** * Controlling Extraction of Specific Types *)
36 |
37 | (** We can tell Coq to extract certain [Inductive] definitions to
38 | specific OCaml types. For each one, we must say
39 | - how the Coq type itself should be represented in OCaml, and
40 | - how each constructor should be translated. *)
41 |
42 | Extract Inductive bool => "bool" [ "true" "false" ].
43 |
44 | (** Also, for non-enumeration types (where the constructors take
45 | arguments), we give an OCaml expression that can be used as a
46 | "recursor" over elements of the type. (Think Church numerals.) *)
47 |
48 | Extract Inductive nat => "int"
49 | [ "0" "(fun x -> x + 1)" ]
50 | "(fun zero succ n ->
51 | if n=0 then zero () else succ (n-1))".
52 |
53 | (** We can also extract defined constants to specific OCaml terms or
54 | operators. *)
55 |
56 | Extract Constant plus => "( + )".
57 | Extract Constant mult => "( * )".
58 | Extract Constant eqb => "( = )".
59 |
60 | (** Important: It is entirely _your responsibility_ to make sure that
61 | the translations you're proving make sense. For example, it might
62 | be tempting to include this one
63 |
64 | Extract Constant minus => "( - )".
65 |
66 | but doing so could lead to serious confusion! (Why?)
67 | *)
68 |
69 | Extraction "imp2.ml" ceval_step.
70 |
71 | (** Have a look at the file [imp2.ml]. Notice how the fundamental
72 | definitions have changed from [imp1.ml]. *)
73 |
74 | (* ################################################################# *)
75 | (** * A Complete Example *)
76 |
77 | (** To use our extracted evaluator to run Imp programs, all we need to
78 | add is a tiny driver program that calls the evaluator and prints
79 | out the result.
80 |
81 | For simplicity, we'll print results by dumping out the first four
82 | memory locations in the final state.
83 |
84 | Also, to make it easier to type in examples, let's extract a
85 | parser from the [ImpParser] Coq module. To do this, we first need
86 | to set up the right correspondence between Coq strings and lists
87 | of OCaml characters. *)
88 |
89 | Require Import ExtrOcamlBasic.
90 | Require Import ExtrOcamlString.
91 |
92 | (** We also need one more variant of booleans. *)
93 |
94 | Extract Inductive sumbool => "bool" ["true" "false"].
95 |
96 | (** The extraction is the same as always. *)
97 |
98 | From LF Require Import Imp.
99 | From LF Require Import ImpParser.
100 |
101 | From LF Require Import Maps.
102 | Extraction "imp.ml" empty_st ceval_step parse.
103 |
104 | (** Now let's run our generated Imp evaluator. First, have a look at
105 | [impdriver.ml]. (This was written by hand, not extracted.)
106 |
107 | Next, compile the driver together with the extracted code and
108 | execute it, as follows.
109 |
110 | ocamlc -w -20 -w -26 -o impdriver imp.mli imp.ml impdriver.ml
111 | ./impdriver
112 |
113 | (The [-w] flags to [ocamlc] are just there to suppress a few
114 | spurious warnings.) *)
115 |
116 | (* ################################################################# *)
117 | (** * Discussion *)
118 |
119 | (** Since we've proved that the [ceval_step] function behaves the same
120 | as the [ceval] relation in an appropriate sense, the extracted
121 | program can be viewed as a _certified_ Imp interpreter. Of
122 | course, the parser we're using is not certified, since we didn't
123 | prove anything about it! *)
124 |
125 | (* ################################################################# *)
126 | (** * Going Further *)
127 |
128 | (** Further details about extraction can be found in the Extract
129 | chapter in _Verified Functional Algorithms_ (_Software
130 | Foundations_ volume 3). *)
131 |
132 | (* 2022-06-16 11:18 *)
133 |
--------------------------------------------------------------------------------
/install.md:
--------------------------------------------------------------------------------
1 | # Coq Installation Advice
2 |
3 | > **Note**
4 | > Coq and its standard library evolve with each release. The files in this
5 | > repo have been tested against Coq 8.13.2, 8.14.1, and 8.15.2. YMMV with
6 | > older or newer versions.
7 |
8 | There are three main possibilities I suggest for installation:
9 |
10 | - Use the Coq Scratchpad in your browser.
11 |
12 | - Install Coq locally with Coq Platform, and use CoqIDE as your IDE.
13 |
14 | - [more expertise required] Install Coq through OPAM, the OCaml Package Manager,
15 | and install either VS Code or Emacs as an IDE.
16 |
17 | Below I provide advice about each of those possibilities.
18 |
19 | ## Coq Scratchpad
20 |
21 | The easiest way to install Coq is to avoid installing it altogether! The
22 | [jsCoq][jsCoq] project makes it possible run Coq entirely in your browser. For
23 | at least the first chapter of the textbook, that's probably good enough. If
24 | you're hooked after that, I recommend a local installation.
25 |
26 | [jsCoq]: https://coq.vercel.app/
27 |
28 | ## Coq Platform
29 |
30 | The primary way to install Coq locally is with the [Coq Platform][coq-platform]
31 | distribution. It provides installation instructions for
32 | [macOS][coq-platform-mac], [Windows][coq-platform-win], and
33 | [Linux][coq-platform-linux].
34 |
35 | [coq-platform]: https://github.com/coq/platform/blob/main/README.md
36 | [coq-platform-mac]: https://github.com/coq/platform/blob/main/doc/README_macOS.md
37 | [coq-platform-win]: https://github.com/coq/platform/blob/main/doc/README_Windows.md
38 | [coq-platform-linux]: https://github.com/coq/platform/blob/main/doc/README_Linux.md
39 |
40 | ## Coq through OPAM
41 |
42 | You might choose this option if you prefer to develop software from the terminal
43 | with your choice of editor, such as VS Code or Emacs. Or, if you are already an
44 | OCaml developer, you might prefer to use OPAM anyway. (Actually, Coq Platform
45 | itself uses OPAM under the hood.)
46 |
47 | **Step 1A. If you have NOT previously installed OPAM:** Follow the
48 | [OPAM install instructions][opam-install].
49 |
50 | [opam-install]: https://opam.ocaml.org/doc/Install.html
51 |
52 | Then initialize OPAM:
53 |
54 | ```console
55 | $ opam init
56 | ```
57 |
58 | Now skip to Step 2.
59 |
60 | **Step 1B. If you HAVE previously installed OPAM:** Take a moment to update its
61 | package repository:
62 |
63 | ```console
64 | $ opam update
65 | ```
66 |
67 | When the update is done, it might prompt you to upgrade. It's up to you
68 | whether you want to upgrade the packages in your current switch. We're
69 | instead going to create a separate switch, next.
70 |
71 | **Step 2. Create a switch for Software Foundations:** Run the following
72 | commands. See the notes below them for some hints about troubleshooting and
73 | options.
74 |
75 | ```console
76 | $ opam switch create coq-sf ocaml-base-compiler.4.14.0
77 | $ opam install utop
78 | $ opam pin add coq 8.15.2
79 | ```
80 |
81 | Notes:
82 |
83 | - *Pinning* v8.15.2, as the last command above does, will ensure that OPAM does
84 | not try to upgrade it to a higher (possibly incompatible) version later.
85 |
86 | - By create a new *switch*, we ensure Coq doesn't interfere with any other OCaml
87 | development you might do or have done in the past.
88 |
89 | - Feel free to pick a different compiler version than 4.14.0. At the time of
90 | writing these notes, that was simply the most recent version.
91 |
92 | - Feel free to pick a different switch name than `coq-sf`.
93 |
94 | - If the `pin` command gives you an error because you are missing a library,
95 | install that library with your Unix package manager. The usual culprit seems
96 | to be the GNU Multiple Precision Arithmetic library.
97 |
98 | **Step 3. Check that Coq is working.** The Coq *toplevel* is `coqtop`. Here is a
99 | sample interaction:
100 |
101 | ```console
102 | $ coqtop
103 | Welcome to Coq 8.15.2
104 |
105 | Coq < Check true.
106 | true
107 | : bool
108 |
109 | Coq < Quit.
110 | ```
111 |
112 | Next you need to install an IDE. There are two main options: VS Code and Proof
113 | General.
114 |
115 | **Step 4A. Install VS Code.**
116 |
117 | (Or skip to step 4B.)
118 |
119 | Install [Visual Studio Code][vsc-install], then install the VSCoq extension by
120 | Maxime Dénès. Optionally you can also install the Prettify Symbols Mode
121 | extension by siegebell.
122 |
123 | [vsc-install]: https://code.visualstudio.com/
124 |
125 | > **Warning:**
126 | > When you edit Coq source files with VS Code, you should make sure that you
127 | > open the *directory* the file is in, rather than opening the *file* itself.
128 | > For example, if `foo.v` is a file in the current working directory, open it
129 | > with `code .` not `code foo.v`. This is necessary to make sure that other
130 | > files in the same directory can be imported by `foo`.
131 |
132 | **Step 4B. Install Proof General.**
133 |
134 | Proof General is a plugin for Emacs. Note that you can use
135 | [Evil mode][evil-mode] to get Vim keybindings, if you prefer those.
136 |
137 | - Install [Emacs][emacs]. If you're new to Emacs, start by doing the built-in
138 | tutorial with `C-h t`. That is, `Control-h` followed by `t`. It will take
139 | maybe an hour.
140 |
141 | - Install Proof General and Company Coq (which is an extension of Proof General
142 | for Coq) by following [these instructions][company-coq]. The Company Coq
143 | tutorial, mentioned at the end of those instructions, might not make much
144 | sense yet. It assumes you know Coq already.
145 |
146 | - You can double check that Proof General is working correctly as follows. Visit
147 | a new Coq file in Emacs with `C-x C-f test.v`. Enter this code: `Check true.`
148 | Press `C-c C-n` to compile it. You should get the output `true : bool` in the
149 | Coq Response window. In a correctly configured GUI Emacs you will see 𝔹
150 | instead of `bool`.
151 |
152 | [evil-mode]: https://evil.readthedocs.io/en/latest/overview.html#installation-via-package-el
153 | [emacs]: https://www.gnu.org/software/emacs/download.html
154 | [company-coq]: https://github.com/cpitclaudel/company-coq#setup
155 |
156 |
--------------------------------------------------------------------------------
/textbook/lf/Postscript.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
Postscript
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
29 |
30 |
31 |
32 |
Postscript
33 |
34 |
35 |
36 |
37 |
38 |
39 | Congratulations: We've made it to the end of
Logical
40 | Foundations !
41 |
42 |
43 |
Looking Back
44 |
45 |
46 |
47 | We've covered quite a bit of ground so far. Here's a quick review...
48 |
49 |
50 |
51 |
52 | Functional programming :
53 |
54 | "declarative" programming style (recursion over immutable
55 | data structures, rather than looping over mutable arrays
56 | or pointer structures)
57 |
58 |
59 | higher-order functions
60 |
61 |
62 | polymorphism
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | Coq , an industrial-strength proof assistant
105 |
106 | functional core language
107 |
108 |
109 | core tactics
110 |
111 |
112 | automation
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
Looking Forward
124 |
125 |
126 |
127 | If what you've seen so far has whetted your interest, you have
128 | several choices for further reading in later volumes of the
129 |
Software Foundations series. Some of these are intended to be
130 | accessible to readers immediately after finishing
Logical
131 | Foundations ; others require a few chapters from Volume 2,
132 |
Programming Language Foundations . The Preface chapter in each
133 | volume gives details about prerequisites.
134 |
135 |
136 |
137 |
Resources
138 |
139 |
140 |
141 | Here are some other good places to learn more...
142 |
143 |
144 |
145 |
146 | This book includes some optional chapters covering topics
147 | that you may find useful. Take a look at the table of contents and the chapter dependency diagram to find
150 | them.
151 |
152 |
153 |
154 |
155 |
156 | For questions about Coq, the #coq area of Stack
157 | Overflow (https://stackoverflow.com/questions/tagged/coq )
158 | is an excellent community resource.
159 |
160 |
161 |
162 |
163 |
164 | Here are some great books on functional programming
165 |
166 | Learn You a Haskell for Great Good, by Miran Lipovaca
167 | [Lipovaca 2011] .
168 |
169 |
170 | Real World Haskell, by Bryan O'Sullivan, John Goerzen,
171 | and Don Stewart [O'Sullivan 2008]
172 |
173 |
174 | ...and many other excellent books on Haskell, OCaml,
175 | Scheme, Racket, Scala, F sharp, etc., etc.
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 | And some further resources for Coq:
185 |
186 | Certified Programming with Dependent Types, by Adam
187 | Chlipala [Chlipala 2013] .
188 |
189 |
190 | Interactive Theorem Proving and Program Development:
191 | Coq'Art: The Calculus of Inductive Constructions, by Yves
192 | Bertot and Pierre Casteran [Bertot 2004] .
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 | If you're interested in real-world applications of formal
202 | verification to critical software, see the Postscript chapter
203 | of Programming Language Foundations .
204 |
205 |
206 |
207 |
208 |
209 | For applications of Coq in building verified systems, the
210 | lectures and course materials for the 2017 DeepSpec Summer
211 | School are a great resource.
212 | https://deepspec.org/event/dsss17/index.html
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
227 |
228 |
229 |
230 |
231 |
--------------------------------------------------------------------------------
/textbook/lf/InductionTest.v:
--------------------------------------------------------------------------------
1 | Set Warnings "-notation-overridden,-parsing".
2 | From Coq Require Export String.
3 | From LF Require Import Induction.
4 |
5 | Parameter MISSING: Type.
6 |
7 | Module Check.
8 |
9 | Ltac check_type A B :=
10 | match type of A with
11 | | context[MISSING] => idtac "Missing:" A
12 | | ?T => first [unify T B; idtac "Type: ok" | idtac "Type: wrong - should be (" B ")"]
13 | end.
14 |
15 | Ltac print_manual_grade A :=
16 | match eval compute in A with
17 | | Some (_ ?S ?C) =>
18 | idtac "Score:" S;
19 | match eval compute in C with
20 | | ""%string => idtac "Comment: None"
21 | | _ => idtac "Comment:" C
22 | end
23 | | None =>
24 | idtac "Score: Ungraded";
25 | idtac "Comment: None"
26 | end.
27 |
28 | End Check.
29 |
30 | From LF Require Import Induction.
31 | Import Check.
32 |
33 | Goal True.
34 |
35 | idtac "------------------- basic_induction --------------------".
36 | idtac " ".
37 |
38 | idtac "#> mul_0_r".
39 | idtac "Possible points: 0.5".
40 | check_type @mul_0_r ((forall n : nat, n * 0 = 0)).
41 | idtac "Assumptions:".
42 | Abort.
43 | Print Assumptions mul_0_r.
44 | Goal True.
45 | idtac " ".
46 |
47 | idtac "#> plus_n_Sm".
48 | idtac "Possible points: 0.5".
49 | check_type @plus_n_Sm ((forall n m : nat, S (n + m) = n + S m)).
50 | idtac "Assumptions:".
51 | Abort.
52 | Print Assumptions plus_n_Sm.
53 | Goal True.
54 | idtac " ".
55 |
56 | idtac "#> add_comm".
57 | idtac "Possible points: 0.5".
58 | check_type @add_comm ((forall n m : nat, n + m = m + n)).
59 | idtac "Assumptions:".
60 | Abort.
61 | Print Assumptions add_comm.
62 | Goal True.
63 | idtac " ".
64 |
65 | idtac "#> add_assoc".
66 | idtac "Possible points: 0.5".
67 | check_type @add_assoc ((forall n m p : nat, n + (m + p) = n + m + p)).
68 | idtac "Assumptions:".
69 | Abort.
70 | Print Assumptions add_assoc.
71 | Goal True.
72 | idtac " ".
73 |
74 | idtac "------------------- double_plus --------------------".
75 | idtac " ".
76 |
77 | idtac "#> double_plus".
78 | idtac "Possible points: 2".
79 | check_type @double_plus ((forall n : nat, double n = n + n)).
80 | idtac "Assumptions:".
81 | Abort.
82 | Print Assumptions double_plus.
83 | Goal True.
84 | idtac " ".
85 |
86 | idtac "------------------- eqb_refl --------------------".
87 | idtac " ".
88 |
89 | idtac "#> eqb_refl".
90 | idtac "Possible points: 2".
91 | check_type @eqb_refl ((forall n : nat, (n =? n) = true)).
92 | idtac "Assumptions:".
93 | Abort.
94 | Print Assumptions eqb_refl.
95 | Goal True.
96 | idtac " ".
97 |
98 | idtac "------------------- add_comm_informal --------------------".
99 | idtac " ".
100 |
101 | idtac "#> Manually graded: add_comm_informal".
102 | idtac "Advanced".
103 | idtac "Possible points: 2".
104 | print_manual_grade manual_grade_for_add_comm_informal.
105 | idtac " ".
106 |
107 | idtac "------------------- mul_comm --------------------".
108 | idtac " ".
109 |
110 | idtac "#> add_shuffle3".
111 | idtac "Possible points: 1".
112 | check_type @add_shuffle3 ((forall n m p : nat, n + (m + p) = m + (n + p))).
113 | idtac "Assumptions:".
114 | Abort.
115 | Print Assumptions add_shuffle3.
116 | Goal True.
117 | idtac " ".
118 |
119 | idtac "#> mul_comm".
120 | idtac "Possible points: 2".
121 | check_type @mul_comm ((forall m n : nat, m * n = n * m)).
122 | idtac "Assumptions:".
123 | Abort.
124 | Print Assumptions mul_comm.
125 | Goal True.
126 | idtac " ".
127 |
128 | idtac "------------------- binary_commute --------------------".
129 | idtac " ".
130 |
131 | idtac "#> bin_to_nat_pres_incr".
132 | idtac "Possible points: 3".
133 | check_type @bin_to_nat_pres_incr (
134 | (forall b : bin, bin_to_nat (incr b) = 1 + bin_to_nat b)).
135 | idtac "Assumptions:".
136 | Abort.
137 | Print Assumptions bin_to_nat_pres_incr.
138 | Goal True.
139 | idtac " ".
140 |
141 | idtac "------------------- nat_bin_nat --------------------".
142 | idtac " ".
143 |
144 | idtac "#> nat_bin_nat".
145 | idtac "Possible points: 3".
146 | check_type @nat_bin_nat ((forall n : nat, bin_to_nat (nat_to_bin n) = n)).
147 | idtac "Assumptions:".
148 | Abort.
149 | Print Assumptions nat_bin_nat.
150 | Goal True.
151 | idtac " ".
152 |
153 | idtac "------------------- double_bin --------------------".
154 | idtac " ".
155 |
156 | idtac "#> double_incr".
157 | idtac "Advanced".
158 | idtac "Possible points: 0.5".
159 | check_type @double_incr ((forall n : nat, double (S n) = S (S (double n)))).
160 | idtac "Assumptions:".
161 | Abort.
162 | Print Assumptions double_incr.
163 | Goal True.
164 | idtac " ".
165 |
166 | idtac "#> double_bin_zero".
167 | idtac "Advanced".
168 | idtac "Possible points: 0.5".
169 | check_type @double_bin_zero ((double_bin Z = Z)).
170 | idtac "Assumptions:".
171 | Abort.
172 | Print Assumptions double_bin_zero.
173 | Goal True.
174 | idtac " ".
175 |
176 | idtac "#> double_incr_bin".
177 | idtac "Advanced".
178 | idtac "Possible points: 1".
179 | check_type @double_incr_bin (
180 | (forall b : bin, double_bin (incr b) = incr (incr (double_bin b)))).
181 | idtac "Assumptions:".
182 | Abort.
183 | Print Assumptions double_incr_bin.
184 | Goal True.
185 | idtac " ".
186 |
187 | idtac "------------------- bin_nat_bin --------------------".
188 | idtac " ".
189 |
190 | idtac "#> bin_nat_bin".
191 | idtac "Advanced".
192 | idtac "Possible points: 6".
193 | check_type @bin_nat_bin ((forall b : bin, nat_to_bin (bin_to_nat b) = normalize b)).
194 | idtac "Assumptions:".
195 | Abort.
196 | Print Assumptions bin_nat_bin.
197 | Goal True.
198 | idtac " ".
199 |
200 | idtac " ".
201 |
202 | idtac "Max points - standard: 15".
203 | idtac "Max points - advanced: 25".
204 | idtac "".
205 | idtac "Allowed Axioms:".
206 | idtac "functional_extensionality".
207 | idtac "FunctionalExtensionality.functional_extensionality_dep".
208 | idtac "plus_le".
209 | idtac "le_trans".
210 | idtac "le_plus_l".
211 | idtac "add_le_cases".
212 | idtac "Sn_le_Sm__n_le_m".
213 | idtac "O_le_n".
214 | idtac "".
215 | idtac "".
216 | idtac "********** Summary **********".
217 | idtac "".
218 | idtac "Below is a summary of the automatically graded exercises that are incomplete.".
219 | idtac "".
220 | idtac "The output for each exercise can be any of the following:".
221 | idtac " - 'Closed under the global context', if it is complete".
222 | idtac " - 'MANUAL', if it is manually graded".
223 | idtac " - A list of pending axioms, containing unproven assumptions. In this case".
224 | idtac " the exercise is considered complete, if the axioms are all allowed.".
225 | idtac "".
226 | idtac "********** Standard **********".
227 | idtac "---------- mul_0_r ---------".
228 | Print Assumptions mul_0_r.
229 | idtac "---------- plus_n_Sm ---------".
230 | Print Assumptions plus_n_Sm.
231 | idtac "---------- add_comm ---------".
232 | Print Assumptions add_comm.
233 | idtac "---------- add_assoc ---------".
234 | Print Assumptions add_assoc.
235 | idtac "---------- double_plus ---------".
236 | Print Assumptions double_plus.
237 | idtac "---------- eqb_refl ---------".
238 | Print Assumptions eqb_refl.
239 | idtac "---------- add_shuffle3 ---------".
240 | Print Assumptions add_shuffle3.
241 | idtac "---------- mul_comm ---------".
242 | Print Assumptions mul_comm.
243 | idtac "---------- bin_to_nat_pres_incr ---------".
244 | Print Assumptions bin_to_nat_pres_incr.
245 | idtac "---------- nat_bin_nat ---------".
246 | Print Assumptions nat_bin_nat.
247 | idtac "".
248 | idtac "********** Advanced **********".
249 | idtac "---------- add_comm_informal ---------".
250 | idtac "MANUAL".
251 | idtac "---------- double_incr ---------".
252 | Print Assumptions double_incr.
253 | idtac "---------- double_bin_zero ---------".
254 | Print Assumptions double_bin_zero.
255 | idtac "---------- double_incr_bin ---------".
256 | Print Assumptions double_incr_bin.
257 | idtac "---------- bin_nat_bin ---------".
258 | Print Assumptions bin_nat_bin.
259 | Abort.
260 |
261 | (* 2022-06-16 11:18 *)
262 |
263 | (* 2022-06-16 11:18 *)
264 |
--------------------------------------------------------------------------------
/textbook/lf/TacticsTest.v:
--------------------------------------------------------------------------------
1 | Set Warnings "-notation-overridden,-parsing".
2 | From Coq Require Export String.
3 | From LF Require Import Tactics.
4 |
5 | Parameter MISSING: Type.
6 |
7 | Module Check.
8 |
9 | Ltac check_type A B :=
10 | match type of A with
11 | | context[MISSING] => idtac "Missing:" A
12 | | ?T => first [unify T B; idtac "Type: ok" | idtac "Type: wrong - should be (" B ")"]
13 | end.
14 |
15 | Ltac print_manual_grade A :=
16 | match eval compute in A with
17 | | Some (_ ?S ?C) =>
18 | idtac "Score:" S;
19 | match eval compute in C with
20 | | ""%string => idtac "Comment: None"
21 | | _ => idtac "Comment:" C
22 | end
23 | | None =>
24 | idtac "Score: Ungraded";
25 | idtac "Comment: None"
26 | end.
27 |
28 | End Check.
29 |
30 | From LF Require Import Tactics.
31 | Import Check.
32 |
33 | Goal True.
34 |
35 | idtac "------------------- apply_exercise1 --------------------".
36 | idtac " ".
37 |
38 | idtac "#> rev_exercise1".
39 | idtac "Possible points: 2".
40 | check_type @rev_exercise1 ((forall l l' : list nat, l = @rev nat l' -> l' = @rev nat l)).
41 | idtac "Assumptions:".
42 | Abort.
43 | Print Assumptions rev_exercise1.
44 | Goal True.
45 | idtac " ".
46 |
47 | idtac "------------------- injection_ex3 --------------------".
48 | idtac " ".
49 |
50 | idtac "#> injection_ex3".
51 | idtac "Possible points: 3".
52 | check_type @injection_ex3 (
53 | (forall (X : Type) (x y z : X) (l j : list X),
54 | x :: y :: l = z :: j -> j = z :: l -> x = y)).
55 | idtac "Assumptions:".
56 | Abort.
57 | Print Assumptions injection_ex3.
58 | Goal True.
59 | idtac " ".
60 |
61 | idtac "------------------- discriminate_ex3 --------------------".
62 | idtac " ".
63 |
64 | idtac "#> discriminate_ex3".
65 | idtac "Possible points: 1".
66 | check_type @discriminate_ex3 (
67 | (forall (X : Type) (x y z : X) (l : list X),
68 | list X -> x :: y :: l = [ ] -> x = z)).
69 | idtac "Assumptions:".
70 | Abort.
71 | Print Assumptions discriminate_ex3.
72 | Goal True.
73 | idtac " ".
74 |
75 | idtac "------------------- eqb_true --------------------".
76 | idtac " ".
77 |
78 | idtac "#> eqb_true".
79 | idtac "Possible points: 2".
80 | check_type @eqb_true ((forall n m : nat, (n =? m) = true -> n = m)).
81 | idtac "Assumptions:".
82 | Abort.
83 | Print Assumptions eqb_true.
84 | Goal True.
85 | idtac " ".
86 |
87 | idtac "------------------- eqb_true_informal --------------------".
88 | idtac " ".
89 |
90 | idtac "#> Manually graded: informal_proof".
91 | idtac "Advanced".
92 | idtac "Possible points: 2".
93 | print_manual_grade manual_grade_for_informal_proof.
94 | idtac " ".
95 |
96 | idtac "------------------- plus_n_n_injective --------------------".
97 | idtac " ".
98 |
99 | idtac "#> plus_n_n_injective".
100 | idtac "Possible points: 3".
101 | check_type @plus_n_n_injective ((forall n m : nat, n + n = m + m -> n = m)).
102 | idtac "Assumptions:".
103 | Abort.
104 | Print Assumptions plus_n_n_injective.
105 | Goal True.
106 | idtac " ".
107 |
108 | idtac "------------------- gen_dep_practice --------------------".
109 | idtac " ".
110 |
111 | idtac "#> nth_error_after_last".
112 | idtac "Possible points: 3".
113 | check_type @nth_error_after_last (
114 | (forall (n : nat) (X : Type) (l : list X),
115 | @length X l = n -> @nth_error X l n = @None X)).
116 | idtac "Assumptions:".
117 | Abort.
118 | Print Assumptions nth_error_after_last.
119 | Goal True.
120 | idtac " ".
121 |
122 | idtac "------------------- combine_split --------------------".
123 | idtac " ".
124 |
125 | idtac "#> combine_split".
126 | idtac "Possible points: 3".
127 | check_type @combine_split (
128 | (forall (X Y : Type) (l : list (X * Y)) (l1 : list X) (l2 : list Y),
129 | @split X Y l = (l1, l2) -> @combine X Y l1 l2 = l)).
130 | idtac "Assumptions:".
131 | Abort.
132 | Print Assumptions combine_split.
133 | Goal True.
134 | idtac " ".
135 |
136 | idtac "------------------- destruct_eqn_practice --------------------".
137 | idtac " ".
138 |
139 | idtac "#> bool_fn_applied_thrice".
140 | idtac "Possible points: 2".
141 | check_type @bool_fn_applied_thrice (
142 | (forall (f : bool -> bool) (b : bool), f (f (f b)) = f b)).
143 | idtac "Assumptions:".
144 | Abort.
145 | Print Assumptions bool_fn_applied_thrice.
146 | Goal True.
147 | idtac " ".
148 |
149 | idtac "------------------- eqb_sym --------------------".
150 | idtac " ".
151 |
152 | idtac "#> eqb_sym".
153 | idtac "Possible points: 3".
154 | check_type @eqb_sym ((forall n m : nat, (n =? m) = (m =? n))).
155 | idtac "Assumptions:".
156 | Abort.
157 | Print Assumptions eqb_sym.
158 | Goal True.
159 | idtac " ".
160 |
161 | idtac "------------------- split_combine --------------------".
162 | idtac " ".
163 |
164 | idtac "#> Manually graded: split_combine".
165 | idtac "Advanced".
166 | idtac "Possible points: 3".
167 | print_manual_grade manual_grade_for_split_combine.
168 | idtac " ".
169 |
170 | idtac "------------------- filter_exercise --------------------".
171 | idtac " ".
172 |
173 | idtac "#> filter_exercise".
174 | idtac "Advanced".
175 | idtac "Possible points: 3".
176 | check_type @filter_exercise (
177 | (forall (X : Type) (test : X -> bool) (x : X) (l lf : list X),
178 | @filter X test l = x :: lf -> test x = true)).
179 | idtac "Assumptions:".
180 | Abort.
181 | Print Assumptions filter_exercise.
182 | Goal True.
183 | idtac " ".
184 |
185 | idtac "------------------- forall_exists_challenge --------------------".
186 | idtac " ".
187 |
188 | idtac "#> existsb_existsb'".
189 | idtac "Advanced".
190 | idtac "Possible points: 6".
191 | check_type @existsb_existsb' (
192 | (forall (X : Type) (test : X -> bool) (l : list X),
193 | @existsb X test l = @existsb' X test l)).
194 | idtac "Assumptions:".
195 | Abort.
196 | Print Assumptions existsb_existsb'.
197 | Goal True.
198 | idtac " ".
199 |
200 | idtac " ".
201 |
202 | idtac "Max points - standard: 22".
203 | idtac "Max points - advanced: 36".
204 | idtac "".
205 | idtac "Allowed Axioms:".
206 | idtac "functional_extensionality".
207 | idtac "FunctionalExtensionality.functional_extensionality_dep".
208 | idtac "plus_le".
209 | idtac "le_trans".
210 | idtac "le_plus_l".
211 | idtac "add_le_cases".
212 | idtac "Sn_le_Sm__n_le_m".
213 | idtac "O_le_n".
214 | idtac "".
215 | idtac "".
216 | idtac "********** Summary **********".
217 | idtac "".
218 | idtac "Below is a summary of the automatically graded exercises that are incomplete.".
219 | idtac "".
220 | idtac "The output for each exercise can be any of the following:".
221 | idtac " - 'Closed under the global context', if it is complete".
222 | idtac " - 'MANUAL', if it is manually graded".
223 | idtac " - A list of pending axioms, containing unproven assumptions. In this case".
224 | idtac " the exercise is considered complete, if the axioms are all allowed.".
225 | idtac "".
226 | idtac "********** Standard **********".
227 | idtac "---------- rev_exercise1 ---------".
228 | Print Assumptions rev_exercise1.
229 | idtac "---------- injection_ex3 ---------".
230 | Print Assumptions injection_ex3.
231 | idtac "---------- discriminate_ex3 ---------".
232 | Print Assumptions discriminate_ex3.
233 | idtac "---------- eqb_true ---------".
234 | Print Assumptions eqb_true.
235 | idtac "---------- plus_n_n_injective ---------".
236 | Print Assumptions plus_n_n_injective.
237 | idtac "---------- nth_error_after_last ---------".
238 | Print Assumptions nth_error_after_last.
239 | idtac "---------- combine_split ---------".
240 | Print Assumptions combine_split.
241 | idtac "---------- bool_fn_applied_thrice ---------".
242 | Print Assumptions bool_fn_applied_thrice.
243 | idtac "---------- eqb_sym ---------".
244 | Print Assumptions eqb_sym.
245 | idtac "".
246 | idtac "********** Advanced **********".
247 | idtac "---------- informal_proof ---------".
248 | idtac "MANUAL".
249 | idtac "---------- split_combine ---------".
250 | idtac "MANUAL".
251 | idtac "---------- filter_exercise ---------".
252 | Print Assumptions filter_exercise.
253 | idtac "---------- existsb_existsb' ---------".
254 | Print Assumptions existsb_existsb'.
255 | Abort.
256 |
257 | (* 2022-06-16 11:18 *)
258 |
259 | (* 2022-06-16 11:18 *)
260 |
--------------------------------------------------------------------------------
/textbook/lf/AltAutoTest.v:
--------------------------------------------------------------------------------
1 | Set Warnings "-notation-overridden,-parsing".
2 | From Coq Require Export String.
3 | From LF Require Import AltAuto.
4 |
5 | Parameter MISSING: Type.
6 |
7 | Module Check.
8 |
9 | Ltac check_type A B :=
10 | match type of A with
11 | | context[MISSING] => idtac "Missing:" A
12 | | ?T => first [unify T B; idtac "Type: ok" | idtac "Type: wrong - should be (" B ")"]
13 | end.
14 |
15 | Ltac print_manual_grade A :=
16 | match eval compute in A with
17 | | Some (_ ?S ?C) =>
18 | idtac "Score:" S;
19 | match eval compute in C with
20 | | ""%string => idtac "Comment: None"
21 | | _ => idtac "Comment:" C
22 | end
23 | | None =>
24 | idtac "Score: Ungraded";
25 | idtac "Comment: None"
26 | end.
27 |
28 | End Check.
29 |
30 | From LF Require Import AltAuto.
31 | Import Check.
32 |
33 | Goal True.
34 |
35 | idtac "------------------- try_sequence --------------------".
36 | idtac " ".
37 |
38 | idtac "#> andb_eq_orb".
39 | idtac "Possible points: 1".
40 | check_type @andb_eq_orb (
41 | (forall b c : Basics.bool, Basics.andb b c = Basics.orb b c -> b = c)).
42 | idtac "Assumptions:".
43 | Abort.
44 | Print Assumptions andb_eq_orb.
45 | Goal True.
46 | idtac " ".
47 |
48 | idtac "#> add_assoc".
49 | idtac "Possible points: 1".
50 | check_type @add_assoc ((forall n m p : nat, n + (m + p) = n + m + p)).
51 | idtac "Assumptions:".
52 | Abort.
53 | Print Assumptions add_assoc.
54 | Goal True.
55 | idtac " ".
56 |
57 | idtac "#> nonzeros_app".
58 | idtac "Possible points: 1".
59 | check_type @nonzeros_app (
60 | (forall lst1 lst2 : Poly.list nat,
61 | nonzeros (@Poly.app nat lst1 lst2) =
62 | @Poly.app nat (nonzeros lst1) (nonzeros lst2))).
63 | idtac "Assumptions:".
64 | Abort.
65 | Print Assumptions nonzeros_app.
66 | Goal True.
67 | idtac " ".
68 |
69 | idtac "------------------- notry_sequence --------------------".
70 | idtac " ".
71 |
72 | idtac "#> add_assoc'".
73 | idtac "Possible points: 1".
74 | check_type @add_assoc' ((forall n m p : nat, n + (m + p) = n + m + p)).
75 | idtac "Assumptions:".
76 | Abort.
77 | Print Assumptions add_assoc'.
78 | Goal True.
79 | idtac " ".
80 |
81 | idtac "------------------- ev100 --------------------".
82 | idtac " ".
83 |
84 | idtac "#> ev100".
85 | idtac "Possible points: 1".
86 | check_type @ev100 ((IndProp.ev 100)).
87 | idtac "Assumptions:".
88 | Abort.
89 | Print Assumptions ev100.
90 | Goal True.
91 | idtac " ".
92 |
93 | idtac "------------------- re_opt --------------------".
94 | idtac " ".
95 |
96 | idtac "#> Manually graded: re_opt".
97 | idtac "Possible points: 6".
98 | print_manual_grade manual_grade_for_re_opt.
99 | idtac " ".
100 |
101 | idtac "------------------- automatic_solvers --------------------".
102 | idtac " ".
103 |
104 | idtac "#> plus_id_exercise_from_basics".
105 | idtac "Possible points: 0.5".
106 | check_type @plus_id_exercise_from_basics (
107 | (forall n m o : nat, n = m -> m = o -> n + m = m + o)).
108 | idtac "Assumptions:".
109 | Abort.
110 | Print Assumptions plus_id_exercise_from_basics.
111 | Goal True.
112 | idtac " ".
113 |
114 | idtac "#> add_assoc_from_induction".
115 | idtac "Possible points: 0.5".
116 | check_type @add_assoc_from_induction ((forall n m p : nat, n + (m + p) = n + m + p)).
117 | idtac "Assumptions:".
118 | Abort.
119 | Print Assumptions add_assoc_from_induction.
120 | Goal True.
121 | idtac " ".
122 |
123 | idtac "#> S_injective_from_tactics".
124 | idtac "Possible points: 0.5".
125 | check_type @S_injective_from_tactics ((forall n m : nat, S n = S m -> n = m)).
126 | idtac "Assumptions:".
127 | Abort.
128 | Print Assumptions S_injective_from_tactics.
129 | Goal True.
130 | idtac " ".
131 |
132 | idtac "#> or_distributes_over_and_from_logic".
133 | idtac "Possible points: 0.5".
134 | check_type @or_distributes_over_and_from_logic (
135 | (forall P Q R : Prop, P \/ Q /\ R <-> (P \/ Q) /\ (P \/ R))).
136 | idtac "Assumptions:".
137 | Abort.
138 | Print Assumptions or_distributes_over_and_from_logic.
139 | Goal True.
140 | idtac " ".
141 |
142 | idtac "------------------- re_opt_match_auto --------------------".
143 | idtac " ".
144 |
145 | idtac "#> Manually graded: re_opt_match''".
146 | idtac "Possible points: 3".
147 | print_manual_grade manual_grade_for_re_opt_match''.
148 | idtac " ".
149 |
150 | idtac "------------------- andb3_exchange --------------------".
151 | idtac " ".
152 |
153 | idtac "#> andb3_exchange".
154 | idtac "Possible points: 1".
155 | check_type @andb3_exchange (
156 | (forall b c d : Basics.bool,
157 | Basics.andb (Basics.andb b c) d = Basics.andb (Basics.andb b d) c)).
158 | idtac "Assumptions:".
159 | Abort.
160 | Print Assumptions andb3_exchange.
161 | Goal True.
162 | idtac " ".
163 |
164 | idtac "------------------- andb_true_elim2 --------------------".
165 | idtac " ".
166 |
167 | idtac "#> andb_true_elim2'".
168 | idtac "Possible points: 1.5".
169 | check_type @andb_true_elim2' (
170 | (forall b c : Basics.bool, Basics.andb b c = Basics.true -> c = Basics.true)).
171 | idtac "Assumptions:".
172 | Abort.
173 | Print Assumptions andb_true_elim2'.
174 | Goal True.
175 | idtac " ".
176 |
177 | idtac "#> andb3_exchange'".
178 | idtac "Possible points: 0.5".
179 | check_type @andb3_exchange' (
180 | (forall b c d : Basics.bool,
181 | Basics.andb (Basics.andb b c) d = Basics.andb (Basics.andb b d) c)).
182 | idtac "Assumptions:".
183 | Abort.
184 | Print Assumptions andb3_exchange'.
185 | Goal True.
186 | idtac " ".
187 |
188 | idtac "------------------- nand_intuition --------------------".
189 | idtac " ".
190 |
191 | idtac "#> Manually graded: nand_intuition".
192 | idtac "Advanced".
193 | idtac "Possible points: 6".
194 | print_manual_grade manual_grade_for_nand_intuition.
195 | idtac " ".
196 |
197 | idtac " ".
198 |
199 | idtac "Max points - standard: 19".
200 | idtac "Max points - advanced: 25".
201 | idtac "".
202 | idtac "Allowed Axioms:".
203 | idtac "functional_extensionality".
204 | idtac "FunctionalExtensionality.functional_extensionality_dep".
205 | idtac "plus_le".
206 | idtac "le_trans".
207 | idtac "le_plus_l".
208 | idtac "add_le_cases".
209 | idtac "Sn_le_Sm__n_le_m".
210 | idtac "O_le_n".
211 | idtac "".
212 | idtac "".
213 | idtac "********** Summary **********".
214 | idtac "".
215 | idtac "Below is a summary of the automatically graded exercises that are incomplete.".
216 | idtac "".
217 | idtac "The output for each exercise can be any of the following:".
218 | idtac " - 'Closed under the global context', if it is complete".
219 | idtac " - 'MANUAL', if it is manually graded".
220 | idtac " - A list of pending axioms, containing unproven assumptions. In this case".
221 | idtac " the exercise is considered complete, if the axioms are all allowed.".
222 | idtac "".
223 | idtac "********** Standard **********".
224 | idtac "---------- andb_eq_orb ---------".
225 | Print Assumptions andb_eq_orb.
226 | idtac "---------- add_assoc ---------".
227 | Print Assumptions add_assoc.
228 | idtac "---------- nonzeros_app ---------".
229 | Print Assumptions nonzeros_app.
230 | idtac "---------- add_assoc' ---------".
231 | Print Assumptions add_assoc'.
232 | idtac "---------- ev100 ---------".
233 | Print Assumptions ev100.
234 | idtac "---------- re_opt ---------".
235 | idtac "MANUAL".
236 | idtac "---------- plus_id_exercise_from_basics ---------".
237 | Print Assumptions plus_id_exercise_from_basics.
238 | idtac "---------- add_assoc_from_induction ---------".
239 | Print Assumptions add_assoc_from_induction.
240 | idtac "---------- S_injective_from_tactics ---------".
241 | Print Assumptions S_injective_from_tactics.
242 | idtac "---------- or_distributes_over_and_from_logic ---------".
243 | Print Assumptions or_distributes_over_and_from_logic.
244 | idtac "---------- re_opt_match'' ---------".
245 | idtac "MANUAL".
246 | idtac "---------- andb3_exchange ---------".
247 | Print Assumptions andb3_exchange.
248 | idtac "---------- andb_true_elim2' ---------".
249 | Print Assumptions andb_true_elim2'.
250 | idtac "---------- andb3_exchange' ---------".
251 | Print Assumptions andb3_exchange'.
252 | idtac "".
253 | idtac "********** Advanced **********".
254 | idtac "---------- nand_intuition ---------".
255 | idtac "MANUAL".
256 | Abort.
257 |
258 | (* 2022-06-16 11:23 *)
259 |
260 | (* 2022-06-16 11:23 *)
261 |
--------------------------------------------------------------------------------
/textbook/lf/BasicsTest.v:
--------------------------------------------------------------------------------
1 | Set Warnings "-notation-overridden,-parsing".
2 | From Coq Require Export String.
3 | From LF Require Import Basics.
4 |
5 | Parameter MISSING: Type.
6 |
7 | Module Check.
8 |
9 | Ltac check_type A B :=
10 | match type of A with
11 | | context[MISSING] => idtac "Missing:" A
12 | | ?T => first [unify T B; idtac "Type: ok" | idtac "Type: wrong - should be (" B ")"]
13 | end.
14 |
15 | Ltac print_manual_grade A :=
16 | match eval compute in A with
17 | | Some (_ ?S ?C) =>
18 | idtac "Score:" S;
19 | match eval compute in C with
20 | | ""%string => idtac "Comment: None"
21 | | _ => idtac "Comment:" C
22 | end
23 | | None =>
24 | idtac "Score: Ungraded";
25 | idtac "Comment: None"
26 | end.
27 |
28 | End Check.
29 |
30 | From LF Require Import Basics.
31 | Import Check.
32 |
33 | Goal True.
34 |
35 | idtac "------------------- nandb --------------------".
36 | idtac " ".
37 |
38 | idtac "#> test_nandb4".
39 | idtac "Possible points: 1".
40 | check_type @test_nandb4 ((nandb true true = false)).
41 | idtac "Assumptions:".
42 | Abort.
43 | Print Assumptions test_nandb4.
44 | Goal True.
45 | idtac " ".
46 |
47 | idtac "------------------- andb3 --------------------".
48 | idtac " ".
49 |
50 | idtac "#> test_andb34".
51 | idtac "Possible points: 1".
52 | check_type @test_andb34 ((andb3 true true false = false)).
53 | idtac "Assumptions:".
54 | Abort.
55 | Print Assumptions test_andb34.
56 | Goal True.
57 | idtac " ".
58 |
59 | idtac "------------------- factorial --------------------".
60 | idtac " ".
61 |
62 | idtac "#> test_factorial2".
63 | idtac "Possible points: 1".
64 | check_type @test_factorial2 ((factorial 5 = 10 * 12)).
65 | idtac "Assumptions:".
66 | Abort.
67 | Print Assumptions test_factorial2.
68 | Goal True.
69 | idtac " ".
70 |
71 | idtac "------------------- ltb --------------------".
72 | idtac " ".
73 |
74 | idtac "#> test_ltb3".
75 | idtac "Possible points: 1".
76 | check_type @test_ltb3 (((4 2) = false)).
77 | idtac "Assumptions:".
78 | Abort.
79 | Print Assumptions test_ltb3.
80 | Goal True.
81 | idtac " ".
82 |
83 | idtac "------------------- plus_id_exercise --------------------".
84 | idtac " ".
85 |
86 | idtac "#> plus_id_exercise".
87 | idtac "Possible points: 1".
88 | check_type @plus_id_exercise ((forall n m o : nat, n = m -> m = o -> n + m = m + o)).
89 | idtac "Assumptions:".
90 | Abort.
91 | Print Assumptions plus_id_exercise.
92 | Goal True.
93 | idtac " ".
94 |
95 | idtac "------------------- mult_n_1 --------------------".
96 | idtac " ".
97 |
98 | idtac "#> mult_n_1".
99 | idtac "Possible points: 1".
100 | check_type @mult_n_1 ((forall p : nat, p * 1 = p)).
101 | idtac "Assumptions:".
102 | Abort.
103 | Print Assumptions mult_n_1.
104 | Goal True.
105 | idtac " ".
106 |
107 | idtac "------------------- andb_true_elim2 --------------------".
108 | idtac " ".
109 |
110 | idtac "#> andb_true_elim2".
111 | idtac "Possible points: 2".
112 | check_type @andb_true_elim2 ((forall b c : bool, b && c = true -> c = true)).
113 | idtac "Assumptions:".
114 | Abort.
115 | Print Assumptions andb_true_elim2.
116 | Goal True.
117 | idtac " ".
118 |
119 | idtac "------------------- zero_nbeq_plus_1 --------------------".
120 | idtac " ".
121 |
122 | idtac "#> zero_nbeq_plus_1".
123 | idtac "Possible points: 1".
124 | check_type @zero_nbeq_plus_1 ((forall n : nat, (0 =? n + 1) = false)).
125 | idtac "Assumptions:".
126 | Abort.
127 | Print Assumptions zero_nbeq_plus_1.
128 | Goal True.
129 | idtac " ".
130 |
131 | idtac "------------------- identity_fn_applied_twice --------------------".
132 | idtac " ".
133 |
134 | idtac "#> identity_fn_applied_twice".
135 | idtac "Possible points: 1".
136 | check_type @identity_fn_applied_twice (
137 | (forall f : bool -> bool,
138 | (forall x : bool, f x = x) -> forall b : bool, f (f b) = b)).
139 | idtac "Assumptions:".
140 | Abort.
141 | Print Assumptions identity_fn_applied_twice.
142 | Goal True.
143 | idtac " ".
144 |
145 | idtac "------------------- negation_fn_applied_twice --------------------".
146 | idtac " ".
147 |
148 | idtac "#> Manually graded: negation_fn_applied_twice".
149 | idtac "Possible points: 1".
150 | print_manual_grade manual_grade_for_negation_fn_applied_twice.
151 | idtac " ".
152 |
153 | idtac "------------------- binary --------------------".
154 | idtac " ".
155 |
156 | idtac "#> test_bin_incr1".
157 | idtac "Possible points: 0.5".
158 | check_type @test_bin_incr1 ((incr (B1 Z) = B0 (B1 Z))).
159 | idtac "Assumptions:".
160 | Abort.
161 | Print Assumptions test_bin_incr1.
162 | Goal True.
163 | idtac " ".
164 |
165 | idtac "#> test_bin_incr2".
166 | idtac "Possible points: 0.5".
167 | check_type @test_bin_incr2 ((incr (B0 (B1 Z)) = B1 (B1 Z))).
168 | idtac "Assumptions:".
169 | Abort.
170 | Print Assumptions test_bin_incr2.
171 | Goal True.
172 | idtac " ".
173 |
174 | idtac "#> test_bin_incr3".
175 | idtac "Possible points: 0.5".
176 | check_type @test_bin_incr3 ((incr (B1 (B1 Z)) = B0 (B0 (B1 Z)))).
177 | idtac "Assumptions:".
178 | Abort.
179 | Print Assumptions test_bin_incr3.
180 | Goal True.
181 | idtac " ".
182 |
183 | idtac "#> test_bin_incr4".
184 | idtac "Possible points: 0.5".
185 | check_type @test_bin_incr4 ((bin_to_nat (B0 (B1 Z)) = 2)).
186 | idtac "Assumptions:".
187 | Abort.
188 | Print Assumptions test_bin_incr4.
189 | Goal True.
190 | idtac " ".
191 |
192 | idtac "#> test_bin_incr5".
193 | idtac "Possible points: 0.5".
194 | check_type @test_bin_incr5 ((bin_to_nat (incr (B1 Z)) = 1 + bin_to_nat (B1 Z))).
195 | idtac "Assumptions:".
196 | Abort.
197 | Print Assumptions test_bin_incr5.
198 | Goal True.
199 | idtac " ".
200 |
201 | idtac "#> test_bin_incr6".
202 | idtac "Possible points: 0.5".
203 | check_type @test_bin_incr6 ((bin_to_nat (incr (incr (B1 Z))) = 2 + bin_to_nat (B1 Z))).
204 | idtac "Assumptions:".
205 | Abort.
206 | Print Assumptions test_bin_incr6.
207 | Goal True.
208 | idtac " ".
209 |
210 | idtac " ".
211 |
212 | idtac "Max points - standard: 14".
213 | idtac "Max points - advanced: 14".
214 | idtac "".
215 | idtac "Allowed Axioms:".
216 | idtac "functional_extensionality".
217 | idtac "FunctionalExtensionality.functional_extensionality_dep".
218 | idtac "plus_le".
219 | idtac "le_trans".
220 | idtac "le_plus_l".
221 | idtac "add_le_cases".
222 | idtac "Sn_le_Sm__n_le_m".
223 | idtac "O_le_n".
224 | idtac "".
225 | idtac "".
226 | idtac "********** Summary **********".
227 | idtac "".
228 | idtac "Below is a summary of the automatically graded exercises that are incomplete.".
229 | idtac "".
230 | idtac "The output for each exercise can be any of the following:".
231 | idtac " - 'Closed under the global context', if it is complete".
232 | idtac " - 'MANUAL', if it is manually graded".
233 | idtac " - A list of pending axioms, containing unproven assumptions. In this case".
234 | idtac " the exercise is considered complete, if the axioms are all allowed.".
235 | idtac "".
236 | idtac "********** Standard **********".
237 | idtac "---------- test_nandb4 ---------".
238 | Print Assumptions test_nandb4.
239 | idtac "---------- test_andb34 ---------".
240 | Print Assumptions test_andb34.
241 | idtac "---------- test_factorial2 ---------".
242 | Print Assumptions test_factorial2.
243 | idtac "---------- test_ltb3 ---------".
244 | Print Assumptions test_ltb3.
245 | idtac "---------- plus_id_exercise ---------".
246 | Print Assumptions plus_id_exercise.
247 | idtac "---------- mult_n_1 ---------".
248 | Print Assumptions mult_n_1.
249 | idtac "---------- andb_true_elim2 ---------".
250 | Print Assumptions andb_true_elim2.
251 | idtac "---------- zero_nbeq_plus_1 ---------".
252 | Print Assumptions zero_nbeq_plus_1.
253 | idtac "---------- identity_fn_applied_twice ---------".
254 | Print Assumptions identity_fn_applied_twice.
255 | idtac "---------- negation_fn_applied_twice ---------".
256 | idtac "MANUAL".
257 | idtac "---------- test_bin_incr1 ---------".
258 | Print Assumptions test_bin_incr1.
259 | idtac "---------- test_bin_incr2 ---------".
260 | Print Assumptions test_bin_incr2.
261 | idtac "---------- test_bin_incr3 ---------".
262 | Print Assumptions test_bin_incr3.
263 | idtac "---------- test_bin_incr4 ---------".
264 | Print Assumptions test_bin_incr4.
265 | idtac "---------- test_bin_incr5 ---------".
266 | Print Assumptions test_bin_incr5.
267 | idtac "---------- test_bin_incr6 ---------".
268 | Print Assumptions test_bin_incr6.
269 | idtac "".
270 | idtac "********** Advanced **********".
271 | Abort.
272 |
273 | (* 2022-06-16 11:18 *)
274 |
275 | (* 2022-06-16 11:18 *)
276 |
--------------------------------------------------------------------------------
/notes/lf/Induction.v:
--------------------------------------------------------------------------------
1 | (** * Induction: Proof by Induction *)
2 |
3 | (** Previous proof techniques:
4 |
5 | - reflexivity of equality [reflexivity]
6 | - substitution of equals for equals [rewrite]
7 | - case analysis [destruct]
8 |
9 | Next: _induction_ on data types. *)
10 |
11 | (* ################################################################# *)
12 | (** * Separate Compilation *)
13 |
14 | (** Coq will first need to compile [Basics.v] into [Basics.vo]
15 | so it can be imported here -- detailed instructions are in the
16 | full version of this chapter. To create a Makefile, run
17 | [coq_makefile -f _CoqProject -o Makefile *.v]. *)
18 |
19 | From LF Require Export Basics.
20 |
21 | (* ################################################################# *)
22 | (** * Proof by Induction *)
23 |
24 | (** We can prove that [0] is a neutral
25 | element for [+] on the _left_
26 | using just [reflexivity]. *)
27 |
28 | Example add_0_l : forall n : nat,
29 | 0 + n = n.
30 | Proof. reflexivity. Qed.
31 |
32 | (** But the proof that it is also a neutral
33 | element on the _right_ ... *)
34 |
35 | Theorem add_0_r_firsttry : forall n:nat,
36 | n + 0 = n.
37 | (** ... gets stuck. *)
38 | Proof.
39 | intros n.
40 | simpl. (* Does nothing! *)
41 | Abort.
42 |
43 | (** And reasoning by cases using [destruct n] doesn't get us much
44 | further: the branch of the case analysis where we assume [n = 0]
45 | goes through fine, but in the branch where [n = S n'] for some [n'] we
46 | get stuck in exactly the same way. *)
47 |
48 | Theorem add_0_r_secondtry : forall n:nat,
49 | n + 0 = n.
50 | Proof.
51 | intros n. destruct n as [| n'] eqn:E.
52 | - (* n = 0 *)
53 | reflexivity. (* so far so good... *)
54 | - (* n = S n' *)
55 | simpl. (* ...but here we are stuck again *)
56 | Abort.
57 |
58 | (** We need a bigger hammer: the _principle of induction_ over
59 | natural numbers...
60 |
61 | - If [P(n)] is some proposition involving a natural number [n],
62 | and we want to show that [P] holds for _all_ numbers, we can
63 | reason like this:
64 |
65 | - show that [P(O)] holds
66 |
67 | - show that, if [P(n')] holds, then so does [P(S n')]
68 |
69 | - conclude that [P(n)] holds for all [n].
70 |
71 | For example... *)
72 |
73 | Theorem add_0_r : forall n:nat, n + 0 = n.
74 | Proof.
75 | intros n. induction n as [| n' IHn'].
76 | - (* n = 0 *) reflexivity.
77 | - (* n = S n' *) simpl. rewrite -> IHn'. reflexivity. Qed.
78 |
79 | (** Let's try this one together: *)
80 |
81 | Theorem minus_n_n : forall n,
82 | n - n = 0.
83 | Proof.
84 | (* WORK IN CLASS *) Admitted.
85 |
86 | (** Here's another related fact about addition, which we'll
87 | need later. *)
88 |
89 | Theorem add_comm : forall n m : nat,
90 | n + m = m + n.
91 | (* FILL IN HERE *) Admitted.
92 | (* ################################################################# *)
93 | (** * Proofs Within Proofs *)
94 |
95 | (** Here's a way to use an in-line assertion instead of a separate
96 | lemma.
97 |
98 | New tactic: [assert]. *)
99 |
100 | Theorem mult_0_plus' : forall n m : nat,
101 | (n + 0 + 0) * m = n * m.
102 | Proof.
103 | intros n m.
104 | assert (H: n + 0 + 0 = n).
105 | { rewrite add_comm. simpl. rewrite add_comm. reflexivity. }
106 | rewrite -> H.
107 | reflexivity. Qed.
108 |
109 | Theorem plus_rearrange_firsttry : forall n m p q : nat,
110 | (n + m) + (p + q) = (m + n) + (p + q).
111 | Proof.
112 | intros n m p q.
113 | (* We just need to swap (n + m) for (m + n)... seems
114 | like add_comm should do the trick! *)
115 | rewrite add_comm.
116 | (* Doesn't work... Coq rewrites the wrong plus! :-( *)
117 | Abort.
118 |
119 | (** To use [add_comm] at the point where we need it, we can introduce
120 | a local lemma stating that [n + m = m + n] (for the _particular_ [m]
121 | and [n] that we are talking about here), prove this lemma using
122 | [add_comm], and then use it to do the desired rewrite. *)
123 |
124 | Theorem plus_rearrange : forall n m p q : nat,
125 | (n + m) + (p + q) = (m + n) + (p + q).
126 | Proof.
127 | intros n m p q.
128 | assert (H: n + m = m + n).
129 | { rewrite add_comm. reflexivity. }
130 | rewrite H. reflexivity. Qed.
131 |
132 | (* ################################################################# *)
133 | (** * Formal vs. Informal Proof *)
134 |
135 | (** "_Informal proofs are algorithms; formal proofs are code_." *)
136 |
137 | (** An unreadable formal proof: *)
138 |
139 | Theorem add_assoc' : forall n m p : nat,
140 | n + (m + p) = (n + m) + p.
141 | Proof. intros n m p. induction n as [| n' IHn']. reflexivity.
142 | simpl. rewrite IHn'. reflexivity. Qed.
143 |
144 | (** Comments and bullets can make things clearer... *)
145 |
146 | Theorem add_assoc'' : forall n m p : nat,
147 | n + (m + p) = (n + m) + p.
148 | Proof.
149 | intros n m p. induction n as [| n' IHn'].
150 | - (* n = 0 *)
151 | reflexivity.
152 | - (* n = S n' *)
153 | simpl. rewrite IHn'. reflexivity. Qed.
154 |
155 | (** ... but it's still nowhere near as readable for a human as
156 | a careful informal proof: *)
157 |
158 | (** - _Theorem_: For any [n], [m] and [p],
159 |
160 | n + (m + p) = (n + m) + p.
161 |
162 | _Proof_: By induction on [n].
163 |
164 | - First, suppose [n = 0]. We must show that
165 |
166 | 0 + (m + p) = (0 + m) + p.
167 |
168 | This follows directly from the definition of [+].
169 |
170 | - Next, suppose [n = S n'], where
171 |
172 | n' + (m + p) = (n' + m) + p.
173 |
174 | We must now show that
175 |
176 | (S n') + (m + p) = ((S n') + m) + p.
177 |
178 | By the definition of [+], this follows from
179 |
180 | S (n' + (m + p)) = S ((n' + m) + p),
181 |
182 | which is immediate from the induction hypothesis. _Qed_. *)
183 |
184 | (* ################################################################# *)
185 | (** * More Exercises *)
186 | (* These additional exercises will be used in later chapters. We
187 | don't need to work them in class. *)
188 |
189 | Theorem even_S : forall n : nat,
190 | even (S n) = negb (even n).
191 | Proof.
192 | (* FILL IN HERE *) Admitted.
193 | (** [] *)
194 |
195 | Theorem eqb_refl : forall n : nat,
196 | (n =? n) = true.
197 | Proof. (* FILL IN HERE *) Admitted.
198 | (** [] *)
199 |
200 | (** **** Exercise: 3 stars, standard, especially useful (mul_comm)
201 |
202 | Use [assert] to help prove [add_shuffle3]. You don't need to
203 | use induction yet. *)
204 |
205 | Theorem add_shuffle3 : forall n m p : nat,
206 | n + (m + p) = m + (n + p).
207 | Proof.
208 | (* FILL IN HERE *) Admitted.
209 |
210 | (** Now prove commutativity of multiplication. You will probably want
211 | to look for (or define and prove) a "helper" theorem to be used in
212 | the proof of this one. Hint: what is [n * (1 + k)]? *)
213 |
214 | Theorem mul_comm : forall m n : nat,
215 | m * n = n * m.
216 | Proof.
217 | (* FILL IN HERE *) Admitted.
218 | (** [] *)
219 |
220 | (** **** Exercise: 2 stars, standard, optional (plus_leb_compat_l)
221 |
222 | If a hypothesis has the form [H: P -> a = b], then [rewrite H] will
223 | rewrite [a] to [b] in the goal, and add [P] as a new subgoal. Use
224 | that in the inductive step of this exercise. *)
225 |
226 | Check leb.
227 |
228 | Theorem plus_leb_compat_l : forall n m p : nat,
229 | n <=? m = true -> (p + n) <=? (p + m) = true.
230 | Proof.
231 | (* FILL IN HERE *) Admitted.
232 |
233 | (** [] *)
234 |
235 | (** **** Exercise: 3 stars, standard, optional (more_exercises)
236 |
237 | Take a piece of paper. For each of the following theorems, first
238 | _think_ about whether (a) it can be proved using only
239 | simplification and rewriting, (b) it also requires case
240 | analysis ([destruct]), or (c) it also requires induction. Write
241 | down your prediction. Then fill in the proof. (There is no need
242 | to turn in your piece of paper; this is just to encourage you to
243 | reflect before you hack!) *)
244 |
245 | Theorem leb_refl : forall n:nat,
246 | (n <=? n) = true.
247 | Proof.
248 | (* FILL IN HERE *) Admitted.
249 |
250 | Theorem zero_neqb_S : forall n:nat,
251 | 0 =? (S n) = false.
252 | Proof.
253 | (* FILL IN HERE *) Admitted.
254 |
255 | Theorem andb_false_r : forall b : bool,
256 | andb b false = false.
257 | Proof.
258 | (* FILL IN HERE *) Admitted.
259 |
260 | Theorem S_neqb_0 : forall n:nat,
261 | (S n) =? 0 = false.
262 | Proof.
263 | (* FILL IN HERE *) Admitted.
264 |
265 | Theorem mult_1_l : forall n:nat, 1 * n = n.
266 | Proof.
267 | (* FILL IN HERE *) Admitted.
268 |
269 | Theorem all3_spec : forall b c : bool,
270 | orb
271 | (andb b c)
272 | (orb (negb b)
273 | (negb c))
274 | = true.
275 | Proof.
276 | (* FILL IN HERE *) Admitted.
277 |
278 | Theorem mult_plus_distr_r : forall n m p : nat,
279 | (n + m) * p = (n * p) + (m * p).
280 | Proof.
281 | (* FILL IN HERE *) Admitted.
282 |
283 | Theorem mult_assoc : forall n m p : nat,
284 | n * (m * p) = (n * m) * p.
285 | Proof.
286 | (* FILL IN HERE *) Admitted.
287 | (** [] *)
288 |
--------------------------------------------------------------------------------
/textbook/lf/IndPropTest.v:
--------------------------------------------------------------------------------
1 | Set Warnings "-notation-overridden,-parsing".
2 | From Coq Require Export String.
3 | From LF Require Import IndProp.
4 |
5 | Parameter MISSING: Type.
6 |
7 | Module Check.
8 |
9 | Ltac check_type A B :=
10 | match type of A with
11 | | context[MISSING] => idtac "Missing:" A
12 | | ?T => first [unify T B; idtac "Type: ok" | idtac "Type: wrong - should be (" B ")"]
13 | end.
14 |
15 | Ltac print_manual_grade A :=
16 | match eval compute in A with
17 | | Some (_ ?S ?C) =>
18 | idtac "Score:" S;
19 | match eval compute in C with
20 | | ""%string => idtac "Comment: None"
21 | | _ => idtac "Comment:" C
22 | end
23 | | None =>
24 | idtac "Score: Ungraded";
25 | idtac "Comment: None"
26 | end.
27 |
28 | End Check.
29 |
30 | From LF Require Import IndProp.
31 | Import Check.
32 |
33 | Goal True.
34 |
35 | idtac "------------------- ev_double --------------------".
36 | idtac " ".
37 |
38 | idtac "#> ev_double".
39 | idtac "Possible points: 1".
40 | check_type @ev_double ((forall n : nat, ev (double n))).
41 | idtac "Assumptions:".
42 | Abort.
43 | Print Assumptions ev_double.
44 | Goal True.
45 | idtac " ".
46 |
47 | idtac "------------------- inversion_practice --------------------".
48 | idtac " ".
49 |
50 | idtac "#> SSSSev__even".
51 | idtac "Possible points: 1".
52 | check_type @SSSSev__even ((forall n : nat, ev (S (S (S (S n)))) -> ev n)).
53 | idtac "Assumptions:".
54 | Abort.
55 | Print Assumptions SSSSev__even.
56 | Goal True.
57 | idtac " ".
58 |
59 | idtac "------------------- ev5_nonsense --------------------".
60 | idtac " ".
61 |
62 | idtac "#> ev5_nonsense".
63 | idtac "Possible points: 1".
64 | check_type @ev5_nonsense ((ev 5 -> 2 + 2 = 9)).
65 | idtac "Assumptions:".
66 | Abort.
67 | Print Assumptions ev5_nonsense.
68 | Goal True.
69 | idtac " ".
70 |
71 | idtac "------------------- ev_sum --------------------".
72 | idtac " ".
73 |
74 | idtac "#> ev_sum".
75 | idtac "Possible points: 2".
76 | check_type @ev_sum ((forall n m : nat, ev n -> ev m -> ev (n + m))).
77 | idtac "Assumptions:".
78 | Abort.
79 | Print Assumptions ev_sum.
80 | Goal True.
81 | idtac " ".
82 |
83 | idtac "------------------- ev_ev__ev --------------------".
84 | idtac " ".
85 |
86 | idtac "#> ev_ev__ev".
87 | idtac "Advanced".
88 | idtac "Possible points: 3".
89 | check_type @ev_ev__ev ((forall n m : nat, ev (n + m) -> ev n -> ev m)).
90 | idtac "Assumptions:".
91 | Abort.
92 | Print Assumptions ev_ev__ev.
93 | Goal True.
94 | idtac " ".
95 |
96 | idtac "------------------- R_provability --------------------".
97 | idtac " ".
98 |
99 | idtac "#> Manually graded: R.R_provability".
100 | idtac "Possible points: 3".
101 | print_manual_grade R.manual_grade_for_R_provability.
102 | idtac " ".
103 |
104 | idtac "------------------- subsequence --------------------".
105 | idtac " ".
106 |
107 | idtac "#> subseq_refl".
108 | idtac "Advanced".
109 | idtac "Possible points: 1".
110 | check_type @subseq_refl ((forall l : list nat, subseq l l)).
111 | idtac "Assumptions:".
112 | Abort.
113 | Print Assumptions subseq_refl.
114 | Goal True.
115 | idtac " ".
116 |
117 | idtac "#> subseq_app".
118 | idtac "Advanced".
119 | idtac "Possible points: 1".
120 | check_type @subseq_app (
121 | (forall l1 l2 l3 : list nat, subseq l1 l2 -> subseq l1 (l2 ++ l3))).
122 | idtac "Assumptions:".
123 | Abort.
124 | Print Assumptions subseq_app.
125 | Goal True.
126 | idtac " ".
127 |
128 | idtac "#> subseq_trans".
129 | idtac "Advanced".
130 | idtac "Possible points: 1".
131 | check_type @subseq_trans (
132 | (forall l1 l2 l3 : list nat, subseq l1 l2 -> subseq l2 l3 -> subseq l1 l3)).
133 | idtac "Assumptions:".
134 | Abort.
135 | Print Assumptions subseq_trans.
136 | Goal True.
137 | idtac " ".
138 |
139 | idtac "------------------- exp_match_ex1 --------------------".
140 | idtac " ".
141 |
142 | idtac "#> empty_is_empty".
143 | idtac "Possible points: 1".
144 | check_type @empty_is_empty ((forall (T : Type) (s : list T), ~ (s =~ @EmptySet T))).
145 | idtac "Assumptions:".
146 | Abort.
147 | Print Assumptions empty_is_empty.
148 | Goal True.
149 | idtac " ".
150 |
151 | idtac "#> MUnion'".
152 | idtac "Possible points: 1".
153 | check_type @MUnion' (
154 | (forall (T : Type) (s : list T) (re1 re2 : reg_exp T),
155 | s =~ re1 \/ s =~ re2 -> s =~ @Union T re1 re2)).
156 | idtac "Assumptions:".
157 | Abort.
158 | Print Assumptions MUnion'.
159 | Goal True.
160 | idtac " ".
161 |
162 | idtac "#> MStar'".
163 | idtac "Possible points: 1".
164 | check_type @MStar' (
165 | (forall (T : Type) (ss : list (list T)) (re : reg_exp T),
166 | (forall s : list T, @In (list T) s ss -> s =~ re) ->
167 | @fold (list T) (list T) (@app T) ss [ ] =~ @Star T re)).
168 | idtac "Assumptions:".
169 | Abort.
170 | Print Assumptions MStar'.
171 | Goal True.
172 | idtac " ".
173 |
174 | idtac "------------------- re_not_empty --------------------".
175 | idtac " ".
176 |
177 | idtac "#> re_not_empty".
178 | idtac "Possible points: 3".
179 | check_type @re_not_empty ((forall T : Type, reg_exp T -> bool)).
180 | idtac "Assumptions:".
181 | Abort.
182 | Print Assumptions re_not_empty.
183 | Goal True.
184 | idtac " ".
185 |
186 | idtac "#> re_not_empty_correct".
187 | idtac "Possible points: 3".
188 | check_type @re_not_empty_correct (
189 | (forall (T : Type) (re : reg_exp T),
190 | (exists s : list T, s =~ re) <-> @re_not_empty T re = true)).
191 | idtac "Assumptions:".
192 | Abort.
193 | Print Assumptions re_not_empty_correct.
194 | Goal True.
195 | idtac " ".
196 |
197 | idtac "------------------- weak_pumping --------------------".
198 | idtac " ".
199 |
200 | idtac "#> Pumping.weak_pumping".
201 | idtac "Advanced".
202 | idtac "Possible points: 10".
203 | check_type @Pumping.weak_pumping (
204 | (forall (T : Type) (re : reg_exp T) (s : list T),
205 | s =~ re ->
206 | @Pumping.pumping_constant T re <= @length T s ->
207 | exists s1 s2 s3 : list T,
208 | s = s1 ++ s2 ++ s3 /\
209 | s2 <> [ ] /\ (forall m : nat, s1 ++ @Pumping.napp T m s2 ++ s3 =~ re))).
210 | idtac "Assumptions:".
211 | Abort.
212 | Print Assumptions Pumping.weak_pumping.
213 | Goal True.
214 | idtac " ".
215 |
216 | idtac "------------------- reflect_iff --------------------".
217 | idtac " ".
218 |
219 | idtac "#> reflect_iff".
220 | idtac "Possible points: 2".
221 | check_type @reflect_iff ((forall (P : Prop) (b : bool), reflect P b -> P <-> b = true)).
222 | idtac "Assumptions:".
223 | Abort.
224 | Print Assumptions reflect_iff.
225 | Goal True.
226 | idtac " ".
227 |
228 | idtac "------------------- eqbP_practice --------------------".
229 | idtac " ".
230 |
231 | idtac "#> eqbP_practice".
232 | idtac "Possible points: 3".
233 | check_type @eqbP_practice (
234 | (forall (n : nat) (l : list nat), count n l = 0 -> ~ @In nat n l)).
235 | idtac "Assumptions:".
236 | Abort.
237 | Print Assumptions eqbP_practice.
238 | Goal True.
239 | idtac " ".
240 |
241 | idtac "------------------- nostutter_defn --------------------".
242 | idtac " ".
243 |
244 | idtac "#> Manually graded: nostutter".
245 | idtac "Possible points: 3".
246 | print_manual_grade manual_grade_for_nostutter.
247 | idtac " ".
248 |
249 | idtac "------------------- filter_challenge --------------------".
250 | idtac " ".
251 |
252 | idtac "#> Manually graded: filter_challenge".
253 | idtac "Advanced".
254 | idtac "Possible points: 6".
255 | print_manual_grade manual_grade_for_filter_challenge.
256 | idtac " ".
257 |
258 | idtac " ".
259 |
260 | idtac "Max points - standard: 25".
261 | idtac "Max points - advanced: 47".
262 | idtac "".
263 | idtac "Allowed Axioms:".
264 | idtac "functional_extensionality".
265 | idtac "FunctionalExtensionality.functional_extensionality_dep".
266 | idtac "plus_le".
267 | idtac "le_trans".
268 | idtac "le_plus_l".
269 | idtac "add_le_cases".
270 | idtac "Sn_le_Sm__n_le_m".
271 | idtac "O_le_n".
272 | idtac "".
273 | idtac "".
274 | idtac "********** Summary **********".
275 | idtac "".
276 | idtac "Below is a summary of the automatically graded exercises that are incomplete.".
277 | idtac "".
278 | idtac "The output for each exercise can be any of the following:".
279 | idtac " - 'Closed under the global context', if it is complete".
280 | idtac " - 'MANUAL', if it is manually graded".
281 | idtac " - A list of pending axioms, containing unproven assumptions. In this case".
282 | idtac " the exercise is considered complete, if the axioms are all allowed.".
283 | idtac "".
284 | idtac "********** Standard **********".
285 | idtac "---------- ev_double ---------".
286 | Print Assumptions ev_double.
287 | idtac "---------- SSSSev__even ---------".
288 | Print Assumptions SSSSev__even.
289 | idtac "---------- ev5_nonsense ---------".
290 | Print Assumptions ev5_nonsense.
291 | idtac "---------- ev_sum ---------".
292 | Print Assumptions ev_sum.
293 | idtac "---------- R_provability ---------".
294 | idtac "MANUAL".
295 | idtac "---------- empty_is_empty ---------".
296 | Print Assumptions empty_is_empty.
297 | idtac "---------- MUnion' ---------".
298 | Print Assumptions MUnion'.
299 | idtac "---------- MStar' ---------".
300 | Print Assumptions MStar'.
301 | idtac "---------- re_not_empty ---------".
302 | Print Assumptions re_not_empty.
303 | idtac "---------- re_not_empty_correct ---------".
304 | Print Assumptions re_not_empty_correct.
305 | idtac "---------- reflect_iff ---------".
306 | Print Assumptions reflect_iff.
307 | idtac "---------- eqbP_practice ---------".
308 | Print Assumptions eqbP_practice.
309 | idtac "---------- nostutter ---------".
310 | idtac "MANUAL".
311 | idtac "".
312 | idtac "********** Advanced **********".
313 | idtac "---------- ev_ev__ev ---------".
314 | Print Assumptions ev_ev__ev.
315 | idtac "---------- subseq_refl ---------".
316 | Print Assumptions subseq_refl.
317 | idtac "---------- subseq_app ---------".
318 | Print Assumptions subseq_app.
319 | idtac "---------- subseq_trans ---------".
320 | Print Assumptions subseq_trans.
321 | idtac "---------- Pumping.weak_pumping ---------".
322 | Print Assumptions Pumping.weak_pumping.
323 | idtac "---------- filter_challenge ---------".
324 | idtac "MANUAL".
325 | Abort.
326 |
327 | (* 2022-06-16 11:18 *)
328 |
329 | (* 2022-06-16 11:18 *)
330 |
--------------------------------------------------------------------------------
/textbook/lf/ImpTest.v:
--------------------------------------------------------------------------------
1 | Set Warnings "-notation-overridden,-parsing".
2 | From Coq Require Export String.
3 | From LF Require Import Imp.
4 |
5 | Parameter MISSING: Type.
6 |
7 | Module Check.
8 |
9 | Ltac check_type A B :=
10 | match type of A with
11 | | context[MISSING] => idtac "Missing:" A
12 | | ?T => first [unify T B; idtac "Type: ok" | idtac "Type: wrong - should be (" B ")"]
13 | end.
14 |
15 | Ltac print_manual_grade A :=
16 | match eval compute in A with
17 | | Some (_ ?S ?C) =>
18 | idtac "Score:" S;
19 | match eval compute in C with
20 | | ""%string => idtac "Comment: None"
21 | | _ => idtac "Comment:" C
22 | end
23 | | None =>
24 | idtac "Score: Ungraded";
25 | idtac "Comment: None"
26 | end.
27 |
28 | End Check.
29 |
30 | From LF Require Import Imp.
31 | Import Check.
32 |
33 | Goal True.
34 |
35 | idtac "------------------- optimize_0plus_b_sound --------------------".
36 | idtac " ".
37 |
38 | idtac "#> AExp.optimize_0plus_b_sound".
39 | idtac "Possible points: 3".
40 | check_type @AExp.optimize_0plus_b_sound (
41 | (forall b : AExp.bexp, AExp.beval (AExp.optimize_0plus_b b) = AExp.beval b)).
42 | idtac "Assumptions:".
43 | Abort.
44 | Print Assumptions AExp.optimize_0plus_b_sound.
45 | Goal True.
46 | idtac " ".
47 |
48 | idtac "------------------- bevalR --------------------".
49 | idtac " ".
50 |
51 | idtac "#> AExp.beval_iff_bevalR".
52 | idtac "Possible points: 3".
53 | check_type @AExp.beval_iff_bevalR (
54 | (forall (b : AExp.bexp) (bv : bool), AExp.bevalR b bv <-> AExp.beval b = bv)).
55 | idtac "Assumptions:".
56 | Abort.
57 | Print Assumptions AExp.beval_iff_bevalR.
58 | Goal True.
59 | idtac " ".
60 |
61 | idtac "------------------- ceval_example2 --------------------".
62 | idtac " ".
63 |
64 | idtac "#> ceval_example2".
65 | idtac "Possible points: 2".
66 | check_type @ceval_example2 (
67 | (empty_st =[ X := (ANum 0); Y := (ANum 1); Z := (ANum 2)
68 | ]=> @Maps.t_update nat (@Maps.t_update nat (X !-> 0) Y 1) Z 2)).
69 | idtac "Assumptions:".
70 | Abort.
71 | Print Assumptions ceval_example2.
72 | Goal True.
73 | idtac " ".
74 |
75 | idtac "------------------- loop_never_stops --------------------".
76 | idtac " ".
77 |
78 | idtac "#> loop_never_stops".
79 | idtac "Possible points: 3".
80 | check_type @loop_never_stops ((forall st st' : state, ~ st =[ loop ]=> st')).
81 | idtac "Assumptions:".
82 | Abort.
83 | Print Assumptions loop_never_stops.
84 | Goal True.
85 | idtac " ".
86 |
87 | idtac "------------------- no_whiles_eqv --------------------".
88 | idtac " ".
89 |
90 | idtac "#> no_whiles_eqv".
91 | idtac "Possible points: 3".
92 | check_type @no_whiles_eqv ((forall c : com, no_whiles c = true <-> no_whilesR c)).
93 | idtac "Assumptions:".
94 | Abort.
95 | Print Assumptions no_whiles_eqv.
96 | Goal True.
97 | idtac " ".
98 |
99 | idtac "------------------- no_whiles_terminating --------------------".
100 | idtac " ".
101 |
102 | idtac "#> Manually graded: no_whiles_terminating".
103 | idtac "Possible points: 6".
104 | print_manual_grade manual_grade_for_no_whiles_terminating.
105 | idtac " ".
106 |
107 | idtac "------------------- stack_compiler --------------------".
108 | idtac " ".
109 |
110 | idtac "#> s_execute1".
111 | idtac "Possible points: 1".
112 | check_type @s_execute1 (
113 | (s_execute empty_st (@nil nat)
114 | (SPush 5 :: SPush 3 :: SPush 1 :: SMinus :: @nil sinstr) =
115 | (2 :: 5 :: @nil nat)%list)).
116 | idtac "Assumptions:".
117 | Abort.
118 | Print Assumptions s_execute1.
119 | Goal True.
120 | idtac " ".
121 |
122 | idtac "#> s_execute2".
123 | idtac "Possible points: 0.5".
124 | check_type @s_execute2 (
125 | (s_execute (X !-> 3) (3 :: 4 :: @nil nat)
126 | (SPush 4 :: SLoad X :: SMult :: SPlus :: @nil sinstr) =
127 | (15 :: 4 :: @nil nat)%list)).
128 | idtac "Assumptions:".
129 | Abort.
130 | Print Assumptions s_execute2.
131 | Goal True.
132 | idtac " ".
133 |
134 | idtac "#> s_compile1".
135 | idtac "Possible points: 1.5".
136 | check_type @s_compile1 (
137 | (s_compile <{ (AId X) - (ANum 2) * (AId Y) }> =
138 | (SLoad X :: SPush 2 :: SLoad Y :: SMult :: SMinus :: @nil sinstr)%list)).
139 | idtac "Assumptions:".
140 | Abort.
141 | Print Assumptions s_compile1.
142 | Goal True.
143 | idtac " ".
144 |
145 | idtac "------------------- execute_app --------------------".
146 | idtac " ".
147 |
148 | idtac "#> execute_app".
149 | idtac "Possible points: 3".
150 | check_type @execute_app (
151 | (forall (st : state) (p1 p2 : list sinstr) (stack : list nat),
152 | s_execute st stack (p1 ++ p2) = s_execute st (s_execute st stack p1) p2)).
153 | idtac "Assumptions:".
154 | Abort.
155 | Print Assumptions execute_app.
156 | Goal True.
157 | idtac " ".
158 |
159 | idtac "------------------- stack_compiler_correct --------------------".
160 | idtac " ".
161 |
162 | idtac "#> s_compile_correct_aux".
163 | idtac "Possible points: 2.5".
164 | check_type @s_compile_correct_aux (
165 | (forall (st : state) (e : aexp) (stack : list nat),
166 | s_execute st stack (s_compile e) = (aeval st e :: stack)%list)).
167 | idtac "Assumptions:".
168 | Abort.
169 | Print Assumptions s_compile_correct_aux.
170 | Goal True.
171 | idtac " ".
172 |
173 | idtac "#> s_compile_correct".
174 | idtac "Possible points: 0.5".
175 | check_type @s_compile_correct (
176 | (forall (st : state) (e : aexp),
177 | s_execute st (@nil nat) (s_compile e) = (aeval st e :: @nil nat)%list)).
178 | idtac "Assumptions:".
179 | Abort.
180 | Print Assumptions s_compile_correct.
181 | Goal True.
182 | idtac " ".
183 |
184 | idtac "------------------- break_imp --------------------".
185 | idtac " ".
186 |
187 | idtac "#> BreakImp.break_ignore".
188 | idtac "Advanced".
189 | idtac "Possible points: 1.5".
190 | check_type @BreakImp.break_ignore (
191 | (forall (c : BreakImp.com) (st st' : state) (s : BreakImp.result),
192 | BreakImp.ceval (BreakImp.CSeq BreakImp.CBreak c) st s st' -> st = st')).
193 | idtac "Assumptions:".
194 | Abort.
195 | Print Assumptions BreakImp.break_ignore.
196 | Goal True.
197 | idtac " ".
198 |
199 | idtac "#> BreakImp.while_continue".
200 | idtac "Advanced".
201 | idtac "Possible points: 1.5".
202 | check_type @BreakImp.while_continue (
203 | (forall (b : bexp) (c : BreakImp.com) (st st' : state) (s : BreakImp.result),
204 | BreakImp.ceval (BreakImp.CWhile b c) st s st' -> s = BreakImp.SContinue)).
205 | idtac "Assumptions:".
206 | Abort.
207 | Print Assumptions BreakImp.while_continue.
208 | Goal True.
209 | idtac " ".
210 |
211 | idtac "#> BreakImp.while_stops_on_break".
212 | idtac "Advanced".
213 | idtac "Possible points: 1".
214 | check_type @BreakImp.while_stops_on_break (
215 | (forall (b : bexp) (c : BreakImp.com) (st st' : state),
216 | beval st b = true ->
217 | BreakImp.ceval c st BreakImp.SBreak st' ->
218 | BreakImp.ceval (BreakImp.CWhile b c) st BreakImp.SContinue st')).
219 | idtac "Assumptions:".
220 | Abort.
221 | Print Assumptions BreakImp.while_stops_on_break.
222 | Goal True.
223 | idtac " ".
224 |
225 | idtac "#> BreakImp.seq_continue".
226 | idtac "Advanced".
227 | idtac "Possible points: 1".
228 | check_type @BreakImp.seq_continue (
229 | (forall (c1 c2 : BreakImp.com) (st st' st'' : state),
230 | BreakImp.ceval c1 st BreakImp.SContinue st' ->
231 | BreakImp.ceval c2 st' BreakImp.SContinue st'' ->
232 | BreakImp.ceval (BreakImp.CSeq c1 c2) st BreakImp.SContinue st'')).
233 | idtac "Assumptions:".
234 | Abort.
235 | Print Assumptions BreakImp.seq_continue.
236 | Goal True.
237 | idtac " ".
238 |
239 | idtac "#> BreakImp.seq_stops_on_break".
240 | idtac "Advanced".
241 | idtac "Possible points: 1".
242 | check_type @BreakImp.seq_stops_on_break (
243 | (forall (c1 c2 : BreakImp.com) (st st' : state),
244 | BreakImp.ceval c1 st BreakImp.SBreak st' ->
245 | BreakImp.ceval (BreakImp.CSeq c1 c2) st BreakImp.SBreak st')).
246 | idtac "Assumptions:".
247 | Abort.
248 | Print Assumptions BreakImp.seq_stops_on_break.
249 | Goal True.
250 | idtac " ".
251 |
252 | idtac " ".
253 |
254 | idtac "Max points - standard: 29".
255 | idtac "Max points - advanced: 35".
256 | idtac "".
257 | idtac "Allowed Axioms:".
258 | idtac "functional_extensionality".
259 | idtac "FunctionalExtensionality.functional_extensionality_dep".
260 | idtac "plus_le".
261 | idtac "le_trans".
262 | idtac "le_plus_l".
263 | idtac "add_le_cases".
264 | idtac "Sn_le_Sm__n_le_m".
265 | idtac "O_le_n".
266 | idtac "".
267 | idtac "".
268 | idtac "********** Summary **********".
269 | idtac "".
270 | idtac "Below is a summary of the automatically graded exercises that are incomplete.".
271 | idtac "".
272 | idtac "The output for each exercise can be any of the following:".
273 | idtac " - 'Closed under the global context', if it is complete".
274 | idtac " - 'MANUAL', if it is manually graded".
275 | idtac " - A list of pending axioms, containing unproven assumptions. In this case".
276 | idtac " the exercise is considered complete, if the axioms are all allowed.".
277 | idtac "".
278 | idtac "********** Standard **********".
279 | idtac "---------- AExp.optimize_0plus_b_sound ---------".
280 | Print Assumptions AExp.optimize_0plus_b_sound.
281 | idtac "---------- AExp.beval_iff_bevalR ---------".
282 | Print Assumptions AExp.beval_iff_bevalR.
283 | idtac "---------- ceval_example2 ---------".
284 | Print Assumptions ceval_example2.
285 | idtac "---------- loop_never_stops ---------".
286 | Print Assumptions loop_never_stops.
287 | idtac "---------- no_whiles_eqv ---------".
288 | Print Assumptions no_whiles_eqv.
289 | idtac "---------- no_whiles_terminating ---------".
290 | idtac "MANUAL".
291 | idtac "---------- s_execute1 ---------".
292 | Print Assumptions s_execute1.
293 | idtac "---------- s_execute2 ---------".
294 | Print Assumptions s_execute2.
295 | idtac "---------- s_compile1 ---------".
296 | Print Assumptions s_compile1.
297 | idtac "---------- execute_app ---------".
298 | Print Assumptions execute_app.
299 | idtac "---------- s_compile_correct_aux ---------".
300 | Print Assumptions s_compile_correct_aux.
301 | idtac "---------- s_compile_correct ---------".
302 | Print Assumptions s_compile_correct.
303 | idtac "".
304 | idtac "********** Advanced **********".
305 | idtac "---------- BreakImp.break_ignore ---------".
306 | Print Assumptions BreakImp.break_ignore.
307 | idtac "---------- BreakImp.while_continue ---------".
308 | Print Assumptions BreakImp.while_continue.
309 | idtac "---------- BreakImp.while_stops_on_break ---------".
310 | Print Assumptions BreakImp.while_stops_on_break.
311 | idtac "---------- BreakImp.seq_continue ---------".
312 | Print Assumptions BreakImp.seq_continue.
313 | idtac "---------- BreakImp.seq_stops_on_break ---------".
314 | Print Assumptions BreakImp.seq_stops_on_break.
315 | Abort.
316 |
317 | (* 2022-06-16 11:18 *)
318 |
319 | (* 2022-06-16 11:18 *)
320 |
--------------------------------------------------------------------------------
/notes/lf/Lists.v:
--------------------------------------------------------------------------------
1 | (** * Lists: Working with Structured Data *)
2 |
3 | From LF Require Export Induction.
4 | Module NatList.
5 |
6 | (* ################################################################# *)
7 | (** * Pairs of Numbers *)
8 |
9 | (** An [Inductive] definition of pairs of numbers. Note that
10 | it has just one constructor, (taking two arguments): *)
11 |
12 | Inductive natprod : Type :=
13 | | pair (n1 n2 : nat).
14 |
15 | Check (pair 3 5) : natprod.
16 |
17 | (** Functions for extracting the first and second components of a pair
18 | can then be defined by pattern matching. *)
19 |
20 | Definition fst (p : natprod) : nat :=
21 | match p with
22 | | pair x _ => x
23 | end.
24 |
25 | Definition snd (p : natprod) : nat :=
26 | match p with
27 | | pair _ y => y
28 | end.
29 |
30 | Compute (fst (pair 3 5)).
31 | (* ===> 3 *)
32 |
33 | (** A nicer notation for pairs: *)
34 |
35 | Notation "( x , y )" := (pair x y).
36 |
37 | (** The new notation can be used both in expressions and in pattern
38 | matches. *)
39 |
40 | Compute (fst (3,5)).
41 |
42 | Definition fst' (p : natprod) : nat :=
43 | match p with
44 | | (x,_) => x
45 | end.
46 |
47 | Definition snd' (p : natprod) : nat :=
48 | match p with
49 | | (_,y) => y
50 | end.
51 |
52 | Definition swap_pair (p : natprod) : natprod :=
53 | match p with
54 | | (x,y) => (y,x)
55 | end.
56 |
57 | (** Now let's try to prove a few simple facts about pairs.
58 |
59 | If we state properties of pairs in a slightly peculiar way, we can
60 | sometimes complete their proofs with just reflexivity (and its
61 | built-in simplification): *)
62 |
63 | Theorem surjective_pairing' : forall (n m : nat),
64 | (n,m) = (fst (n,m), snd (n,m)).
65 | Proof. reflexivity. Qed.
66 |
67 | (** But just [reflexivity] is not enough if we state the lemma in the
68 | most natural way: *)
69 |
70 | Theorem surjective_pairing_stuck : forall (p : natprod),
71 | p = (fst p, snd p).
72 | Proof.
73 | intros p. simpl. (* Doesn't reduce anything! *)
74 | Abort.
75 |
76 | (** Solution: use [destruct]. *)
77 |
78 | Theorem surjective_pairing : forall (p : natprod),
79 | p = (fst p, snd p).
80 | Proof.
81 | intros p. destruct p as [n m]. simpl.
82 | reflexivity.
83 | Qed.
84 |
85 | (* ################################################################# *)
86 | (** * Lists of Numbers *)
87 |
88 | (** An inductive definition of _lists_ of numbers: *)
89 |
90 | Inductive natlist : Type :=
91 | | nil
92 | | cons (n : nat) (l : natlist).
93 |
94 | Definition mylist := cons 1 (cons 2 (cons 3 nil)).
95 |
96 | (** Some notation for lists to make our lives easier: *)
97 |
98 | Notation "x :: l" := (cons x l)
99 | (at level 60, right associativity).
100 | Notation "[ ]" := nil.
101 | Notation "[ x ; .. ; y ]" := (cons x .. (cons y nil) ..).
102 |
103 | (** Now these all mean exactly the same thing: *)
104 |
105 | Definition mylist1 := 1 :: (2 :: (3 :: nil)).
106 | Definition mylist2 := 1 :: 2 :: 3 :: [].
107 | Definition mylist3 := [1;2;3].
108 |
109 | (** Some useful list-manipulation functions... *)
110 |
111 | (* ----------------------------------------------------------------- *)
112 | (** *** Repeat *)
113 |
114 | Fixpoint repeat (n count : nat) : natlist :=
115 | match count with
116 | | O => []
117 | | S count' => n :: (repeat n count')
118 | end.
119 |
120 | Compute repeat 42 3.
121 |
122 | (* ----------------------------------------------------------------- *)
123 | (** *** Length *)
124 |
125 | Fixpoint length (lst : natlist) : nat :=
126 | match lst with
127 | | [] => 0
128 | | _ :: t => S (length t)
129 | end.
130 |
131 | Compute length (repeat 42 3).
132 |
133 | (* ----------------------------------------------------------------- *)
134 | (** *** Append *)
135 |
136 | Fixpoint app (l1 l2 : natlist) : natlist :=
137 | match l1 with
138 | | [] => l2
139 | | h :: t => h :: (app t l2)
140 | end.
141 |
142 | Compute app [1;2;3] [4;5;6].
143 |
144 | Notation "x ++ y" := (app x y)
145 | (right associativity, at level 60).
146 |
147 | Example test_app1: [1;2;3] ++ [4;5] = [1;2;3;4;5].
148 | Proof. reflexivity. Qed.
149 | Example test_app2: [] ++ [4;5] = [4;5].
150 | Proof. reflexivity. Qed.
151 | Example test_app3: [1;2;3] ++ [] = [1;2;3].
152 | Proof. reflexivity. Qed.
153 |
154 | (* ----------------------------------------------------------------- *)
155 | (** *** Head and Tail *)
156 |
157 | Definition hd (default : nat) (l : natlist) : nat :=
158 | match l with
159 | | [] => default
160 | | h :: _ => h
161 | end.
162 |
163 | Definition tl (l : natlist) : natlist :=
164 | match l with
165 | | [] => []
166 | | _ :: t => t
167 | end.
168 |
169 | Example test_hd1: hd 0 [1;2;3] = 1.
170 | Proof. reflexivity. Qed.
171 | Example test_hd2: hd 0 [] = 0.
172 | Proof. reflexivity. Qed.
173 | Example test_tl: tl [1;2;3] = [2;3].
174 | Proof. reflexivity. Qed.
175 |
176 | (* ################################################################# *)
177 | (** * Reasoning About Lists *)
178 |
179 | (** As with numbers, some proofs about list functions need only
180 | simplification... *)
181 |
182 | Theorem nil_app : forall (lst : natlist),
183 | [] ++ lst = lst.
184 | Proof. reflexivity. Qed.
185 |
186 | (** ...and some need case analysis. *)
187 |
188 | Theorem tl_length_pred : forall (lst : natlist),
189 | pred (length lst) = length (tl lst).
190 | Proof.
191 | intros lst. destruct lst as [ | h t].
192 | - reflexivity.
193 | - reflexivity.
194 | Qed.
195 |
196 | (** Usually, though, interesting theorems about lists require
197 | induction for their proofs. We'll see how to do this next. *)
198 |
199 | (* ================================================================= *)
200 | (** ** Induction on Lists *)
201 |
202 | (** Coq generates an induction principle for every [Inductive]
203 | definition, including lists. We can use the [induction] tactic on
204 | lists to prove things like the associativity of list-append... *)
205 |
206 | Theorem app_assoc : forall (lst1 lst2 lst3 : natlist),
207 | (lst1 ++ lst2) ++ lst3 = lst1 ++ (lst2 ++ lst3).
208 | Proof.
209 | intros lst1 lst2 lst3. induction lst1 as [| h1 t1].
210 | - reflexivity.
211 | - simpl. rewrite -> IHt1. reflexivity.
212 | Qed.
213 |
214 | (* ----------------------------------------------------------------- *)
215 | (** *** Reversing a List *)
216 |
217 | (** A more interesting example of induction over lists: *)
218 |
219 | Fixpoint rev (lst : natlist) : natlist :=
220 | match lst with
221 | | [] => []
222 | | h :: t => rev t ++ [h]
223 | end.
224 |
225 | Example test_rev1: rev [1;2;3] = [3;2;1].
226 | Proof. reflexivity. Qed.
227 | Example test_rev2: rev [] = [].
228 | Proof. reflexivity. Qed.
229 |
230 | (** Let's try to prove [length (rev lst) = length lst]. *)
231 |
232 | Theorem rev_length_firsttry : forall (lst : natlist),
233 | length (rev lst) = length lst.
234 | Proof.
235 | intros lst. induction lst as [| h t].
236 | - reflexivity.
237 | - simpl. rewrite <- IHt.
238 | Abort.
239 |
240 | (** We can prove a lemma to bridge the gap. *)
241 |
242 | Theorem app_length : forall (lst1 lst2 : natlist),
243 | length (lst1 ++ lst2) = (length lst1) + (length lst2).
244 | Proof.
245 | intros lst1 lst2. induction lst1 as [| h1 t1].
246 | - reflexivity.
247 | - simpl. rewrite IHt1. reflexivity.
248 | Qed.
249 |
250 | (** Now we can complete the original proof. *)
251 |
252 | Theorem rev_length : forall (lst : natlist),
253 | length (rev lst) = length lst.
254 | Proof.
255 | intros lst. induction lst as [| h t].
256 | - reflexivity.
257 | - simpl. rewrite -> app_length.
258 | simpl. rewrite -> IHt. rewrite add_comm.
259 | reflexivity.
260 | Qed.
261 |
262 | (* ################################################################# *)
263 | (** * Options *)
264 |
265 | (** Suppose we'd like a function to retrieve the [n]th element
266 | of a list. What to do if the list is too short? *)
267 |
268 | Fixpoint nth_bad (lst : natlist) (n : nat) : nat :=
269 | match lst with
270 | | [] => 42 (* no good choice of what to return *)
271 | | h :: t =>
272 | match n with
273 | | 0 => h
274 | | S k => nth_bad t k
275 | end
276 | end.
277 |
278 | (** The solution: [natoption]. *)
279 |
280 | Inductive natoption : Type :=
281 | | Some (n : nat)
282 | | None.
283 |
284 | Fixpoint nth_error (lst : natlist) (n : nat) : natoption :=
285 | match lst with
286 | | [] => None
287 | | h :: t =>
288 | match n with
289 | | 0 => Some h
290 | | S k => nth_error t k
291 | end
292 | end.
293 |
294 | Example test_nth_error1 : nth_error [4;5;6;7] 0 = Some 4.
295 | Proof. reflexivity. Qed.
296 | Example test_nth_error2 : nth_error [4;5;6;7] 3 = Some 7.
297 | Proof. reflexivity. Qed.
298 | Example test_nth_error3 : nth_error [4;5;6;7] 9 = None.
299 | Proof. reflexivity. Qed.
300 |
301 | (* A simultaneous pattern match cleans up the code. *)
302 |
303 | Fixpoint nth_error' (lst : natlist) (n : nat) : natoption :=
304 | match lst, n with
305 | | [], _ => None
306 | | h :: _, 0 => Some h
307 | | _ :: t, S k => nth_error' t k
308 | end.
309 |
310 | Example test_nth_error'1 : nth_error' [4;5;6;7] 0 = Some 4.
311 | Proof. reflexivity. Qed.
312 | Example test_nth_error'2 : nth_error' [4;5;6;7] 3 = Some 7.
313 | Proof. reflexivity. Qed.
314 | Example test_nth_error'3 : nth_error' [4;5;6;7] 9 = None.
315 | Proof. reflexivity. Qed.
316 |
317 | End NatList.
318 |
319 | (* ################################################################# *)
320 | (** * Partial Maps *)
321 |
322 | (** As a final illustration of how data structures can be defined in
323 | Coq, here is a simple _partial map_ data type, analogous to the
324 | map or dictionary data structures found in most programming
325 | languages. *)
326 |
327 | Module PartialMap.
328 | Export NatList. (* make the definitions from NatList available here *)
329 |
330 | Inductive partial_map : Type :=
331 | | Empty
332 | | Binding (k : nat) (v : nat) (m : partial_map).
333 |
334 | (** [partial_map] is similar to [nat_list], but the non-empty constructor
335 | carries an extra value. *)
336 |
337 | (** The [update] function records a binding for a key. If the key
338 | was already present, that shadows the old binding. *)
339 |
340 | Definition update (k : nat) (v : nat) (m : partial_map) : partial_map :=
341 | Binding k v m.
342 |
343 | (** We can define functions on [partial_map]s by pattern matching. *)
344 |
345 | Fixpoint find (k : nat) (m : partial_map) : natoption :=
346 | match m with
347 | | Empty => None
348 | | Binding k2 v m' =>
349 | if k =? k2 then Some v else find k m'
350 | end.
351 |
352 | Theorem find_update : forall (m : partial_map) (k v : nat),
353 | find k (update k v m) = Some v.
354 | Proof.
355 | intros m k v. simpl. rewrite eqb_refl. reflexivity.
356 | Qed.
357 |
358 | End PartialMap.
359 |
360 |
--------------------------------------------------------------------------------
/textbook/lf/ProofObjectsTest.v:
--------------------------------------------------------------------------------
1 | Set Warnings "-notation-overridden,-parsing".
2 | From Coq Require Export String.
3 | From LF Require Import ProofObjects.
4 |
5 | Parameter MISSING: Type.
6 |
7 | Module Check.
8 |
9 | Ltac check_type A B :=
10 | match type of A with
11 | | context[MISSING] => idtac "Missing:" A
12 | | ?T => first [unify T B; idtac "Type: ok" | idtac "Type: wrong - should be (" B ")"]
13 | end.
14 |
15 | Ltac print_manual_grade A :=
16 | match eval compute in A with
17 | | Some (_ ?S ?C) =>
18 | idtac "Score:" S;
19 | match eval compute in C with
20 | | ""%string => idtac "Comment: None"
21 | | _ => idtac "Comment:" C
22 | end
23 | | None =>
24 | idtac "Score: Ungraded";
25 | idtac "Comment: None"
26 | end.
27 |
28 | End Check.
29 |
30 | From LF Require Import ProofObjects.
31 | Import Check.
32 |
33 | Goal True.
34 |
35 | idtac "------------------- eight_is_even --------------------".
36 | idtac " ".
37 |
38 | idtac "#> ev_8".
39 | idtac "Possible points: 1".
40 | check_type @ev_8 ((ev 8)).
41 | idtac "Assumptions:".
42 | Abort.
43 | Print Assumptions ev_8.
44 | Goal True.
45 | idtac " ".
46 |
47 | idtac "#> ev_8'".
48 | idtac "Possible points: 1".
49 | check_type @ev_8' ((ev 8)).
50 | idtac "Assumptions:".
51 | Abort.
52 | Print Assumptions ev_8'.
53 | Goal True.
54 | idtac " ".
55 |
56 | idtac "------------------- conj_fact --------------------".
57 | idtac " ".
58 |
59 | idtac "#> Props.conj_fact".
60 | idtac "Possible points: 2".
61 | check_type @Props.conj_fact ((forall P Q R : Prop, P /\ Q -> Q /\ R -> P /\ R)).
62 | idtac "Assumptions:".
63 | Abort.
64 | Print Assumptions Props.conj_fact.
65 | Goal True.
66 | idtac " ".
67 |
68 | idtac "------------------- or_commut' --------------------".
69 | idtac " ".
70 |
71 | idtac "#> Props.or_commut'".
72 | idtac "Possible points: 2".
73 | check_type @Props.or_commut' ((forall P Q : Prop, P \/ Q -> Q \/ P)).
74 | idtac "Assumptions:".
75 | Abort.
76 | Print Assumptions Props.or_commut'.
77 | Goal True.
78 | idtac " ".
79 |
80 | idtac "------------------- ex_ev_Sn --------------------".
81 | idtac " ".
82 |
83 | idtac "#> Props.ex_ev_Sn".
84 | idtac "Possible points: 2".
85 | check_type @Props.ex_ev_Sn ((exists n : nat, ev (S n))).
86 | idtac "Assumptions:".
87 | Abort.
88 | Print Assumptions Props.ex_ev_Sn.
89 | Goal True.
90 | idtac " ".
91 |
92 | idtac "------------------- p_implies_true --------------------".
93 | idtac " ".
94 |
95 | idtac "#> Props.p_implies_true".
96 | idtac "Possible points: 1".
97 | check_type @Props.p_implies_true ((forall P : Type, P -> Props.True)).
98 | idtac "Assumptions:".
99 | Abort.
100 | Print Assumptions Props.p_implies_true.
101 | Goal True.
102 | idtac " ".
103 |
104 | idtac "------------------- ex_falso_quodlibet' --------------------".
105 | idtac " ".
106 |
107 | idtac "#> Props.ex_falso_quodlibet'".
108 | idtac "Possible points: 1".
109 | check_type @Props.ex_falso_quodlibet' ((forall P : Type, Props.False -> P)).
110 | idtac "Assumptions:".
111 | Abort.
112 | Print Assumptions Props.ex_falso_quodlibet'.
113 | Goal True.
114 | idtac " ".
115 |
116 | idtac "------------------- eq_cons --------------------".
117 | idtac " ".
118 |
119 | idtac "#> EqualityPlayground.eq_cons".
120 | idtac "Possible points: 2".
121 | check_type @EqualityPlayground.eq_cons (
122 | (forall (X : Type) (h1 h2 : X) (t1 t2 : list X),
123 | @EqualityPlayground.eq X h1 h2 ->
124 | @EqualityPlayground.eq (list X) t1 t2 ->
125 | @EqualityPlayground.eq (list X) (h1 :: t1) (h2 :: t2))).
126 | idtac "Assumptions:".
127 | Abort.
128 | Print Assumptions EqualityPlayground.eq_cons.
129 | Goal True.
130 | idtac " ".
131 |
132 | idtac "------------------- equality__leibniz_equality --------------------".
133 | idtac " ".
134 |
135 | idtac "#> EqualityPlayground.equality__leibniz_equality".
136 | idtac "Possible points: 2".
137 | check_type @EqualityPlayground.equality__leibniz_equality (
138 | (forall (X : Type) (x y : X),
139 | @EqualityPlayground.eq X x y -> forall P : X -> Prop, P x -> P y)).
140 | idtac "Assumptions:".
141 | Abort.
142 | Print Assumptions EqualityPlayground.equality__leibniz_equality.
143 | Goal True.
144 | idtac " ".
145 |
146 | idtac "------------------- equality__leibniz_equality_term --------------------".
147 | idtac " ".
148 |
149 | idtac "#> EqualityPlayground.equality__leibniz_equality_term".
150 | idtac "Possible points: 2".
151 | check_type @EqualityPlayground.equality__leibniz_equality_term (
152 | (forall (X : Type) (x y : X),
153 | @EqualityPlayground.eq X x y -> forall P : X -> Prop, P x -> P y)).
154 | idtac "Assumptions:".
155 | Abort.
156 | Print Assumptions EqualityPlayground.equality__leibniz_equality_term.
157 | Goal True.
158 | idtac " ".
159 |
160 | idtac "------------------- and_assoc --------------------".
161 | idtac " ".
162 |
163 | idtac "#> and_assoc".
164 | idtac "Possible points: 2".
165 | check_type @and_assoc ((forall P Q R : Prop, P /\ Q /\ R -> (P /\ Q) /\ R)).
166 | idtac "Assumptions:".
167 | Abort.
168 | Print Assumptions and_assoc.
169 | Goal True.
170 | idtac " ".
171 |
172 | idtac "------------------- or_distributes_over_and --------------------".
173 | idtac " ".
174 |
175 | idtac "#> or_distributes_over_and".
176 | idtac "Possible points: 3".
177 | check_type @or_distributes_over_and (
178 | (forall P Q R : Prop, P \/ Q /\ R <-> (P \/ Q) /\ (P \/ R))).
179 | idtac "Assumptions:".
180 | Abort.
181 | Print Assumptions or_distributes_over_and.
182 | Goal True.
183 | idtac " ".
184 |
185 | idtac "------------------- negations --------------------".
186 | idtac " ".
187 |
188 | idtac "#> double_neg".
189 | idtac "Possible points: 1".
190 | check_type @double_neg ((forall P : Prop, P -> ~ ~ P)).
191 | idtac "Assumptions:".
192 | Abort.
193 | Print Assumptions double_neg.
194 | Goal True.
195 | idtac " ".
196 |
197 | idtac "#> contradiction_implies_anything".
198 | idtac "Possible points: 1".
199 | check_type @contradiction_implies_anything ((forall P Q : Prop, P /\ ~ P -> Q)).
200 | idtac "Assumptions:".
201 | Abort.
202 | Print Assumptions contradiction_implies_anything.
203 | Goal True.
204 | idtac " ".
205 |
206 | idtac "#> de_morgan_not_or".
207 | idtac "Possible points: 1".
208 | check_type @de_morgan_not_or ((forall P Q : Prop, ~ (P \/ Q) -> ~ P /\ ~ Q)).
209 | idtac "Assumptions:".
210 | Abort.
211 | Print Assumptions de_morgan_not_or.
212 | Goal True.
213 | idtac " ".
214 |
215 | idtac "------------------- currying --------------------".
216 | idtac " ".
217 |
218 | idtac "#> curry".
219 | idtac "Possible points: 1".
220 | check_type @curry ((forall P Q R : Prop, (P /\ Q -> R) -> P -> Q -> R)).
221 | idtac "Assumptions:".
222 | Abort.
223 | Print Assumptions curry.
224 | Goal True.
225 | idtac " ".
226 |
227 | idtac "#> uncurry".
228 | idtac "Possible points: 1".
229 | check_type @uncurry ((forall P Q R : Prop, (P -> Q -> R) -> P /\ Q -> R)).
230 | idtac "Assumptions:".
231 | Abort.
232 | Print Assumptions uncurry.
233 | Goal True.
234 | idtac " ".
235 |
236 | idtac "------------------- pe_implies_or_eq --------------------".
237 | idtac " ".
238 |
239 | idtac "#> pe_implies_or_eq".
240 | idtac "Advanced".
241 | idtac "Possible points: 1".
242 | check_type @pe_implies_or_eq (
243 | (propositional_extensionality -> forall P Q : Prop, (P \/ Q) = (Q \/ P))).
244 | idtac "Assumptions:".
245 | Abort.
246 | Print Assumptions pe_implies_or_eq.
247 | Goal True.
248 | idtac " ".
249 |
250 | idtac "------------------- pe_implies_true_eq --------------------".
251 | idtac " ".
252 |
253 | idtac "#> pe_implies_true_eq".
254 | idtac "Advanced".
255 | idtac "Possible points: 1".
256 | check_type @pe_implies_true_eq (
257 | (propositional_extensionality -> forall P : Prop, P -> True = P)).
258 | idtac "Assumptions:".
259 | Abort.
260 | Print Assumptions pe_implies_true_eq.
261 | Goal True.
262 | idtac " ".
263 |
264 | idtac "------------------- pe_implies_pi --------------------".
265 | idtac " ".
266 |
267 | idtac "#> pe_implies_pi".
268 | idtac "Advanced".
269 | idtac "Possible points: 3".
270 | check_type @pe_implies_pi ((propositional_extensionality -> proof_irrelevance)).
271 | idtac "Assumptions:".
272 | Abort.
273 | Print Assumptions pe_implies_pi.
274 | Goal True.
275 | idtac " ".
276 |
277 | idtac " ".
278 |
279 | idtac "Max points - standard: 26".
280 | idtac "Max points - advanced: 31".
281 | idtac "".
282 | idtac "Allowed Axioms:".
283 | idtac "functional_extensionality".
284 | idtac "FunctionalExtensionality.functional_extensionality_dep".
285 | idtac "plus_le".
286 | idtac "le_trans".
287 | idtac "le_plus_l".
288 | idtac "add_le_cases".
289 | idtac "Sn_le_Sm__n_le_m".
290 | idtac "O_le_n".
291 | idtac "".
292 | idtac "".
293 | idtac "********** Summary **********".
294 | idtac "".
295 | idtac "Below is a summary of the automatically graded exercises that are incomplete.".
296 | idtac "".
297 | idtac "The output for each exercise can be any of the following:".
298 | idtac " - 'Closed under the global context', if it is complete".
299 | idtac " - 'MANUAL', if it is manually graded".
300 | idtac " - A list of pending axioms, containing unproven assumptions. In this case".
301 | idtac " the exercise is considered complete, if the axioms are all allowed.".
302 | idtac "".
303 | idtac "********** Standard **********".
304 | idtac "---------- ev_8 ---------".
305 | Print Assumptions ev_8.
306 | idtac "---------- ev_8' ---------".
307 | Print Assumptions ev_8'.
308 | idtac "---------- Props.conj_fact ---------".
309 | Print Assumptions Props.conj_fact.
310 | idtac "---------- Props.or_commut' ---------".
311 | Print Assumptions Props.or_commut'.
312 | idtac "---------- Props.ex_ev_Sn ---------".
313 | Print Assumptions Props.ex_ev_Sn.
314 | idtac "---------- Props.p_implies_true ---------".
315 | Print Assumptions Props.p_implies_true.
316 | idtac "---------- Props.ex_falso_quodlibet' ---------".
317 | Print Assumptions Props.ex_falso_quodlibet'.
318 | idtac "---------- EqualityPlayground.eq_cons ---------".
319 | Print Assumptions EqualityPlayground.eq_cons.
320 | idtac "---------- EqualityPlayground.equality__leibniz_equality ---------".
321 | Print Assumptions EqualityPlayground.equality__leibniz_equality.
322 | idtac "---------- EqualityPlayground.equality__leibniz_equality_term ---------".
323 | Print Assumptions EqualityPlayground.equality__leibniz_equality_term.
324 | idtac "---------- and_assoc ---------".
325 | Print Assumptions and_assoc.
326 | idtac "---------- or_distributes_over_and ---------".
327 | Print Assumptions or_distributes_over_and.
328 | idtac "---------- double_neg ---------".
329 | Print Assumptions double_neg.
330 | idtac "---------- contradiction_implies_anything ---------".
331 | Print Assumptions contradiction_implies_anything.
332 | idtac "---------- de_morgan_not_or ---------".
333 | Print Assumptions de_morgan_not_or.
334 | idtac "---------- curry ---------".
335 | Print Assumptions curry.
336 | idtac "---------- uncurry ---------".
337 | Print Assumptions uncurry.
338 | idtac "".
339 | idtac "********** Advanced **********".
340 | idtac "---------- pe_implies_or_eq ---------".
341 | Print Assumptions pe_implies_or_eq.
342 | idtac "---------- pe_implies_true_eq ---------".
343 | Print Assumptions pe_implies_true_eq.
344 | idtac "---------- pe_implies_pi ---------".
345 | Print Assumptions pe_implies_pi.
346 | Abort.
347 |
348 | (* 2022-06-16 11:18 *)
349 |
350 | (* 2022-06-16 11:18 *)
351 |
--------------------------------------------------------------------------------
/notes/lf/IndPrinciples.v:
--------------------------------------------------------------------------------
1 | (** * IndPrinciples: Induction Principles *)
2 |
3 | (** Let's take a deeper look at induction. *)
4 |
5 | Set Warnings "-notation-overridden,-parsing,-deprecated-hint-without-locality".
6 | From LF Require Export ProofObjects.
7 |
8 | (* ################################################################# *)
9 | (** * Basics *)
10 |
11 | (** The automatically generated _induction principle_ for [nat]: *)
12 |
13 | Check nat_ind :
14 | forall P : nat -> Prop,
15 | P 0 ->
16 | (forall n : nat, P n -> P (S n)) ->
17 | forall n : nat, P n.
18 |
19 | (** In English: Suppose [P] is a property of natural numbers (that is,
20 | [P n] is a [Prop] for every [n]). To show that [P n] holds of all
21 | [n], it suffices to show:
22 |
23 | - [P] holds of [0]
24 | - for any [n], if [P] holds of [n], then [P] holds of [S n]. *)
25 |
26 | (** We can directly use the induction principle with [apply]: *)
27 |
28 | Theorem mul_0_r' : forall n:nat,
29 | n * 0 = 0.
30 | Proof.
31 | apply nat_ind.
32 | - (* n = O *) reflexivity.
33 | - (* n = S n' *) simpl. intros n' IHn'. rewrite -> IHn'.
34 | reflexivity. Qed.
35 |
36 | (** Why the [induction] tactic is nicer than [apply]:
37 | - [apply] requires extra manual bookkeeping (the [intros] in the
38 | inductive case)
39 | - [apply] requires [n] to be left universally quantified
40 | - [apply] requires us to manually specify the name of the induction
41 | principle. *)
42 |
43 | (** Coq generates induction principles for every datatype defined with
44 | [Inductive], including those that aren't recursive. *)
45 |
46 | (** If we define type [t] with constructors [c1] ... [cn],
47 | Coq generates:
48 |
49 | t_ind : forall P : t -> Prop,
50 | ... case for c1 ... ->
51 | ... case for c2 ... -> ...
52 | ... case for cn ... ->
53 | forall n : t, P n
54 |
55 | The specific shape of each case depends on the arguments to the
56 | corresponding constructor. *)
57 |
58 | (** An example with no constructor arguments: *)
59 |
60 | Inductive time : Type :=
61 | | day
62 | | night.
63 |
64 | Check time_ind :
65 | forall P : time -> Prop,
66 | P day ->
67 | P night ->
68 | forall t : time, P t.
69 |
70 | (** An example with constructor arguments: *)
71 |
72 | Inductive natlist : Type :=
73 | | nnil
74 | | ncons (n : nat) (l : natlist).
75 |
76 | Check natlist_ind :
77 | forall P : natlist -> Prop,
78 | P nnil ->
79 | (forall (n : nat) (l : natlist),
80 | P l -> P (ncons n l)) ->
81 | forall l : natlist, P l.
82 |
83 | (** In general, the automatically generated induction principle for
84 | inductive type [t] is formed as follows:
85 |
86 | - Each constructor [c] generates one case of the principle.
87 | - If [c] takes no arguments, that case is:
88 |
89 | "P holds of c"
90 |
91 | - If [c] takes arguments [x1:a1] ... [xn:an], that case is:
92 |
93 | "For all x1:a1 ... xn:an,
94 | if [P] holds of each of the arguments of type [t],
95 | then [P] holds of [c x1 ... xn]"
96 |
97 | But that oversimplifies a little. An assumption about [P]
98 | holding of an argument [x] of type [t] actually occurs
99 | immediately after the quantification of [x].
100 | *)
101 |
102 | (** For example, suppose we had written the definition of [natlist] a little
103 | differently: *)
104 |
105 | Inductive natlist' : Type :=
106 | | nnil'
107 | | nsnoc (l : natlist') (n : nat).
108 |
109 | (** Now the induction principle case for [nsnoc1] is a bit different
110 | than the earlier case for [ncons]: *)
111 |
112 | Check natlist'_ind :
113 | forall P : natlist' -> Prop,
114 | P nnil' ->
115 | (forall l : natlist', P l -> forall n : nat, P (nsnoc l n)) ->
116 | forall n : natlist', P n.
117 |
118 |
119 |
120 | (* ################################################################# *)
121 | (** * Induction Principles for Propositions *)
122 |
123 | (** Inductive definitions of propositions also cause Coq to generate
124 | induction priniciples. For example, recall our proposition [ev]
125 | from [IndProp]: *)
126 |
127 | Print ev.
128 |
129 | (* ===>
130 |
131 | Inductive ev : nat -> Prop :=
132 | | ev_0 : ev 0
133 | | ev_SS : forall n : nat, ev n -> ev (S (S n)))
134 |
135 | *)
136 |
137 | Check ev_ind :
138 | forall P : nat -> Prop,
139 | P 0 ->
140 | (forall n : nat, ev n -> P n -> P (S (S n))) ->
141 | forall n : nat, ev n -> P n.
142 |
143 | (** In English, [ev_ind] says: Suppose [P] is a property of natural
144 | numbers. To show that [P n] holds whenever [n] is even, it suffices
145 | to show:
146 |
147 | - [P] holds for [0],
148 |
149 | - for any [n], if [n] is even and [P] holds for [n], then [P]
150 | holds for [S (S n)]. *)
151 |
152 | (** The precise form of an [Inductive] definition can affect the
153 | induction principle Coq generates. *)
154 |
155 | Inductive le1 : nat -> nat -> Prop :=
156 | | le1_n : forall n, le1 n n
157 | | le1_S : forall n m, (le1 n m) -> (le1 n (S m)).
158 |
159 | Notation "m <=1 n" := (le1 m n) (at level 70).
160 |
161 | (** [n] could instead be a parameter: *)
162 |
163 | Inductive le2 (n:nat) : nat -> Prop :=
164 | | le2_n : le2 n n
165 | | le2_S m (H : le2 n m) : le2 n (S m).
166 |
167 | Notation "m <=2 n" := (le2 m n) (at level 70).
168 |
169 | Check le1_ind :
170 | forall P : nat -> nat -> Prop,
171 | (forall n : nat, P n n) ->
172 | (forall n m : nat, n <=1 m -> P n m -> P n (S m)) ->
173 | forall n n0 : nat, n <=1 n0 -> P n n0.
174 |
175 | Check le2_ind :
176 | forall (n : nat) (P : nat -> Prop),
177 | P n ->
178 | (forall m : nat, n <=2 m -> P m -> P (S m)) ->
179 | forall n0 : nat, n <=2 n0 -> P n0.
180 |
181 | (** The latter is simpler, and corresponds to Coq's own
182 | definition. *)
183 |
184 | (* ################################################################# *)
185 | (** * Explicit Proof Objects for Induction (Optional) *)
186 |
187 | (** Recall again the induction principle on naturals that Coq generates for
188 | us automatically from the Inductive declaration for [nat]. *)
189 |
190 | Check nat_ind :
191 | forall P : nat -> Prop,
192 | P 0 ->
193 | (forall n : nat, P n -> P (S n)) ->
194 | forall n : nat, P n.
195 |
196 | (** There's nothing magic about this induction lemma: it's just
197 | another Coq lemma that requires a proof. Coq generates the proof
198 | automatically too... *)
199 |
200 | Print nat_ind.
201 |
202 | (** We can rewrite that more tidily as follows: *)
203 | Fixpoint build_proof
204 | (P : nat -> Prop)
205 | (evPO : P 0)
206 | (evPS : forall n : nat, P n -> P (S n))
207 | (n : nat) : P n :=
208 | match n with
209 | | 0 => evPO
210 | | S k => evPS k (build_proof P evPO evPS k)
211 | end.
212 |
213 | Definition nat_ind_tidy := build_proof.
214 |
215 | (** Recursive function [build_proof] thus pattern matches against
216 | [n], recursing all the way down to 0, and building up a proof
217 | as it returns. *)
218 |
219 | (** We can also define _non-standard_ induction principles
220 | in this style. Recall this troublesome thoerem: *)
221 |
222 | Lemma even_ev : forall n: nat, even n = true -> ev n.
223 | Proof.
224 | induction n; intros.
225 | - apply ev_0.
226 | - destruct n.
227 | + simpl in H. inversion H.
228 | + simpl in H.
229 | apply ev_SS.
230 | Abort.
231 |
232 | (** Attempts to prove this by standard induction on [n] fail in the case for
233 | [S (S n)], because the induction hypothesis only tells us something about
234 | [S n], which is useless. There are various ways to hack around this problem;
235 | for example, we _can_ use ordinary induction on [n] to prove this (try it!):
236 |
237 | [Lemma even_ev' : forall n : nat,
238 | (even n = true -> ev n) /\ (even (S n) = true -> ev (S n))].
239 |
240 | But we can make a much better proof by defining and proving a
241 | non-standard induction principle that goes "by twos":
242 | *)
243 |
244 | Definition nat_ind2 :
245 | forall (P : nat -> Prop),
246 | P 0 ->
247 | P 1 ->
248 | (forall n : nat, P n -> P (S(S n))) ->
249 | forall n : nat , P n :=
250 | fun P => fun P0 => fun P1 => fun PSS =>
251 | fix f (n:nat) := match n with
252 | 0 => P0
253 | | 1 => P1
254 | | S (S n') => PSS n' (f n')
255 | end.
256 |
257 | (** Once you get the hang of it, it is entirely straightforward to
258 | give an explicit proof term for induction principles like this.
259 | Proving this as a lemma using tactics is much less intuitive.
260 |
261 | The [induction ... using] tactic variant gives a convenient way to
262 | utilize a non-standard induction principle like this. *)
263 |
264 | Lemma even_ev : forall n, even n = true -> ev n.
265 | Proof.
266 | intros.
267 | induction n as [ | |n'] using nat_ind2.
268 | - apply ev_0.
269 | - simpl in H.
270 | inversion H.
271 | - simpl in H.
272 | apply ev_SS.
273 | apply IHn'.
274 | apply H.
275 | Qed.
276 |
277 |
278 |
279 | (** **** Exercise: 4 stars, standard, optional (t_tree)
280 |
281 | What if we wanted to define binary trees as follows, using a
282 | constructor that bundles the children and value at a node into a
283 | tuple? *)
284 |
285 | Notation "( x , y , .. , z )" := (pair .. (pair x y) .. z) : core_scope.
286 |
287 | Inductive t_tree (X : Type) : Type :=
288 | | t_leaf
289 | | t_branch : (t_tree X * X * t_tree X) -> t_tree X.
290 |
291 | Arguments t_leaf {X}.
292 | Arguments t_branch {X}.
293 |
294 | (** Unfortunately, the automatically-generated induction principle is
295 | not as strong as we need. It doesn't introduce induction hypotheses
296 | for the subtrees. *)
297 |
298 | Check t_tree_ind.
299 |
300 | (** That will get us in trouble if we want to prove something by
301 | induction, such as that [reflect] is an involution. *)
302 |
303 | Fixpoint reflect {X : Type} (t : t_tree X) : t_tree X :=
304 | match t with
305 | | t_leaf => t_leaf
306 | | t_branch (l, v, r) => t_branch (reflect r, v, reflect l)
307 | end.
308 |
309 | Theorem reflect_involution : forall (X : Type) (t : t_tree X),
310 | reflect (reflect t) = t.
311 | Proof.
312 | intros X t. induction t.
313 | - reflexivity.
314 | - destruct p as [[l v] r]. simpl. Abort.
315 |
316 | (** We get stuck, because we have no inductive hypothesis for [l] or
317 | [r]. So, we need to define our own custom induction principle, and
318 | use it to complete the proof.
319 |
320 | First, define the type of the induction principle that you want to
321 | use. There are many possible answers. Recall that you can use
322 | [match] as part of the definition. *)
323 |
324 | Definition better_t_tree_ind_type : Prop
325 | (* REPLACE THIS LINE WITH ":= _your_definition_ ." *). Admitted.
326 |
327 | (** Second, define the induction principle by giving a term of that
328 | type. Use the examples about [nat], above, as models. *)
329 |
330 | Definition better_t_tree_ind : better_t_tree_ind_type
331 | (* REPLACE THIS LINE WITH ":= _your_definition_ ." *). Admitted.
332 |
333 | (** Finally, prove the theorem. If [induction...using] gives you an
334 | error about "Cannot recognize an induction scheme", don't worry
335 | about it. The [induction] tactic is picky about the shape of the
336 | theorem you pass to it, but it doesn't give you much information
337 | to debug what is wrong about that shape. You can use [apply]
338 | instead, as we saw at the beginning of this file. *)
339 |
340 | Theorem reflect_involution : forall (X : Type) (t : t_tree X),
341 | reflect (reflect t) = t.
342 | Proof. (* FILL IN HERE *) Admitted.
343 |
344 | (** [] *)
345 |
346 |
--------------------------------------------------------------------------------
/textbook/lf/common/media/font/Open-Sans-300/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------