├── .gitignore ├── Gemfile ├── Gemfile.lock ├── Makefile ├── README.md ├── ROOT ├── _config.yml ├── _data ├── common_errors.yml ├── common_pitfalls.yml └── lemma_collections.yml ├── _includes └── head-custom.html ├── _layouts └── default.html ├── about.md ├── assets ├── css │ └── style.scss └── images │ ├── Isabelle.jpg │ └── favicon.ico ├── index.md └── src ├── commands ├── Find.thy ├── datatypes │ └── index.md └── index.md ├── common_errors └── index.md ├── common_pitfalls └── index.md ├── general └── index.md ├── proofs ├── finite_sets │ ├── Finite_Sets.thy │ └── index.md ├── index.md ├── lemma_collections.md ├── methods │ ├── Chained_Facts.thy │ └── index.md └── proof_patterns │ └── index.md └── searching_isabelle └── index.md /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | build/ 3 | _site/ 4 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | gem 'github-pages', group: :jekyll_plugins 4 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | activesupport (6.0.4.4) 5 | concurrent-ruby (~> 1.0, >= 1.0.2) 6 | i18n (>= 0.7, < 2) 7 | minitest (~> 5.1) 8 | tzinfo (~> 1.1) 9 | zeitwerk (~> 2.2, >= 2.2.2) 10 | addressable (2.8.0) 11 | public_suffix (>= 2.0.2, < 5.0) 12 | coffee-script (2.4.1) 13 | coffee-script-source 14 | execjs 15 | coffee-script-source (1.11.1) 16 | colorator (1.1.0) 17 | commonmarker (0.17.13) 18 | ruby-enum (~> 0.5) 19 | concurrent-ruby (1.1.9) 20 | dnsruby (1.61.7) 21 | simpleidn (~> 0.1) 22 | em-websocket (0.5.3) 23 | eventmachine (>= 0.12.9) 24 | http_parser.rb (~> 0) 25 | ethon (0.15.0) 26 | ffi (>= 1.15.0) 27 | eventmachine (1.2.7) 28 | execjs (2.8.1) 29 | faraday (1.9.3) 30 | faraday-em_http (~> 1.0) 31 | faraday-em_synchrony (~> 1.0) 32 | faraday-excon (~> 1.1) 33 | faraday-httpclient (~> 1.0) 34 | faraday-multipart (~> 1.0) 35 | faraday-net_http (~> 1.0) 36 | faraday-net_http_persistent (~> 1.0) 37 | faraday-patron (~> 1.0) 38 | faraday-rack (~> 1.0) 39 | faraday-retry (~> 1.0) 40 | ruby2_keywords (>= 0.0.4) 41 | faraday-em_http (1.0.0) 42 | faraday-em_synchrony (1.0.0) 43 | faraday-excon (1.1.0) 44 | faraday-httpclient (1.0.1) 45 | faraday-multipart (1.0.3) 46 | multipart-post (>= 1.2, < 3) 47 | faraday-net_http (1.0.1) 48 | faraday-net_http_persistent (1.2.0) 49 | faraday-patron (1.0.0) 50 | faraday-rack (1.0.0) 51 | faraday-retry (1.0.3) 52 | ffi (1.15.5) 53 | forwardable-extended (2.6.0) 54 | gemoji (3.0.1) 55 | github-pages (223) 56 | github-pages-health-check (= 1.17.9) 57 | jekyll (= 3.9.0) 58 | jekyll-avatar (= 0.7.0) 59 | jekyll-coffeescript (= 1.1.1) 60 | jekyll-commonmark-ghpages (= 0.1.6) 61 | jekyll-default-layout (= 0.1.4) 62 | jekyll-feed (= 0.15.1) 63 | jekyll-gist (= 1.5.0) 64 | jekyll-github-metadata (= 2.13.0) 65 | jekyll-include-cache (= 0.2.1) 66 | jekyll-mentions (= 1.6.0) 67 | jekyll-optional-front-matter (= 0.3.2) 68 | jekyll-paginate (= 1.1.0) 69 | jekyll-readme-index (= 0.3.0) 70 | jekyll-redirect-from (= 0.16.0) 71 | jekyll-relative-links (= 0.6.1) 72 | jekyll-remote-theme (= 0.4.3) 73 | jekyll-sass-converter (= 1.5.2) 74 | jekyll-seo-tag (= 2.7.1) 75 | jekyll-sitemap (= 1.4.0) 76 | jekyll-swiss (= 1.0.0) 77 | jekyll-theme-architect (= 0.2.0) 78 | jekyll-theme-cayman (= 0.2.0) 79 | jekyll-theme-dinky (= 0.2.0) 80 | jekyll-theme-hacker (= 0.2.0) 81 | jekyll-theme-leap-day (= 0.2.0) 82 | jekyll-theme-merlot (= 0.2.0) 83 | jekyll-theme-midnight (= 0.2.0) 84 | jekyll-theme-minimal (= 0.2.0) 85 | jekyll-theme-modernist (= 0.2.0) 86 | jekyll-theme-primer (= 0.6.0) 87 | jekyll-theme-slate (= 0.2.0) 88 | jekyll-theme-tactile (= 0.2.0) 89 | jekyll-theme-time-machine (= 0.2.0) 90 | jekyll-titles-from-headings (= 0.5.3) 91 | jemoji (= 0.12.0) 92 | kramdown (= 2.3.1) 93 | kramdown-parser-gfm (= 1.1.0) 94 | liquid (= 4.0.3) 95 | mercenary (~> 0.3) 96 | minima (= 2.5.1) 97 | nokogiri (>= 1.12.5, < 2.0) 98 | rouge (= 3.26.0) 99 | terminal-table (~> 1.4) 100 | github-pages-health-check (1.17.9) 101 | addressable (~> 2.3) 102 | dnsruby (~> 1.60) 103 | octokit (~> 4.0) 104 | public_suffix (>= 3.0, < 5.0) 105 | typhoeus (~> 1.3) 106 | html-pipeline (2.14.0) 107 | activesupport (>= 2) 108 | nokogiri (>= 1.4) 109 | http_parser.rb (0.8.0) 110 | i18n (0.9.5) 111 | concurrent-ruby (~> 1.0) 112 | jekyll (3.9.0) 113 | addressable (~> 2.4) 114 | colorator (~> 1.0) 115 | em-websocket (~> 0.5) 116 | i18n (~> 0.7) 117 | jekyll-sass-converter (~> 1.0) 118 | jekyll-watch (~> 2.0) 119 | kramdown (>= 1.17, < 3) 120 | liquid (~> 4.0) 121 | mercenary (~> 0.3.3) 122 | pathutil (~> 0.9) 123 | rouge (>= 1.7, < 4) 124 | safe_yaml (~> 1.0) 125 | jekyll-avatar (0.7.0) 126 | jekyll (>= 3.0, < 5.0) 127 | jekyll-coffeescript (1.1.1) 128 | coffee-script (~> 2.2) 129 | coffee-script-source (~> 1.11.1) 130 | jekyll-commonmark (1.3.1) 131 | commonmarker (~> 0.14) 132 | jekyll (>= 3.7, < 5.0) 133 | jekyll-commonmark-ghpages (0.1.6) 134 | commonmarker (~> 0.17.6) 135 | jekyll-commonmark (~> 1.2) 136 | rouge (>= 2.0, < 4.0) 137 | jekyll-default-layout (0.1.4) 138 | jekyll (~> 3.0) 139 | jekyll-feed (0.15.1) 140 | jekyll (>= 3.7, < 5.0) 141 | jekyll-gist (1.5.0) 142 | octokit (~> 4.2) 143 | jekyll-github-metadata (2.13.0) 144 | jekyll (>= 3.4, < 5.0) 145 | octokit (~> 4.0, != 4.4.0) 146 | jekyll-include-cache (0.2.1) 147 | jekyll (>= 3.7, < 5.0) 148 | jekyll-mentions (1.6.0) 149 | html-pipeline (~> 2.3) 150 | jekyll (>= 3.7, < 5.0) 151 | jekyll-optional-front-matter (0.3.2) 152 | jekyll (>= 3.0, < 5.0) 153 | jekyll-paginate (1.1.0) 154 | jekyll-readme-index (0.3.0) 155 | jekyll (>= 3.0, < 5.0) 156 | jekyll-redirect-from (0.16.0) 157 | jekyll (>= 3.3, < 5.0) 158 | jekyll-relative-links (0.6.1) 159 | jekyll (>= 3.3, < 5.0) 160 | jekyll-remote-theme (0.4.3) 161 | addressable (~> 2.0) 162 | jekyll (>= 3.5, < 5.0) 163 | jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0) 164 | rubyzip (>= 1.3.0, < 3.0) 165 | jekyll-sass-converter (1.5.2) 166 | sass (~> 3.4) 167 | jekyll-seo-tag (2.7.1) 168 | jekyll (>= 3.8, < 5.0) 169 | jekyll-sitemap (1.4.0) 170 | jekyll (>= 3.7, < 5.0) 171 | jekyll-swiss (1.0.0) 172 | jekyll-theme-architect (0.2.0) 173 | jekyll (> 3.5, < 5.0) 174 | jekyll-seo-tag (~> 2.0) 175 | jekyll-theme-cayman (0.2.0) 176 | jekyll (> 3.5, < 5.0) 177 | jekyll-seo-tag (~> 2.0) 178 | jekyll-theme-dinky (0.2.0) 179 | jekyll (> 3.5, < 5.0) 180 | jekyll-seo-tag (~> 2.0) 181 | jekyll-theme-hacker (0.2.0) 182 | jekyll (> 3.5, < 5.0) 183 | jekyll-seo-tag (~> 2.0) 184 | jekyll-theme-leap-day (0.2.0) 185 | jekyll (> 3.5, < 5.0) 186 | jekyll-seo-tag (~> 2.0) 187 | jekyll-theme-merlot (0.2.0) 188 | jekyll (> 3.5, < 5.0) 189 | jekyll-seo-tag (~> 2.0) 190 | jekyll-theme-midnight (0.2.0) 191 | jekyll (> 3.5, < 5.0) 192 | jekyll-seo-tag (~> 2.0) 193 | jekyll-theme-minimal (0.2.0) 194 | jekyll (> 3.5, < 5.0) 195 | jekyll-seo-tag (~> 2.0) 196 | jekyll-theme-modernist (0.2.0) 197 | jekyll (> 3.5, < 5.0) 198 | jekyll-seo-tag (~> 2.0) 199 | jekyll-theme-primer (0.6.0) 200 | jekyll (> 3.5, < 5.0) 201 | jekyll-github-metadata (~> 2.9) 202 | jekyll-seo-tag (~> 2.0) 203 | jekyll-theme-slate (0.2.0) 204 | jekyll (> 3.5, < 5.0) 205 | jekyll-seo-tag (~> 2.0) 206 | jekyll-theme-tactile (0.2.0) 207 | jekyll (> 3.5, < 5.0) 208 | jekyll-seo-tag (~> 2.0) 209 | jekyll-theme-time-machine (0.2.0) 210 | jekyll (> 3.5, < 5.0) 211 | jekyll-seo-tag (~> 2.0) 212 | jekyll-titles-from-headings (0.5.3) 213 | jekyll (>= 3.3, < 5.0) 214 | jekyll-watch (2.2.1) 215 | listen (~> 3.0) 216 | jemoji (0.12.0) 217 | gemoji (~> 3.0) 218 | html-pipeline (~> 2.2) 219 | jekyll (>= 3.0, < 5.0) 220 | kramdown (2.3.1) 221 | rexml 222 | kramdown-parser-gfm (1.1.0) 223 | kramdown (~> 2.0) 224 | liquid (4.0.3) 225 | listen (3.7.0) 226 | rb-fsevent (~> 0.10, >= 0.10.3) 227 | rb-inotify (~> 0.9, >= 0.9.10) 228 | mercenary (0.3.6) 229 | minima (2.5.1) 230 | jekyll (>= 3.5, < 5.0) 231 | jekyll-feed (~> 0.9) 232 | jekyll-seo-tag (~> 2.1) 233 | minitest (5.15.0) 234 | multipart-post (2.1.1) 235 | nokogiri (1.13.0-x86_64-linux) 236 | racc (~> 1.4) 237 | octokit (4.21.0) 238 | faraday (>= 0.9) 239 | sawyer (~> 0.8.0, >= 0.5.3) 240 | pathutil (0.16.2) 241 | forwardable-extended (~> 2.6) 242 | public_suffix (4.0.6) 243 | racc (1.6.0) 244 | rb-fsevent (0.11.0) 245 | rb-inotify (0.10.1) 246 | ffi (~> 1.0) 247 | rexml (3.2.5) 248 | rouge (3.26.0) 249 | ruby-enum (0.9.0) 250 | i18n 251 | ruby2_keywords (0.0.5) 252 | rubyzip (2.3.2) 253 | safe_yaml (1.0.5) 254 | sass (3.7.4) 255 | sass-listen (~> 4.0.0) 256 | sass-listen (4.0.0) 257 | rb-fsevent (~> 0.9, >= 0.9.4) 258 | rb-inotify (~> 0.9, >= 0.9.7) 259 | sawyer (0.8.2) 260 | addressable (>= 2.3.5) 261 | faraday (> 0.8, < 2.0) 262 | simpleidn (0.2.1) 263 | unf (~> 0.1.4) 264 | terminal-table (1.8.0) 265 | unicode-display_width (~> 1.1, >= 1.1.1) 266 | thread_safe (0.3.6) 267 | typhoeus (1.4.0) 268 | ethon (>= 0.9.0) 269 | tzinfo (1.2.9) 270 | thread_safe (~> 0.1) 271 | unf (0.1.4) 272 | unf_ext 273 | unf_ext (0.0.8) 274 | unicode-display_width (1.8.0) 275 | zeitwerk (2.5.3) 276 | 277 | PLATFORMS 278 | x86_64-linux 279 | 280 | DEPENDENCIES 281 | github-pages 282 | 283 | BUNDLED WITH 284 | 2.2.28 285 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all browse clean 2 | 3 | OBJDIR := build 4 | 5 | all: $(OBJDIR)/index.html 6 | 7 | $(OBJDIR)/index.html: $(wildcard src/**/*.thy) $(wildcard src/**/*.md) 8 | isabelle build -o browser_info -d . -v Index 9 | cp -r "$$(isabelle getenv -b ISABELLE_BROWSER_INFO)/Unsorted/Index/." $(OBJDIR)/ 10 | chmod -R u+w $(OBJDIR)/fonts 11 | 12 | browse: $(OBJDIR)/index.html 13 | xdg-open $< 14 | 15 | clean: 16 | rm -rf $(OBJDIR) 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Isabelle Community Cookbook 2 | 3 | ## What is this? 4 | 5 | This repository contains the resources for the [isabelle community cookbook](https://isabelle.systems/cookbook). 6 | The cookbook contains a collection of useful tips/tricks/hints 7 | for Isabelle users. 8 | 9 | ## How to contribute 10 | 11 | If you want to add/udpdate an entry, simply add/edit the corresponding entry in the corresponding directory and create a pull request. 12 | If you need help, simply create an [issue](https://github.com/isabelle-prover/cookbook/issues). 13 | 14 | ## Build site locally 15 | 16 | To build and view the website locally, see [here](https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/testing-your-github-pages-site-locally-with-jekyll). 17 | 18 | ## TODO 19 | - Add CI and html output for linked theory files (cf current Makefile) 20 | - Move material from [https://isabelle.in.tum.de/community/](https://isabelle.in.tum.de/community/) 21 | - Recipes for proving existential statements 22 | - Primer on conversions 23 | - Latex tips 24 | - Debugging ML code (`print_tac`, `print` antiquotation, debugger etc.) 25 | - Overview of different tactics (should also include `rewrite` etc.) 26 | - Difference between methods and tactics 27 | - Namespacing of operators and more with bundles 28 | - Function package tutorial 29 | - Isabelle/jEdit FAQ. For instance: how do I get symbols to display properly? 30 | -------------------------------------------------------------------------------- /ROOT: -------------------------------------------------------------------------------- 1 | session Index = HOL + 2 | options [browser_info] 3 | sessions 4 | "HOL-Library" 5 | directories 6 | "src/commands/" 7 | "src/proofs/finite_sets/" 8 | "src/proofs/methods/" 9 | theories 10 | (*src/commands/*) 11 | "Find" 12 | 13 | (*src/proofs/*) 14 | (*finite_sets/*) 15 | "Finite_Sets" 16 | (*methods/*) 17 | "Chained_Facts" 18 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal 2 | title: Isabelle Community Cookbook 3 | markdown: GFM 4 | logo: /assets/images/Isabelle.jpg 5 | -------------------------------------------------------------------------------- /_data/common_errors.yml: -------------------------------------------------------------------------------- 1 | - error_msg: > 2 | exception TYPE raised (line XXX of "envir.ML"): expand_atom: ill-typed replacement 3 | explanation: | 4 | This error can occur if you bind and use a pattern in a lemma statement, e.g. 5 | 6 | ``` 7 | lemma assumes "P foo" (is "P ?bar") shows "Q ?bar" 8 | ``` 9 | 10 | This is due to the fact that parsing and type inference for the whole lemma statement is done at once. 11 | 12 | **Fix:** 13 | Sufficiently verbose type annotations might help, e.g. 14 | 15 | ``` 16 | lemma assumes "P (foo ::'a)" (is "P ?bar") shows "Q (?bar :: 'a)" 17 | ``` 18 | - error_msg: > 19 | Bad Name: "t :: T" 20 | explanation: | 21 | When typing a definition and using type annotations at the wrong position, as in: 22 | 23 | ``` 24 | definition "a :: bool" where "a ≡ False" 25 | ``` 26 | 27 | Isabelle returns `Bad name: "a :: bool"`. 28 | 29 | **Fix:** use type annotations in the `where` clause instead: 30 | 31 | ``` 32 | definition "a" where "a :: bool ≡ False" 33 | ``` 34 | - error_msg: > 35 | Not an equation | Not a meta-equality (≡) 36 | explanation: | 37 | Most commonly, these errors occur because Isabelle's equality `=` binds relatively strongly. 38 | For example 39 | 40 | ``` 41 | definition d where "d b = b ∧ False" 42 | 43 | fun f where "f b = b ∧ False" 44 | ``` 45 | 46 | lead both to above error. 47 | Isabelle parses the term `t b = b ∧ False` as `(t b = b) ∧ False` and not `t b = (b ∧ False)`. 48 | 49 | **Fix:** 50 | Explicitly set the parentheses, e.g. `t b = (b ∧ False)` 51 | 52 | - error_msg: > 53 | (in an instantiation proof) 54 | Failed to refine any pending goal. 55 | Local statement fails to refine any pending goal. 56 | explanation: | 57 | When attempting to prove the necessary assumptions for the instantiation of a class, Isabelle may not infer the correct type. 58 | Assume there is a class `C`: 59 | ``` 60 | class C = 61 | fixes f :: "'a option ⇒ 'a option" 62 | assumes "f None = None" 63 | ``` 64 | When instantiating the class for an arbitrary type, e.g. `int`, one goal is: `f None = None`. 65 | ``` 66 | instantiation int :: C 67 | begin 68 | definition "f_int (x :: int option) ≡ (None :: int option)" (*arbitrary definition*) 69 | instance proof 70 | show "f None = None" sorry 71 | qed 72 | end 73 | ``` 74 | Isabelle does not infer the right type for `f` (since `f` may refer to another instantiation of `C`). 75 | 76 | **Fix:** Add a type annotation. For example: 77 | ``` 78 | show "f None = (None :: int option)" sorry 79 | ``` 80 | 81 | -------------------------------------------------------------------------------- /_data/common_pitfalls.yml: -------------------------------------------------------------------------------- 1 | - title: Misleading variable naming in set comprehension 2 | explanation: | 3 | **Problem:** The expression 4 | 5 | ``` 6 | {(v, v). v ∈ {''a'', ''b''}} 7 | ``` 8 | 9 | is actually interpreted as 10 | 11 | ``` 12 | {(va ∷ 'a, v ∷ char list). v ∈ {''a'', ''b''}} 13 | ``` 14 | 15 | **Fix**: Write 16 | 17 | ``` 18 | {(v, v) | v. v ∈ {''a'', ''b''}} 19 | ``` 20 | - title: The simplifier does not apply my rule 21 | explanation: | 22 | Most commonly this is a typing problem. 23 | The rule you want to apply may require a more special (or just plain different) type from what you have in the current goal. 24 | Use `declare [[show_types, show_sorts]]` to display types and sorts, and then check whether the types in your rule and your goal match up. 25 | - title: What is the difference between the ⇒, ⟹ , and ⟶ arrows? 26 | explanation: | 27 | Isabelle uses the `⇒` arrow for the function type (contrary to most functional languages which use `->`). 28 | So `a ⇒ b` is the type of a function that takes an element of type `a` as input and gives you an element of type `b` as output. 29 | 30 | The long arrows ⟶ and ⟹ are object and meta level implication, respectively. 31 | Roughly speaking, meta level implication should be used to separate the assumptions from the conclusion in statements. 32 | Whenever you need an implication inside a closed HOL formula, use ⟶. 33 | - title: Where do I have to put double quotes? 34 | explanation: | 35 | Isabelle distinguishes between *inner* and *outer* syntax. 36 | The outer syntax comes from the Isabelle framework, 37 | the inner syntax is the one in between quotation marks and comes from the object logic (in this case HOL). 38 | With time the distinction between the two becomes obvious, 39 | but in the beginning the following rules of thumb may work: 40 | 41 | Types should be inside quotation marks, formulas and lemmas should be inside quotation marks, 42 | rules and equations (e.g. for definitions) should be inside quotation marks, 43 | commands like `lemma`, `definition`, `primrec`, `inductive`, `apply`, `fun`, `done` are without quotation marks, 44 | as are the names of constants in constant definitions (`consts`) 45 | 46 | -------------------------------------------------------------------------------- /_data/lemma_collections.yml: -------------------------------------------------------------------------------- 1 | - name: eval_nat_numeral 2 | explanation: | 3 | simp rules to convert numerals to Suc/Zero notation 4 | - name: ac_simps 5 | explanation: | 6 | TODO 7 | - name: algebra_simps 8 | explanation: | 9 | simp rules to deal with the classical algebraic structures of groups and rings and fields. 10 | They simplify terms by multiplying everything out (in case of a ring) and bringing sums and products into a canonical form (by ordered rewriting). 11 | As a result, it decides group and ring equalities but also helps with inequalities. 12 | 13 | Of course it also works for fields, but it knows nothing about multiplicative inverses or division. 14 | This is catered for by `field_simps`. 15 | - name: field_simps 16 | explanation: | 17 | simp rules that multiply with denominators in (in)equations if they can be proved to be non-zero (for equations) or positive/negative (for inequations); 18 | can be too aggressive and is therefore separate from the more benign algebra_simps. 19 | - name: sign_simps 20 | explanation: | 21 | TODO 22 | - name: DERIV_intros 23 | explanation: | 24 | TODO 25 | - name: tendsto_intros 26 | explanation: | 27 | TODO 28 | 29 | -------------------------------------------------------------------------------- /_includes/head-custom.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include head-custom-google-analytics.html %} 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | {% seo %} 9 | 10 | 13 | {% include head-custom.html %} 14 | 15 | 16 |
17 |
18 | 19 | 20 | {% if site.logo %} 21 | 22 | 23 | 24 | {% endif %} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | {% if site.show_downloads %} 37 | 42 | {% endif %} 43 |
44 |
45 | 46 | {{ content }} 47 | 48 |
49 | 59 |
60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /about.md: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | This website contains a collection of useful tips/tricks/hints 4 | for Isabelle users. 5 | It is maintained by the [isabelle-prover GitHub group]({{ site.github.owner_url }}), 6 | a self-managed community of Isabelle users. 7 | Feel free to reach out if you are interested in becoming a maintainer or have any questions by creating an [issue on GitHub]({{ site.github.repository_url | append: "/issues/new?labels=community" }}). 8 | 9 | -------------------------------------------------------------------------------- /assets/css/style.scss: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | @import "{{ site.theme }}"; 5 | 6 | $space-baseline: 16px; 7 | 8 | #logo { 9 | display: block; 10 | margin-left: auto; 11 | margin-right: auto; 12 | width: 125px; 13 | } 14 | 15 | body, header { 16 | background-image: none; 17 | background-color: white; 18 | margin: 0; 19 | } 20 | 21 | body { 22 | padding: $space-baseline; 23 | } 24 | 25 | header { 26 | padding: 0; 27 | padding-bottom: $space-baseline; 28 | } 29 | 30 | @media print, screen and (min-width: 960px) { 31 | 32 | .wrapper { 33 | width: auto; 34 | max-width: 1200px; 35 | display: flex; 36 | flex-flow: row wrap; 37 | justify-content: space-between; 38 | } 39 | 40 | header, footer { 41 | position: inherit; 42 | width: 20%; 43 | } 44 | 45 | section { 46 | position: inherit; 47 | width: 75%; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /assets/images/Isabelle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isabelle-prover/cookbook/10771cc92b16f118887f9bbb1106fdcf78544c76/assets/images/Isabelle.jpg -------------------------------------------------------------------------------- /assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isabelle-prover/cookbook/10771cc92b16f118887f9bbb1106fdcf78544c76/assets/images/favicon.ico -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | # Isabelle Community Cookbook 2 | 3 | This website contains a collection of useful tips/tricks/hints for [Isabelle](https://isabelle.in.tum.de/) users contributed by the community. 4 | It is in an early stage – please contribute [here]({{ site.github.repository_url }}). 5 | 6 | Other useful resources can be found on [isabelle.systems](https://isabelle.systems#resources). 7 | 8 | ## Table of Contents 9 | - [Commands](src/commands): important Isabelle commands and tips on how to use them effectively 10 | - [Common Errors](src/common_errors): common errors and how to fix them 11 | - [Common Pitfalls](src/common_pitfalls): common pitfalls and how to avoid them 12 | - [General](src/general): general tips to get started with Isabelle 13 | - [Proofs](src/proofs): how to effectively write proofs for common proof obligations 14 | - [Searching Isabelle](src/searching_isabelle): how to search Isabelle and the AFP. 15 | 16 | -------------------------------------------------------------------------------- /src/commands/Find.thy: -------------------------------------------------------------------------------- 1 | theory Find 2 | imports Main 3 | begin 4 | 5 | section \Find theorems with @{command find_theorems}\ 6 | text \ 7 | Theorems can be searched by name where \*\ wildcards are allowed. 8 | One of the theorems found with the query below is @{thm gauss_sum_nat}. 9 | \ 10 | find_theorems name: "gau*" 11 | 12 | text \ 13 | You can also search theorems by specifying an arbitrary number of patterns. 14 | Patterns are allowed to contain wildcards (\*\) constants, schematic variables, and types. 15 | It is also possible to negate a pattern by prefixing it with a \-\. 16 | If a negated pattern occurs in a theorem, it will not be considered by the search. 17 | \ 18 | find_theorems "finite (?A::'a rel)" 19 | find_theorems "finite _ \ _" "insert _ _" -"card _" 20 | find_theorems "finite ?A \ finite ?B \ _ (?A \ ?B)" 21 | 22 | text \ 23 | In addition to patterns, we can take the goal state into account to search for theorems. 24 | The example below uses \intro\ to search for introduction rules that solve the current goal. 25 | For the given goal, @{command find_theorems} finds the lemma @{thm bij_betw_byWitness} which we 26 | instantiate accordingly. 27 | Then, we solve the the first two subgoals with @{method simp_all}. 28 | This leaves us with two subgoals: @{prop \(\x. x + 1) ` \ \ \\} and 29 | @{prop \(\x. x - 1) ` \ \ \\}. 30 | Searching with intro returns a lot of theorems since @{verbatim \\\} often occurs in the 31 | conclusion of theorems. 32 | To filter out irrelevant theorems, we pass the goal as a pattern with the appropriate wildcards. 33 | Then, @{command find_theorems} gives us the lemma @{thm image_subsetI} with which we can solve the 34 | remaining goals. 35 | In addition to \intro\, there are also \elim\, \dest\, and \solves\ which work analogously. 36 | \ 37 | lemma "bij_betw (\x. x + 1) \ \" 38 | find_theorems intro 39 | apply(intro bij_betw_byWitness[where ?f'="\x. x - 1"]) 40 | apply(simp_all) 41 | find_theorems intro 42 | find_theorems intro "_ ` _ \ _" 43 | apply(simp_all add: image_subsetI) 44 | done 45 | 46 | text \ 47 | To search for theorems that simplify a given term, one can pass \simp\ and a term to 48 | @{command find_theorems}. 49 | In the example below, @{command find_theorems} returns the lemma @{thm rev_rev_ident} with which 50 | we can rewrite @{term \rev (rev xs)\} to @{term \xs\}. 51 | \ 52 | 53 | find_theorems simp: "rev (rev _)" 54 | 55 | 56 | section \Find constants with @{command find_consts}\ 57 | text \ 58 | Finding constants (e.g. functions or definitions) can be done with the @{command find_consts}. 59 | As with @{command find_theorems}, you can search for constants by name as seen below. 60 | \ 61 | find_consts name: metric 62 | 63 | text \ 64 | Perhaps more useful than searching for constants by name, it is possible to search for them by 65 | type. 66 | The default search returns all constants which contain the given type pattern. 67 | If you are only interested in exact matches, then you can use the \strict\ annotation. 68 | The example below illustrates this behaviour: the first search returns functions 69 | @{term_type List.replicate} while the second only returns @{term_type List.subseqs} 70 | (and some functions from @{theory HOL.Quickcheck_Narrowing}). 71 | \ 72 | find_consts "'a \ 'a list" 73 | find_consts strict: "'a \ 'a list" 74 | 75 | text \ 76 | We can also use wildcards and negated patterns. 77 | \ 78 | find_consts strict: "_ \ 'a list \ _ list" 79 | find_consts strict: "_ \ 'a list \ _ list" -"('a \ 'b) list" 80 | 81 | text \ 82 | Finally, type variables can also have class constraints. 83 | \ 84 | find_consts "('a::ord) list \ ('a::ord) list" 85 | 86 | end -------------------------------------------------------------------------------- /src/commands/datatypes/index.md: -------------------------------------------------------------------------------- 1 | # Datatypes 2 | 3 | ## Selectors 4 | 5 | In the definition of a datatype, 6 | you can specify selectors that extract a specific position. 7 | 8 | **Example:** 9 | ``` 10 | datatype foo = Foo (foo_l : int) (foo_r : int) 11 | ``` 12 | 13 | You can then access the first element of a foo value `x` 14 | by `foo_l x` and the second one by `foo_r x`. 15 | 16 | -------------------------------------------------------------------------------- /src/commands/index.md: -------------------------------------------------------------------------------- 1 | # Commands 2 | 3 | ## Table of Contents 4 | - [Find Theorems and Constants](Find.thy) 5 | - [Datatypes](datatypes) 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/common_errors/index.md: -------------------------------------------------------------------------------- 1 | # Common Errors 2 | 3 |
    4 | {% for item in site.data.common_errors %} 5 |
  1. 6 |
    7 | 8 | {{ item.error_msg }} 9 | 10 | 11 | {{ item.explanation }} 12 | 13 |
    14 |
  2. 15 | {% endfor %} 16 |
17 | 18 | -------------------------------------------------------------------------------- /src/common_pitfalls/index.md: -------------------------------------------------------------------------------- 1 | # Common Pitfalls 2 | 3 |
    4 | {% for item in site.data.common_pitfalls %} 5 |
  1. 6 |
    7 | {{ item.title }} 8 | 9 | {{ item.explanation }} 10 | 11 |
    12 |
  2. 13 | {% endfor %} 14 |
15 | 16 | -------------------------------------------------------------------------------- /src/general/index.md: -------------------------------------------------------------------------------- 1 | # General Tips 2 | 3 | On [isabelle.systems](https://isabelle.systems), you can find 4 | a collection of links to useful Isabelle resources. 5 | In particular, the mailing lists and Zulip are a good place to ask questions. 6 | -------------------------------------------------------------------------------- /src/proofs/finite_sets/Finite_Sets.thy: -------------------------------------------------------------------------------- 1 | theory Finite_Sets 2 | imports Main 3 | begin 4 | 5 | section \Lemmas For Proving Finiteness of Sets\ 6 | 7 | text \In an Isar proof, these two are typically your silver bullets for proving the finiteness 8 | of sets:\ 9 | lemmas finite_helpers = finite_imageI finite_subset 10 | 11 | text \Some more helpful lemmas:\ 12 | lemmas more_finite_helpers = finite_cartesian_product finite_vimageI finite_Un 13 | 14 | \ \Example:\ 15 | lemma 16 | "finite {x + y | x y :: nat. x < n \ y \ {0..3} \ x \ y}" (is "finite ?S") 17 | proof - 18 | have "?S \ (\(x, y). x + y) ` ({0.. {0..3})" 19 | by auto 20 | also have "finite \" 21 | \ \This is just to show what is going on: \by simp\ would also do the job.\ 22 | by (intro finite_imageI finite_cartesian_product finite_atLeastLessThan finite_atLeastAtMost) 23 | finally (finite_subset) show ?thesis . 24 | \ \Instead of giving @{thm finite_subset} explicitly, we could also have declared it like this: 25 | \<^verbatim>\lemmas [trans] = finite_subset\.\ 26 | qed 27 | 28 | text \ 29 | For automated proofs, it can often help to just pass these with the \<^verbatim>\intro\ modifier 30 | to @{method auto} and friends. 31 | The theorem @{thm finite_imageI} is set up as an default, but it can help to add \<^verbatim>\intro!\. 32 | Have a look at the example of the end of the file, to see both theorems in action in an 33 | automated proof. 34 | \ 35 | 36 | 37 | 38 | section \Simproc \<^verbatim>\finite_Collect\\ 39 | text \ 40 | The simproc \<^verbatim>\finite_Collect\ can be used to solve certain finiteness proof oblgations. 41 | Essentially, the simproc attempts to rewrite set comprehensions to terms that consist 42 | of applications @{term image}, @{term vimage}, @{term "(\)"}, 43 | and @{term "(\)"} as far as possible. 44 | Below is an example from @{theory HOL.Relation}. 45 | \ 46 | lemma "finite (r\) = finite r" 47 | unfolding converse_def conversep_iff using [[simproc add: finite_Collect]] 48 | apply simp \ \The set was rewritten to an application of @{term image}.\ 49 | by (auto elim: finite_imageD simp: inj_on_def) 50 | 51 | 52 | section \Tuning The Simplifier For Finiteness Proofs\ 53 | 54 | subsection \Rewriting to Images\ 55 | text \ 56 | One useful technique is to rewrite set comprehensions to images of sets under functions as far as 57 | possible by passing @{thm setcompr_eq_image} or its \n\-ary generalizations to the simplifier. 58 | \ 59 | 60 | text \Here is the \2\-ary generalization of @{thm setcompr_eq_image}.\ 61 | lemma setcompr_eq_image2: 62 | "{f x y | x y. P x y} = (\(x, y). f x y) ` {(x, y). P x y}" 63 | using setcompr_eq_image[where f = "(\(x, y). f x y)" and P = "\(x, y). P x y"] by simp 64 | 65 | text \In this example, \<^verbatim>\finite_Collect\ still does the right thing:\ 66 | lemma 67 | assumes "finite A" 68 | shows "finite {f x | x. x \ A \ P x}" 69 | using assms [[simproc add: finite_Collect]] by simp 70 | 71 | text \Here, however, it will produce quite a mess:\ 72 | lemma 73 | assumes "finite (A \ B)" 74 | shows "finite {f x y | x y. x \ A \ y \ B \ R x y}" 75 | using assms [[simproc add: finite_Collect]] 76 | apply simp 77 | oops 78 | 79 | text \Instead, we use @{thm setcompr_eq_image2} to an image:\ 80 | lemma 81 | assumes "finite (A \ B)" 82 | shows "finite {f x y | x y. x \ A \ y \ B \ R x y}" 83 | using assms 84 | apply (simp add: setcompr_eq_image2) \ \Looks much better.\ 85 | \ \\<^verbatim>\auto\ will apply the following theorems to solve the goal:\ 86 | thm finite_imageI finite_subset[rotated] 87 | \ \We rotate @{thm finite_subset} to use it as an \elim\-rule\ 88 | apply (auto elim: finite_subset[rotated]) 89 | done 90 | 91 | 92 | subsection \Finiteness With Context\ 93 | text \The theorem @{thm finite_Collect_bounded_ex} (and its obvious \n\-ary generalizations) 94 | can be highly useful for proving finiteness of sets where some of the finiteness theorems 95 | one wants to apply rely on a precondition to hold. Consider the following example:\ 96 | lemma 97 | "finite {s'. \s. Some s = x \ Some s' = g s}" \ \Clearly there is at most one such \s'\.\ 98 | proof - 99 | \ \The statement follows quite immediately from this lemma.\ 100 | have Some_finite: "finite {x. Some x = y}" for y :: "'x option" 101 | using not_finite_existsD by fastforce 102 | show ?thesis 103 | \ \Something like this will not work, however:\ 104 | \ \apply (auto intro: Some_finite)\ 105 | \ \The reason is that we need \<^emph>\context\. 106 | The argument should go along the lines: there are only finitely such \s\, 107 | and for each \s\ there are only finitely many such \s'\, thus the whole set is finite.\ 108 | apply (subst finite_Collect_bounded_ex) \ \this gives us what we want\ 109 | apply (intro allI impI Some_finite)+ 110 | done 111 | qed 112 | 113 | 114 | subsection \Advanced Examples Of Proving Finiteness With the Simplifier\ 115 | 116 | text \The simplifier can sometimes be surprisingly good at solving finiteness goals. 117 | Here is an example:\ 118 | lemma 119 | assumes "finite A" "finite (Collect P)" 120 | shows "finite {(a,b,c) | a b c. a \ A \ b < (n :: nat) \ P c}" 121 | using assms [[simproc add: finite_Collect]] by simp 122 | 123 | text \This shows what is going on here:\ 124 | lemma 125 | assumes "finite A" "finite (Collect P)" 126 | shows "finite {(a,b,c) | a b c. a \ A \ b < (n :: nat) \ P c}" 127 | using [[simproc add: finite_Collect]] apply simp 128 | apply (intro finite_SigmaI finite_Collect_less_nat assms) 129 | done 130 | 131 | text \A slightly more complicated variant:\ 132 | lemma 133 | assumes "finite A" "finite (Collect P)" 134 | shows "finite {(d, c, a, b) | a b c d. d < (n :: nat) \ P c \ (a, b) \ A}" 135 | using assms [[simproc add: finite_Collect]] by simp 136 | 137 | text \Here is a more involved example:\ 138 | lemma 139 | fixes n :: nat 140 | assumes "finite A" 141 | shows "finite {t. \ a c. a \ A \ c < n \ t = (a,c)}" 142 | using assms by simp 143 | 144 | text \Here is an explanation of what is going on:\ 145 | lemma 146 | fixes n :: nat 147 | assumes "finite A" 148 | shows "finite {t. \ a c. a \ A \ c < n \ t = (a,c)}" 149 | apply simp \ \First the simplifier applies some specific procedures for miniscoping\ 150 | apply (subst finite_Collect_bounded_ex) \ \Now, the context rule comes in\ 151 | apply (subst Collect_mem_eq, rule assms) \ \Solve first subgoal\ 152 | 153 | supply [simp del] = finite_Collect_bounded_ex 154 | apply(intro allI impI) 155 | \ \The simplifier walks down the propositional connectives using congruence rules\ 156 | apply (subst finite_Collect_bounded_ex) \ \Another application of the congruence rule\ 157 | apply (rule finite_Collect_less_nat) \ \Solve first subgoal\ 158 | apply (simp only: singleton_conv) \ \Rewrite to singleton set\ 159 | apply simp \ \The rest is trivial\ 160 | done 161 | 162 | 163 | section \Further Pointers\ 164 | text \For more examples and an attempt at an proof method for finiteness proof obligations, 165 | see \<^url>\https://github.com/wimmers/isabelle-finite\. 166 | It also contains the \n\-ary generalizations of @{thm setcompr_eq_image} 167 | and @{thm finite_Collect_bounded_ex}.\ 168 | 169 | end 170 | -------------------------------------------------------------------------------- /src/proofs/finite_sets/index.md: -------------------------------------------------------------------------------- 1 | # Finiteness of Sets 2 | 3 | See [Finite_Sets.thy](Finite_Sets.thy). 4 | -------------------------------------------------------------------------------- /src/proofs/index.md: -------------------------------------------------------------------------------- 1 | # Proofs 2 | 3 | ## Table of Contents 4 | - [Finiteness of Sets](finite_sets): how to prove the finiteness of sets 5 | - [Lemma Collections](lemma_collections): overview on useful lemma collections 6 | - [Methods](methods): overview on available proof methods 7 | - [Proof Patterns](proof_patterns): common proof patterns 8 | -------------------------------------------------------------------------------- /src/proofs/lemma_collections.md: -------------------------------------------------------------------------------- 1 | # Lemma Collections 2 | 3 | The default setup of the simplifier and other automatic proof methods in Isabelle includes lemmas which are considered generally useful 4 | and (almost) never make a goal harder to prove (or unprovable). 5 | Apart from this default setup, Isabelle offers some collections of lemmas that are useful to prove specific kinds of goals: 6 | 7 | 8 | 9 | 10 | 11 | 12 | {% for item in site.data.lemma_collections %} 13 | 14 | 15 | 16 | 17 | {% endfor %} 18 |
CollectionUsage
{{ item.name }}{{ item.explanation }}
19 | -------------------------------------------------------------------------------- /src/proofs/methods/Chained_Facts.thy: -------------------------------------------------------------------------------- 1 | \<^marker>\author Simon Wimmer\ 2 | theory Chained_Facts 3 | imports Main 4 | begin 5 | 6 | text \To better understand the way methods work in Isabelle, 7 | it is important to understand the concept of \chained facts\. 8 | This often causes confusion, particularly to the users of 9 | the \intro/elim\ and \rule/erule\ methods.\ 10 | 11 | section \Basic Example and Explanation\ 12 | 13 | text \In the following examples, @{method rule} and @{method intro} behave the same way.\ 14 | 15 | lemma 16 | "\x::nat. x > 0" 17 | apply (rule exI) 18 | apply (rule zero_less_one) 19 | done 20 | 21 | lemma 22 | "\x::nat. x > 0" 23 | apply (intro exI) 24 | apply (rule zero_less_one) 25 | done 26 | 27 | text \We now \<^emph>\chain\ in the fact @{thm zero_less_one} with \using\.\ 28 | lemma 29 | "\x::nat. x > 0" 30 | using zero_less_one 31 | apply (rule exI) 32 | done 33 | 34 | lemma 35 | "\x::nat. x > 0" 36 | using zero_less_one 37 | apply (intro exI) 38 | apply assumption 39 | done 40 | 41 | text \We note a slight difference. In the variant with intro, a trivial goal remains 42 | that we need to solve by \assumption\. 43 | The reason is that \intro\ is a \<^emph>\simple method\ in Isabelle jargon, while \rule\ is \<^emph>\proper\. 44 | Simple methods ignore chained facts and insert them into the goal state, 45 | while proper methods will usually act on them in some way. 46 | 47 | In the example, \rule\ matches the chained fact @{thm zero_less_one} on the first premise 48 | of @{thm exI}, and the conclusion of @{thm exI} on the goal. 49 | As @{thm exI} only has one premise, no subgoals are left. 50 | In contrast, \intro\ simply ignores @{thm zero_less_one} and matches @{thm exI} only on 51 | the conclusion. The fact is nevertheless inserted into the goal that arises, which 52 | is why we can solve it by \assumption\. 53 | 54 | Most older proof methods such as \simp\, \auto\, or \blast\ are simple. 55 | Two noteworthy proper methods are \induction\ and \cases\. 56 | \ 57 | 58 | 59 | section \Inserting Facts\ 60 | 61 | text \The behaviour of simple methods can be simulated by \-\, which will insert 62 | any chained facts into the current goal state.\ 63 | lemma 64 | "\x::nat. x > 0" 65 | using zero_less_one 66 | apply - 67 | apply (rule exI) 68 | apply assumption 69 | done 70 | 71 | text \Method insert will ignore any chained facts and insert its arguments in the goal state:\ 72 | lemma 73 | "\x::nat. x > 0" 74 | using exI 75 | apply (insert zero_less_one) 76 | apply (rule exI) 77 | apply assumption 78 | done 79 | 80 | 81 | section \Chained Facts Are Chained\ 82 | 83 | text \Chained facts are chained through method combinators.\ 84 | lemma \ \This works.\ 85 | "\x::nat. x > 0" 86 | apply (insert zero_less_one, rule exI) 87 | apply assumption 88 | done 89 | 90 | lemma \ \This fails because \0 \ 1\ does not match \0 < 1\.\ 91 | "\x::nat. x > 0" 92 | using zero_neq_one 93 | \<^cancel>\apply (insert zero_less_one, rule exI)\ 94 | oops 95 | 96 | lemma \ \This works again.\ 97 | "\x::nat. x > 0" 98 | using zero_neq_one 99 | apply (insert zero_less_one) 100 | apply (rule exI) 101 | apply assumption 102 | done 103 | 104 | section \More Examples\ 105 | 106 | text \The following examples outline some typical Isar proof patterns that come up when 107 | chained facts are involved.\ 108 | 109 | notepad 110 | begin 111 | have fin_lt_5: "finite {x::nat. x < 5}" 112 | by auto 113 | moreover have subs: "{x::nat. x < 4} \ {x::nat. x < 5}" 114 | by auto 115 | ultimately have "finite {x::nat. x < 4}" \ \Both previous facts are currently chained.\ 116 | \<^cancel>\apply (rule finite_subset)\ \ \This fails. Both premises are given but in the wrong order.\ 117 | \<^cancel>\apply (rule finite_subset[rotated])\ \ \Hence this works.\ 118 | \<^cancel>\apply (erule finite_subset[rotated])\ \ \ 119 | This fails because after matching the premises against the chained facts, 120 | there is no premise left for \erule\ to match on.\ 121 | \<^cancel>\apply (intro finite_subset)\ \ \This loops. Be careful! Better stop it quickly.\ 122 | apply (elim finite_subset) \ \ 123 | This does not loop because \elim\ matches any of the chained facts against the first premise.\ 124 | apply assumption 125 | \<^cancel>\apply (elim finite_subset, assumption)\ \ \ 126 | This does not work because \assumption\ is not happy with chained facts.\ 127 | \<^cancel>\apply (rule finite_subset[rotated])\ \ \Hence this works.\ 128 | done 129 | end 130 | 131 | 132 | lemma length_gt_0_E: 133 | assumes "length xs = n" "n > 0" 134 | obtains y ys where "xs = y # ys" 135 | using assms by (cases xs) auto 136 | 137 | notepad 138 | begin 139 | let ?xs = "[1::nat, 2, 3]" 140 | have three_gt_0: "(3 :: nat) > 0" 141 | by auto 142 | have len: "length ?xs = 3" 143 | by auto 144 | then obtain y ys where "?xs = y # ys" 145 | by (rule length_gt_0_E) simp 146 | from len obtain y ys where "?xs = y # ys" 147 | \<^cancel>\apply (intro length_gt_0_E)\ \ \Loops. For this kind of \elim\-rules \intro\ is useless.\ 148 | by (elim length_gt_0_E; simp) 149 | from len three_gt_0 obtain y ys where "?xs = y # ys" 150 | by (rule length_gt_0_E) 151 | \ \Facts in wrong order.\ 152 | from three_gt_0 len obtain y ys where "?xs = y # ys" 153 | \<^cancel>\apply (rule length_gt_0_E)\ \ \Wrong fact order. Fails.\ 154 | by - (rule length_gt_0_E) \ \Insert facts first.\ 155 | from three_gt_0 len obtain y ys where "?xs = y # ys" 156 | by - (erule length_gt_0_E) \ \Matching the first fact explicitly.\ 157 | from three_gt_0 len obtain y ys where "?xs = y # ys" 158 | by (elim length_gt_0_E) \ \In this type of situation \elim\ is cleaner.\ 159 | from three_gt_0 len obtain y ys where "?xs = y # ys" 160 | \<^cancel>\apply (rule length_gt_0_E)\ \ \Wrong fact order. Fails.\ 161 | by (elim length_gt_0_E) \ \In this type of situation \elim\ is cleaner.\ 162 | from len three_gt_0 obtain y ys where "?xs = y # ys" 163 | by (elim length_gt_0_E) \ \Because it works essentially uniformly w.r.t\ to fact order.\ 164 | end 165 | 166 | 167 | section \Notes\ 168 | text \ 169 | \<^item> Eisbach methods are usually proper and can act on the chained facts in various ways. 170 | You can find more information in the Eisbach user manual. 171 | \<^item> In Isabelle/ML, the combinator @{ML SIMPLE_METHOD} is used to turn tactics into simple methods. 172 | \ 173 | 174 | end 175 | -------------------------------------------------------------------------------- /src/proofs/methods/index.md: -------------------------------------------------------------------------------- 1 | # Proof Methods 2 | 3 | To get started, have a look at [Chained facts and proof methods](Chained_Facts.thy). 4 | It introduces the concept of *chained facts* as well as *simple* and *proper methods*. 5 | Moreover, it talks about the behaviour of the methods `intro/elim`, `rule/erule`, `-` and `insert`. 6 | 7 | Below, you can find a list of methods and their description. 8 | In the following, all methods only act on the first subgoal unless otherwise stated and fail if they cannot solve the goal, unless stated otherwise. 9 | 10 | ## General-Purpose Automation 11 | 12 | ### Simplifier 13 | 14 | - `simp` rewrites the goal using the simplifier (for more information, refer to the cookbook section on the simplifier). This method never fails except when it cannot perform any simplification at all. 15 | - `simp_all` is like `simp`, but acts on *all* goals 16 | 17 | You can find a list of useful simpsets [here]({{ "/src/proofs/lemma_collections" | relative_url }}). 18 | 19 | ### Classical Automation 20 | 21 | - `blast` is a Tableaux prover that is good at predicate logic and set theory. It can take claset modifiers like `intro`, `dest`, `elim`. It can occasionally solve goals involving equality, but generally handles equality rather poorly compared to methods that use the simplifier. However, for purely ‘logical’ goals that do not require rewriting, it can often be superior. 22 | - `fastforce` and `force` perform both classical proof search using the claset and rewriting using the simplifier. They differ in which heuristic the classical search uses. 23 | - `auto` is similar to `fastforce`/`force`, but does not try quite as hard. It also acts on *all* goals and never fails (unless it cannot do *anything*). It uses a variant of `blast` internally to close prove goals. Two numeric parameters can be used to steer auto's proof search: 24 | in `auto b d`, `b` specifies the search depth of `blast` and `d` specifies the number of classical proof steps to be taken. 25 | The defaults are `b = 4` and `d = 2`, and typically it is more helpful to modify `d`—if one wants to use these modifiers at all. 26 | - `auto2` TODO 27 | 28 | The following methods are a bit more specialised, but still useful in some cases: 29 | 30 | - `metis` and `meson` are automated theorem provers for first-order logic. They are sometimes suggested by `sledgehammer` or `try0`. Unlike most other Isabelle automation, they do not use any fact database (like the claset), so they will usually require the user to pass many low-level facts explicitly to them, which makes them impractical to use manually (as opposed to generated by `sledgehammer`). However, there are occasional cases where fairly big (but logically simple) goals can easily be solved by `metis` and `meson` but not by any of Isabelle's other methods. 31 | - `smt` (an Isabelle wrapper around the Z3 SMT solver) also needs to be given relevant facts manually and is sometimes suggested by sledgehammer. Unlike the previous two, however, it also knows some things about linear arithmetic and a few other things. 32 | - `satx` uses an external proof-producing SAT solver, replaying its proof in Isabelle 33 | - `argo` is a prover for propositional logic with equality and linear arithmetic 34 | 35 | ### Less Relevant Methods 36 | 37 | The following methods are not used much these days and you can probably safely ignore them: 38 | 39 | - `fast`, `slow`, and `best` are classical provers with different heuristics and roughly the same field of applications as `blast`. 40 | - `slowsimp` and `bestsimp` are variants of `fastforce` with different heuristics. 41 | 42 | ### Summary 43 | 44 | The most widely used and useful methods are `simp`/`simp_all` and `auto`. Since they never fail, they are also very useful for exploration: a usual pattern in writing Isabelle proofs is to do `apply auto` and inspect the proof state to see which goals are ‘left over’. One can then give additional facts to the methods or prove remaining goals separately until nothing remains. 45 | 46 | If there is a goal that `auto` should be able to solve but somehow cannot, `force` often works because it tries a bit harder. Despite its name, `fastforce` is usually not really faster than `force`. Which of them is better in any given case seems to be quite random, and it usually does not matter. 47 | 48 | ## One-Step Methods 49 | 50 | - `assumption` solves the goal with one of the premises 51 | - `subst` performs single-step rewriting of the goal with a given equation. Optional arguments can be used to rewrite the premises instead, or to specify the position to rewrite. 52 | - `rewrite` is essentially a more powerful version of `subst`. It allows one to use term patterns to specify the position where the rewriting should be applied. It needs to be imported from `HOL-Library.Rewrite`. Some instructive examples can be found in [HOL-ex.Rewrite_Examples](https://isabelle.in.tum.de/library/HOL/HOL-ex/Rewrite_Examples.html). 53 | - `rule` performs a single resolution step (it ‘applies’ a rule to the current goal, reasoning backwards) 54 | - `drule` and `frule` peform a single step of foward reasoning (they ‘apply’ a rule to one of the premises, yielding a new premise). The difference is that `drule` deletes the premise that is being transformed, whereas `frule` does not. 55 | - `erule` applies resolution of a rule with the goal and with one of the premises being consumed by the first assumption of the rule. An optional numeric argument can be used to consume more than one premise. It is more or less equivalent to `rule, assumption`. This is often useful for elimination rules (e.g. case analyses or rules written in the `fixes ... assume ... obtains ...` format). 56 | - `intro` applies resolution with the given rules repeatedly. 57 | - `elim` applies elimination with the given rules repeatedly. 58 | - `safe` applies safe rules from the claset only. This is typically used to split conjunctions in goals with several subgoals, or to split conjunctions in the assumptions by several assumptions, or to prove set equivalence by proving membership in both directions. However, sometimes it can do a bit too much (e.g. `x ∈ {a}` becomes `x ∉ {} ⟹ x = a`). In those cases, using the `intro`/`elim` methods by hand is preferable. 59 | - `clarsimp` is similar to `safe` but also invokes the `simplifier`. You can think of it as a less aggressive version of `auto`. 60 | - `clarify` TODO: What does clarify do precisely 61 | 62 | All of these except `drule`, `frule`, `erule` are often useful even in high-level proofs, especially when used as the first step of a proof. They are often used as the initial proof method, and the goals they produce are then ‘finished off’ using e.g. `auto`. 63 | 64 | ## Transfer 65 | 66 | TODO 67 | 68 | ## Special-Purpose Automation 69 | 70 | ### Termination 71 | 72 | - `relation` can be used in manual termination proofs by giving a suitable well-founded relation by hand (often used in combination with `measure` or `<*lex*>`/`<*mlex*>`). 73 | - `lexicographic_order` attempts to prove termination of a multivariate function automatically by finding a lexicographic combination of termination measures. 74 | - `size_change` is a more sophisticated termination method TODO what does it do 75 | 76 | ### Arithmetic 77 | 78 | - `linarith` solves linear arithmetic goals on natural numbers, integers, and reals. It deals with disjunctions by performing a case distinction, so if the goal contains many disjunctions, this becomes prohibitively slow. 79 | - `smt` also supports linear arithmetic and often deals with disjunctions much better than `linarith`. 80 | - `presburger` solves Presburger arithmetic goals. It can be very useful to prove goals involving divisibility and `mod` on naturals and integers, but in practice it is often prohibitively slow on all but very small goals. TODO link 81 | - `arith` was created to become a wrapper tactic for all kinds of arithmetic decision procedures, but in practice, it only calls `linarith` and `presburger` at the moment. 82 | 83 | ### Polynomials 84 | 85 | - `sos` can prove polynomial inequalities using sum-of-squares witnesses. It is complete for univariate polynomials, but the witness search can often take quite long for larger ones. 86 | - `sturm` can prove various things about univariate real polynomials, such as non-negativity, number of roots, etc. 87 | 88 | ### Other 89 | 90 | - `measurable` proves measurability of functions and sets 91 | - `pratt` can prove that a number is prime using prime certificates. This works even for fairly large primes. TODO link AFP 92 | - `master_theorem` can prove asymptotic relations for divide-and-conquer recurrences corresponding to a generalised version of the Master Theorem. TODO link AFP 93 | - `approximation` proves inequalities on various real-valued functions using interval arithmetic. TODO link 94 | - `real_asymp` proves various asymptotic properties of concrete real-valued functions, such limits, ‘Big-O’, and asymptotic equivalence 95 | - `eval_winding` provides support for evaluating winding numbers of paths in the complex plane in many practically relevant cases TODO link AFP 96 | -------------------------------------------------------------------------------- /src/proofs/proof_patterns/index.md: -------------------------------------------------------------------------------- 1 | # Proof Patterns 2 | 3 | Chapter 1 of the [Isabelle/Isar Reference Manual](https://isabelle.in.tum.de/doc/isar-ref.pdf#chapter.1) 4 | and 5 | Chapter 4 of the official [Programming and Proving in Isabelle/HOL](https://isabelle.in.tum.de/dist/Isabelle2021-1/doc/prog-prove.pdf#chapter.4) 6 | tutorial provide a comprehensive guide for common proof patterns. 7 | Here we list some additional patterns. 8 | Throughout this page, placeholders are put between angle braces `<...>`. 9 | 10 | ## Definitions in Lemmas 11 | 12 | When stating a lemma, 13 | you can use the following syntax to introduce a local definition: 14 | 15 | ``` 16 | defines "" 17 | ``` 18 | 19 | The fact of such a definition then becomes accessible by `_def`. 20 | 21 | **Example:** `defines "m ≡ n mod k"`; accessible through `m_def` 22 | 23 | ## Definitions in Proofs 24 | 25 | Inside a proof, 26 | you can use the following syntax to introduce a local definition: 27 | 28 | ``` 29 | define where "" 30 | ``` 31 | 32 | The fact of such a definition then becomes accessible by `_def`. 33 | 34 | Note that local definitions are different from term abbreviations 35 | introduced by `let` (cf [Isabelle/Isar Reference Manual](https://isabelle.in.tum.de/doc/isar-ref.pdf#command.let)): 36 | the former are visible within the logic as actual equations 37 | while the latter disappear when Isabelle processes the input. 38 | 39 | **Example:** `define m where "m ≡ n mod k"`; accessible through `m_def` 40 | 41 | -------------------------------------------------------------------------------- /src/searching_isabelle/index.md: -------------------------------------------------------------------------------- 1 | # Searching Isabelle 2 | 3 | 1. To search for theorems and constants inside imported sessions, check out this [tutorial]({{ "/src/commands/Find.thy" | relative_url }}). 4 | 2. For a string- and entity-based search platform including the AFP, 5 | check out [search.isabelle.in.tum.de](https://search.isabelle.in.tum.de/). 6 | 3. For a concept-oriented search platform including the AFP, 7 | check out [SErAPIS](https://behemoth.cl.cam.ac.uk/search/). 8 | 9 | --------------------------------------------------------------------------------