├── .gitignore ├── .travis.yml ├── 01_Introduction.org ├── 02_Dependent_Type_Theory.org ├── 03_Propositions_and_Proofs.org ├── 04_Quantifiers_and_Equality.org ├── 05_Interacting_with_Lean.org ├── 06_Inductive_Types.org ├── 07_Induction_and_Recursion.org ├── 08_Building_Theories_and_Proofs.org ├── 09_Type_Classes.org ├── 10_Structures_and_Records.org ├── 11_Tactic-Style_Proofs.org ├── 12_Axioms.org ├── 13_More_Tactics.org ├── A1_Quick_Reference.org ├── Cask ├── LICENSE ├── Makefile ├── README.md ├── adjcalc.sty ├── adjustbox.sty ├── basics.org ├── collectbox.sty ├── csquotes.sty ├── css ├── code.css ├── images │ ├── handle-h.png │ ├── handle-v.png │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ ├── ui-bg_flat_75_ffffff_40x100.png │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ ├── ui-bg_glass_65_ffffff_1x400.png │ ├── ui-bg_glass_75_dadada_1x400.png │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ ├── ui-bg_glass_95_fef1ec_1x400.png │ ├── ui-bg_highlight-soft_75_cccccc_1x100.png │ ├── ui-icons_222222_256x240.png │ ├── ui-icons_2e83ff_256x240.png │ ├── ui-icons_454545_256x240.png │ ├── ui-icons_888888_256x240.png │ └── ui-icons_cd0a0a_256x240.png ├── jquery-ui.css ├── main_live.css └── tutorial.css ├── deploy.sh ├── elisp ├── lean-export-util.el ├── org-html-export.el └── org-pdf-export.el ├── etoolbox.sty ├── example.org ├── fonts ├── DejaVuSansMono-Bold.eot ├── DejaVuSansMono-Bold.svg ├── DejaVuSansMono-Bold.ttf ├── DejaVuSansMono-Bold.woff ├── DejaVuSansMono.eot ├── DejaVuSansMono.svg ├── DejaVuSansMono.ttf ├── DejaVuSansMono.woff ├── FreeMono.eot ├── FreeMono.otf ├── FreeMono.svg ├── FreeMono.ttf ├── FreeMono.woff ├── FreeMono.woff2 ├── FreeMonoBold.eot ├── FreeMonoBold.svg ├── FreeMonoBold.ttf ├── FreeMonoBold.woff └── FreeMonoBold.woff2 ├── footer ├── .gitignore ├── bib.html.org └── latex.org ├── gitinfo.sty ├── gitsetinfo.sty ├── header ├── .gitignore ├── html.org ├── index.html.org ├── l3kernel.tar.gz ├── latex.org ├── latex.tex ├── latex_quickref.org └── latex_quickref.tex ├── images ├── android-chrome-144x144.png ├── android-chrome-192x192.png ├── android-chrome-36x36.png ├── android-chrome-48x48.png ├── android-chrome-72x72.png ├── android-chrome-96x96.png ├── apple-touch-icon-114x114.png ├── apple-touch-icon-120x120.png ├── apple-touch-icon-144x144.png ├── apple-touch-icon-152x152.png ├── apple-touch-icon-180x180.png ├── apple-touch-icon-57x57.png ├── apple-touch-icon-60x60.png ├── apple-touch-icon-72x72.png ├── apple-touch-icon-76x76.png ├── apple-touch-icon-precomposed.png ├── apple-touch-icon.png ├── book.svg ├── browserconfig.xml ├── console.svg ├── dropbox.svg ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon-96x96.png ├── favicon.ico ├── favicon.pxm ├── gear.svg ├── lean_logo_small.svg ├── load.svg ├── manifest.json ├── mstile-144x144.png ├── mstile-150x150.png ├── mstile-310x150.png ├── mstile-310x310.png ├── mstile-70x70.png ├── new.svg ├── run.svg ├── save.svg ├── share.svg ├── square-landscape-main-code-console.svg ├── square-landscape-main-code.svg ├── square-portrait-main-code-console.svg ├── square-portrait-main-code.svg └── square.svg ├── imakeidx.sty ├── index.html ├── js ├── .gitignore ├── completion.js ├── completion_input.in ├── completion_input.lean ├── input-method.js └── main_live.js ├── juicy-ace-editor.html ├── lean.bib ├── mathspec.sty ├── merge_chapters.sh ├── minted.sty ├── newunicodechar.sty ├── structures.org ├── tc-pgf.def ├── test.sh ├── test_js.sh ├── trimclip.sty ├── ulem.sty ├── unixode.sty ├── xetex-inputenc.sty ├── xparse.sty ├── xstring.sty └── xstring.tex /.gitignore: -------------------------------------------------------------------------------- 1 | .lean_trace 2 | *.acn 3 | *.aux 4 | *.aux 5 | *.bbl 6 | *.blg 7 | *.fdb_latexmk 8 | *.fls 9 | *.glo 10 | *.html 11 | *.idx 12 | *.ilg 13 | *.ind 14 | *.ist 15 | *.log 16 | *.out 17 | *.out.pyg 18 | *.pdf 19 | *.pyg 20 | *.tex 21 | *.toc 22 | *~ 23 | .cask/ 24 | watchman/ 25 | pygments-main/ 26 | auto/ 27 | tutorial.html 28 | tutorial.org 29 | _minted-*/ 30 | .DS_Store 31 | gitHeadInfo.gin 32 | *.org.*.lean 33 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | os: 2 | - linux 3 | language: c++ 4 | sudo: true 5 | dist: trusty 6 | cache: apt 7 | addons: 8 | apt: 9 | sources: 10 | - ubuntu-toolchain-r-test 11 | packages: 12 | - cmake 13 | - cmake-data 14 | - mercurial 15 | - python2.7 16 | - texlive-latex-recommended 17 | - texlive-humanities 18 | - texlive-xetex 19 | - texlive-science 20 | - texlive-latex-extra 21 | - texlive-luatex 22 | - texlive-fonts-recommended 23 | - latexmk 24 | - latex-xcolor 25 | - lmodern 26 | - pgf 27 | - moreutils 28 | - nodejs 29 | - npm 30 | - g++-5 31 | - libstdc++-5-dev 32 | - libgmp-dev 33 | - libmpfr-dev 34 | - liblua5.2-dev 35 | - emacs24 36 | env: 37 | global: 38 | # GH_TOKEN=[secure] (to push to leanprover org) 39 | - secure: "LAgBomK36BzF2mN/lOwua+gDzLgF6RyuMYBjMlP5KY3knUZT8m/9wff2GlWGm87anb6aIJH69ERjVyFU4sWi9qcD+26vs1m9agMFxuqTfpibeDoz/rd9D/9LA3mNeO6v5kR2FTQ/OTTC6nMC4olRxdzz22Jg9ly7cNzfFPuSGFA=" 40 | # REPOn=BLESSED (to perform extra stuff only for pushes to the blessed repo) 41 | - secure: "Du/ZXFXdhRZL6AU6t6G8A3BNr3oPpHK4h2UCK00b+bgonHy7kDgTE0YxRVOf8VpXqfJwekzT4hWJhnKXasTp5avNEVEbdWC4nyM4tZbl6a8g8iI3Oo+JB6seSO6fIhrv6sZ7BCa6iuKDwzWJ0sQnXL+kx/zUqcle5eVUu5ic/24=" 42 | matrix: 43 | - TEST=FALSE 44 | 45 | before_install: 46 | - mkdir ~/bin 47 | - export PATH="/home/travis/.cask/bin:~/bin:$PATH" 48 | - curl -fsSL https://raw.github.com/cask/cask/master/go | python 49 | - cask 50 | - tar xvfz header/l3kernel.tar.gz -C ~/ 51 | 52 | install: 53 | # Install Lean dependencies 54 | - git clone https://github.com/leanprover/lean 55 | # Build Lean 56 | - if [[ $TEST == TRUE ]] ; then 57 | cd lean && 58 | mkdir build && 59 | cd build && 60 | cmake -DIGNORE_SORRY=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++-5 ../src && 61 | make && 62 | cd ../../; 63 | fi 64 | # bibtex2html 65 | - wget --no-check-certificate http://www.lri.fr/\~filliatr/ftp/bibtex2html/bibtex2html-1.98-linux.tar.gz 66 | - tar xvfz bibtex2html-1.98-linux.tar.gz 67 | - cp -v bibtex2html-1.98-linux/* ~/bin 68 | - rm -rf bibtex2html-1.98-linux bibtex2html-1.98-linux.tar.gz 69 | - sudo npm -g i cssmin minify 70 | 71 | script: 72 | - EMACS_BIN=emacs make 73 | # Build completion.js 74 | - echo "var completions = [" > js/completion.js 75 | - ./lean/bin/lean --server < js/completion_input.in | grep "|" | grep -v "^private\." | sort | uniq | sed -e "s/\([^|]\+\)|\(.\+\)/{name:\"\1\", value:\"\1\", meta:\"\2\"},/" >> js/completion.js 76 | - echo "]" >> js/completion.js 77 | # Build input-method.js 78 | - cask exec emacs --no-site-file --no-site-lisp -q --batch -l ./elisp/org-html-export.el -l ./lean/src/emacs/lean-input.el -f lean-input-export-translations-to-stdout > js/input-method.js 79 | # Push to gh-pages 80 | - if [[ "${REPO}" == "BLESSED" ]] && [[ "${TRAVIS_PULL_REQUEST}" == "false" ]] ; then 81 | git config --global user.email "notifications@travis-ci.org" && 82 | git config --global user.name "Travis CI" && 83 | git checkout --orphan gh-pages && 84 | rm -f .git/index && 85 | git add -f *.html tutorial.pdf quickref.pdf && 86 | for CSS in css/*.css; do cssmin ${CSS} | sponge ${CSS} ; done && 87 | git add css && 88 | git add images && 89 | git add fonts && 90 | for JS in js/*.js; do minify ${JS} | sponge ${JS} ; done && 91 | git add -f js/* && 92 | rm -rf pygments-main && 93 | git clean -fxd && 94 | git commit -m "Update `date -R`" && 95 | git push -q https://soonhokong:${GH_TOKEN}@github.com/leanprover/tutorial.git +HEAD:gh-pages && 96 | git checkout -f master; 97 | fi 98 | # Test 99 | - if [[ $TEST == TRUE ]] ; then 100 | LEAN_BIN=lean/bin/lean make -j2 test; 101 | fi 102 | - if [[ $TEST_JS == TRUE ]] ; then 103 | make -j2 test_js; 104 | fi 105 | 106 | notifications: 107 | email: 108 | recipients: 109 | - lean-build@googlegroups.com 110 | -------------------------------------------------------------------------------- /01_Introduction.org: -------------------------------------------------------------------------------- 1 | #+Title: Theorem Proving in Lean 2 | #+Author: [[http://www.andrew.cmu.edu/user/avigad][Jeremy Avigad]], [[http://leodemoura.github.io][Leonardo de Moura]], [[http://www.cs.cmu.edu/~soonhok][Soonho Kong]] 3 | 4 | * Introduction 5 | 6 | #+begin_warning 7 | Please note that this is the tutorial for [[https://github.com/leanprover/lean2][Lean 2]], which allows the use of 8 | homotopy type theory (HoTT). It is /not/ the [[https://leanprover.github.io/introduction_to_lean][tutorial]] for the 9 | [[https://github.com/leanprover/lean][current version of Lean]]. 10 | #+end_warning 11 | 12 | ** Computers and Theorem Proving 13 | 14 | /Formal verification/ involves the use of logical and computational 15 | methods to establish claims that are expressed in precise mathematical 16 | terms. These can include ordinary mathematical theorems, as well as 17 | claims that pieces of hardware or software, network protocols, and 18 | mechanical and hybrid systems meet their specifications. In practice, 19 | there is not a sharp distinction between verifying a piece of 20 | mathematics and verifying the correctness of a system: formal 21 | verification requires describing hardware and software systems in 22 | mathematical terms, at which point establishing claims as to their 23 | correctness becomes a form of theorem proving. Conversely, the proof 24 | of a mathematical theorem may require a lengthy computation, in which 25 | case verifying the truth of the theorem requires verifying that the 26 | computation does what it is supposed to do. 27 | 28 | The gold standard for supporting a mathematical claim is to provide a 29 | proof, and twentieth-century developments in logic show most if not 30 | all conventional proof methods can be reduced to a small set of axioms 31 | and rules in any of a number of foundational systems. With this 32 | reduction, there are two ways that a computer can help establish a 33 | claim: it can help find a proof in the first place, and it can help 34 | verify that a purported proof is correct. 35 | 36 | /Automated theorem proving/ focuses on the "finding" 37 | aspect. Resolution theorem provers, tableau theorem provers, fast 38 | satisfiability solvers, and so on provide means of establishing the 39 | validity of formulas in propositional and first-order logic. Other 40 | systems provide search procedures and decision procedures for specific 41 | languages and domains, such as linear or nonlinear expressions over 42 | the integers or the real numbers. Architectures like SMT 43 | ("satisfiability modulo theories") combine domain-general search 44 | methods with domain-specific procedures. Computer algebra systems and 45 | specialized mathematical software packages provide means of 46 | carrying out mathematical computations, establishing mathematical 47 | bounds, or finding mathematical objects. A calculation can be viewed 48 | as a proof as well, and these systems, too, help establish 49 | mathematical claims. 50 | 51 | Automated reasoning systems strive for power and efficiency, often at 52 | the expense of guaranteed soundness. Such systems can have bugs, and 53 | it can be difficult to ensure that the results they deliver are 54 | correct. In contrast, /interactive theorem proving/ focuses on the 55 | "verification" aspect of theorem proving, requiring that every claim 56 | is supported by a proof in a suitable axiomatic foundation. This sets 57 | a very high standard: every rule of inference and every step of a 58 | calculation has to be justified by appealing to prior definitions and 59 | theorems, all the way down to basic axioms and rules. In fact, most 60 | such systems provide fully elaborated "proof objects" that can be 61 | communicated to other systems and checked independently. Constructing 62 | such proofs typically requires much more input and interaction from 63 | users, but it allows us to obtain deeper and more complex proofs. 64 | 65 | The /Lean Theorem Prover/ aims to bridge the gap between interactive 66 | and automated theorem proving, by situating automated tools and 67 | methods in a framework that supports user interaction and the 68 | construction of fully specified axiomatic proofs. The goal is to 69 | support both mathematical reasoning and reasoning about complex 70 | systems, and to verify claims in both domains. 71 | 72 | ** About Lean 73 | 74 | The /Lean/ project was launched by Leonardo de Moura at Microsoft 75 | Research Redmond in 2012. It is an ongoing, long-term effort, and 76 | much of the potential for automation will be realized only gradually 77 | over time. Lean is released under the Apache 2.0 license, a permissive 78 | open source license that permits others to use and extend the code and 79 | mathematical libraries freely. 80 | 81 | There are currently two ways to use Lean. The first is to run it from 82 | the web: a Javascript version of Lean, a standard library of 83 | definitions and theorems, and an editor are actually downloaded to 84 | your browser and run there. This provides a quick and convenient way to 85 | begin experimenting with the system. 86 | 87 | The second way to use Lean is to install and run it natively on your 88 | computer. The native version is much faster than the web version, and 89 | is more flexible in other ways, too. It comes with an Emacs mode that 90 | offers powerful support for writing and debugging proofs, and is much 91 | better suited for serious use. 92 | 93 | ** About this Book 94 | 95 | This book is designed to teach you to develop and verify proofs in 96 | Lean. Much of the background information you will need in order to do 97 | this is not specific to Lean at all. To start with, we will explain 98 | the logical system that Lean is based on, a version of /dependent type 99 | theory/ that is powerful enough to prove almost any conventional 100 | mathematical theorem, and expressive enough to do it in a natural 101 | way. We will explain not only how to define mathematical objects and 102 | express mathematical assertions in dependent type theory, but also how 103 | to use it as a language for writing proofs. 104 | 105 | In fact, Lean supports two versions of dependent type theory. The 106 | first is a variant of a system known as the /Calculus of Inductive 107 | Constructions/\cite{Coquand1988,pfenning:paulin:mohring:89}, or 108 | /CIC/. This is the system used by Lean's standard library, and is the 109 | focus of this tutorial. The second version of dependent type theory 110 | implements an axiomatic framework for [[http://homotopytypetheory.org/][homotopy type theory]], 111 | which we will discuss in a later chapter. 112 | 113 | Because fully detailed axiomatic proofs are so complicated, the 114 | challenge of theorem proving is to have the computer fill in as many 115 | of the details as possible. We will describe various methods to 116 | support this in dependent type theory. For example, we will discuss 117 | term rewriting, and Lean's automated methods for simplifying terms and 118 | expressions automatically. Similarly, we will discuss methods of 119 | /elaboration/ and /type inference/, which can be used to support 120 | flexible forms of algebraic reasoning. 121 | 122 | Finally, of course, we will discuss features that are specific to 123 | Lean, including the language with which you can communicate with the 124 | system, and the mechanisms Lean offers for managing complex theories 125 | and data. 126 | 127 | If you are reading this book within Lean's online tutorial system, you 128 | will see a copy of the Lean editor at right, with an output buffer 129 | beneath it. At any point, you can type things into the editor, press 130 | the "play" button, and see Lean's response. Notice that you can resize 131 | the various windows if you would like. 132 | 133 | Throughout the text you will find examples of Lean code like the one 134 | below: 135 | #+BEGIN_SRC lean 136 | -- BEGIN 137 | theorem and_commutative (p q : Prop) : p ∧ q → q ∧ p := 138 | assume Hpq : p ∧ q, 139 | have Hp : p, from and.elim_left Hpq, 140 | have Hq : q, from and.elim_right Hpq, 141 | show q ∧ p, from and.intro Hq Hp 142 | -- END 143 | #+END_SRC 144 | Once again, if you are reading the book online, you will see a button 145 | that reads "try it yourself." Pressing the button copies the example 146 | into the Lean editor with enough surrounding context to make the 147 | example compile correctly, and then runs Lean. We recommend running 148 | the examples and experimenting with the code on your own as you work 149 | through the chapters that follow. 150 | 151 | ** Acknowledgments 152 | 153 | This tutorial is an open access project maintained on Github. Many 154 | people have contributed to the effort, providing corrections, 155 | suggestions, examples, and text. We are grateful to Ulrik Buchholz, 156 | Nathan Carter, Amine Chaieb, Floris van Doorn, Anthony Hart, Sean 157 | Leather, Christopher John Mazey, Daniel Velleman, and Théo Zimmerman 158 | for their contributions, and we apologize to those whose names we have 159 | inadvertently omitted. 160 | -------------------------------------------------------------------------------- /13_More_Tactics.org: -------------------------------------------------------------------------------- 1 | #+Title: Theorem Proving in Lean 2 | #+Author: [[http://www.andrew.cmu.edu/user/avigad][Jeremy Avigad]], [[http://leodemoura.github.io][Leonardo de Moura]], [[http://www.cs.cmu.edu/~soonhok][Soonho Kong]] 3 | 4 | * More Tactics 5 | :PROPERTIES: 6 | :CUSTOM_ID: More_Tactics 7 | :END: 8 | 9 | We have seen that tactics provide a powerful language for describing 10 | and constructing proofs. Care is required: a proof that is a long 11 | string of tactic applications can be very hard to read and 12 | maintain. But when combined with the various structuring mechanisms 13 | that Lean's proof language has to offer, they provide efficient means 14 | for filling in the details of a proof. The goal of this chapter is to 15 | add some additional tactics to your repertoire. 16 | 17 | [This chapter is still under construction.] 18 | 19 | ** Induction 20 | 21 | Just as the =cases= tactic performs proof by cases on an element of an 22 | inductively defined type, the =induction= tactic performs a proof by 23 | induction. As with the =cases= tactic, the =with= clause allows you to 24 | name the variables and hypotheses that are introduced. Also as with 25 | the =cases= tactic, the =induction= tactic will revert any hypotheses 26 | that depend on the induction variable and then reintroduce them for 27 | you automatically. The following examples prove the commutativity of 28 | addition on the natural numbers, using only the defining equations for 29 | addition (in particular, the property =add_succ=, which asserts that 30 | =x + succ y = succ (x + y)= for every =x= and =y=). 31 | #+BEGIN_SRC lean 32 | import data.nat 33 | namespace hide 34 | -- BEGIN 35 | open nat 36 | 37 | theorem zero_add (x : ℕ) : 0 + x = x := 38 | begin 39 | induction x with x ih, 40 | {exact rfl}, 41 | rewrite [add_succ, ih] 42 | end 43 | 44 | theorem succ_add (x y : ℕ) : succ x + y = succ (x + y) := 45 | begin 46 | induction y with y ih, 47 | {exact rfl}, 48 | rewrite [add_succ, ih] 49 | end 50 | 51 | theorem add.comm (x y : ℕ) : x + y = y + x := 52 | begin 53 | induction x with x ih, 54 | {show 0 + y = y + 0, by rewrite zero_add}, 55 | show succ x + y = y + succ x, 56 | begin 57 | induction y with y ihy, 58 | {krewrite zero_add}, 59 | rewrite [succ_add, ih] 60 | end 61 | end 62 | -- END 63 | end hide 64 | #+END_SRC 65 | (For the use of =krewrite= here, see the end of Chapter [[file:11_Tactic-Style_Proofs.org::#Tactic-Style_Proofs][Tactic-Style 66 | Proofs]].) 67 | 68 | The induction tactic can be used not only with the induction 69 | principles that are created automatically when an inductive type is 70 | defined, but also induction principles that prove on their own. For 71 | example, recall that the standard library defines the type =finset A= 72 | of finite sets of elements of any type =A=. Typically, we assume =A= 73 | has decidable equality, which means in particular that we can decide 74 | whether an element =a : A= is a member of a finite set =s=. Clearly, a 75 | property =P= holds for an arbitrary finite set when it holds for the 76 | empty set and when it is maintained for a finite set =s= after a new 77 | element =a=, that was not previosly in =s=, is added to =s=. This is 78 | encapsulated by the following principle of induction: 79 | #+BEGIN_SRC lean 80 | open finset 81 | namespace hide 82 | -- BEGIN 83 | theorem finset.induction {A : Type} [h : decidable_eq A] {P : finset A → Prop} 84 | (H₁ : P finset.empty) 85 | (H₂ : ∀ ⦃a : A⦄ {s : finset A}, a ∉ s → P s → P (insert a s)) 86 | : (∀ s, P s) 87 | -- END 88 | := sorry 89 | end hide 90 | #+END_SRC 91 | To use this as an induction principle, one has to mark it with the 92 | attribute =[recursor 6]=, which tells the induction tactic that this 93 | is a user defined induction principle in which induction is carried 94 | out on the sixth argument. This is done in the standard library. Then, 95 | when induction is carried out on an element of =finset=, the induction 96 | tactic finds the relevant principle. 97 | #+BEGIN_SRC lean 98 | import data.finset data.nat 99 | open finset nat 100 | 101 | variables (A : Type) [deceqA : decidable_eq A] 102 | include deceqA 103 | 104 | theorem card_add_card (s₁ s₂ : finset A) : card s₁ + card s₂ = card (s₁ ∪ s₂) + card (s₁ ∩ s₂) := 105 | begin 106 | induction s₂ with a s₂ hs₂ ih, 107 | show card s₁ + card (∅:finset A) = card (s₁ ∪ ∅) + card (s₁ ∩ ∅), 108 | by rewrite [union_empty, card_empty, inter_empty], 109 | show card s₁ + card (insert a s₂) = card (s₁ ∪ (insert a s₂)) + card (s₁ ∩ (insert a s₂)), 110 | from sorry 111 | end 112 | #+END_SRC 113 | The proof is carried out by induction on =s₂=. According to the =with= 114 | clause, the inductive step concerns the set =insert a s₂= in place of 115 | =s₂=, =hs₂= denotes the assuption =a ∉ s₂=, and =ih= denotes the 116 | inductive hypothesis. (The full proof can be found in the library.) If 117 | necessary, we can specify the induction principle manually: 118 | #+BEGIN_SRC lean 119 | import data.finset data.nat 120 | open finset nat 121 | 122 | variables (A : Type) [deceqA : decidable_eq A] 123 | include deceqA 124 | 125 | -- BEGIN 126 | theorem card_add_card (s₁ s₂ : finset A) : card s₁ + card s₂ = card (s₁ ∪ s₂) + card (s₁ ∩ s₂) := 127 | begin 128 | induction s₂ using finset.induction with a s₂ hs₂ ih, 129 | show card s₁ + card (∅:finset A) = card (s₁ ∪ ∅) + card (s₁ ∩ ∅), 130 | by rewrite [union_empty, card_empty, inter_empty], 131 | show card s₁ + card (insert a s₂) = card (s₁ ∪ (insert a s₂)) + card (s₁ ∩ (insert a s₂)), 132 | from sorry 133 | end 134 | -- END 135 | #+END_SRC 136 | 137 | ** Other Tactics 138 | 139 | The tactic =subst= substitutes a variable defined in the context, and 140 | clears both the variable and the hypothesis. The tactic =substvars= 141 | substitutes all the variables in the context. 142 | #+BEGIN_SRC lean 143 | import data.nat 144 | open nat 145 | 146 | variables a b c d : ℕ 147 | 148 | example (Ha : a = b + c) : c + a = c + (b + c) := 149 | by subst a 150 | 151 | example (Ha : a = b + c) (Hd : d = b) : a + d = b + c + d := 152 | by subst [a, d] 153 | 154 | example (Ha : a = b + c) (Hd : d = b) : a + d = b + c + d := 155 | by substvars 156 | 157 | example (Ha : a = b + c) (Hd : b = d) : a + d = d + c + d := 158 | by substvars 159 | 160 | example (Hd : b = d) (Ha : a = b + c) : a + d = d + c + d := 161 | by substvars 162 | #+END_SRC 163 | 164 | A number of tactics are designed to help construct elements of 165 | inductive types. For example =constructor = constructs an element of an 166 | inductive type by applying the ith constructor; =constructor= alone 167 | applies the first constructor that succeeds. The tactic =split= can 168 | only be applied to inductive types with only one constructor, and is 169 | then equivalent to =constructor 1=. Similarly, =left= and =right= are 170 | designed for use with inductive types with two constructors, and are 171 | then equivalent to =constructor 1= and =constructor 2=, 172 | respectively. Here are prototypical examples: 173 | #+BEGIN_SRC lean 174 | 175 | variables p q : Prop 176 | 177 | example (Hp : p) (Hq : q) : p ∧ q := 178 | by split; exact Hp; exact Hq 179 | 180 | example (Hp : p) (Hq : q) : p ∧ q := 181 | by split; repeat assumption 182 | 183 | example (Hp : p) : p ∨ q := 184 | by constructor; assumption 185 | 186 | example (Hq : q) : p ∨ q := 187 | by constructor; assumption 188 | 189 | example (Hp : p) : p ∨ q := 190 | by constructor 1; assumption 191 | 192 | example (Hq : q) : p ∨ q := 193 | by constructor 2; assumption 194 | 195 | example (Hp : p) : p ∨ q := 196 | by left; assumption 197 | 198 | example (Hq : q) : p ∨ q := 199 | by right; assumption 200 | #+END_SRC 201 | The tactic =existsi= is similar to =constructor 1=, but it 202 | allows us to provide an argument, as is commonly done with when 203 | introducing an element of an =exists= or =sigma= type. 204 | #+BEGIN_SRC lean 205 | import data.nat 206 | open nat 207 | 208 | example : ∃ x : ℕ, x > 2 := 209 | by existsi 3; exact dec_trivial 210 | 211 | example (B : ℕ → Type) (b : B 2) : Σ x : ℕ, B x := 212 | by existsi 2; assumption 213 | #+END_SRC 214 | 215 | The =injection= tactic makes use of the fact that constructors to an 216 | inductive type are injective: 217 | #+BEGIN_SRC lean 218 | import data.nat 219 | open nat 220 | 221 | example (x y : ℕ) (H : succ x = succ y) : x = y := 222 | by injection H with H'; exact H' 223 | 224 | example (x y : ℕ) (H : succ x = succ y) : x = y := 225 | by injection H; assumption 226 | #+END_SRC 227 | The first version gives the name the consequence of applying 228 | injectivity to the hypothesis =H=. The second version lets Lean choose 229 | the name. 230 | 231 | The tactics =reflexivity=, =symmetry=, and =transitivity= work not 232 | just for equality, but also for any relation with a corresponding 233 | theorem marked with the attribute =refl=, =symm=, or =trans=, 234 | respectively. Here is an example of their use: 235 | #+BEGIN_SRC lean 236 | variables (A : Type) (a b c d : A) 237 | 238 | example (H₁ : a = b) (H₂ : c = b) (H₃ : c = d) : a = d := 239 | by transitivity b; assumption; transitivity c; symmetry; assumption; assumption 240 | #+END_SRC 241 | The =contradiction= tactic closes a goal when contradictory hypotheses 242 | have been derived: 243 | #+BEGIN_SRC lean 244 | variables p q : Prop 245 | 246 | example (Hp : p) (Hnp : ¬ p) : q := 247 | by contradiction 248 | #+END_SRC 249 | Similarly, =exfalso= and =trivial= implement "ex falso quodlibet" and 250 | the introduction rule for =true=, respectively. 251 | 252 | ** Combinators 253 | 254 | Combinators are used to combine tactics. The most basic one is the 255 | =and_then= combinator, written with a semicolon (=;=), which applies tactics 256 | successively. 257 | 258 | # This is not the same as listing tactics separated by 259 | # commas in a =begin ... end= block, since when multiple solutions are 260 | # available, =and_then= will backtrack until it finds a solution or 261 | # exhausts all the possibilities. The following example fails if we 262 | # replace the semicolon by a comma: 263 | # #+BEGIN_SRC lean 264 | # example (p q : Prop) (Hq : q) : p ∨ q := 265 | # begin constructor; assumption end 266 | # #+END_SRC 267 | # The =constructor= tactic creates a /stream/ of outcomes, one for each 268 | # possible result. A comma forces the tactic to commit to an answer at 269 | # that point, whereas the semicolon causes Lean to systematically try 270 | # all the possibilities. Here is a more elaborate example: 271 | # #+BEGIN_SRC lean 272 | # variable p : nat → Prop 273 | # variable q : nat → Prop 274 | # variables a b c : nat 275 | 276 | # example : p c → p b → q b → p a → ∃ x, p x ∧ q x := 277 | # by intros; apply exists.intro; split; eassumption; eassumption 278 | # #+END_SRC 279 | # The =eassumption= tactic is stronger than =assumption= in that it is 280 | # more aggressive when it comes to reducing expressions, and in that it 281 | # returns a stream of solutions rather than the first one that 282 | # matches. In this case, the first solution that matches =p ?x= is 283 | # ultimately not the right choice, and backtracking is crucial. 284 | 285 | The =par= combinator, written with a vertical bar (=|=), tries one tactic and then the other, 286 | using the first one that succeeds. The =repeat= tactic applies a 287 | tactic repeatedly. Here is an example of these in use: 288 | #+BEGIN_SRC lean 289 | example (a b c d : Prop) : a ∧ b ∧ c ∧ d ↔ d ∧ c ∧ b ∧ a := 290 | begin 291 | apply iff.intro, 292 | repeat (intro H; repeat (cases H with [H', H] | apply and.intro | assumption)) 293 | end 294 | #+END_SRC 295 | Here is another one: 296 | #+BEGIN_SRC lean 297 | import data.set 298 | open set function eq.ops 299 | 300 | variables {X Y Z : Type} 301 | 302 | lemma image_comp (f : Y → X) (g : X → Y) (a : set X) : (f ∘ g) ' a = f ' (g ' a) := 303 | set.ext (take z, 304 | iff.intro 305 | (assume Hz, 306 | obtain x Hx₁ Hx₂, from Hz, 307 | by repeat (apply mem_image | assumption | reflexivity)) 308 | (assume Hz, 309 | obtain y [x Hz₁ Hz₂] Hy₂, from Hz, 310 | by repeat (apply mem_image | assumption | esimp [comp] | rewrite Hz₂))) 311 | #+END_SRC 312 | 313 | # TODO: need more and better examples, both above and below. 314 | 315 | Finally, some tactics can be used to "debug" a tactic proof by 316 | printing output to the screen when Lean is run from the command 317 | line. The command =trace= produces the given output, =state= shows the 318 | current goal, =now= fails if there are any current goals, and 319 | =check_expr t= displays the type of the expression in the context of 320 | the current goal. 321 | #+BEGIN_SRC lean 322 | open tactic 323 | 324 | theorem tst {A B : Prop} (H1 : A) (H2 : B) : A := 325 | by (trace "first"; state; now | 326 | trace "second"; state; fail | 327 | trace "third"; assumption) 328 | #+END_SRC 329 | Other tactics can be used to manipulate goals. For example, 330 | =rotate_left= or =rotate_right= followed by a number rotates through 331 | the goals. The tactic =rotate= is equivalent to =rotate_left=. 332 | -------------------------------------------------------------------------------- /Cask: -------------------------------------------------------------------------------- 1 | (source melpa) 2 | (source gnu) 3 | (source org) 4 | (development 5 | (depends-on "cl-lib") 6 | (depends-on "dash" 2.8.0) 7 | (depends-on "dash-functional" 1.1.0) 8 | (depends-on "f") 9 | (depends-on "company") 10 | (depends-on "flymake") 11 | (depends-on "s") 12 | (depends-on "org-plus-contrib") 13 | (depends-on "htmlize")) 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2.0 (Apache) 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, and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. 13 | 14 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 15 | 16 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. 17 | 18 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. 19 | 20 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. 21 | 22 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). 23 | 24 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. 25 | 26 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." 27 | 28 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 29 | 30 | 2. Grant of Copyright License. 31 | 32 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 33 | 34 | 3. Grant of Patent License. 35 | 36 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 37 | 38 | 4. Redistribution. 39 | 40 | You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: 41 | 42 | 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and 43 | 44 | 2. You must cause any modified files to carry prominent notices stating that You changed the files; and 45 | 46 | 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 47 | 48 | 4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. 49 | 50 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 51 | 52 | 5. Submission of Contributions. 53 | 54 | Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 55 | 56 | 6. Trademarks. 57 | 58 | This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 59 | 60 | 7. Disclaimer of Warranty. 61 | 62 | Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 63 | 64 | 8. Limitation of Liability. 65 | 66 | In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 67 | 68 | 9. Accepting Warranty or Additional Liability. 69 | 70 | While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. 71 | 72 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CASK_BIN ?= cask 2 | EMACS_BIN ?= emacs 3 | LEAN_BIN ?= lean 4 | ORGS := $(wildcard [0-9A][0-9]_*.org) 5 | HTMLS := $(ORGS:.org=.html) 6 | TEXS := $(ORGS:.org=.tex) 7 | PDFS := $(ORGS:.org=.pdf) 8 | CWD := $(shell pwd) 9 | WATCHMAN_BIN ?= $(CWD)/watchman/bin/watchman 10 | TMPDIR := $(shell mktemp -d /tmp/lean-tutorial.XXXX) 11 | NAV_DATA := js/nav_data.js 12 | 13 | all: $(HTMLS) tutorial.pdf quickref.pdf build_nav_data 14 | 15 | htmls: $(HTMLS) 16 | 17 | tutorial.org: $(ORGS) 18 | ./merge_chapters.sh 19 | 20 | %.html: %.org .cask elisp/org-html-export.el header/html.org footer/bib.html.org lean.bib 21 | # @if [ ! -f ~/.cask/bin/cask ]; then echo "Cask Not Found. Please do 'make install-cask' first"; exit 1; fi 22 | cat header/html.org $< > $(TMPDIR)/$<.temp.org 23 | (grep "\\\\cite{" $< && cat footer/bib.html.org >> $(TMPDIR)/$<.temp.org) || true 24 | cp *.bib $(TMPDIR) 25 | $(CASK_BIN) exec $(EMACS_BIN) --no-site-file --no-site-lisp -q --batch -l elisp/org-html-export.el --visit $(TMPDIR)/$<.temp.org -f org-html-export-to-html 26 | mv $(TMPDIR)/$<.temp.html $@ 27 | rm $(TMPDIR)/$<.temp.org 28 | 29 | quickref.tex: A1_Quick_Reference.org .cask elisp/org-pdf-export.el header/latex_quickref.org header/latex_quickref.tex 30 | make gitinfo 31 | cat header/latex_quickref.org $< > $(TMPDIR)/$<.temp.org 32 | $(CASK_BIN) exec $(EMACS_BIN) --no-site-file --no-site-lisp -q --batch -l elisp/org-pdf-export.el --visit $(TMPDIR)/$<.temp.org -f org-latex-export-to-latex 33 | mv $(TMPDIR)/$<.temp.tex $@ 34 | rm $(TMPDIR)/$<.temp.org 35 | 36 | tutorial.tex: tutorial.org .cask elisp/org-pdf-export.el header/latex.org header/latex.tex footer/latex.org lean.bib 37 | make gitinfo 38 | cat header/latex.org $< footer/latex.org > $(TMPDIR)/$<.temp.org 39 | $(CASK_BIN) exec $(EMACS_BIN) --no-site-file --no-site-lisp -q --batch -l elisp/org-pdf-export.el --visit $(TMPDIR)/$<.temp.org -f org-latex-export-to-latex 40 | mv $(TMPDIR)/$<.temp.tex $@ 41 | rm $(TMPDIR)/$<.temp.org 42 | 43 | %.pdf: %.tex pygments-main 44 | # # Use latexmk if exists otherwise use xelatex + bibtex 45 | # if hash latexmk 2>/dev/null; then \ 46 | # latexmk --xelatex --shell-escape $<; \ 47 | # else \ 48 | # xelatex -shell-escape $<; bibtex $(<:.tex=); xelatex -shell-escape $<; xelatex -shell-escape $<; \ 49 | # fi 50 | # Ubuntu-12.04 uses an old version of latexmk which does not support XeLaTeX related options 51 | xelatex -shell-escape $<; bibtex $(<:.tex=); xelatex -shell-escape $<; xelatex -shell-escape $< 52 | 53 | .cask: Cask 54 | @EMACS=$(EMACS_BIN) $(CASK_BIN) install 55 | @touch .cask 56 | 57 | clean: 58 | rm -rf $(HTMLS) \ 59 | ${PDFS} \ 60 | ${TEXS} \ 61 | *.acn *.aux *.glo *.idx *.ist *.log *.out *.toc *.fdb_latexmk *.fls *.ilg *.ind \ 62 | *.out.pyg *.pyg tutorial.* \ 63 | [0-9][0-9]*.lean \ 64 | _minted-* 65 | 66 | dist-clean: 67 | make clean 68 | rm -rf .cask watchman pygments-main 69 | 70 | watch-on: 71 | $(WATCHMAN_BIN) watch $(CWD) 72 | $(WATCHMAN_BIN) -- trigger $(CWD) org-files '*.org' -- make all 73 | 74 | watch-off: 75 | $(WATCHMAN_BIN) -- trigger-del $(CWD) org-files 76 | $(WATCHMAN_BIN) watch-del $(CWD) 77 | 78 | install-cask: 79 | curl -fsSkL https://raw.github.com/cask/cask/master/go | python 80 | 81 | install-watchman: 82 | git clone https://github.com/facebook/watchman.git 83 | cd watchman &&./autogen.sh && ./configure --prefix $(CWD)/watchman && make install 84 | 85 | pygments-main: install-pygments 86 | 87 | install-pygments: 88 | if [ ! -d pygments-main ] ; then hg clone https://bitbucket.org/leanprover/pygments-main && cd pygments-main && python setup.py build; fi 89 | 90 | gitinfo: 91 | git log -1 --date=short \ 92 | --pretty=format:"\usepackage[shash={%h},lhash={%H},authname={%an},authemail={%ae},authsdate={%ad},authidate={%ai},authudate={%at},commname={%an},commemail={%ae},commsdate={%ad},commidate={%ai},commudate={%at},refnames={%d}]{gitsetinfo}" HEAD > $(CWD)/gitHeadInfo.gin 93 | 94 | test: 95 | for ORG in $(ORGS); do ./test.sh $(LEAN_BIN) $$ORG || exit 1; done 96 | test_js: 97 | for ORG in $(ORGS); do ./test_js.sh $$ORG || exit 1; done 98 | 99 | build_nav_data: $(HTMLS) 100 | echo "var lean_nav_data = [" > $(NAV_DATA) 101 | ls -1 [A0-9][0-9]_*.html | sed 's/\(.*\)/"\1",/' >> $(NAV_DATA) 102 | echo "];" >> $(NAV_DATA) 103 | 104 | .PHONY: all clean install-cask install-watchman watch-on watch-off gitinfo 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/leanprover/tutorial.svg?branch=master)](https://travis-ci.org/leanprover/tutorial) 2 | 3 | Lean Tutorial 4 | ============= 5 | 6 | - Web : https://leanprover.github.io/tutorial 7 | - PDF : https://leanprover.github.io/tutorial/tutorial.pdf 8 | 9 | Please note that this is the tutorial for [Lean 2](https://github.com/leanprover/lean2), which allows the use of homotopy type theory (HoTT). It is /not/ the [tutorial](https://leanprover.github.io/introduction_to_lean) for the [current version of Lean](https://github.com/leanprover/lean). 10 | 11 | How to Build 12 | ------------ 13 | 14 | We use [cask][cask] to install emacs dependencies ([org-mode][org-mode], [lean-mode][lean-mode], [htmlize][htmlize]) and [pygments][pygments] and [minted][minted] to syntax-highlight Lean code in LaTeX. We assume that you already have emacs-24.3 or higher installed in your system. 15 | 16 | ``` 17 | sudo apt-get install mercurial python2.7 texlive-latex-recommended \ 18 | texlive-humanities texlive-xetex texlive-science \ 19 | texlive-latex-extra texlive-fonts-recommended texlive-luatex\ 20 | bibtex2html git make mercurial autoconf automake gcc curl 21 | git clone https://github.com/leanprover/tutorial 22 | cd tutorial 23 | tar xvfz header/l3kernel.tar.gz -C ~/ 24 | make install-cask # after this, you need to add the cask binary to your $PATH 25 | make install-pygments 26 | make 27 | ``` 28 | 29 | [cask]: https://github.com/cask/cask 30 | [org-mode]: http://orgmode.org/ 31 | [lean-mode]: https://github.com/leanprover/lean/tree/master/src/emacs 32 | [htmlize]: https://github.com/emacsmirror/htmlize 33 | [pygments]: http://pygments.org/ 34 | [minted]: https://github.com/gpoore/minted 35 | 36 | 37 | Automatic Build using Watchman 38 | ------------------------------ 39 | 40 | Using [watchman][watchman], we can detect any changes on the 41 | org-files, and trigger re-builds automatically on the background. 42 | 43 | To install [watchman][watchman]: 44 | 45 | ``` 46 | sudo apt-get install automake 47 | make install-watchman 48 | ``` 49 | 50 | To enable watch: 51 | 52 | ``` 53 | make watch-on 54 | ``` 55 | 56 | To disable watch: 57 | 58 | ``` 59 | make watch-off 60 | ``` 61 | 62 | [watchman]: https://github.com/facebook/watchman 63 | 64 | 65 | How to preview generated HTML files 66 | ----------------------------------- 67 | 68 | It requires a webserver to preview generated HTML files. We can use Python's `SimpleHTTPServer` module: 69 | 70 | ```bash 71 | tutorial $ python -m SimpleHTTPServer 72 | ``` 73 | 74 | The above command starts a HTTP server at `tutorial` directory (default port: `8000`). For example, `01_Introduction.html` is available at `http://localhost:8000/01_Introduction.html`. 75 | 76 | 77 | Auto-reload HTML page 78 | --------------------- 79 | 80 | - Firefox: [Auto Reload][firefox-auto-reload] add-on 81 | - Tools > AutoReload Preferences 82 | ![1](https://cloud.githubusercontent.com/assets/403281/4966611/b211cda0-67d5-11e4-876e-a705f3326ac0.png) 83 | - Create Reload Rule 84 | ![2](https://cloud.githubusercontent.com/assets/403281/4966612/b3bdac00-67d5-11e4-83c9-118a4af8b0ea.png) 85 | - Link .html in the filesystem 86 | ![3](https://cloud.githubusercontent.com/assets/403281/4966613/b6461110-67d5-11e4-9d62-93c1e2a8f0da.png) 87 | 88 | - Chrome: [Tincr][google-tincr] (does *not* work on Linux) 89 | - Right-click and choose "Inspect Element" 90 | ![5](https://cloud.githubusercontent.com/assets/403281/5134646/03701bf0-70de-11e4-801f-65f307d30e69.png) 91 | - Go to "tincr" tab, choose "Http Web Server" for project type, then select Root directory. 92 | ![4](https://cloud.githubusercontent.com/assets/403281/5134645/036c6bfe-70de-11e4-86af-c21ec79a4471.png) 93 | 94 | [firefox-auto-reload]: https://addons.mozilla.org/en-US/firefox/addon/auto-reload 95 | [google-tincr]: http://tin.cr 96 | 97 | 98 | Test Lean Code in .org files 99 | ---------------------------- 100 | 101 | 1. Using Native Lean: First, you need to install Lean. Please follow the instructions at the [download page](http://leanprover.github.io/download/). You can test all Lean code blocks in `*.org` files by executing the following command: 102 | 103 | ```bash 104 | make test 105 | ``` 106 | 107 | To use a specific binary of Lean in test, please do the following: 108 | ```bash 109 | LEAN_BIN=/path/to/your/lean make test 110 | ``` 111 | 112 | 2. Using Lean.JS: 113 | 114 | ```bash 115 | make test_js 116 | ``` 117 | -------------------------------------------------------------------------------- /adjcalc.sty: -------------------------------------------------------------------------------- 1 | % \begin{macrocode} 2 | % 3 | \ProvidesPackage{adjcalc}[% 4 | % 5 | % 6 | %<*DRIVER> 7 | 2099/01/01 develop 8 | % 9 | Provides advanced setlength with multiple back-ends (calc, etex, pgfmath)] 10 | % \end{macrocode} 11 | % 12 | % 13 | % \begin{macrocode} 14 | \RequirePackage{xkeyval} 15 | % \end{macrocode} 16 | % 17 | % 18 | % Use e-TeX by default if available, otherwise the \pkg{calc} package. 19 | % \begin{macrocode} 20 | \def\adjcalc@atend{% 21 | \begingroup 22 | \expandafter\ifx\csname glueexpr\endcsname\relax 23 | \endgroup 24 | \RequirePackage{calc}% 25 | \adjcalc@calc 26 | \def\adjcalc@etex{\PackageError{adjcalc}{e-TeX not available for current compiler!}}% 27 | \else 28 | \endgroup 29 | \adjcalc@etex 30 | \fi 31 | } 32 | % \end{macrocode} 33 | % 34 | % Initial definitions for the package options. This macros are later redefined because the same keys 35 | % can be used as macro options. 36 | % \begin{macrocode} 37 | \def\adjcalc@pgfmath{\AtEndOfPackage{\RequirePackage{pgf}}\def\adjcalc@atend{\adjcalc@pgfmath}} 38 | \def\adjcalc@etex{\def\adjcalc@atend{\adjcalc@etex}} 39 | \def\adjcalc@calc{\AtEndOfPackage{\RequirePackage{calc}}\def\adjcalc@atend{\adjcalc@calc}} 40 | \def\adjcalc@overwrite{\AtEndOfPackage{\adjcalc@overwrite}} 41 | % \end{macrocode} 42 | % 43 | % The initial default unit is `|bp|' like for \pkg{graphicx}. 44 | % \begin{macrocode} 45 | \def\adjcalc@defaultunit{bp}% 46 | % \end{macrocode} 47 | % 48 | % 49 | % Options: 50 | % \begin{macrocode} 51 | \DeclareOptionX{pgfmath}{\adjcalc@pgfmath} 52 | \DeclareOptionX{etex}{\adjcalc@etex} 53 | \DeclareOptionX{calc}{\adjcalc@calc} 54 | \DeclareOptionX{none}{% 55 | \let\adjcalc@atend\relax 56 | \let\adjcalc@overwrite\relax 57 | \def\adjsetlength{\setlength}% 58 | \def\adjaddtolength{\addtolength}% 59 | \def\adjsetcounter{\setcounter}% 60 | \def\adjaddtocounter{\addtocounter}% 61 | } 62 | \DeclareOptionX{overwrite}{\adjcalc@overwrite} 63 | \DeclareOptionX{defaultunit}[bp]{% 64 | \begingroup 65 | \def\@tempa{#1}% 66 | \def\@tempb{none}% 67 | \ifx\@tempa\@tempb% 'none': 68 | \endgroup 69 | \def\adjsetlengthdefault{\adjsetlength}% 70 | \else 71 | \ifx\@tempb\adjcalc@defaultunit 72 | \endgroup 73 | % was 'none' before 74 | \let\adjsetlengthdefault\adjsetlengthdefault@ 75 | \else 76 | \endgroup 77 | \fi 78 | \fi 79 | \def\adjcalc@defaultunit{#1}% 80 | } 81 | \ProcessOptionsX* 82 | \disable@keys{adjcalc}{none} 83 | % \end{macrocode} 84 | % 85 | % 86 | % \begin{macro}{\adjcalcset} 87 | % User level settings macro. 88 | % \begin{macrocode} 89 | \def\adjcalcset{% 90 | \setkeys{adjcalc}% 91 | } 92 | % \end{macrocode} 93 | % \end{macro} 94 | % 95 | % 96 | % \begin{macro}{\adjcalc@etex} 97 | % \begin{macrocode} 98 | \def\adjcalc@etex{% 99 | \protected\def\adjsetlength##1##2{% 100 | ##1=\glueexpr(##2)\relax 101 | }% 102 | \protected\def\adjaddtolength##1##2{% 103 | \advance##1 by \glueexpr(##2)\relax 104 | }% 105 | \protected\def\adjsetcounter##1##2{% 106 | \@ifundefined{c@##1}% 107 | {\@nocounterr{##1}}% 108 | {\global\csname c@##1\endcsname\numexpr(##2)\relax}% 109 | }% 110 | \protected\def\adjaddtocounter##1##2{% 111 | \@ifundefined{c@##1}% 112 | {\@nocounterr{##1}}% 113 | {\global\advance\csname c@##1\endcsname\numexpr(##2)\relax}% 114 | }% 115 | \def\adjsetlengthdefault@##1##2{% 116 | \@defaultunits##1=\glueexpr##2 \adjcalc@defaultunit\relax\@nnil 117 | }% 118 | \let\adjsetlengthdefault\adjsetlengthdefault@ 119 | } 120 | % \end{macrocode} 121 | % \end{macro} 122 | % 123 | % \begin{macrocode} 124 | \newif\if@adjcalc@needsdefault 125 | % \end{macrocode} 126 | % 127 | % 128 | % \begin{macro}{\adjcalc@calc} 129 | % This uses the underlying (re-)definitions of the normal macros (\Macro\setlength, ...) done by the \pkg{calc} package. 130 | % This allows to locally redefine \Macro\setlength to call \Macro\adjsetlength, etc., without causing an infinite loop. 131 | % \begin{macrocode} 132 | \def\adjcalc@calc{% 133 | \DeclareRobustCommand\adjsetlength{\calc@assign@skip}% 134 | \DeclareRobustCommand\adjaddtolength[1]{\calc@assign@skip{\advance ##1}}% 135 | \DeclareRobustCommand\adjsetcounter[2]{\@ifundefined{c@##1}{\@nocounterr{##1}}{\calc@assign@count{\global\csname c@##1\endcsname}{##2}}}% 136 | \DeclareRobustCommand\adjaddtocounter[2]{\@ifundefined{c@##1}{\@nocounterr{##1}}{\calc@assign@count{\global\advance\csname c@##1\endcsname}{##2}}}% 137 | \def\adjsetlengthdefault@##1##2{% 138 | \begingroup 139 | \def\calc@post@scan####1!{% 140 | \def\@tempa{####1}% 141 | \ifx\@tempa\@empty 142 | \endgroup% to end calc processing 143 | % is number only 144 | \global\@adjcalc@needsdefaulttrue 145 | \else 146 | \endgroup% to end calc processing 147 | % full expression 148 | \global\@adjcalc@needsdefaultfalse 149 | \fi 150 | }% 151 | \calc@assign@skip{##1}{##2 \adjcalc@defaultunit}% 152 | \endgroup 153 | \if@adjcalc@needsdefault 154 | ##1=##2 \adjcalc@defaultunit\relax 155 | \else 156 | \calc@assign@skip{##1}{##2}% 157 | \fi 158 | }% 159 | \def\adjcalc@checkdefault##1\@nnil##2##3{% 160 | \ifx\relax##1\relax\else 161 | \calc@assign@skip{##2}{##3}% 162 | \fi 163 | }% 164 | \let\adjsetlengthdefault\adjsetlengthdefault@ 165 | } 166 | % \end{macrocode} 167 | % \end{macro} 168 | % 169 | % 170 | % \begin{macro}{\adjcalc@pgfmath} 171 | % \begin{macrocode} 172 | \def\adjcalc@pgfmath{% 173 | \DeclareRobustCommand\adjsetlength{\pgfmathsetlength}% 174 | \DeclareRobustCommand\adjaddtolength{\pgfmathaddtolength}% 175 | \DeclareRobustCommand\adjsetcounter{\pgfmathsetcounter}% 176 | \DeclareRobustCommand\adjaddtocounter{\pgfmathaddtocounter}% 177 | \def\adjsetlengthdefault@##1##2{% 178 | \edef\pgfmathresultunitscale{1\adjcalc@defaultunit}% 179 | \let\pgfmathpostparse\pgfmathscaleresult 180 | \pgfmathparse{##2}% 181 | ##1=\pgfmathresult pt\relax 182 | }% 183 | \let\adjsetlengthdefault\adjsetlengthdefault@ 184 | } 185 | % \end{macrocode} 186 | % \end{macro} 187 | % 188 | % 189 | % \begin{macro}{\adjbox@settobp} 190 | % \begin{macrocode} 191 | \def\adjcalc@settobp#1#2{% 192 | \begingroup 193 | \adjsetlength\@tempdima{#2}% 194 | \@tempdima=0.99626\@tempdima 195 | \edef\@tempa{\endgroup\def\noexpand#1{\strip@pt\@tempdima\space}}% 196 | \@tempa 197 | }% 198 | % \end{macrocode} 199 | % \end{macro} 200 | % 201 | % 202 | % \begin{macro}{\adjcalc@overwrite} 203 | % \begin{macrocode} 204 | \def\adjcalc@overwrite{% 205 | \let\setlength\adjsetlength 206 | \let\addtolength\adjaddtolength 207 | \let\setcounter\adjsetcounter 208 | \let\addtocounter\adjaddtocounter 209 | } 210 | % \end{macrocode} 211 | % \end{macro} 212 | % 213 | % Execute at-end code. 214 | % \begin{macrocode} 215 | \adjcalc@atend 216 | % \end{macrocode} 217 | -------------------------------------------------------------------------------- /collectbox.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `collectbox.sty', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% collectbox.dtx (with options: `collectbox.sty') 8 | %% 9 | %% IMPORTANT NOTICE: 10 | %% 11 | %% For the copyright see the source file. 12 | %% 13 | %% Any modified versions of this file must be renamed 14 | %% with new filenames distinct from collectbox.sty. 15 | %% 16 | %% For distribution of the original source see the terms 17 | %% for copying and modification in the file collectbox.dtx. 18 | %% 19 | %% This generated file may be distributed as long as the 20 | %% original source files, as listed above, are part of the 21 | %% same distribution. (The sources need not necessarily be 22 | %% in the same archive or directory.) 23 | %% Copyright (C) 2012 by Martin Scharrer 24 | %% -------------------------------------------------------------------- 25 | %% This work may be distributed and/or modified under the 26 | %% conditions of the LaTeX Project Public License, either version 1.3 27 | %% of this license or (at your option) any later version. 28 | %% The latest version of this license is in 29 | %% http://www.latex-project.org/lppl.txt 30 | %% and version 1.3 or later is part of all distributions of LaTeX 31 | %% version 2005/12/01 or later. 32 | %% 33 | %% This work has the LPPL maintenance status `maintained'. 34 | %% 35 | %% The Current Maintainer of this work is Martin Scharrer. 36 | %% 37 | %% This work consists of the files collectbox.dtx and collectbox.ins 38 | %% and the derived filebase collectbox.sty. 39 | %% 40 | \NeedsTeXFormat{LaTeX2e}[1999/12/01] 41 | \ProvidesPackage{collectbox}[% 42 | 2012/05/17 43 | v0.4b 44 | Collect macro arguments as boxes] 45 | \newsavebox\collectedbox 46 | \newcommand*\collectbox{% 47 | \@ifstar 48 | {\collectbox@a{{\BOXCONTENT}}}% 49 | {\collectbox@a{}}% 50 | } 51 | \long\def\collectbox@a#1{% 52 | \@ifnextchar[% 53 | {\collectbox@b{#1}}% 54 | {\collectbox@b{#1}[]}% 55 | } 56 | \long\def\collectbox@b#1[#2]#3{% 57 | \@ifnextchar[% 58 | {\collectbox@c{#2}{#3#1}}% 59 | {\collectbox@c{#2}{#3#1}[]}% 60 | } 61 | \long\def\collectbox@c#1#2[#3]{% 62 | \collectbox@{#1}{#2}{#3}% 63 | } 64 | \let\collect@box\hbox 65 | \let\collectbox@mode\leavevmode 66 | \newcommand\collectbox@[3]{% 67 | \begingroup 68 | \collectbox@mode 69 | \@temptokena{#3\collectbox@end#2\endgroup}% 70 | \setbox\collectedbox\collect@box\bgroup 71 | \collectbox@setgroup 72 | #1\bgroup 73 | \aftergroup\the 74 | \aftergroup\@temptokena 75 | \collectbox@bgroup 76 | } 77 | \let\collectbox@macro\collectbox@ 78 | \newcommand\collectbox@env[3]{% 79 | \collectbox@mode 80 | \def\collectboxenvend{#3\collectbox@end#2\collectbox@currenvir}% 81 | \setbox\collectedbox\collect@box\bgroup 82 | \collectbox@setgroup 83 | \collectbox@reset 84 | \ignorespaces 85 | #1% 86 | } 87 | \def\collectbox@currenvir{% 88 | \edef\@currenvir{\@currenvir}% 89 | } 90 | \def\collectbox@macro@bgroup{% 91 | \@ifnextchar\bgroup 92 | {\let\@let@token=}% 93 | {\collectbox@arg}% 94 | } 95 | \def\collectbox@env@bgroup{% 96 | \collectbox@reset 97 | \ignorespaces 98 | } 99 | \let\collectbox@bgroup\collectbox@macro@bgroup 100 | \def\collectbox@setgroup{% 101 | \color@setgroup 102 | } 103 | \def\collectbox@endgroup{% 104 | \collectbox@endcode 105 | \color@endgroup 106 | } 107 | \let\collectbox@endcode\relax 108 | \newcommand\@collectbox[1]{% 109 | \begingroup 110 | \collectbox@mode 111 | \@temptokena{\collectbox@end#1\endgroup}% 112 | \setbox\collectedbox\collect@box\bgroup 113 | \collectbox@setgroup\bgroup 114 | \aftergroup\the 115 | \aftergroup\@temptokena 116 | \collectbox@bgroup 117 | } 118 | \newcommand\@Collectbox[2]{% 119 | \begingroup 120 | \collectbox@mode 121 | \sbox\collectedbox{#2}% 122 | \collectbox@setdims 123 | #1% 124 | \endgroup 125 | } 126 | \def\collectbox@arg#1{% 127 | #1\egroup 128 | } 129 | \def\collectbox@end{% 130 | \collectbox@endgroup 131 | \egroup 132 | \collectbox@setdims 133 | \ifcollectboxenv 134 | \collectbox@reset 135 | \collectbox@currenvir 136 | \fi 137 | } 138 | \def\collectbox@setdims{% 139 | \collectbox@protecteddef\BOXCONTENT{\usebox\collectedbox}% 140 | \collectbox@protecteddef\width{\wd\collectedbox}% 141 | \collectbox@protecteddef\height{\ht\collectedbox}% 142 | \collectbox@protecteddef\depth{\dp\collectedbox}% 143 | \collectbox@protecteddef\totalheight{\@ovri}% 144 | \totalheight\height 145 | \advance\totalheight\depth 146 | }% 147 | \def\collectbox@reset{% 148 | \let\collectbox@endcode\relax 149 | \let\collectbox@bgroup\collectbox@macro@bgroup 150 | \let\collectbox@\collectbox@macro 151 | \collectboxenvfalse 152 | } 153 | \begingroup 154 | \expandafter\ifx\csname protected\endcsname\relax 155 | \let\collectbox@protecteddef\def% 156 | \else 157 | \gdef\collectbox@protecteddef{\protected\def}% 158 | \fi 159 | \endgroup 160 | \let\collectbox@code\empty 161 | \newcommand\collectboxto[1]{% 162 | \@ifnextchar[% 163 | {\collectboxto@a{#1}}% 164 | {\collectboxto@a{#1}[]}% 165 | } 166 | \long\def\collectboxto@a#1[#2]#3{% 167 | \@ifnextchar[% 168 | {\collectboxto@b{#1}{#2}{#3}}% 169 | {\collectboxto@b{#1}{#2}{#3}[]}% 170 | } 171 | \long\def\collectboxto@b#1#2#3[#4]{% 172 | \collectboxto@{#1}{#2}{#3}{#4}% 173 | } 174 | \newcommand\collectboxto@[4]{% 175 | \collectbox@mode 176 | \setbox#1\collect@box\bgroup 177 | \def\collectbox@code{#4\collectbox@endgroup\egroup#3}% 178 | \collectbox@setgroup#2\bgroup 179 | \aftergroup\collectbox@code 180 | \collectbox@bgroup 181 | } 182 | \newcommand\@collectboxto[2]{% 183 | \collectbox@mode 184 | \setbox#1\collect@box\bgroup 185 | \def\collectbox@code{\collectbox@endgroup\egroup#2}% 186 | \collectbox@setgroup\bgroup 187 | \aftergroup\collectbox@code 188 | \collectbox@bgroup 189 | } 190 | \newcommand\nocollectbox@[3]{% 191 | \collectbox@mode 192 | \collect@box\bgroup 193 | \def\collectbox@code{#3\egroup#2}% 194 | #1\bgroup 195 | \aftergroup\collectbox@code 196 | \collectbox@bgroup 197 | } 198 | \newcommand\nocollectbox@to[4]{% 199 | \collectbox@mode 200 | \collect@box to #1\bgroup 201 | \def\collectbox@code{#4\egroup#3}% 202 | #2\bgroup 203 | \aftergroup\collectbox@code 204 | \collectbox@bgroup 205 | } 206 | \newcommand*\collectboxcheckenv[1]{% 207 | \begingroup 208 | \def\@tempa{#1}% 209 | \expandafter\endgroup 210 | \ifx\@currenvir\@tempa 211 | \@collectboxisenv{#1}% 212 | \fi 213 | } 214 | \def\@collectboxisenv#1{% 215 | \collectbox@noindent 216 | \collectboxenvtrue 217 | \edef\@currenvir{\@currenvir\noexpand\empty}% 218 | \let\collectbox@bgroup\collectbox@env@bgroup 219 | \let\collectbox@endcode\collectbox@env@endcode 220 | \let\collectbox@\collectbox@env 221 | \expandafter\ifx\csname end#1\endcsname\relax 222 | \expandafter\let\csname end#1\endcsname\collectbox@envend 223 | \fi 224 | } 225 | \newif\ifcollectboxenv 226 | \let\collectbox@noindent\noindent 227 | \def\collectbox@env@endcode{\ifhmode\unskip\fi}% 228 | \def\collectbox@envend{\collectboxenvend}% 229 | \def\collectboxenvend{% 230 | \egroup 231 | \collectbox@currenvir 232 | }% 233 | \newcommand\collectboxtabular[3][c]{% 234 | \collectbox@tab{tabular}{[#1]{#2}}{}{#3}{}% 235 | } 236 | \newcommand\collectboxtabularstar[4][c]{% 237 | \collectbox@tab{tabular*}{[#1]{#2}{#3}}{}{#4}{}% 238 | } 239 | \newcommand\collectboxarray[2]{% 240 | \collectbox@tab{array}{{#1}}{\(}{#2}{\)}% 241 | } 242 | \def\collectbox@checkarray{% 243 | \@ifpackageloaded{array}{% 244 | \let\collectbox@realarraycr\@arraycr 245 | \def\collectbox@setarraycr{% 246 | \let\@arraycr\collebox@cr 247 | \def\ialign{\let\@arraycr\collectbox@realarraycr \everycr {}\tabskip \z@skip \halign}% 248 | }% 249 | }{% 250 | \let\collectbox@realarraycr\@tabularcr 251 | \def\collectbox@setarraycr{% 252 | \let\@tabularcr\collebox@cr 253 | \def\ialign{\let\noexpand\@tabularcr\noexpand\collectbox@realarraycr \everycr {}\tabskip \z@skip \halign}% 254 | }% 255 | }% 256 | } 257 | \collectbox@checkarray 258 | \AtBeginDocument{\collectbox@checkarray}% 259 | \def\collectbox@dorealarraycr{% 260 | \expandafter\collectbox@realarraycr\collectbox@aftercrstuff 261 | } 262 | \let\collectbox@aftercrstuff\empty 263 | \def\collectbox@tab#1#2#3#4#5{% 264 | \begingroup 265 | \collectbox@mode 266 | \def\collectbox@codeafter{#4\endgroup}% 267 | \def\collectbox@endtabenv{\end{#1}#5\collectbox@end}% 268 | \def\collectbox@dotab{#3\begin{#1}#2}% 269 | \setbox\collectedbox\collect@box\bgroup 270 | \collectbox@setgroup 271 | \collectbox@setarraycr 272 | \afterassignment\collectbox@dotab 273 | \let\@let@token=% 274 | } 275 | \def\collebox@cr{% 276 | \@ifstar\collebox@@cr\collebox@@cr% 277 | } 278 | \def\collebox@@cr{% 279 | \@ifnextchar[% 280 | \collebox@@cr@opt 281 | {\collebox@@@cr{}}% 282 | } 283 | \def\collebox@@cr@opt[#1]{% 284 | \collebox@@@cr{[#1]}% 285 | } 286 | \def\collebox@@@cr#1{% 287 | \def\collectbox@aftercrstuff{#1}% 288 | \expandafter\collebox@@@@cr 289 | \romannumeral-`0% 290 | } 291 | \def\collebox@@@@cr{% 292 | \@ifnextchar\egroup{\collectbox@dorealarraycr\collectbox@aftertab}{% 293 | \ifx\@let@token\noalign 294 | \expandafter\collectbox@handlenoalign 295 | \else 296 | \expandafter\collectbox@dorealarraycr 297 | \fi 298 | }% 299 | } 300 | \def\collectbox@handlenoalign#1#2{% 301 | \collectbox@dorealarraycr 302 | \noalign{\bgroup\aftergroup\collectbox@afternoalign#2}% 303 | } 304 | \def\collectbox@handlenextnoalign#1#2{% 305 | \egroup 306 | \noalign{\bgroup\aftergroup\collectbox@afternoalign#2}% 307 | } 308 | \def\collectbox@afternoalign{% 309 | \expandafter\collectbox@@afternoalign 310 | \romannumeral-`0% 311 | } 312 | \def\collectbox@@afternoalign{% 313 | \@ifnextchar\egroup{\egroup\collectbox@aftertab}{% 314 | \ifx\@let@token\noalign 315 | \expandafter\collectbox@handlenextnoalign 316 | \else 317 | \expandafter\egroup 318 | \fi 319 | }% 320 | } 321 | \def\collectbox@aftertab{% 322 | \collectbox@endtabenv 323 | \afterassignment\collectbox@codeafter 324 | \let\@let@token=% 325 | } 326 | \endinput 327 | %% 328 | %% End of file `collectbox.sty'. 329 | -------------------------------------------------------------------------------- /css/code.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'FreeMono-lean'; 3 | src: url('../fonts/FreeMono.eot'); 4 | src: url('../fonts/FreeMono.eot?#iefix') format('embedded-opentype'), 5 | url('../fonts/FreeMono.woff2') format('woff2'), 6 | url('../fonts/FreeMono.woff') format('woff'), 7 | url('../fonts/FreeMono.ttf') format('truetype'), 8 | url('../fonts/FreeMono.svg') format('svg'); 9 | font-weight: normal; 10 | font-style: normal; 11 | } 12 | 13 | @font-face { 14 | font-family: 'FreeMono-lean'; 15 | src: url('../fonts/FreeMonoBold.eot'); 16 | src: url('../fonts/FreeMonoBold.eot?#iefix') format('embedded-opentype'), 17 | url('../fonts/FreeMonoBold.woff2') format('woff2'), 18 | url('../fonts/FreeMonoBold.woff') format('woff'), 19 | url('../fonts/FreeMonoBold.ttf') format('truetype'), 20 | url('../fonts/FreeMonoBold.svg') format('svg'); 21 | font-weight: bold; 22 | font-style: normal; 23 | } 24 | 25 | @font-face { 26 | font-family: 'DejaVuSansMono-lean'; 27 | src: url('../fonts/DejaVuSansMono.eot'); 28 | src: url('../fonts/DejaVuSansMono.eot?#iefix') format('embedded-opentype'), 29 | url('../fonts/DejaVuSansMono.woff') format('woff'), 30 | url('../fonts/DejaVuSansMono.ttf') format('truetype'), 31 | url('../fonts/DejaVuSansMono.svg') format('svg'); 32 | font-weight: normal; 33 | font-style: normal; 34 | } 35 | 36 | @font-face { 37 | font-family: 'DejaVuSansMono-lean'; 38 | src: url('../fonts/DejaVuSansMono-Bold.eot'); 39 | src: url('../fonts/DejaVuSansMono-Bold.eot?#iefix') format('embedded-opentype'), 40 | url('../fonts/DejaVuSansMono-Bold.woff') format('woff'), 41 | url('../fonts/DejaVuSansMono-Bold.ttf') format('truetype'), 42 | url('../fonts/DejaVuSansMono-Bold.svg') format('svg'); 43 | font-weight: bold; 44 | font-style: normal; 45 | } 46 | 47 | #juicy-ace-editor-container { 48 | font-family: 'FreeMono-lean', 'DejaVuSansMono-lean', Monaco, Menlo, 'Ubuntu Mono', 'Arial Unicode MS', Consolas, source-code-pro, monospace; 49 | line-height: inherit; 50 | margin-top:20px; 51 | margin-bottom:20px; 52 | } 53 | -------------------------------------------------------------------------------- /css/images/handle-h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/css/images/handle-h.png -------------------------------------------------------------------------------- /css/images/handle-v.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/css/images/handle-v.png -------------------------------------------------------------------------------- /css/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/css/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /css/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/css/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /css/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/css/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /css/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/css/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /css/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/css/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /css/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/css/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /css/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/css/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /css/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /css/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/css/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /css/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/css/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /css/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/css/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /css/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/css/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /css/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/css/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /css/main_live.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | body, html { 6 | height: 100%; 7 | overflow-y: hidden; 8 | text-align:left; 9 | } 10 | #editor_main { 11 | overflow-y: auto; 12 | position: absolute; 13 | /* border-top: solid 1px #000000; */ 14 | font-family: 'FreeMono-lean', 'DejaVuSansMono-lean', Monaco, Menlo, 'Ubuntu Mono', 'Arial Unicode MS', Consolas, source-code-pro, monospace; 15 | font-size:20px; 16 | top:0; bottom:0; left:0; right:0; 17 | } 18 | #editor_console { 19 | position:absolute; 20 | font-size:20px; 21 | /* border-left: solid 1px #000000; */ 22 | /* border-top: solid 1px #000000; */ 23 | font-family: 'FreeMono-lean', 'DejaVuSansMono-lean', Monaco, Menlo, 'Ubuntu Mono', 'Arial Unicode MS', Consolas, source-code-pro, monospace; 24 | font-size:20px; 25 | top:0; bottom:0; left:0; right:0; 26 | } 27 | #menu_bar { 28 | font-size:15px; 29 | color:#cccccc; 30 | background:#333333; 31 | height:40px; 32 | } 33 | #button_container { 34 | position:absolute; 35 | top:0; left:0px; 36 | z-index:1; 37 | float: left; 38 | display: flex; 39 | } 40 | .button { 41 | float:left; 42 | margin-right:5px; 43 | width:35px; 44 | } 45 | #lean_logo { 46 | margin-left:0px; 47 | padding-left:0px; 48 | margin-right:20px; 49 | } 50 | .menu_icon { 51 | width: 35px; 52 | height: 35px; 53 | margin-top: 2px; 54 | cursor: pointer; 55 | fill:#ffffff; 56 | stroke:#ffffff; 57 | } 58 | .menu_icon:hover { 59 | fill:#ffc52c; 60 | stroke:#000000; 61 | } 62 | #lean_logo { float: left; margin-left:2px; margin-top:2px; height: 36px; } 63 | #username { margin-top: 12px; margin-left:10px; margin-right:10px;} 64 | 65 | #resizable_main {position: absolute; 66 | border: 0} 67 | #resizable_console {position: absolute; 68 | border: 0} 69 | #new-button { 70 | margin-right:10px; 71 | } 72 | 73 | #console-button { 74 | margin-left:5px; 75 | margin-right:13px; 76 | } 77 | div#tutorial_contents th { 78 | padding-left: 15px; 79 | padding-right: 15px; 80 | } 81 | div#tutorial_contents td { 82 | padding-left: 15px; 83 | padding-right: 15px; 84 | } 85 | -------------------------------------------------------------------------------- /css/tutorial.css: -------------------------------------------------------------------------------- 1 | body{ 2 | margin: 0 auto; 3 | font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; 4 | color: #444444; 5 | line-height: 1; 6 | } 7 | h1, h2, h3, h4 { 8 | color: #111111; 9 | font-weight: 400; 10 | } 11 | h1, h2, h3, h4, h5 { 12 | margin-bottom: 35px; 13 | padding: 0; 14 | } 15 | p { 16 | margin-top: 20px; 17 | margin-bottom: 20px; 18 | padding: 0; 19 | } 20 | h1 { 21 | font-size: 48px; 22 | } 23 | h2 { 24 | font-size: 36px; 25 | /* The bottom margin is small. It's designed to be used with gray meta text 26 | * below a post title. */ 27 | margin: 24px 0 6px; 28 | border-bottom: 8px solid #225378; 29 | /* border-bottom: 8px solid #b08011; */ 30 | display: inline-block 31 | } 32 | h3 { 33 | font-size: 24px; 34 | margin: 24px 0 6px; 35 | border-bottom: 4px solid #1695a3; 36 | /* border-bottom: 4px solid #d4a319; */ 37 | display: inline-block 38 | } 39 | h4 { 40 | font-size: 21px; 41 | } 42 | h5 { 43 | font-size: 18px; 44 | } 45 | a { 46 | color: #0099ff; 47 | margin: 0; 48 | padding: 0; 49 | vertical-align: baseline; 50 | } 51 | a:hover { 52 | text-decoration: none; 53 | color: #ff6600; 54 | } 55 | a:visited { 56 | color: purple; 57 | } 58 | ul, ol { 59 | padding: 0; 60 | margin: 0; 61 | } 62 | li { 63 | margin-left: 30px; 64 | line-height: 24px; 65 | } 66 | li ul, li ul { 67 | margin-left: 24px; 68 | } 69 | p, ul, ol { 70 | font-size: 16px; 71 | line-height: 24px; 72 | } 73 | pre { 74 | font-family: 'FreeMono-lean', 'DejaVuSansMono-lean'; 75 | border:0; 76 | box-shadow:none; 77 | white-space: pre-wrap; 78 | /* background: #FDF6E3; */ 79 | } 80 | pre.example { 81 | padding: 20px; 82 | border:0; 83 | margin:0px; 84 | } 85 | code { 86 | font-family: Consolas, Monaco, Andale Mono, monospace; 87 | line-height: 1.5; 88 | font-size: 13px; 89 | } 90 | aside { 91 | display: block; 92 | float: right; 93 | width: 390px; 94 | } 95 | blockquote { 96 | border-left:.5em solid #eee; 97 | padding: 0 2em; 98 | margin-left:0; 99 | max-width: 476px; 100 | } 101 | blockquote cite { 102 | font-size:14px; 103 | line-height:20px; 104 | color:#bfbfbf; 105 | } 106 | blockquote cite:before { 107 | content: '\2014 \00A0'; 108 | } 109 | 110 | blockquote p { 111 | color: #666; 112 | max-width: 460px; 113 | } 114 | hr { 115 | width: 540px; 116 | text-align: left; 117 | margin: 0 auto 0 0; 118 | color: #999; 119 | } 120 | 121 | /* Code below this line is copyright Twitter Inc. */ 122 | 123 | button, 124 | input, 125 | select, 126 | textarea { 127 | font-size: 100%; 128 | margin: 0; 129 | vertical-align: baseline; 130 | *vertical-align: middle; 131 | } 132 | button, input { 133 | line-height: normal; 134 | *overflow: visible; 135 | } 136 | button::-moz-focus-inner, input::-moz-focus-inner { 137 | border: 0; 138 | padding: 0; 139 | } 140 | button, 141 | input[type="button"], 142 | input[type="reset"], 143 | input[type="submit"] { 144 | cursor: pointer; 145 | -webkit-appearance: button; 146 | } 147 | input[type=checkbox], input[type=radio] { 148 | cursor: pointer; 149 | } 150 | /* override default chrome & firefox settings */ 151 | input:not([type="image"]), textarea { 152 | -webkit-box-sizing: content-box; 153 | -moz-box-sizing: content-box; 154 | box-sizing: content-box; 155 | } 156 | 157 | input[type="search"] { 158 | -webkit-appearance: textfield; 159 | -webkit-box-sizing: content-box; 160 | -moz-box-sizing: content-box; 161 | box-sizing: content-box; 162 | } 163 | input[type="search"]::-webkit-search-decoration { 164 | -webkit-appearance: none; 165 | } 166 | label, 167 | input, 168 | select, 169 | textarea { 170 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 171 | font-size: 13px; 172 | font-weight: normal; 173 | line-height: normal; 174 | margin-bottom: 18px; 175 | } 176 | input[type=checkbox], input[type=radio] { 177 | cursor: pointer; 178 | margin-bottom: 0; 179 | } 180 | input[type=text], 181 | input[type=password], 182 | textarea, 183 | select { 184 | display: inline-block; 185 | width: 210px; 186 | padding: 4px; 187 | font-size: 13px; 188 | font-weight: normal; 189 | line-height: 18px; 190 | height: 18px; 191 | color: #808080; 192 | border: 1px solid #ccc; 193 | -webkit-border-radius: 3px; 194 | -moz-border-radius: 3px; 195 | border-radius: 3px; 196 | } 197 | select, input[type=file] { 198 | height: 27px; 199 | line-height: 27px; 200 | } 201 | textarea { 202 | height: auto; 203 | } 204 | 205 | /* grey out placeholders */ 206 | :-moz-placeholder { 207 | color: #bfbfbf; 208 | } 209 | ::-webkit-input-placeholder { 210 | color: #bfbfbf; 211 | } 212 | 213 | input[type=text], 214 | input[type=password], 215 | select, 216 | textarea { 217 | -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; 218 | -moz-transition: border linear 0.2s, box-shadow linear 0.2s; 219 | transition: border linear 0.2s, box-shadow linear 0.2s; 220 | -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); 221 | -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); 222 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); 223 | } 224 | input[type=text]:focus, input[type=password]:focus, textarea:focus { 225 | outline: none; 226 | border-color: rgba(82, 168, 236, 0.8); 227 | -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); 228 | -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); 229 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); 230 | } 231 | 232 | /* buttons */ 233 | button { 234 | display: inline-block; 235 | padding: 4px 14px; 236 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 237 | font-size: 13px; 238 | line-height: 18px; 239 | -webkit-border-radius: 4px; 240 | -moz-border-radius: 4px; 241 | border-radius: 4px; 242 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 243 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 244 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); 245 | /* background-color: #f9b529; */ 246 | background-color: #0064cd; 247 | background-repeat: repeat-x; 248 | 249 | background-image: -khtml-gradient(linear, left top, left bottom, from(#049cdb), to(#0064cd)); 250 | background-image: -moz-linear-gradient(top, #049cdb, #0064cd); 251 | background-image: -ms-linear-gradient(top, #049cdb, #0064cd); 252 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #049cdb), color-stop(100%, #0064cd)); 253 | background-image: -webkit-linear-gradient(top, #049cdb, #0064cd); 254 | background-image: -o-linear-gradient(top, #049cdb, #0064cd); 255 | background-image: linear-gradient(top, #049cdb, #0064cd); 256 | color: #fff; 257 | /* 258 | background-image: -khtml-gradient(linear, left top, left bottom, from(#fac539), to(#f2b225)); 259 | background-image: -moz-linear-gradient(top, #fac539, #f2b225); 260 | background-image: -ms-linear-gradient(top, #fac539, #f2b225); 261 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fac539), color-stop(100%, #f2b225)); 262 | background-image: -webkit-linear-gradient(top, #fac539, #f2b225); 263 | background-image: -o-linear-gradient(top, #fac539, #f2b225); 264 | background-image: linear-gradient(top, #fac539, #f2b225); 265 | color: #000; 266 | */ 267 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); 268 | border: 1px solid #004b9a; 269 | border-bottom-color: #003f81; 270 | -webkit-transition: 0.1s linear all; 271 | -moz-transition: 0.1s linear all; 272 | transition: 0.1s linear all; 273 | border-color: #0064cd #0064cd #003f81; 274 | border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); 275 | /* border-color: #fac539 #f9b529 #f2b225; */ 276 | /* border-color: #f9b529; */ 277 | } 278 | button:hover { 279 | color: #fff; 280 | background-position: 0 -15px; 281 | text-decoration: none; 282 | } 283 | button:active { 284 | -webkit-box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); 285 | -moz-box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); 286 | box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); 287 | } 288 | button::-moz-focus-inner { 289 | padding: 0; 290 | border: 0; 291 | } 292 | .warning { 293 | padding: 15px; 294 | margin-bottom: 20px; 295 | border: 1px solid transparent; 296 | border-radius: 4px; 297 | background-color: #fcf8e3; 298 | border-color: #faebcc; 299 | color: #8a6d3b; 300 | } 301 | .warning > p { 302 | margin: 0; 303 | } 304 | 305 | .org-src-container { 306 | margin-bottom: 15px; 307 | } 308 | 309 | .ace_scrollbar { 310 | display: none !important; 311 | } 312 | 313 | @media print 314 | { 315 | .no-print, .no-print * 316 | { 317 | display: none !important; 318 | } 319 | } 320 | #resizable_tutorial { 321 | overflow-y: scroll; 322 | overflow-x: hidden; 323 | } 324 | #tutorial_contents { 325 | margin: 0px; 326 | padding: 0px; 327 | overflow:auto; 328 | } 329 | #content { 330 | margin: 20px; 331 | margin-left: 40px; 332 | } 333 | .resizable_handle { background-position: center; } 334 | 335 | .exercise { 336 | margin-top: 20px; 337 | margin-bottom: 20px; 338 | padding: 5px; 339 | border: solid 1px #333333; 340 | } 341 | .exercise:before { 342 | content: "Exercise"; 343 | } 344 | #tutorialNav { 345 | margin-top:6px; 346 | } 347 | pre.src.src-text { 348 | margin-left: 24px; 349 | } 350 | fieldset { 351 | border:0; 352 | } 353 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 1. Build 4 | make 5 | make build_nav_data 6 | 7 | # 2. Check cssmin, minify 8 | hash cssmin 2>/dev/null || { echo >&2 "cssmin is not installed. Run 'npm -g i minify'."; exit 1; } 9 | hash minify 2>/dev/null || { echo >&2 "minify is not installed. Run 'npm -g i minify'."; exit 1; } 10 | 11 | # 3. Deploy 12 | mkdir deploy 13 | cd deploy 14 | rm -rf * 15 | git init 16 | cp ../*.html ../tutorial.pdf ../quickref.pdf . 17 | cp -r ../css ../images ../fonts ../js . 18 | for CSS in css/*.css 19 | do 20 | cssmin ${CSS} > ${CSS}.min 21 | mv ${CSS}.min ${CSS} 22 | done 23 | for JS in js/*.js 24 | do 25 | minify ${JS} > ${JS}.min 26 | mv ${JS}.min ${JS} 27 | done 28 | git add -f *.html tutorial.pdf quickref.pdf 29 | git add -f css/* 30 | git add -f images/* 31 | git add -f fonts/* 32 | git add -f js/* 33 | git commit -m "Update `date`" 34 | git push git@github.com:leanprover/tutorial.git +HEAD:gh-pages 35 | cd ../ 36 | rm -rf deploy 37 | -------------------------------------------------------------------------------- /elisp/lean-export-util.el: -------------------------------------------------------------------------------- 1 | (require 'dash) 2 | (require 'dash-functional) 3 | (defun lean-extract-code (code) 4 | "Given a code, extract the main part wrapped with -- BEGIN and -- END (if any)" 5 | (let* ((lines (s-split "\n" code)) 6 | (begin-marker "-- BEGIN") 7 | (end-marker "-- END") 8 | (core-lines 9 | (cond ((and (-contains? lines begin-marker) (-contains? lines end-marker)) 10 | (car (--split-when (or (s-equals? it begin-marker) 11 | (s-equals? it end-marker)) 12 | (--drop-while (not (s-equals? it begin-marker)) lines)))) 13 | (t lines))) 14 | (full-lines 15 | (--filter (and (not (s-equals? begin-marker it)) 16 | (not (s-equals? end-marker it))) 17 | lines))) 18 | (cons (s-join "\n" core-lines) 19 | (s-join "\n" full-lines)))) 20 | (provide 'lean-export-util) 21 | -------------------------------------------------------------------------------- /elisp/org-html-export.el: -------------------------------------------------------------------------------- 1 | (require 'f) 2 | (setq working-dir (f-dirname (f-this-file))) 3 | (add-to-list 'load-path working-dir) 4 | (setq make-backup-files nil) 5 | 6 | ;;; ORG mode 7 | (require 's) 8 | (require 'org) 9 | (require 'ox-bibtex) 10 | (require 'dash) 11 | (require 'dash-functional) 12 | (add-to-list 'load-path (f-join working-dir "elisp")) 13 | (require 'lean-export-util) 14 | 15 | (setq org-html-style-include-default nil) 16 | (setq org-html-style-include-scripts nil) 17 | 18 | ;; set auto load on .org files 19 | (add-to-list 'auto-mode-alist '("\\.org\\'" . org-mode)) 20 | 21 | ;; org mode customisations 22 | '(org-export-blocks (quote ((comment org-export-blocks-format-comment t) (ditaa org-export-blocks-format-ditaa nil) (dot org-export-blocks-format-dot t) (r org-export-blocks-format-R nil) (R org-export-blocks-format-R nil)))) 23 | '(org-export-html-inline-images t) 24 | '(org-export-html-use-infojs t) 25 | '(org-export-htmlize-output-type "css") 26 | '(org-export-html-validation-link "

Validate XHTML 1.0

") 27 | '(org-export-html-with-timestamp nil) 28 | '(org-modules (quote (org-bbdb org-bibtex org-info org-jsinfo org-irc org-w3m org-mouse org-eval org-eval-light org-exp-bibtex org-man org-mtags org-panel org-R org-special-blocks org-exp-blocks))) 29 | 30 | ;; Return the Lean tutorial example main part 31 | (defun lean-example-main-part (code) 32 | (car (lean-extract-code code))) 33 | 34 | ;; Return the Lean tutorial example full code. 35 | (defun lean-example-full (code) 36 | (cdr (lean-extract-code code))) 37 | 38 | (defvar-local lean-src-block-counter 0) 39 | 40 | ;; Redefine org-html-src-block to use juicy-ace-editor 41 | (eval-after-load "ox-html" 42 | '(defun org-html-src-block (src-block contents info) 43 | "Transcode a SRC-BLOCK element from Org to HTML. 44 | CONTENTS holds the contents of the item. INFO is a plist holding 45 | contextual information." 46 | (setq lean-src-block-counter (1+ lean-src-block-counter)) 47 | (if (org-export-read-attribute :attr_html src-block :textarea) 48 | (org-html--textarea-block src-block) 49 | (let ((lang (org-element-property :language src-block)) 50 | (caption (org-export-get-caption src-block)) 51 | (code (org-html-format-code src-block info)) 52 | (label (let ((lbl (org-element-property :name src-block))) 53 | (if (not lbl) "" 54 | (format " id=\"%s\"" 55 | (org-export-solidify-link-text lbl)))))) 56 | (if (not lang) (format "
\n%s
" label code) 57 | (format 58 | "
\n%s%s\n
" 59 | (if (not caption) "" 60 | (format "" 61 | (org-export-data caption info))) 62 | (cond ((or (string= lang "lean") 63 | (string= lang "lean_text")) 64 | (let ((juicy-ace-editor-html 65 | (format "%s" 66 | lean-src-block-counter 67 | "lean" 68 | (lean-example-main-part code))) 69 | (full-code-html (format "" 70 | lean-src-block-counter 71 | (lean-example-full code))) 72 | (button-html 73 | (if (string= lang "lean") 74 | (format "
" 75 | lean-src-block-counter) 76 | ""))) 77 | (concat juicy-ace-editor-html full-code-html button-html))) 78 | (t 79 | (format "\n
%s
" lang label code))))))))) 80 | (setq org-confirm-babel-evaluate nil) 81 | 82 | ; don't convert spaces to tabs 83 | (setq org-src-preserve-indentation t 84 | org-edit-src-content-indentation 0) 85 | 86 | (defun lean-extract-chapter-name (str) 87 | (let ((num (string-to-number str))) 88 | (cond ((= num 0) str) 89 | (t (format "%d" num))))) 90 | 91 | (defun lean-filter-headline (text backend info) 92 | "Adjust the chapter number based on the filename. For example, 93 | when the filename is '07_Induction_and_Recursion.org', it uses 94 | '7' as a chapter number instead of '1' which is the default 95 | value." 96 | (when (org-export-derived-backend-p backend 'html) 97 | (let ((file-name (f-filename (buffer-file-name)))) 98 | (save-match-data 99 | (when (and 100 | (>= (length file-name) 2) 101 | (let ((case-fold-search t)) 102 | (string-match (rx 103 | (group "") 106 | (group (char digit)) 107 | (group (* (char digit "."))) 108 | (group "")) 109 | text))) 110 | (replace-match (format "\\1 %s\\3\\4" 111 | (lean-extract-chapter-name (s-left 2 file-name))) 112 | t nil text)))))) 113 | 114 | (defun lean-filter-html-link (text backend info) 115 | (when (eq backend 'html) 116 | (cond 117 | ;; 1. Extenral Links (starting with 'https://', 'http://', or '//') 118 | ;; => add "target='_blank'" 119 | ((string-match 120 | (rx (group "href=\"" (or "http://" "https://" "//"))) text) 121 | (message "=================") 122 | (message "External Link: %s" text) 123 | (replace-match "target='_blank' \\1" t nil text)) 124 | ;; 2. Internal Links 125 | ;; 2.1. (matched with " 126 | ((string-match 127 | (rx " 132 | ((string-match 133 | (rx "" 149 | chapter-num-from-file 150 | rest 151 | "" 152 | ))) 153 | ;; 2.2.2 (matched with " 154 | ((string-match 155 | (rx " 161 | ((string-match 162 | (rx " 180 | MathJax.Hub.Config({ 181 | // Only one of the two following lines, depending on user settings 182 | // First allows browser-native MathML display, second forces HTML/CSS 183 | :MMLYES: config: [\"MMLorHTML.js\"], jax: [\"input/TeX\"], 184 | :MMLNO: jax: [\"input/TeX\", \"output/HTML-CSS\"], 185 | extensions: [\"tex2jax.js\",\"TeX/AMSmath.js\",\"TeX/AMSsymbols.js\", 186 | \"TeX/noUndefined.js\"], 187 | tex2jax: { 188 | inlineMath: [ [\"\\\\(\",\"\\\\)\"] ], 189 | displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"], [\"\\\\begin{displaymath}\",\"\\\\end{displaymath}\"] ], 190 | skipTags: [\"script\",\"noscript\",\"style\",\"textarea\",\"pre\",\"code\"], 191 | ignoreClass: \"tex2jax_ignore\", 192 | processEscapes: false, 193 | processEnvironments: true, 194 | preview: \"TeX\" 195 | }, 196 | showProcessingMessages: true, 197 | displayAlign: \"%ALIGN\", 198 | displayIndent: \"%INDENT\", 199 | 200 | \"HTML-CSS\": { 201 | scale: %SCALE, 202 | availableFonts: [\"STIX\",\"TeX\"], 203 | preferredFont: \"TeX\", 204 | webFont: \"TeX\", 205 | imageFont: \"TeX\", 206 | showMathMenu: true, 207 | }, 208 | MMLorHTML: { 209 | prefer: { 210 | MSIE: \"MML\", 211 | Firefox: \"MML\", 212 | Opera: \"HTML\", 213 | other: \"HTML\" 214 | } 215 | } 216 | }); 217 | 218 | "))) 219 | -------------------------------------------------------------------------------- /elisp/org-pdf-export.el: -------------------------------------------------------------------------------- 1 | (require 'f) 2 | (setq working-dir (f-dirname (f-this-file))) 3 | (add-to-list 'load-path working-dir) 4 | (setq make-backup-files nil) 5 | (require 'org) 6 | (require 'ox) 7 | (require 'lean-export-util) 8 | (setq org-confirm-babel-evaluate nil) 9 | 10 | ;;; XeLaTeX customisations 11 | ;; remove "inputenc" from default packages as it clashes with xelatex 12 | ;; (setf org-latex-default-packages-alist 13 | ;; (remove '("AUTO" "inputenc" t) org-latex-default-packages-alist)) 14 | 15 | (setq org-latex-default-packages-alist 16 | '(("T1" "fontenc" t) 17 | ("" "fixltx2e" nil) 18 | ("" "graphicx" t) 19 | ("" "longtable" nil) 20 | ("" "float" nil) 21 | ("" "wrapfig" nil) 22 | ("" "rotating" nil) 23 | ("normalem" "ulem" t) 24 | ("" "amsmath" t) 25 | ("" "textcomp" t) 26 | ("" "marvosym" t) 27 | ("" "wasysym" t) 28 | ("" "amssymb" t) 29 | ("" "imakeidx" nil) 30 | ("" "hyperref" nil) 31 | "\\tolerance=1000")) 32 | 33 | (setq org-latex-listings 'minted) 34 | (setq org-export-with-smart-quotes t) 35 | (add-to-list 'org-export-smart-quotes-alist 36 | '("en" 37 | (primary-opening :utf-8 "“" :html "“" :latex "``" :texinfo "``") 38 | (primary-closing :utf-8 "”" :html "”" :latex "''" :texinfo "''") 39 | (secondary-opening :utf-8 "‘" :html "‘" :latex "`" :texinfo "`") 40 | (secondary-closing :utf-8 "’" :html "’" :latex "'" :texinfo "'") 41 | (apostrophe :utf-8 "’" :html "’"))) 42 | 43 | ;; Header.tex explicitly loads all necessary packages. 44 | (make-local-variable 'org-latex-default-packages-alist) 45 | (setf org-latex-default-packages-alist nil) 46 | (setq org-export-latex-listings 'minted) 47 | (setq org-latex-minted-options 48 | '(("frame" "lines") 49 | ("fontsize" "\\scriptsize"))) 50 | (setq-default indent-tabs-mode nil) 51 | 52 | (defun lean-filter-latex-link (text backend info) 53 | (when (eq backend 'latex) 54 | (cond ((string-match 55 | (rx "\\hyperref" 56 | "\[" 57 | "sec-" 58 | (group (one-or-more (in digit "-"))) 59 | "\]" 60 | "\{" (one-or-more (in alnum " ")) "\}" 61 | (group (zero-or-more " ")) 62 | ) text) 63 | (let* ((sec-number-org (match-string 1 text)) 64 | (sec-number (s-replace-all 65 | '(("-" . ".")) 66 | sec-number-org)) 67 | (spaces (match-string 2 text))) 68 | (s-concat "\\hyperref[sec-" 69 | sec-number-org 70 | "]{" 71 | sec-number 72 | "}" 73 | spaces)))))) 74 | 75 | (eval-after-load "ox-latex" 76 | '(progn 77 | (add-to-list 'org-export-filter-link-functions 'lean-filter-latex-link) 78 | (defun lean-extract-core-code (code-info) 79 | "Given a code-info which is a cons cell whose car element is source code, 80 | Extract the core code between -- BEGIN and -- END lines" 81 | (let* ((code (car code-info)) 82 | (rest (cdr code-info)) 83 | (core-lines (car (lean-extract-code code)))) 84 | (cons core-lines rest))) 85 | (defun org-latex-src-block (src-block contents info) 86 | "Transcode a SRC-BLOCK element from Org to LaTeX. 87 | CONTENTS holds the contents of the item. INFO is a plist holding 88 | contextual information." 89 | (when (org-string-nw-p (org-element-property :value src-block)) 90 | (let* ((org-lang (org-element-property :language src-block)) 91 | (lang (if (string= org-lang "lean_text") "lean" org-lang)) 92 | (caption (org-element-property :caption src-block)) 93 | (label (org-element-property :name src-block)) 94 | (custom-env (and lang 95 | (cadr (assq (intern lang) 96 | org-latex-custom-lang-environments)))) 97 | (num-start (case (org-element-property :number-lines src-block) 98 | (continued (org-export-get-loc src-block info)) 99 | (new 0))) 100 | (retain-labels (org-element-property :retain-labels src-block)) 101 | (attributes (org-export-read-attribute :attr_latex src-block)) 102 | (float (plist-get attributes :float))) 103 | (cond 104 | ;; Case 1. No source fontification. 105 | ((not org-latex-listings) 106 | (let* ((caption-str (org-latex--caption/label-string src-block info)) 107 | (float-env 108 | (cond ((and (not float) (plist-member attributes :float)) "%s") 109 | ((string= "multicolumn" float) 110 | (format "\\begin{figure*}[%s]\n%%s%s\n\\end{figure*}" 111 | org-latex-default-figure-position 112 | caption-str)) 113 | ((or caption float) 114 | (format "\\begin{figure}[H]\n%%s%s\n\\end{figure}" 115 | caption-str)) 116 | (t "%s")))) 117 | (format 118 | float-env 119 | (concat (format "\\begin{verbatim}\n%s\\end{verbatim}" 120 | (org-export-format-code-default src-block info)))))) 121 | ;; Case 2. Custom environment. 122 | (custom-env (format "\\begin{%s}\n%s\\end{%s}\n" 123 | custom-env 124 | (org-export-format-code-default src-block info) 125 | custom-env)) 126 | ;; Case 3. Use minted package. 127 | ((eq org-latex-listings 'minted) 128 | (let* ((caption-str (org-latex--caption/label-string src-block info)) 129 | (float-env 130 | (cond ((and (not float) (plist-member attributes :float)) "%s") 131 | ((string= "multicolumn" float) 132 | (format "\\begin{listing*}\n%%s\n%s\\end{listing*}" 133 | caption-str)) 134 | ((or caption float) 135 | (format "\\begin{listing}[H]\n%%s\n%s\\end{listing}" 136 | caption-str)) 137 | (t "%s"))) 138 | (body 139 | (format 140 | "\\begin{minted}[%s]{%s}\n%s\\end{minted}" 141 | ;; Options. 142 | (org-latex--make-option-string 143 | (if (or (not num-start) 144 | (assoc "linenos" org-latex-minted-options)) 145 | org-latex-minted-options 146 | (append 147 | `(("linenos") 148 | ("firstnumber" ,(number-to-string (1+ num-start)))) 149 | org-latex-minted-options))) 150 | ;; Language. 151 | (or (cadr (assq (intern lang) org-latex-minted-langs)) 152 | (downcase lang)) 153 | ;; Source code. 154 | ;; Soonho Kong: call lean-extract-core-code to 155 | ;; extract the lines between begin and end 156 | (let* ((code-info (lean-extract-core-code (org-export-unravel-code src-block))) 157 | (max-width 158 | (apply 'max 159 | (mapcar 'length 160 | (org-split-string (car code-info) 161 | "\n"))))) 162 | (org-export-format-code 163 | (car code-info) 164 | (lambda (loc num ref) 165 | (concat 166 | loc 167 | (when ref 168 | ;; Ensure references are flushed to the right, 169 | ;; separated with 6 spaces from the widest line 170 | ;; of code. 171 | (concat (make-string (+ (- max-width (length loc)) 6) 172 | ?\s) 173 | (format "(%s)" ref))))) 174 | nil (and retain-labels (cdr code-info))))))) 175 | ;; Return value. 176 | (format float-env body))) 177 | ;; Case 4. Use listings package. 178 | (t 179 | (let ((lst-lang 180 | (or (cadr (assq (intern lang) org-latex-listings-langs)) lang)) 181 | (caption-str 182 | (when caption 183 | (let ((main (org-export-get-caption src-block)) 184 | (secondary (org-export-get-caption src-block t))) 185 | (if (not secondary) 186 | (format "{%s}" (org-export-data main info)) 187 | (format "{[%s]%s}" 188 | (org-export-data secondary info) 189 | (org-export-data main info))))))) 190 | (concat 191 | ;; Options. 192 | (format 193 | "\\lstset{%s}\n" 194 | (org-latex--make-option-string 195 | (append 196 | org-latex-listings-options 197 | (cond 198 | ((and (not float) (plist-member attributes :float)) nil) 199 | ((string= "multicolumn" float) '(("float" "*"))) 200 | ((and float (not (assoc "float" org-latex-listings-options))) 201 | `(("float" ,org-latex-default-figure-position)))) 202 | `(("language" ,lst-lang)) 203 | (if label `(("label" ,label)) '(("label" " "))) 204 | (if caption-str `(("caption" ,caption-str)) '(("caption" " "))) 205 | (cond ((assoc "numbers" org-latex-listings-options) nil) 206 | ((not num-start) '(("numbers" "none"))) 207 | ((zerop num-start) '(("numbers" "left"))) 208 | (t `(("numbers" "left") 209 | ("firstnumber" 210 | ,(number-to-string (1+ num-start))))))))) 211 | ;; Source code. 212 | (format 213 | "\\begin{lstlisting}\n%s\\end{lstlisting}" 214 | (let* ((code-info (org-export-unravel-code src-block)) 215 | (max-width 216 | (apply 'max 217 | (mapcar 'length 218 | (org-split-string (car code-info) "\n"))))) 219 | (org-export-format-code 220 | (car code-info) 221 | (lambda (loc num ref) 222 | (concat 223 | loc 224 | (when ref 225 | ;; Ensure references are flushed to the right, 226 | ;; separated with 6 spaces from the widest line of 227 | ;; code 228 | (concat (make-string (+ (- max-width (length loc)) 6) ? ) 229 | (format "(%s)" ref))))) 230 | nil (and retain-labels (cdr code-info)))))))))))) 231 | )) 232 | -------------------------------------------------------------------------------- /fonts/DejaVuSansMono-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/fonts/DejaVuSansMono-Bold.eot -------------------------------------------------------------------------------- /fonts/DejaVuSansMono-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/fonts/DejaVuSansMono-Bold.ttf -------------------------------------------------------------------------------- /fonts/DejaVuSansMono-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/fonts/DejaVuSansMono-Bold.woff -------------------------------------------------------------------------------- /fonts/DejaVuSansMono.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/fonts/DejaVuSansMono.eot -------------------------------------------------------------------------------- /fonts/DejaVuSansMono.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/fonts/DejaVuSansMono.ttf -------------------------------------------------------------------------------- /fonts/DejaVuSansMono.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/fonts/DejaVuSansMono.woff -------------------------------------------------------------------------------- /fonts/FreeMono.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/fonts/FreeMono.eot -------------------------------------------------------------------------------- /fonts/FreeMono.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/fonts/FreeMono.otf -------------------------------------------------------------------------------- /fonts/FreeMono.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/fonts/FreeMono.ttf -------------------------------------------------------------------------------- /fonts/FreeMono.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/fonts/FreeMono.woff -------------------------------------------------------------------------------- /fonts/FreeMono.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/fonts/FreeMono.woff2 -------------------------------------------------------------------------------- /fonts/FreeMonoBold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/fonts/FreeMonoBold.eot -------------------------------------------------------------------------------- /fonts/FreeMonoBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/fonts/FreeMonoBold.ttf -------------------------------------------------------------------------------- /fonts/FreeMonoBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/fonts/FreeMonoBold.woff -------------------------------------------------------------------------------- /fonts/FreeMonoBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/fonts/FreeMonoBold.woff2 -------------------------------------------------------------------------------- /footer/.gitignore: -------------------------------------------------------------------------------- 1 | !* -------------------------------------------------------------------------------- /footer/bib.html.org: -------------------------------------------------------------------------------- 1 | #+BIBLIOGRAPHY: lean plain limit:t 2 | -------------------------------------------------------------------------------- /footer/latex.org: -------------------------------------------------------------------------------- 1 | #+BEGIN_EXPORT LATEX 2 | \bibliographystyle{plain} 3 | \bibliography{lean} 4 | 5 | %\setglossarystyle{altlisthypergroup} 6 | %\glsaddall 7 | %\printglossaries 8 | 9 | \clearpage 10 | \addcontentsline{toc}{chapter}{Index} 11 | \printindex 12 | #+END_EXPORT 13 | -------------------------------------------------------------------------------- /gitinfo.sty: -------------------------------------------------------------------------------- 1 | % gitinfo.sty 2 | % Copyright 2011 Brent Longborough 3 | % 4 | % This work may be distributed and/or modified under the 5 | % conditions of the LaTeX Project Public License, either version 1.3 6 | % of this license or (at your option) any later version. 7 | % The latest version of this license is in 8 | % http://www.latex-project.org/lppl.txt 9 | % and version 1.3 or later is part of all distributions of LaTeX 10 | % version 2005/12/01 or later. 11 | % 12 | % This work has the LPPL maintenance status `maintained'. 13 | % The Current Maintainer of this work is Brent Longborough. 14 | % 15 | % This work consists of these files: 16 | % gitinfo.sty, gitsetinfo.sty, gitinfo.tex, gitinfo.pdf, 17 | % post-git-sample.txt, and gitHeadInfo.gin 18 | % ----------------------------------------------------- 19 | \NeedsTeXFormat{LaTeX2e} 20 | \ProvidesPackage{gitinfo}[2011/08/10 v1.00 git revision information] 21 | \RequirePackage{etoolbox} 22 | \RequirePackage{kvoptions} 23 | \SetupKeyvalOptions{% 24 | family=gitInfo, 25 | prefix=gitInf@ 26 | } 27 | \DeclareBoolOption{grumpy} 28 | \DeclareBoolOption{pcount} 29 | \DeclareBoolOption{footinfo} 30 | \DeclareStringOption[(None)]{missing} 31 | \ProcessKeyvalOptions* 32 | \newcommand{\gitAbbrevHash}{\gitInf@missing} 33 | \newcommand{\gitHash}{\gitInf@missing} 34 | \newcommand{\gitAuthorName}{\gitInf@missing} 35 | \newcommand{\gitAuthorEmail}{\gitInf@missing} 36 | \newcommand{\gitAuthorDate}{\gitInf@missing} 37 | \newcommand{\gitAuthorIsoDate}{\gitInf@missing} 38 | \newcommand{\gitAuthorUnixDate}{\gitInf@missing} 39 | \newcommand{\gitCommitterName}{\gitInf@missing} 40 | \newcommand{\gitCommitterEmail}{\gitInf@missing} 41 | \newcommand{\gitCommitterDate}{\gitInf@missing} 42 | \newcommand{\gitCommitterIsoDate}{\gitInf@missing} 43 | \newcommand{\gitCommitterUnixDate}{\gitInf@missing} 44 | \newcommand{\gitReferences}{\gitInf@missing} 45 | \newcommand{\gitVtag}{} 46 | \newcommand{\gitVtags}{} 47 | \newcommand{\gitVtagn}{\space\gitInf@missing} 48 | \InputIfFileExists{./gitHeadInfo.gin}{}{% 49 | \ifbool{gitInf@grumpy}{% 50 | \PackageError{gitinfo}{I can't find the file `gitHeadInfo.gin`.\MessageBreak 51 | Please check the manual (gitinfo.pdf) \MessageBreak 52 | if you need more details.}{} 53 | }{% 54 | \PackageWarning{gitInfo}{I can't find the file `gitHeadInfo.gin`.\MessageBreak 55 | All git metadata has been set to ``\gitInf@missing''.} 56 | } 57 | } 58 | \@ifclassloaded{memoir}{% 59 | \ifbool{gitInf@footinfo}{% 60 | \ifbool{gitInf@pcount}{ 61 | \newcommand{\@gitPage}{\thepage/\thelastpage} 62 | \addtodef{\frontmatter}{\renewcommand{\@gitPage}{\thepage}}{} 63 | \addtodef{\mainmatter}{}{\renewcommand{\@gitPage}{\thepage/\thelastpage}} 64 | }{% 65 | \newcommand{\@gitPage}{\thepage} 66 | } 67 | \newcommand{\@gitFootRev}{Revision\gitVtags: \gitAbbrevHash{} (\gitAuthorDate)} 68 | \newcommand{\@gitrFootRev}{% 69 | \tiny\textsf{\raggedleft \@gitFootRev}% 70 | } 71 | \newcommand{\@gitlFootRev}{% 72 | \tiny\textsf{\@gitFootRev}% 73 | } 74 | \makeevenfoot{plain}{\@gitPage}{}{\@gitrFootRev} 75 | \makeoddfoot{plain}{\@gitlFootRev}{}{\@gitPage} 76 | \makeevenfoot{ruled}{\@gitPage}{}{\@gitrFootRev} 77 | \makeoddfoot{ruled}{\@gitlFootRev}{}{\@gitPage} 78 | \makeevenfoot{headings}{\@gitPage}{}{\@gitrFootRev} 79 | \makeoddfoot{headings}{\@gitlFootRev}{}{\@gitPage} 80 | \makeevenhead{headings}{}{}{\slshape\leftmark} 81 | \makeoddhead{headings}{\slshape\rightmark}{}{} 82 | }{} 83 | }{} 84 | -------------------------------------------------------------------------------- /gitsetinfo.sty: -------------------------------------------------------------------------------- 1 | % gitsetinfo.sty 2 | % Copyright 2011 Brent Longborough 3 | % 4 | % This work may be distributed and/or modified under the 5 | % conditions of the LaTeX Project Public License, either version 1.3 6 | % of this license or (at your option) any later version. 7 | % The latest version of this license is in 8 | % http://www.latex-project.org/lppl.txt 9 | % and version 1.3 or later is part of all distributions of LaTeX 10 | % version 2005/12/01 or later. 11 | % 12 | % This work has the LPPL maintenance status `maintained'. 13 | % The Current Maintainer of this work is Brent Longborough. 14 | % 15 | % This work consists of these files: 16 | % gitinfo.sty, gitsetinfo.sty, gitinfo.tex, gitinfo.pdf, 17 | % post-git-sample.txt, and gitHeadInfo.gin 18 | % ----------------------------------------------------- 19 | \NeedsTeXFormat{LaTeX2e} 20 | \ProvidesPackage{gitsetinfo}[2011/08/10 v1.00 Auxiliary package for gitinfo] 21 | \RequirePackage{kvoptions} 22 | \RequirePackage{xstring} 23 | \RequirePackage{etoolbox} 24 | \SetupKeyvalOptions{% 25 | family=gitinfo, 26 | prefix=gitInf@ 27 | } 28 | \DeclareStringOption{shash} 29 | \DeclareStringOption{lhash} 30 | \DeclareStringOption{authname} 31 | \DeclareStringOption{authemail} 32 | \DeclareStringOption{authsdate} 33 | \DeclareStringOption{authidate} 34 | \DeclareStringOption{authudate} 35 | \DeclareStringOption{commname} 36 | \DeclareStringOption{commemail} 37 | \DeclareStringOption{commsdate} 38 | \DeclareStringOption{commidate} 39 | \DeclareStringOption{commudate} 40 | \DeclareStringOption{refnames} 41 | \ProcessKeyvalOptions* 42 | \renewcommand{\gitAbbrevHash}{\gitInf@shash} 43 | \renewcommand{\gitHash}{\gitInf@lhash} 44 | \renewcommand{\gitAuthorName}{\gitInf@authname} 45 | \renewcommand{\gitAuthorEmail}{\gitInf@authemail} 46 | \renewcommand{\gitAuthorDate}{\gitInf@authsdate} 47 | \renewcommand{\gitAuthorIsoDate}{\gitInf@authidate} 48 | \renewcommand{\gitAuthorUnixDate}{\gitInf@authudate} 49 | \renewcommand{\gitCommitterName}{\gitInf@commname} 50 | \renewcommand{\gitCommitterEmail}{\gitInf@commemail} 51 | \renewcommand{\gitCommitterDate}{\gitInf@commsdate} 52 | \renewcommand{\gitCommitterIsoDate}{\gitInf@commidate} 53 | \renewcommand{\gitCommitterUnixDate}{\gitInf@commudate} 54 | \renewcommand{\gitReferences}{\gitInf@refnames} 55 | \newcommand{\git@vtag}[1]{% 56 | \def\do##1{% 57 | \IfDecimal{##1}{% 58 | \renewcommand{\gitVtag}{##1} 59 | \renewcommand{\gitVtags}{\space##1} 60 | \renewcommand{\gitVtagn}{\space##1} 61 | \listbreak 62 | }{}% 63 | }% 64 | \expandafter\docsvlist\expandafter{#1}% 65 | }% 66 | \git@vtag{\gitInf@refnames} 67 | -------------------------------------------------------------------------------- /header/.gitignore: -------------------------------------------------------------------------------- 1 | !* -------------------------------------------------------------------------------- /header/html.org: -------------------------------------------------------------------------------- 1 | #+OPTIONS: toc:nil 2 | #+OPTIONS: html-postamble:nil 3 | #+HTML_HEAD_EXTRA: 4 | #+HTML_HEAD_EXTRA: 5 | #+HTML_HEAD_EXTRA: 6 | #+HTML_HEAD_EXTRA: 7 | -------------------------------------------------------------------------------- /header/index.html.org: -------------------------------------------------------------------------------- 1 | #+HTML_HEAD_EXTRA: 2 | -------------------------------------------------------------------------------- /header/l3kernel.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/header/l3kernel.tar.gz -------------------------------------------------------------------------------- /header/latex.org: -------------------------------------------------------------------------------- 1 | #+OPTIONS: toc:t 2 | #+BEGIN_SRC emacs-lisp :results silent :exports results 3 | (require 'cl) ;; The find function is in the cl library. 4 | (unless (find "per-file-class" org-latex-classes :key 'car :test 'equal) 5 | (add-to-list 'org-latex-classes 6 | '("per-file-class" 7 | "\\documentclass{memoir}" 8 | ("\\chapter{%s}" . "\\chapter*{%s}") 9 | ("\\section{%s}" . "\\section*{%s}") 10 | ("\\subsection{%s}" . "\\subsection*{%s}") 11 | ("\\subsubsection{%s}" . "\\subsubsection*{%s}") 12 | ("\\paragraph{%s}" . "\\paragraph*{%s}") 13 | ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))) 14 | #+END_SRC 15 | #+LANGUAGE: en 16 | #+LATEX_CLASS: per-file-class 17 | #+LATEX_CLASS_OPTIONS: [11pt,book,table,dvipsnames,oneside,openany] 18 | #+LATEX_HEADER: \input{header/latex.tex} 19 | #+BEGIN_EXPORT LATEX 20 | %\OnehalfSpacing 21 | #+END_EXPORT 22 | -------------------------------------------------------------------------------- /header/latex.tex: -------------------------------------------------------------------------------- 1 | % Typography 2 | \usepackage[utf8]{luainputenc} 3 | \usepackage{amsmath} 4 | \usepackage{mathspec} 5 | \usepackage{unixode} 6 | \usepackage{amssymb} 7 | \usepackage{fontspec} 8 | \defaultfontfeatures{Ligatures=TeX} 9 | %% \setmainfont{Adobe Caslon Pro} 10 | %% \setsansfont{Myriad Pro} 11 | %% \setmonofont[Scale=MatchLowercase]{Menlo} 12 | \usepackage{microtype} 13 | \usepackage{setspace} 14 | \usepackage{etoolbox} 15 | \usepackage{csquotes} 16 | \usepackage{ulem} 17 | \usepackage{xstring} 18 | \usepackage{gitinfo} 19 | 20 | % Minted 21 | \usepackage{minted} 22 | \renewcommand{\MintedPygmentize}{./pygments-main/pygmentize} 23 | \setminted{encoding=utf-8} 24 | %\setmonofont{freemono} 25 | %\usepackage{etoolbox} 26 | %\AtBeginEnvironment{minted}{\singlespacing% 27 | % \fontsize{10}{10}\selectfont} 28 | \def\args{linenos,frame=single,fontsize=\normalsize,style=bw} 29 | \newcommand{\makenewmintedfiles}[1]{% 30 | \newmintedfile[inputlatex]{latex}{#1}% 31 | \newmintedfile[inputc]{c}{#1}% 32 | } 33 | \expandafter\makenewmintedfiles\expandafter{\args} 34 | 35 | % Colors, links, syntax highlighting 36 | \usepackage[dvipsnames,table]{xcolor} 37 | \hypersetup{ 38 | pdftitle={Theorem Proving in Lean}, 39 | pdfauthor={Jeremy Avigad, Leonardo de Moura, Soonho Kong}, 40 | colorlinks, 41 | linkcolor=Sepia, 42 | citecolor=Periwinkle 43 | } 44 | 45 | % warning box 46 | \usepackage{mdframed} 47 | \definecolor{warningborder}{HTML}{FAEBCC} 48 | \definecolor{warning}{HTML}{FCF8E3} 49 | \newenvironment{warning}{% 50 | \begin{mdframed}[backgroundcolor=warning,linecolor=warningborder]% 51 | }{\end{mdframed}} 52 | 53 | \usepackage[acronym,toc]{glossaries} 54 | \include{Glossary} 55 | \makeglossaries 56 | \makeindex 57 | 58 | % Localization 59 | \usepackage{polyglossia} 60 | \setdefaultlanguage{english} 61 | 62 | % Mathematical symbols 63 | %% \usepackage{savesym} 64 | %% \savesymbol{iint} 65 | %% \savesymbol{iiint} 66 | \newcommand\xor{\oplus} 67 | 68 | % Advanced command definitions 69 | \usepackage{xparse} 70 | 71 | % Figures and subfigures 72 | \usepackage{float} 73 | \usepackage{rotating} 74 | %\usepackage{subcaption} 75 | \usepackage{array} 76 | \usepackage{calc} 77 | \usepackage{framed} 78 | \usepackage{wrapfig} 79 | \usepackage{longtable} 80 | \newcolumntype{C}[1]{>{\centering\arraybackslash$}p{#1}<{$}} 81 | \usepackage[export]{adjustbox} 82 | % Fancy figure command 83 | \DeclareDocumentCommand{\illustration}{ 84 | m % sub-path to illustration, /Illustrations/{this}.pdf, mandatory 85 | O{.8} % width as fraction of line width, optional 86 | o % caption, optional 87 | o % label, optional 88 | }{ 89 | \begin{figure}[ht!] 90 | \centering 91 | \includegraphics[width=#2\linewidth]{./Illustrations/#1.pdf} 92 | \IfValueTF{#3}{\caption{#3}}{} 93 | \IfValueTF{#4}{\label{#4}}{} 94 | \end{figure} 95 | } 96 | 97 | % Exercise Environment 98 | \newtheorem{exercise}{Exercise}[chapter] 99 | \newenvironment{exercise*} 100 | {\renewcommand\theex{\thechapter.\arabic{ex}\rlap{$^*$}}\ex} 101 | {\endex} 102 | 103 | % Special subsection commands 104 | \definecolor{shadecolor}{HTML}{AABAD1} 105 | \DeclareDocumentCommand{\advanced}{ 106 | o % extra caption, optional 107 | }{ 108 | \begin{shaded} 109 | \begin{wrapfigure}{l}{.2\linewidth} 110 | \vspace{-8pt} 111 | \includegraphics[width=\linewidth]{./Illustrations/Propeller/Propeller.pdf} 112 | \end{wrapfigure} 113 | \noindent This is an optional, in-depth section. It almost 114 | certainly won't help you write better software, so feel free to 115 | skip it. It is only here to satisfy your inner geek's curiosity. 116 | \IfValueTF{#1}{#1}{} 117 | \end{shaded} 118 | } 119 | % Chapter markup 120 | \usepackage{tikz, blindtext} 121 | \makechapterstyle{box}{ 122 | \renewcommand*{\printchaptername}{} 123 | \renewcommand*{\printchapternum}{ 124 | \flushright 125 | \begin{tikzpicture} 126 | \draw[fill,color=black] (0,0) rectangle (2cm,2cm); 127 | \draw[color=white] (1cm,1cm) node { \chapnumfont\thechapter }; 128 | \end{tikzpicture} 129 | } 130 | \renewcommand*{\printchaptertitle}[1]{\flushright\chaptitlefont##1} 131 | } 132 | \chapterstyle{box} 133 | % Title page markup 134 | \usepackage{geometry} 135 | \usepackage{titlesec} 136 | \usepackage{datetime} 137 | \makeatletter 138 | \newlength\drop 139 | \renewcommand{\maketitle}{ 140 | \thispagestyle{empty} 141 | \begingroup 142 | \drop = 0.1\textheight 143 | \vspace*{\baselineskip} 144 | \vfill 145 | \hbox{% 146 | \hspace*{0.22\textwidth}% 147 | \rule{1pt}{\dimexpr\textheight-28pt\relax}% 148 | \hspace*{0.05\textwidth}% 149 | \parbox[b]{0.73\textwidth}{% 150 | \vbox{% 151 | \vspace{\drop} 152 | {\Huge\bfseries\raggedright\@title\par}\vskip2.37\baselineskip 153 | {\raggedleft 154 | \Large\bfseries 155 | \expandarg{\StrSubstitute{\@author}{,}{\par}} 156 | \par} 157 | \vspace{0.5\textheight} 158 | {\bfseries 159 | \href{https://github.com/leanprover/tutorial/commit/\gitHash}{Version \gitAbbrevHash}, 160 | updated at \gitAuthorIsoDate} 161 | }% end of vbox 162 | }% end of parbox 163 | }% end of hbox 164 | \vfill 165 | \null 166 | \endgroup 167 | \thispagestyle{empty} 168 | \par 169 | \noindent 170 | Copyright (c) 2014--2015, Jeremy Avigad, Leonardo de Moura, and Soonho Kong. All rights reserved. 171 | Released under Apache 2.0 license as described in the file LICENSE. 172 | 173 | \clearpage 174 | % \thispagestyle{plain} 175 | % \par 176 | % \vspace*{.3\textheight}{ 177 | % \centering 178 | % \emph{To ...} 179 | % \par 180 | % \clearpage 181 | % } 182 | } 183 | \makeatother 184 | -------------------------------------------------------------------------------- /header/latex_quickref.org: -------------------------------------------------------------------------------- 1 | #+OPTIONS: toc:nil 2 | #+BEGIN_SRC emacs-lisp :results silent :exports results 3 | (require 'cl) ;; The find function is in the cl library. 4 | #+END_SRC 5 | #+LANGUAGE: en 6 | #+LATEX_CLASS_OPTIONS: [11pt,article] 7 | #+LATEX_HEADER: \input{header/latex_quickref.tex} 8 | #+BEGIN_EXPORT LATEX 9 | %\OnehalfSpacing 10 | #+END_EXPORT 11 | -------------------------------------------------------------------------------- /header/latex_quickref.tex: -------------------------------------------------------------------------------- 1 | % Typography 2 | \usepackage[utf8]{luainputenc} 3 | \usepackage{amsmath} 4 | \usepackage{mathspec} 5 | \usepackage{unixode} 6 | \usepackage{amssymb} 7 | \usepackage{fontspec} 8 | \defaultfontfeatures{Ligatures=TeX} 9 | %% \setmainfont{Adobe Caslon Pro} 10 | %% \setsansfont{Myriad Pro} 11 | %% \setmonofont[Scale=MatchLowercase]{Menlo} 12 | \usepackage{microtype} 13 | \usepackage{setspace} 14 | \usepackage{etoolbox} 15 | \usepackage{csquotes} 16 | \usepackage{ulem} 17 | \usepackage{xstring} 18 | \usepackage{gitinfo} 19 | 20 | % Minted 21 | \usepackage{minted} 22 | \renewcommand{\MintedPygmentize}{./pygments-main/pygmentize} 23 | \setminted{encoding=utf-8} 24 | %\setmonofont{freemono} 25 | %\usepackage{etoolbox} 26 | %\AtBeginEnvironment{minted}{\singlespacing% 27 | % \fontsize{10}{10}\selectfont} 28 | \def\args{linenos,frame=single,fontsize=\normalsize,style=bw} 29 | \newcommand{\makenewmintedfiles}[1]{% 30 | \newmintedfile[inputlatex]{latex}{#1}% 31 | \newmintedfile[inputc]{c}{#1}% 32 | } 33 | \expandafter\makenewmintedfiles\expandafter{\args} 34 | 35 | % Colors, links, syntax highlighting 36 | \usepackage[dvipsnames,table]{xcolor} 37 | \hypersetup{ 38 | pdftitle={Lean 2 Quick Reference}, 39 | pdfauthor={Jeremy Avigad, Leonardo de Moura, Soonho Kong}, 40 | colorlinks, 41 | linkcolor=Sepia, 42 | citecolor=Periwinkle 43 | } 44 | 45 | \usepackage[acronym,toc]{glossaries} 46 | \include{Glossary} 47 | \makeglossaries 48 | \makeindex 49 | 50 | % Localization 51 | \usepackage{polyglossia} 52 | \setdefaultlanguage{english} 53 | 54 | % Mathematical symbols 55 | %% \usepackage{savesym} 56 | %% \savesymbol{iint} 57 | %% \savesymbol{iiint} 58 | \newcommand\xor{\oplus} 59 | 60 | % Advanced command definitions 61 | \usepackage{xparse} 62 | 63 | % Figures and subfigures 64 | \usepackage{float} 65 | \usepackage{rotating} 66 | %\usepackage{subcaption} 67 | \usepackage{array} 68 | \usepackage{calc} 69 | \usepackage{framed} 70 | \usepackage{wrapfig} 71 | \usepackage{longtable} 72 | \newcolumntype{C}[1]{>{\centering\arraybackslash$}p{#1}<{$}} 73 | \usepackage[export]{adjustbox} 74 | % Title page markup 75 | \usepackage{geometry} 76 | \usepackage{titlesec} 77 | \usepackage{datetime} 78 | -------------------------------------------------------------------------------- /images/android-chrome-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/android-chrome-144x144.png -------------------------------------------------------------------------------- /images/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/android-chrome-192x192.png -------------------------------------------------------------------------------- /images/android-chrome-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/android-chrome-36x36.png -------------------------------------------------------------------------------- /images/android-chrome-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/android-chrome-48x48.png -------------------------------------------------------------------------------- /images/android-chrome-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/android-chrome-72x72.png -------------------------------------------------------------------------------- /images/android-chrome-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/android-chrome-96x96.png -------------------------------------------------------------------------------- /images/apple-touch-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/apple-touch-icon-114x114.png -------------------------------------------------------------------------------- /images/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /images/apple-touch-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/apple-touch-icon-144x144.png -------------------------------------------------------------------------------- /images/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /images/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /images/apple-touch-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/apple-touch-icon-57x57.png -------------------------------------------------------------------------------- /images/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /images/apple-touch-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/apple-touch-icon-72x72.png -------------------------------------------------------------------------------- /images/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /images/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /images/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/apple-touch-icon.png -------------------------------------------------------------------------------- /images/book.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /images/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | #da532c 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /images/console.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/dropbox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /images/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/favicon-16x16.png -------------------------------------------------------------------------------- /images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/favicon-32x32.png -------------------------------------------------------------------------------- /images/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/favicon-96x96.png -------------------------------------------------------------------------------- /images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/favicon.ico -------------------------------------------------------------------------------- /images/favicon.pxm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/favicon.pxm -------------------------------------------------------------------------------- /images/gear.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/lean_logo_small.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Produced by OmniGraffle 6.0.5 2014-10-18 06:10ZCanvas 1Layer 1 4 | -------------------------------------------------------------------------------- /images/load.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "My app", 3 | "icons": [ 4 | { 5 | "src": "\/android-chrome-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/android-chrome-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/android-chrome-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/android-chrome-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/android-chrome-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/android-chrome-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /images/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/mstile-144x144.png -------------------------------------------------------------------------------- /images/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/mstile-150x150.png -------------------------------------------------------------------------------- /images/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/mstile-310x150.png -------------------------------------------------------------------------------- /images/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/mstile-310x310.png -------------------------------------------------------------------------------- /images/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanprover/tutorial/07c35e0844eb8ef3a19e447b4a1ba800a636fc41/images/mstile-70x70.png -------------------------------------------------------------------------------- /images/new.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/run.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/save.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/share.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /images/square-landscape-main-code-console.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/square-landscape-main-code.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /images/square-portrait-main-code-console.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/square-portrait-main-code.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /images/square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /imakeidx.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `imakeidx.sty', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% imakeidx.dtx (with options: `package') 8 | %% ___________________________________________________________ 9 | %% The imakeidx package for LaTeX 10 | %% Copyright (C) 2010-2012 Claudio Beccari and Enrico Gregorio 11 | %% All rights reserved 12 | %% 13 | %% License information appended 14 | %% 15 | \NeedsTeXFormat{LaTeX2e}[2005/12/01] 16 | \ProvidesPackage{imakeidx}% 17 | [2012/05/09 v1.1 Package for typesetting indices in a synchronous mode] 18 | \RequirePackage{xkeyval} 19 | \DeclareOption{xindy}{\def\imki@progdefault{texindy}} 20 | \DeclareOption{texindy}{\def\imki@progdefault{texindy}} 21 | \DeclareOption{makeindex}{\def\imki@progdefault{makeindex}} 22 | \newif\ifimki@disableautomatic 23 | \DeclareOption{noautomatic}{\imki@disableautomatictrue} 24 | \newif\ifimki@nonewpage 25 | \DeclareOption{nonewpage}{% 26 | \imki@nonewpagetrue\imki@disableautomatictrue 27 | } 28 | \newif\ifimki@splitindex 29 | \DeclareOption{splitindex}{\imki@splitindextrue} 30 | \newif\ifimki@original 31 | \DeclareOption{original}{\imki@originaltrue} 32 | \DeclareOption{quiet}{\AtEndOfPackage{% 33 | \let\imki@finalmessage\@gobble 34 | \let\imki@splitindexmessage\relax}} 35 | \ExecuteOptions{makeindex} 36 | \ProcessOptions\relax 37 | 38 | \if@twocolumn\imki@originaltrue\fi 39 | \def\imki@exec{\immediate\write18} 40 | \def\imki@engine{(pdf)latex} 41 | \ifdefined\XeTeXversion\def\imki@engine{xelatex}\fi 42 | \ifdefined\directlua % luatex doesn't have \(pdf)shellescape 43 | \def\imki@engine{lualatex} 44 | \ifnum\luatexversion<68 45 | \chardef\imki@shellescape\@ne % no way to know the value 46 | \else 47 | \RequirePackage{pdftexcmds} % provides \pdf@shellescape 48 | \chardef\imki@shellescape\pdf@shellescape 49 | \fi 50 | \let\imki@exec\pdf@system 51 | \fi 52 | \edef\imki@splitindexoptions{-m \string"\string"} 53 | \def\splitindexoptions#1{\g@addto@macro\imki@splitindexoptions{ #1}} 54 | \@onlypreamble\splitindexoptions 55 | \@namedef{ver@makeidx.sty}{3000/12/31} 56 | \@ifpackageloaded{multind} 57 | {\PackageError{imakeidx}{Incompatible package `multind' loaded} 58 | {This package is incompatible with multind, don't load both.% 59 | \MessageBreak\@ehc}} 60 | {\@namedef{ver@multind.sty}{3000/12/31}} 61 | \providecommand*\see[2]{\emph{\seename} #1} 62 | \providecommand*\seealso[2]{\emph{\alsoname} #1} 63 | \providecommand*\seename{see} 64 | \providecommand*\alsoname{see also} 65 | \providecommand*\makeindex{} % to use \renewcommand safely 66 | \renewcommand{\makeindex}[1][]{\imki@makeindex{#1}} 67 | \def\imki@makeindex#1{% 68 | \def\imki@name{\jobname}% 69 | \def\imki@title{\indexname}% 70 | \edef\imki@program{\imki@progdefault}% 71 | \let\imki@options\space 72 | \KV@imki@noautomaticfalse\KV@imki@intocfalse 73 | \setkeys{imki}{#1}% 74 | \ifimki@splitindex\KV@imki@noautomaticfalse\fi 75 | \imki@build\imki@name 76 | \imki@startidx\imki@name 77 | \imki@resetdefaults 78 | } 79 | \define@key{imki}{name}{\def\imki@name{#1}} 80 | \define@key{imki}{title}{\def\imki@title{#1}} 81 | \define@choicekey{imki}{program}[\imki@val\imki@nr] 82 | {makeindex,xindy,texindy}{% 83 | \ifcase\imki@nr\relax 84 | \def\imki@program{makeindex}% 85 | \or 86 | \def\imki@program{texindy}% 87 | \or 88 | \def\imki@program{texindy}% 89 | \fi} 90 | \define@key{imki}{options}{\def\imki@options{ #1 }} 91 | \define@boolkey{imki}{noautomatic}[true]{} 92 | \define@boolkey{imki}{intoc}[true]{} 93 | \define@key{imki}{columns}{\def\imki@columns{#1}} 94 | \define@key{imki}{columnsep}{\def\imki@columnsep{#1}} 95 | \define@boolkey{imki}{columnseprule}[true]{} 96 | \def\imki@resetdefaults{% 97 | \def\imki@options{ }% 98 | \def\imki@columns{2}\def\imki@columnsep{35\p@}% 99 | \KV@imki@columnseprulefalse 100 | \KV@imki@intocfalse\KV@imki@noautomaticfalse} 101 | \imki@resetdefaults 102 | \def\imki@build#1{% 103 | \toks@{}% 104 | \imki@dokey\imki@title 105 | \imki@dokey\imki@program 106 | \imki@dokey\imki@options 107 | \imki@dokey\imki@columns 108 | \imki@dokey\imki@columnsep 109 | \ifKV@imki@noautomatic 110 | \addto@hook\toks@{\KV@imki@noautomatictrue}% 111 | \else 112 | \addto@hook\toks@{\KV@imki@noautomaticfalse}% 113 | \fi 114 | \ifKV@imki@intoc 115 | \addto@hook\toks@{\KV@imki@intoctrue}% 116 | \else 117 | \addto@hook\toks@{\KV@imki@intocfalse}% 118 | \fi 119 | \ifKV@imki@columnseprule 120 | \addto@hook\toks@{\KV@imki@columnsepruletrue}% 121 | \else 122 | \addto@hook\toks@{\KV@imki@columnseprulefalse}% 123 | \fi 124 | \expandafter\edef\csname imki@set@#1\endcsname{\the\toks@}% 125 | } 126 | \def\imki@dokey#1{% 127 | \expandafter\addto@hook\expandafter\toks@\expandafter{% 128 | \expandafter\def\expandafter#1\expandafter{#1}}} 129 | \def\imki@startidxsplit#1{% 130 | \if@filesw 131 | \def\index{\@bsphack 132 | \@ifnextchar [{\@index}{\@index[\jobname]}} 133 | \expandafter\newwrite\csname #1@idxfile\endcsname 134 | \immediate\openout \csname #1@idxfile\endcsname #1.idx\relax 135 | \typeout{Writing index file #1.idx}% 136 | \fi} 137 | \newif\ifimki@startedidx 138 | \def\imki@startidxunique#1{% 139 | \if@filesw 140 | \ifimki@startedidx\else 141 | \newwrite\@indexfile 142 | \immediate\openout\@indexfile\jobname.idx% 143 | \global\imki@startedidxtrue 144 | \fi 145 | \def\index{\@bsphack 146 | \@ifnextchar [{\@index}{\@index[\jobname]}} 147 | \expandafter\let\csname #1@idxfile\endcsname\@empty 148 | \typeout{Started index file #1}% 149 | \fi} 150 | \renewcommand{\index}[2][]{\@bsphack\@esphack} 151 | \def\@index[#1]{% 152 | \@ifundefined{#1@idxfile}% 153 | {\PackageWarning{imakeidx}{Undefined index file `#1'}% 154 | \begingroup 155 | \@sanitize 156 | \imki@nowrindex}% 157 | {\edef\@idxfile{#1}% 158 | \begingroup 159 | \@sanitize 160 | \@wrindex\@idxfile}} 161 | \def\imki@nowrindex#1{\endgroup\@esphack} 162 | \def\imki@wrindexsplit#1#2{% 163 | \expandafter\protected@write\csname#1@idxfile\endcsname{}% 164 | {\string\indexentry{#2}{\thepage}}% 165 | \endgroup 166 | \@esphack} 167 | \def\imki@wrindexunique#1#2{% 168 | \protected@write\@indexfile{}% 169 | {\string\indexentry[#1]{#2}{\thepage}}% 170 | \endgroup 171 | \@esphack} 172 | \def\imki@shellwarn{} 173 | \ifdefined\imki@shellescape % luatex 174 | \else 175 | \@ifundefined{shellescape} 176 | {\let\imki@shellescape\pdfshellescape} % pdftex 177 | {\let\imki@shellescape\shellescape} % xetex 178 | \fi 179 | \ifnum\imki@shellescape=\z@ 180 | \let\KV@imki@noautomaticfalse\KV@imki@noautomatictrue 181 | \KV@imki@noautomatictrue 182 | \def\imki@shellwarn{\MessageBreak or call \imki@engine\space with 183 | -shell-escape} 184 | \fi 185 | \ifimki@disableautomatic 186 | \let\KV@imki@noautomaticfalse\KV@imki@noautomatictrue 187 | \KV@imki@noautomatictrue 188 | \fi 189 | \ifimki@original 190 | \expandafter\def\expandafter\theindex\expandafter{\expandafter 191 | \imki@maybeaddtotoc\theindex} 192 | \else 193 | \global\let\imki@idxprologue\relax 194 | \RequirePackage{multicol} 195 | \renewenvironment{theindex} 196 | {\imki@maybeaddtotoc 197 | \imki@indexlevel{\indexname}\imki@indexheaders 198 | \thispagestyle{\imki@firstpagestyle}% 199 | \ifnum\imki@columns>\@ne 200 | \columnsep \imki@columnsep 201 | \ifx\imki@idxprologue\relax 202 | \begin{multicols}{\imki@columns} 203 | \else 204 | \begin{multicols}{\imki@columns}[\imki@idxprologue] 205 | \fi 206 | \else 207 | \imki@idxprologue 208 | \fi 209 | \global\let\imki@idxprologue\relax 210 | \parindent\z@ 211 | \parskip\z@ \@plus .3\p@\relax 212 | \columnseprule \ifKV@imki@columnseprule.4\p@\else\z@\fi 213 | \raggedright 214 | \let\item\@idxitem 215 | \imki@othercode} 216 | {\ifnum\imki@columns>\@ne\end{multicols}\fi 217 | } 218 | \fi 219 | \def\imki@indexlevel{% 220 | \@ifundefined{chapter}{\section}{\chapter}*} 221 | \define@key{imkiindex}{level}{\def\imki@indexlevel{#1}} 222 | \def\imki@toclevel{% 223 | \@ifundefined{chapter}{section}{chapter}} 224 | \define@key{imkiindex}{toclevel}{\def\imki@toclevel{#1}} 225 | \define@boolkey{imkiindex}{noclearpage}[true]{\let\imki@clearpage\relax} 226 | \def\imki@indexheaders{% 227 | \@mkboth{\MakeUppercase\indexname}{\MakeUppercase\indexname}} 228 | \define@key{imkiindex}{headers}{\def\imki@indexheaders{\markboth#1}} 229 | \def\imki@firstpagestyle{plain} 230 | \define@key{imkiindex}{firstpagestyle}{\def\imki@firstpagestyle{#1}} 231 | \let\imki@othercode\relax 232 | \define@key{imkiindex}{othercode}{\def\imki@othercode{#1}} 233 | \newcommand{\indexsetup}[1]{% 234 | \ifimki@original\else\setkeys{imkiindex}{#1}\fi} 235 | \@onlypreamble\indexsetup 236 | \newcommand{\indexprologue}[2][\bigskip]{% 237 | \long\gdef\imki@idxprologue{{#2\par}#1}} 238 | \providecommand*{\printindex}{} 239 | \renewcommand*{\printindex}[1][\jobname]{% 240 | \@ifundefined{#1@idxfile}{\imki@error{#1}}{\imki@putindex{#1}}} 241 | 242 | \def\imki@error#1{% 243 | \def\@tempa{#1}\def\@tempb{\jobname}% 244 | \ifx\@tempa\@tempb 245 | \let\imki@optarg\@empty 246 | \else 247 | \def\imki@optarg{[#1]}% 248 | \fi 249 | \PackageError{imakeidx} 250 | {Misplaced \protect\printindex\imki@optarg} 251 | {You are not making this index, as no appropriate 252 | \protect\makeindex\MessageBreak 253 | command has been issued in the preamble.}} 254 | \def\imki@clearpage{% 255 | \@ifundefined{chapter} 256 | {\clearpage} % article and similar classes 257 | {\@ifundefined{if@openright} 258 | {\cleardoublepage} 259 | {\if@openright 260 | \cleardoublepage 261 | \else 262 | \clearpage 263 | \fi} 264 | }} 265 | \def\imki@check@indexname{\indexname} 266 | \providecommand*\imki@maybeaddtotoc{} 267 | \def\imki@finalmessage#1{% 268 | \expandafter\edef\csname imki@message#1\endcsname 269 | {\imki@program\imki@options#1.idx} 270 | \AtEndDocument{\PackageWarning{imakeidx}{% 271 | Remember to run \imki@engine\space again after calling\MessageBreak 272 | `\@nameuse{imki@message#1}'\imki@shellwarn\@gobble}}} 273 | \def\imki@splitindexmessage{% 274 | \AtEndDocument{\PackageWarningNoLine{imakeidx}{% 275 | Remember to run \imki@engine\space again after calling\MessageBreak 276 | `splitindex' and processing the indices\imki@shellwarn}}} 277 | \def\imki@makeindexname{makeindex} 278 | \def\imki@decide{% 279 | \@tempswafalse 280 | \ifimki@splitindex % splitindex is not "safe" 281 | \ifnum\imki@shellescape=\@ne\@tempswatrue\fi 282 | \else 283 | \ifx\imki@program\imki@makeindexname % nor is texindy 284 | \ifnum\imki@shellescape=\tw@\@tempswatrue\fi 285 | \fi 286 | \ifnum\imki@shellescape=\@ne\@tempswatrue\fi 287 | \fi 288 | \ifKV@imki@noautomatic 289 | \@tempswafalse 290 | \fi} 291 | \def\imki@putindexsplit#1{% 292 | \ifimki@nonewpage\else 293 | \imki@clearpage 294 | \fi 295 | \immediate\closeout\csname #1@idxfile\endcsname 296 | \let\imki@indexname\indexname % keep \indexname 297 | \@nameuse{imki@set@#1}\imki@decide 298 | \if@tempswa % we can call the external program 299 | \imki@exec{\imki@program\imki@options#1.idx}% 300 | \else 301 | \imki@finalmessage{#1}% 302 | \fi 303 | \ifKV@imki@intoc 304 | \def\imki@maybeaddtotoc{\@nameuse{phantomsection}% 305 | \addcontentsline{toc}{\imki@toclevel}{\imki@title}}% 306 | \else 307 | \def\imki@maybeaddtotoc{}% 308 | \fi 309 | \ifx\imki@title\imki@check@indexname\else 310 | \def\indexname{\imki@title}% 311 | \fi 312 | \@input@{#1.ind} 313 | \let\indexname\imki@indexname % restore \indexname 314 | } 315 | 316 | \newif\ifimki@splitdone 317 | \def\imki@putindexunique#1{% 318 | \ifimki@nonewpage\else 319 | \imki@clearpage 320 | \fi 321 | \let\imki@indexname\indexname % keep \indexname 322 | \@nameuse{imki@set@#1}\imki@decide 323 | \if@tempswa % we can call the external program 324 | \ifimki@splitdone\else 325 | \immediate\closeout\@indexfile 326 | \imki@exec{splitindex \imki@splitindexoptions\space\jobname.idx}% 327 | \global\imki@splitdonetrue 328 | \fi 329 | \else 330 | \ifimki@splitdone\else 331 | \imki@splitindexmessage\global\imki@splitdonetrue 332 | \fi 333 | \fi 334 | \if@tempswa % we can call the external program 335 | \imki@exec{\imki@program\imki@options\jobname-#1.idx}% 336 | \fi 337 | \ifKV@imki@intoc 338 | \def\imki@maybeaddtotoc{\@nameuse{phantomsection}% 339 | \addcontentsline{toc}{\imki@toclevel}{\imki@title}}% 340 | \else 341 | \def\imki@maybeaddtotoc{}% 342 | \fi 343 | \ifx\imki@title\imki@check@indexname\else 344 | \def\indexname{\imki@title}% 345 | \fi 346 | \@input@{\jobname-#1.ind} 347 | \let\indexname\imki@indexname % restore \indexname 348 | } 349 | \ifimki@splitindex 350 | \let\imki@startidx\imki@startidxunique 351 | \let\@wrindex\imki@wrindexunique 352 | \let\imki@putindex\imki@putindexunique 353 | \let\imki@startidxsplit\@undefined 354 | \let\imki@wrindexsplit\@undefined 355 | \let\imki@putindexsplit\@undefined 356 | \else 357 | \let\imki@startidx\imki@startidxsplit 358 | \let\@wrindex\imki@wrindexsplit 359 | \let\imki@putindex\imki@putindexsplit 360 | \let\imki@startidxunique\@undefined 361 | \let\imki@wrindexunique\@undefined 362 | \let\imki@putindexunique\@undefined 363 | \fi 364 | \@ifclassloaded{memoir}{\let\@wrindexm@m\@wrindex}{} 365 | 366 | %% 367 | %% Copyright 2010--2012 Claudio Beccari 368 | %% Copyright 2010--2012 Enrico Gregorio 369 | %% 370 | %% Distributable under the LaTeX Project Public License, 371 | %% version 1.3c or higher (your choice). The latest version of 372 | %% this license is at: http://www.latex-project.org/lppl.txt 373 | %% 374 | %% This work is "author-maintained" 375 | %% 376 | %% This work consists of this file imakeidx.dtx, a README file 377 | %% and the derived files imakeidx.sty and imakeidx.pdf. 378 | %% 379 | %% 380 | %% End of file `imakeidx.sty'. 381 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Tutorial: Theorem Proving in Lean 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /js/.gitignore: -------------------------------------------------------------------------------- 1 | nav_data.js -------------------------------------------------------------------------------- /js/completion_input.in: -------------------------------------------------------------------------------- 1 | VISIT ./js/completion_input.lean 2 | WAIT 3 | FINDP 2 4 | a 5 | FINDP 2 6 | b 7 | FINDP 2 8 | c 9 | FINDP 2 10 | d 11 | FINDP 2 12 | e 13 | FINDP 2 14 | f 15 | FINDP 2 16 | g 17 | FINDP 2 18 | h 19 | FINDP 2 20 | i 21 | FINDP 2 22 | j 23 | FINDP 2 24 | k 25 | FINDP 2 26 | l 27 | FINDP 2 28 | m 29 | FINDP 2 30 | n 31 | FINDP 2 32 | o 33 | FINDP 2 34 | p 35 | FINDP 2 36 | q 37 | FINDP 2 38 | r 39 | FINDP 2 40 | s 41 | FINDP 2 42 | t 43 | FINDP 2 44 | u 45 | FINDP 2 46 | v 47 | FINDP 2 48 | w 49 | FINDP 2 50 | x 51 | FINDP 2 52 | y 53 | FINDP 2 54 | z 55 | -------------------------------------------------------------------------------- /js/completion_input.lean: -------------------------------------------------------------------------------- 1 | import standard 2 | -- 3 | -------------------------------------------------------------------------------- /juicy-ace-editor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | 145 | -------------------------------------------------------------------------------- /lean.bib: -------------------------------------------------------------------------------- 1 | @article{Coquand1988, 2 | author = {Coquand, Thierry and Huet, Gerard}, 3 | title = {The Calculus of Constructions}, 4 | journal = {Inf. Comput.}, 5 | issue_date = {February/March 1988}, 6 | volume = {76}, 7 | number = {2-3}, 8 | month = feb, 9 | year = {1988}, 10 | issn = {0890-5401}, 11 | pages = {95--120}, 12 | numpages = {26}, 13 | url = {http://dx.doi.org/10.1016/0890-5401(88)90005-3}, 14 | doi = {10.1016/0890-5401(88)90005-3}, 15 | acmid = {47725}, 16 | publisher = {Academic Press, Inc.}, 17 | address = {Duluth, MN, USA}, 18 | } 19 | 20 | @inproceedings{goguen:et:al:06, 21 | author = {Healfdene Goguen and 22 | Conor McBride and 23 | James McKinna}, 24 | title = {Eliminating Dependent Pattern Matching}, 25 | booktitle = {Algebra, Meaning, and Computation, Essays Dedicated to Joseph A. Goguen 26 | on the Occasion of His 65th Birthday}, 27 | pages = {521--540}, 28 | year = {2006}, 29 | crossref = {DBLP:conf/birthday/2006goguen}, 30 | url = {http://dx.doi.org/10.1007/11780274_27}, 31 | doi = {10.1007/11780274_27}, 32 | timestamp = {Mon, 26 Jun 2006 15:11:47 +0200}, 33 | biburl = {http://dblp.uni-trier.de/rec/bib/conf/birthday/GoguenMM06}, 34 | bibsource = {dblp computer science bibliography, http://dblp.org} 35 | } 36 | @proceedings{DBLP:conf/birthday/2006goguen, 37 | editor = {Kokichi Futatsugi and 38 | Jean{-}Pierre Jouannaud and 39 | Jos{\'{e}} Meseguer}, 40 | title = {Algebra, Meaning, and Computation, Essays Dedicated to Joseph A. Goguen 41 | on the Occasion of His 65th Birthday}, 42 | series = {Lecture Notes in Computer Science}, 43 | volume = {4060}, 44 | publisher = {Springer}, 45 | year = {2006}, 46 | isbn = {3-540-35462-X}, 47 | timestamp = {Mon, 03 Mar 4456324 10:48:48 +nce}, 48 | biburl = {http://dblp.uni-trier.de/rec/bib/conf/birthday/2006goguen}, 49 | bibsource = {dblp computer science bibliography, http://dblp.org} 50 | } 51 | 52 | @inproceedings{mcbride:et:al:04, 53 | author = {Conor McBride and 54 | Healfdene Goguen and 55 | James McKinna}, 56 | title = {A Few Constructions on Constructors}, 57 | booktitle = {Types for Proofs and Programs, International Workshop, {TYPES} 2004, 58 | Jouy-en-Josas, France, December 15-18, 2004, Revised Selected Papers}, 59 | pages = {186--200}, 60 | year = {2004}, 61 | crossref = {DBLP:conf/types/2004}, 62 | url = {http://dx.doi.org/10.1007/11617990_12}, 63 | doi = {10.1007/11617990_12}, 64 | timestamp = {Wed, 01 Feb 2006 14:58:00 +0100}, 65 | biburl = {http://dblp.uni-trier.de/rec/bib/conf/types/McBrideGM04}, 66 | bibsource = {dblp computer science bibliography, http://dblp.org} 67 | } 68 | @proceedings{DBLP:conf/types/2004, 69 | editor = {Jean{-}Christophe Filli{\^{a}}tre and 70 | Christine Paulin{-}Mohring and 71 | Benjamin Werner}, 72 | title = {Types for Proofs and Programs, International Workshop, {TYPES} 2004, 73 | Jouy-en-Josas, France, December 15-18, 2004, Revised Selected Papers}, 74 | series = {Lecture Notes in Computer Science}, 75 | volume = {3839}, 76 | publisher = {Springer}, 77 | year = {2006}, 78 | isbn = {3-540-31428-8}, 79 | timestamp = {Wed, 10 Aug 4439729 02:02:08 +nce}, 80 | biburl = {http://dblp.uni-trier.de/rec/bib/conf/types/2004}, 81 | bibsource = {dblp computer science bibliography, http://dblp.org} 82 | } 83 | 84 | @inproceedings{pfenning:paulin:mohring:89, 85 | author = {Frank Pfenning and 86 | Christine Paulin{-}Mohring}, 87 | title = {Inductively Defined Types in the Calculus of Constructions}, 88 | booktitle = {Mathematical Foundations of Programming Semantics, 5th International 89 | Conference, Tulane University, New Orleans, Louisiana, USA, March 90 | 29 - April 1, 1989, Proceedings}, 91 | pages = {209--228}, 92 | year = {1989}, 93 | crossref = {DBLP:conf/mfps/1989}, 94 | url = {http://dx.doi.org/10.1007/BFb0040259}, 95 | doi = {10.1007/BFb0040259}, 96 | timestamp = {Fri, 09 Oct 2009 11:50:27 +0200}, 97 | biburl = {http://dblp.uni-trier.de/rec/bib/conf/mfps/PfenningP89}, 98 | bibsource = {dblp computer science bibliography, http://dblp.org} 99 | } 100 | @proceedings{DBLP:conf/mfps/1989, 101 | editor = {Michael G. Main and 102 | Austin Melton and 103 | Michael W. Mislove and 104 | David A. Schmidt}, 105 | title = {Mathematical Foundations of Programming Semantics, 5th International 106 | Conference, Tulane University, New Orleans, Louisiana, USA, March 107 | 29 - April 1, 1989, Proceedings}, 108 | series = {Lecture Notes in Computer Science}, 109 | volume = {442}, 110 | publisher = {Springer}, 111 | year = {1990}, 112 | isbn = {3-540-97375-3}, 113 | timestamp = {Mon, 24 May 4447937 03:27:28 +nce}, 114 | biburl = {http://dblp.uni-trier.de/rec/bib/conf/mfps/1989}, 115 | bibsource = {dblp computer science bibliography, http://dblp.org} 116 | } 117 | 118 | @article{dybjer:94, 119 | author = {Peter Dybjer}, 120 | title = {Inductive Families}, 121 | journal = {Formal Asp. Comput.}, 122 | volume = {6}, 123 | number = {4}, 124 | pages = {440--465}, 125 | year = {1994}, 126 | url = {http://dx.doi.org/10.1007/BF01211308}, 127 | doi = {10.1007/BF01211308}, 128 | timestamp = {Wed, 18 Apr 4435506 11:46:40 +}, 129 | biburl = {http://dblp.uni-trier.de/rec/bib/journals/fac/Dybjer94}, 130 | bibsource = {dblp computer science bibliography, http://dblp.org} 131 | } -------------------------------------------------------------------------------- /merge_chapters.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright (c) 2014 Microsoft Corporation. All rights reserved. 4 | # Released under Apache 2.0 license as described in the file LICENSE. 5 | # 6 | # Author: Soonho Kong 7 | # 8 | # Collect 01_xxx.org, 02_xxx.org, ... files and merge them into tutorial.org file 9 | # 10 | TUTORIAL_ORG_FILE=tutorial.org 11 | 12 | rm -f ${TUTORIAL_ORG_FILE} 13 | 14 | # Collect Main Chapters 15 | for CHAPTER in [0-9][0-9]*.org 16 | do 17 | if [ ! -f ${TUTORIAL_ORG_FILE} ] ; then 18 | echo "$CHAPTER -> ${TUTORIAL_ORG_FILE}" 19 | cp -- ${CHAPTER} ${TUTORIAL_ORG_FILE} 20 | else 21 | START_LINE=`grep -n '^\* ' ${CHAPTER} | cut -d ':' -f 1` 22 | echo "$CHAPTER : +${START_LINE} -> ${TUTORIAL_ORG_FILE}" 23 | tail -n +${START_LINE} -- ${CHAPTER} >> ${TUTORIAL_ORG_FILE} 24 | fi 25 | done 26 | 27 | # Collect Appendices 28 | echo "#+BEGIN_EXPORT LATEX" >> ${TUTORIAL_ORG_FILE} 29 | echo "\appendix" >> ${TUTORIAL_ORG_FILE} 30 | echo "#+END_EXPORT" >> ${TUTORIAL_ORG_FILE} 31 | 32 | for APPENDIX in A[0-9]*.org 33 | do 34 | START_LINE=`grep -n '^\* ' ${APPENDIX} | cut -d ':' -f 1` 35 | echo "$APPENDIX : +${START_LINE} -> ${TUTORIAL_ORG_FILE}" 36 | tail -n +${START_LINE} -- ${APPENDIX} >> ${TUTORIAL_ORG_FILE} 37 | done 38 | 39 | 40 | # Replace inter-file links to inner-file links 41 | # 42 | # Example: 43 | # 44 | # In Section [[file:05_Interacting_with_Lean.org::Notation_Overloads_and_Coercions][Notations, Overloads, and Coercions]], we discussed coercions 45 | # 46 | # => 47 | # 48 | # In Section [[Notation_Overloads_and_Coercions][Notations, Overloads, and Coercions]], we discussed coercions 49 | sed -e "s/file:[0-9][0-9]_[^:]*.org:://g" ${TUTORIAL_ORG_FILE} > ${TUTORIAL_ORG_FILE}.tmp 50 | mv -v ${TUTORIAL_ORG_FILE}.tmp ${TUTORIAL_ORG_FILE} 51 | -------------------------------------------------------------------------------- /newunicodechar.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `newunicodechar.sty', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% newunicodechar.dtx (with options: `package') 8 | %% 9 | %% This is a generated file. 10 | %% 11 | %% Copyright (C) 2011 by Enrico Gregorio 12 | %% 13 | %% ------------------------------------------------------- 14 | %% 15 | %% This work may be distributed and/or modified under the 16 | %% conditions of the LaTeX Project Public License, either 17 | %% version 1.3c of this license or (at your option) any 18 | %% later version. The latest version of this license is in 19 | %% http://www.latex-project.org/lppl.txt 20 | %% and version 1.3 or later is part of all distributions 21 | %% of LaTeX version 2005/12/01 or later. 22 | %% 23 | %% This work has the LPPL maintenance status `maintained'. 24 | %% 25 | %% The Current Maintainer of this work is Enrico Gregorio. 26 | %% 27 | %% This work consists of the files 28 | %% newunicodechar.dtx 29 | %% newunicodechar.ins 30 | %% and the derived file newunicodechar.sty. 31 | %% 32 | \NeedsTeXFormat{LaTeX2e}[2008/04/05] 33 | \ProvidesPackage{newunicodechar} 34 | [2011/02/18 v1.0 Defining Unicode characters] 35 | \@ifundefined{eTeXversion} 36 | {\PackageError{newunicodechar}{LaTeX engine too old, aborting} 37 | {Please upgrade your TeX system}\@@end}{} 38 | \DeclareOption{verbose}{\let\nuc@verbose=T} 39 | \ProcessOptions\relax 40 | \def\nuc@onebyteerr{\PackageError{newunicodechar} 41 | {ASCII character requested} 42 | {Only characters above U+007F may be defined; you asked 43 | for\MessageBreak a plain ASCII character and your definition 44 | has been ignored.}} 45 | \def\nuc@emptyargerr{\PackageError{newunicodechar} 46 | {Empty argument} 47 | {You shouldn't write \protect\newunicodechar{}{...}}} 48 | \def\nuc@invalidargerr{\PackageError{newunicodechar} 49 | {Invalid argument} 50 | {The first argument to \protect\newunicodechar\space is 51 | either\MessageBreak too long or an invalid sequence of bytes}} 52 | \begingroup 53 | \catcode`\^=7 \catcode30=12 \catcode`\!=12 % for safety 54 | \edef\next{\@gobble^^^^0021} 55 | \expandafter\endgroup 56 | \ifx\next\@empty % Start of code for Unicode engines 57 | \chardef\nuc@atcode=\catcode`\~ 58 | \catcode`\~=\active 59 | \def\newunicodechar#1#2{% 60 | \if\relax\detokenize{#1}\relax 61 | \nuc@emptyargerr 62 | \else 63 | \if\relax\detokenize\expandafter{\@cdr#1\@nil}\relax 64 | \ifnum`#1>\string"7F 65 | \catcode`#1=\active 66 | \begingroup\lccode`\~=`#1 67 | \lowercase{\endgroup\protected\def~}{#2}% 68 | \else 69 | \nuc@onebyteerr 70 | \fi 71 | \else 72 | \nuc@invalidargerr 73 | \fi 74 | \fi} 75 | \catcode`\~=\nuc@atcode 76 | \@onlypreamble\newunicodechar 77 | \expandafter\endinput 78 | \fi % End of code for Unicode engines 79 | \def\nuc@stop{\PackageWarningNoLine{newunicodechar} 80 | {This package won't work without loading\MessageBreak 81 | `inputenc' with the `utf8' option}% 82 | \let\newunicodechar\@gobbletwo\endinput} 83 | 84 | \@ifpackageloaded{inputenc}{}{\nuc@stop} 85 | \@ifpackagewith{inputenc}{utf8}{}{\nuc@stop} 86 | \@ifpackagewith{inputenc}{utf8x}{\nuc@stop}{} 87 | \def\newunicodechar#1#2{% 88 | \@tempswafalse 89 | \edef\@tempa{\detokenize{#1}}% 90 | \if\relax\@tempa\relax 91 | \nuc@emptyargerr 92 | \else 93 | \edef\@tempb{\expandafter\@car\@tempa\@nil}% 94 | \nuc@check 95 | \if@tempswa 96 | \@ifundefined{u8:\@tempa}{} 97 | {\PackageWarning{newunicodechar} 98 | {Redefining Unicode character\ifdefined\nuc@verbose; 99 | it meant\MessageBreak 100 | ***\space\space\nuc@meaning\space\space***\MessageBreak 101 | before your redefinition\fi}}% 102 | \@namedef{u8:\@tempa}{#2}% 103 | \fi 104 | \fi 105 | } 106 | \def\nuc@getlength#1{% 107 | \ifx#1\@nil 108 | \expandafter\relax 109 | \else 110 | +1\expandafter\nuc@getlength 111 | \fi} 112 | \ifdefined\nuc@verbose 113 | \def\nuc@meaning{\expandafter\expandafter\expandafter 114 | \strip@prefix\expandafter\meaning\csname u8:\@tempa\endcsname} 115 | \fi 116 | \def\nuc@check{% 117 | \ifcase\numexpr0\expandafter\nuc@getlength\@tempa\@nil 118 | \or %0 119 | \nuc@onebyteerr\or %1 120 | \nuc@ch@ck{192}\or %2 121 | \nuc@ch@ck{224}\or %3 122 | \nuc@ch@ck{240}\else %4 123 | \nuc@invalidargerr 124 | \fi} 125 | \def\nuc@ch@ck#1{% 126 | \expandafter\ifnum\expandafter`\@tempb<#1\relax 127 | \nuc@invalidargerr 128 | \else 129 | \@tempswatrue 130 | \fi 131 | } 132 | \@onlypreamble\newunicodechar 133 | \endinput 134 | %% 135 | %% End of file `newunicodechar.sty'. 136 | -------------------------------------------------------------------------------- /structures.org: -------------------------------------------------------------------------------- 1 | #+Author: [[http://leodemoura.github.io][Leonardo de Moura]] 2 | #+TITLE: Structures 3 | #+HTML_HEAD: 4 | #+HTML_HEAD_EXTRA: 5 | #+HTML_HEAD_EXTRA: 6 | #+HTML_HEAD_EXTRA: 7 | #+HTML_HEAD_EXTRA: 8 | #+HTML_HEAD_EXTRA: 9 | #+HTML_HEAD_EXTRA: 10 | #+OPTIONS: toc:nil 11 | 12 | The =structure= command generates _record_ types. They generalize the dependent product type 13 | by providing named fields. It can be viewed as a macro built on top of the inductive datatype 14 | provided by the Lean kernel. Every =structure= declaration introduces a namespace with the 15 | same name. The general form of a structure declaration is as follows: 16 | 17 | 18 | #+BEGIN_SRC 19 | 20 | structure : Type := 21 | :: 22 | 23 | #+END_SRC 24 | 25 | Most parts are optional. Here is a small example 26 | 27 | #+BEGIN_SRC lean 28 | import logic 29 | 30 | structure point (A : Type) := 31 | mk :: (x : A) (y : A) 32 | #+END_SRC 33 | 34 | Values of type =point= are created using =point.mk a b=, the fields of a point =p= are accessed using 35 | =point.x p= and =point.y p=. The structure command also generates useful recursors and theorems. Here are some of the 36 | constructions generated for the declaration above. 37 | 38 | #+BEGIN_SRC lean 39 | import logic 40 | 41 | structure point (A : Type) := 42 | mk :: (x : A) (y : A) 43 | 44 | -- BEGIN 45 | check point 46 | check point.rec_on -- recursor 47 | check point.induction_on -- recursor to Prop 48 | check point.destruct -- alias for point.rec_on 49 | check point.x -- projection/field accessor 50 | check point.y -- projection/field accessor 51 | check point.eta -- eta theorem 52 | check point.x.mk -- projection over constructor theorem 53 | check point.y.mk -- projection over constructor theorem 54 | -- END 55 | #+END_SRC 56 | 57 | We can obtain the complete list of generated construction using the command =print prefix=. 58 | 59 | #+BEGIN_SRC lean 60 | import logic 61 | 62 | structure point (A : Type) := 63 | mk :: (x : A) (y : A) 64 | 65 | -- BEGIN 66 | print prefix point 67 | -- END 68 | #+END_SRC 69 | 70 | Here is some simple theorems and expressions using the generated constructions. 71 | As usual, we can avoid the prefix =point= by using the command =open point=. 72 | 73 | #+BEGIN_SRC lean 74 | import logic 75 | 76 | structure point (A : Type) := 77 | mk :: (x : A) (y : A) 78 | 79 | -- BEGIN 80 | eval point.x (point.mk 10 20) 81 | eval point.y (point.mk 10 20) 82 | 83 | open point 84 | 85 | example (A : Type) (a b : A) : x (mk a b) = a := 86 | x.mk a b 87 | 88 | example (A : Type) (a b : A) : y (mk a b) = b := 89 | y.mk a b 90 | 91 | example (A : Type) (a b : A) : y (mk a b) = b := 92 | !y.mk -- let Lean figure out the arguments 93 | 94 | example (A : Type) (p : point A) : mk (x p) (y p) = p := 95 | eta p 96 | -- END 97 | #+END_SRC 98 | 99 | If the constructor is not provided, then a constructor named =mk= is generated. 100 | 101 | #+BEGIN_SRC lean 102 | import logic 103 | 104 | namespace playground 105 | -- BEGIN 106 | structure prod (A : Type) (B : Type) := 107 | (pr1 : A) (pr2 : B) 108 | 109 | check prod.mk 110 | -- END 111 | end playground 112 | #+END_SRC 113 | 114 | We can provide universe levels explicitly. 115 | 116 | #+BEGIN_SRC lean 117 | import logic 118 | 119 | namespace playground 120 | -- BEGIN 121 | -- Force A and B to be types from the same universe, and return a type also in the same universe. 122 | structure prod.{l} (A : Type.{l}) (B : Type.{l}) : Type.{max 1 l} := 123 | (pr1 : A) (pr2 : B) 124 | 125 | -- Ask Lean to pretty print universe levels 126 | set_option pp.universes true 127 | check prod.mk 128 | -- END 129 | end playground 130 | #+END_SRC 131 | 132 | We use =max 1 l= as the resultant universe level to ensure the universe level is never =0= 133 | even when the parameter =A= and =B= are propositions. 134 | Recall that in Lean, =Type.{0}= is =Prop= which is impredicative and proof irrelevant. 135 | 136 | We can _extend_ existing structures by adding new fields. 137 | 138 | #+BEGIN_SRC lean 139 | import logic 140 | 141 | -- BEGIN 142 | structure point (A : Type) := 143 | mk :: (x : A) (y : A) 144 | 145 | inductive color := 146 | red, green, blue 147 | 148 | structure color_point (A : Type) extends point A := 149 | mk :: (c : color) 150 | -- END 151 | #+END_SRC 152 | 153 | The type =color_point= inherits all the fields from =point= and declares a new one =c : color=. 154 | Lean automatically generates a _coercion_ from =color_point= to =point=. 155 | 156 | #+BEGIN_SRC lean 157 | import logic 158 | open num 159 | 160 | structure point (A : Type) := 161 | mk :: (x : A) (y : A) 162 | 163 | inductive color := 164 | red, green, blue 165 | 166 | structure color_point (A : Type) extends point A := 167 | mk :: (c : color) 168 | -- BEGIN 169 | definition x_plus_y (p : point num) := 170 | point.x p + point.y p 171 | 172 | definition green_point : color_point num := 173 | color_point.mk 10 20 color.green 174 | 175 | eval x_plus_y green_point 176 | 177 | -- Force lean to display implicit coercions 178 | set_option pp.coercions true 179 | 180 | check x_plus_y green_point 181 | 182 | example : green_point = point.mk 10 20 := 183 | rfl 184 | 185 | check color_point.to_point 186 | -- END 187 | #+END_SRC 188 | 189 | The coercions are named =to_=. 190 | Lean always declare functions that map the child structure to its parents. 191 | We can request Lean to *not* mark these functions as coercions by 192 | using the =private= keyword. 193 | 194 | #+BEGIN_SRC lean 195 | import logic 196 | open num 197 | 198 | -- BEGIN 199 | structure point (A : Type) := 200 | mk :: (x : A) (y : A) 201 | 202 | inductive color := 203 | red, green, blue 204 | 205 | structure color_point (A : Type) extends private point A := 206 | mk :: (c : color) 207 | 208 | -- For private parent structures we have to use the coercions explicitly. 209 | -- If we remove color_point.to_point we get a type error. 210 | example : color_point.to_point (color_point.mk 10 20 color.blue) = point.mk 10 20 := 211 | rfl 212 | -- END 213 | #+END_SRC 214 | 215 | We can "rename" fields inherited from parent structures using the =renaming= clause. 216 | 217 | #+BEGIN_SRC lean 218 | import logic 219 | 220 | namespace playground 221 | -- BEGIN 222 | structure prod (A : Type) (B : Type) := 223 | pair :: (pr1 : A) (pr2 : B) 224 | 225 | -- Rename fields pr1 and pr2 to x and y respectively. 226 | structure point3 (A : Type) extends prod A A renaming pr1→x pr2→y := 227 | mk :: (z : A) 228 | 229 | check point3.x 230 | check point3.y 231 | check point3.z 232 | 233 | example : point3.mk 10 20 30 = prod.pair 10 20 := 234 | rfl 235 | -- END 236 | 237 | end playground 238 | #+END_SRC 239 | 240 | Structures can be tagged as a _class_. The class-instance resolution 241 | is used to synthesize implicit arguments marked with the =[]= modifier. 242 | Another difference is that the structure is an _instance implicit_ argument for 243 | every projection. The idea is that the actual structure is inferred by Lean 244 | using the class-instance resolution. 245 | 246 | #+BEGIN_SRC lean 247 | import logic 248 | 249 | structure has_mul [class] (A : Type) := 250 | mk :: (mul : A → A → A) 251 | 252 | check @has_mul.mul 253 | 254 | -- Since [s : has_mul A] is an instance implicit argument for has_mul.mul. 255 | -- The operation has_mul.mul can be used as a binary operator. 256 | infixl `*` := has_mul.mul 257 | 258 | section 259 | -- The structure s in the local context is used to synthesize 260 | -- the implicit argument in a * b 261 | variables (A : Type) (s : has_mul A) (a b : A) 262 | check a * b 263 | end 264 | #+END_SRC 265 | 266 | When a structure is marked as a class, the functions mapping a child structure 267 | to its parents is also marked as an _instance_ unless the =private= modifier is used. 268 | Moreover, whenever an instances of the parent structure is required, and instance 269 | of the child structure can be provided. In the following example, we use 270 | this mechanism to "reuse" the notation defined for the parent structure with 271 | the child structure. 272 | 273 | #+BEGIN_SRC lean 274 | import logic 275 | 276 | structure has_mul [class] (A : Type) := 277 | mk :: (mul : A → A → A) 278 | 279 | -- Since [s : has_mul A] is an instance implicit argument for has_mul.mul. 280 | -- The operation has_mul.mul can be used as a binary operator. 281 | infixl `*` := has_mul.mul 282 | 283 | structure semigroup [class] (A : Type) extends has_mul A := 284 | mk :: (assoc : ∀ a b c, mul (mul a b) c = mul a (mul b c)) 285 | 286 | section 287 | -- The structure s in the local context is used to synthesize 288 | -- the implicit argument in a * b 289 | variables (A : Type) (s : semigroup A) (a b : A) 290 | check a * b 291 | 292 | -- We can see what is going by asking Lean to display implicit 293 | -- arguments, coercions, and disable notation. 294 | set_option pp.implicit true 295 | set_option pp.notation false 296 | set_option pp.coercions true 297 | 298 | check a * b 299 | end 300 | #+END_SRC 301 | 302 | Here is a fragment of the algebraic hierarchy defined using this mechanism. 303 | In Lean, we can also inherit from multiple structures. Moreover, fields with the same 304 | name are merged. If the types do not match an error is generated. 305 | The "merge" can be avoided by using the =renaming= clause. 306 | 307 | #+BEGIN_SRC lean 308 | import logic 309 | 310 | structure has_mul [class] (A : Type) := 311 | mk :: (mul : A → A → A) 312 | 313 | structure has_one [class] (A : Type) := 314 | mk :: (one : A) 315 | 316 | structure has_inv [class] (A : Type) := 317 | mk :: (inv : A → A) 318 | 319 | infixl `*` := has_mul.mul 320 | postfix `⁻¹` := has_inv.inv 321 | notation 1 := has_one.one 322 | 323 | structure semigroup [class] (A : Type) extends has_mul A := 324 | mk :: (assoc : ∀ a b c, mul (mul a b) c = mul a (mul b c)) 325 | 326 | structure comm_semigroup [class] (A : Type) extends semigroup A := 327 | mk :: (comm : ∀ a b, mul a b = mul b a) 328 | 329 | structure monoid [class] (A : Type) extends semigroup A, has_one A := 330 | mk :: (right_id : ∀ a, mul a one = a) (left_id : ∀ a, mul one a = a) 331 | 332 | -- We can suppress := and :: when we are not declaring any new field. 333 | structure comm_monoid [class] (A : Type) extends monoid A, comm_semigroup A 334 | 335 | -- The common fields of monoid and comm_semigroup have been merged 336 | print prefix comm_monoid 337 | #+END_SRC 338 | 339 | The =renaming= clause allow us to perform non-trivial merge operations such as combining an abelian group with a monoid to 340 | obtain a ring. 341 | 342 | #+BEGIN_SRC lean 343 | import logic 344 | 345 | structure has_mul [class] (A : Type) := 346 | (mul : A → A → A) 347 | 348 | structure has_one [class] (A : Type) := 349 | (one : A) 350 | 351 | structure has_inv [class] (A : Type) := 352 | (inv : A → A) 353 | 354 | infixl `*` := has_mul.mul 355 | postfix `⁻¹` := has_inv.inv 356 | notation 1 := has_one.one 357 | 358 | structure semigroup [class] (A : Type) extends has_mul A := 359 | (assoc : ∀ a b c, mul (mul a b) c = mul a (mul b c)) 360 | 361 | structure comm_semigroup [class] (A : Type) extends semigroup A renaming mul→add:= 362 | (comm : ∀ a b, add a b = add b a) 363 | 364 | infixl `+` := comm_semigroup.add 365 | 366 | structure monoid [class] (A : Type) extends semigroup A, has_one A := 367 | (right_id : ∀ a, mul a one = a) (left_id : ∀ a, mul one a = a) 368 | 369 | -- We can suppress := and :: when we are not declaring any new field. 370 | structure comm_monoid [class] (A : Type) extends monoid A renaming mul→add, comm_semigroup A 371 | 372 | structure group [class] (A : Type) extends monoid A, has_inv A := 373 | (is_inv : ∀ a, mul a (inv a) = one) 374 | 375 | structure abelian_group [class] (A : Type) extends group A renaming mul→add, comm_monoid A 376 | 377 | structure ring [class] (A : Type) 378 | extends abelian_group A renaming 379 | assoc→add.assoc 380 | comm→add.comm 381 | one→zero 382 | right_id→add.right_id 383 | left_id→add.left_id 384 | inv→uminus 385 | is_inv→uminus_is_inv, 386 | monoid A renaming 387 | assoc→mul.assoc 388 | right_id→mul.right_id 389 | left_id→mul.left_id 390 | := 391 | (dist_left : ∀ a b c, mul a (add b c) = add (mul a b) (mul a c)) 392 | (dist_right : ∀ a b c, mul (add a b) c = add (mul a c) (mul b c)) 393 | #+END_SRC 394 | -------------------------------------------------------------------------------- /tc-pgf.def: -------------------------------------------------------------------------------- 1 | %% Copyright (C) 2011-2012 by Martin Scharrer 2 | %% ---------------------------------------------------------------------- 3 | %% This work may be distributed and/or modified under the 4 | %% conditions of the LaTeX Project Public License, either version 1.3 5 | %% of this license or (at your option) any later version. 6 | %% The latest version of this license is in 7 | %% http://www.latex-project.org/lppl.txt 8 | %% and version 1.3 or later is part of all distributions of LaTeX 9 | %% version 2005/12/01 or later. 10 | %% 11 | %% This work has the LPPL maintenance status `maintained'. 12 | %% 13 | %% The Current Maintainer of this work is Martin Scharrer. 14 | %% 15 | %% This work consists of the files trimclip.dtx, adjustbox.ins 16 | %% and the derived files trimclip.sty, 17 | %% tc-dvips.def, tc-pdftex.def, tc-pgf.def and tc-xetex.def. 18 | %% Further author information are located in the .def files. 19 | %% 20 | \ProvidesFile{tc-pgf.def}[2012/05/13 v1.0 trimclip fall-back clipping driver using PGF] 21 | \RequirePackage{pgf} 22 | \def\@cliptoboxdim#1{% 23 | \setbox#1\hbox{\begin{pgfpicture}% 24 | \pgfpathmoveto{\pgfqpoint\z@{-\dp#1}}% 25 | \pgfpathlineto{\pgfqpoint\z@{\ht#1}}% 26 | \pgfpathlineto{\pgfqpoint{\wd#1}{\ht#1}}% 27 | \pgfpathlineto{\pgfqpoint{\wd#1}{-\dp#1}}% 28 | \pgfpathclose 29 | \pgfusepathqclip 30 | \pgfset{inner sep=\z@,outer sep=\z@,minimum size=\z@}% 31 | \pgfnode{rectangle}{base west}{\usebox#1}{}{}% 32 | \pgfsetbaselinepointnow{\pgfpoint\z@\z@}% 33 | \end{pgfpicture}}% 34 | } 35 | \endinput 36 | %% 37 | %% End of file `tc-pgf.def'. 38 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Test is all examples in the .org files are working 3 | if [ $# -ne 2 ]; then 4 | echo "Usage: test.sh [lean-executable-path] [file]" 5 | exit 1 6 | fi 7 | ulimit -s unlimited 8 | LEAN=$1 9 | f=$2 10 | i=0 11 | in_code_block=0 12 | lastbegin=0 13 | linenum=0 14 | echo "-- testing $f" 15 | while read -r line; do 16 | linenum=$((linenum + 1)) 17 | if [[ $line =~ ^#\+BEGIN_SRC\ lean[[:space:]]*$ ]]; then 18 | in_code_block=1 19 | i=$((i + 1)) 20 | lastbegin=$linenum 21 | rm -f $f.$i.lean 22 | echo -E "import standard" >> $f.$i.lean 23 | elif [[ $line =~ ^#\+END_SRC ]]; then 24 | if [[ $in_code_block -eq 1 ]]; then 25 | if $LEAN -t 100000 $f.$i.lean > $f.$i.produced.out; then 26 | echo "code fragment #$i worked" 27 | else 28 | echo "ERROR executing $f.$i.lean, for in_code_block block starting at $lastbegin, produced output:" 29 | cat $f.$i.produced.out 30 | exit 1 31 | fi 32 | fi 33 | in_code_block=0 34 | elif [[ $in_code_block -eq 1 ]]; then 35 | echo -E "$line" >> $f.$i.lean 36 | fi 37 | done < $f 38 | rm -f $f.*.produced.out 39 | rm -f $f.*.lean 40 | exit 0 41 | -------------------------------------------------------------------------------- /test_js.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Test is all examples in the .org files are working with lean.js 3 | 4 | LEAN_JS=lean.js 5 | RUN_LEAN_JS=run_lean_js.sh 6 | 7 | if [ $# -ne 1 ]; then 8 | echo "Usage: test.sh [file]" 9 | exit 1 10 | fi 11 | 12 | if [ ! -f ${LEAN_JS} ] ; then 13 | wget https://leanprover.github.io/lean.js/${LEAN_JS} 14 | fi 15 | 16 | if [ ! -f ${RUN_LEAN_JS} ] ; then 17 | wget https://raw.githubusercontent.com/leanprover/lean.js/master/${RUN_LEAN_JS} 18 | chmod +x ${RUN_LEAN_JS} 19 | fi 20 | 21 | ulimit -s unlimited 22 | f=$1 23 | i=0 24 | in_code_block=0 25 | lastbegin=0 26 | linenum=0 27 | echo "-- testing $f" 28 | while read -r line; do 29 | linenum=$((linenum + 1)) 30 | if [[ $line =~ ^#\+BEGIN_SRC\ lean ]]; then 31 | in_code_block=1 32 | i=$((i + 1)) 33 | lastbegin=$linenum 34 | rm -f $f.$i.lean 35 | echo -E "import standard" >> $f.$i.lean 36 | elif [[ $line =~ ^#\+END_SRC ]]; then 37 | if [[ $in_code_block -eq 1 ]]; then 38 | if ./${RUN_LEAN_JS} ./${LEAN_JS} $f.$i.lean > $f.$i.produced.out; then 39 | echo "code fragment #$i worked" 40 | else 41 | echo "ERROR executing $f.$i.lean, for in_code_block block starting at $lastbegin, produced output:" 42 | cat $f.$i.produced.out 43 | exit 1 44 | fi 45 | fi 46 | in_code_block=0 47 | elif [[ $in_code_block -eq 1 ]]; then 48 | echo -E "$line" >> $f.$i.lean 49 | fi 50 | done < $f 51 | rm -f $f.*.produced.out 52 | rm -f $f.*.lean 53 | exit 0 54 | -------------------------------------------------------------------------------- /trimclip.sty: -------------------------------------------------------------------------------- 1 | % \begin{macrocode} 2 | % 3 | \ProvidesPackage{trimclip}[% 4 | % 5 | % 6 | %<*DRIVER> 7 | 2099/01/01 develop 8 | % 9 | Trim and clip general TeX material] 10 | % \end{macrocode} 11 | % 12 | % 13 | % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 14 | % \subsection{Options} 15 | % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 | % \begin{macrocode} 17 | \def\tc@driver{tc-\Gin@driver} 18 | \DeclareOption{pgf}{\def\tc@driver{tc-pgf.def}\AtEndOfPackage{\RequirePackage{pgf}}} 19 | \DeclareOption{pdftex}{\def\tc@driver{tc-pdftex.def}\PassOptionsToPackage{pdftex}{graphicx}} 20 | \DeclareOption{xetex}{\def\tc@driver{tc-xetex.def}\PassOptionsToPackage{xetex}{graphicx}} 21 | \DeclareOption{dvips}{\def\tc@driver{tc-dvips.def}\PassOptionsToPackage{dvips}{graphicx}} 22 | \DeclareOption{dvipdfm}{\def\tc@driver{tc-xetex.def}\PassOptionsToPackage{xetex}{graphicx}} 23 | \DeclareOption{dvipdf}{\def\tc@driver{tc-xetex.def}\PassOptionsToPackage{xetex}{graphicx}} 24 | \DeclareOption*{% 25 | \@ifpackageloaded{graphics}{% 26 | \edef\tc@driver{tc-\CurrentOption.def}% 27 | \begingroup 28 | \edef\@tempa{\CurrentOption.def}% 29 | \ifx\@tempa\Gin@driver\else 30 | \let\on@line\@gobble 31 | \PackageWarning{trimclip}{% 32 | A different clipping driver was requested than the\MessageBreak 33 | one used for 'graphics/x'! This is not recommended\MessageBreak 34 | and can lead to defect output files.% 35 | }% 36 | \fi 37 | \endgroup 38 | }{% 39 | \def\tc@driver{tc-\Gin@driver}% 40 | \PassOptionsToPackage\CurrentOption{graphicx}% 41 | }% 42 | } 43 | \ProcessOptions*\relax 44 | % \end{macrocode} 45 | % 46 | % \begin{macrocode} 47 | \RequirePackage{graphicx}[1999/02/16] 48 | \RequirePackage{collectbox}[2011/08/22] 49 | \RequirePackage{adjcalc} 50 | % \end{macrocode} 51 | % 52 | % 53 | % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 54 | % \subsection{User level and auxiliary macros} 55 | % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 56 | % 57 | % \begin{macro}{\tc@readvalues} 58 | % Reads the four values for trim, viewport and clip. 59 | % Valid inputs are: 60 | % 4 values directly, 61 | % 1 value which is taken four times, 62 | % 2 values which is taken for left/right and top/bottom. 63 | % \begin{macrocode} 64 | \def\tc@readvalues#1{% 65 | \tc@@readvalues#1 {} {} {} \\% 66 | } 67 | % \end{macrocode} 68 | % \end{macro} 69 | % 70 | % 71 | % \begin{macro}{\tc@@readvalues} 72 | % \begin{macrocode} 73 | \def\tc@@readvalues#1 #2 #3 #4 #5\\{% 74 | \adjsetlengthdefault\tc@llx{#1}% 75 | \ifx\@nnil#2\@nnil 76 | \tc@lly\tc@llx 77 | \tc@urx\tc@llx 78 | \tc@ury\tc@llx 79 | \else 80 | \adjsetlengthdefault\tc@lly{#2}% 81 | \ifx\@nnil#3\@nnil 82 | \tc@urx\tc@llx 83 | \tc@ury\tc@lly 84 | \else 85 | \adjsetlengthdefault\tc@urx{#3}% 86 | \adjsetlengthdefault\tc@ury{#4}% 87 | \fi 88 | \fi 89 | }% 90 | % \end{macrocode} 91 | % \end{macro} 92 | % 93 | % 94 | % \begin{macro}{\tc@llx} 95 | % \begin{macro}{\tc@lly} 96 | % \begin{macro}{\tc@urx} 97 | % \begin{macro}{\tc@ury} 98 | % Dimension registers for the four trim/viewport values. 99 | % Legend: ll = lower left, ur = upper right. 100 | % \begin{macrocode} 101 | \newdimen\tc@llx 102 | \newdimen\tc@lly 103 | \newdimen\tc@urx 104 | \newdimen\tc@ury 105 | % \end{macrocode} 106 | % \end{macro} 107 | % \end{macro} 108 | % \end{macro} 109 | % \end{macro} 110 | % 111 | % 112 | % \begin{macro}{\trimbox} 113 | % \begin{macrocode} 114 | \newcommand\trimbox{% 115 | \collectboxcheckenv{trimbox}% 116 | \@ifstar 117 | \trimbox@s 118 | \trimbox@ 119 | } 120 | \def\trimbox@#1{% 121 | \collectbox{\@trimclip\@trimbox{#1}}% 122 | } 123 | \def\trimbox@s#1{% 124 | \collectbox{\@trimclip\@viewportbox{#1}}% 125 | } 126 | % \end{macrocode} 127 | % \end{macro} 128 | % 129 | % 130 | % \begin{environment}{trimbox*} 131 | % \begin{macrocode} 132 | \expandafter\newcommand\expandafter*\csname trimbox*\endcsname{% 133 | \@collectboxisenv{trimbox*}% 134 | \trimbox@s 135 | } 136 | % \end{macrocode} 137 | % \end{environment} 138 | % 139 | % 140 | % \begin{macro}{\clipbox} 141 | % \begin{macrocode} 142 | \newcommand\clipbox{% 143 | \collectboxcheckenv{clipbox}% 144 | \@ifstar 145 | \clipbox@s 146 | \clipbox@ 147 | } 148 | \def\clipbox@#1{% 149 | \collectbox{\@trimclip\@clipbox{#1}}% 150 | } 151 | \def\clipbox@s#1{% 152 | \collectbox{\@trimclip\@clipvpbox{#1}}% 153 | } 154 | % \end{macrocode} 155 | % \end{macro} 156 | % 157 | % 158 | % \begin{environment}{clipbox*} 159 | % \begin{macrocode} 160 | \expandafter\newcommand\expandafter*\csname clipbox*\endcsname{% 161 | \@collectboxisenv{clipbox*}% 162 | \clipbox@s 163 | } 164 | % \end{macrocode} 165 | % \end{environment} 166 | % 167 | % 168 | % \begin{macro}{\marginbox}[1]{Margins as space separated values (like for 'trim')} 169 | % Collect box first. 170 | % \begin{macrocode} 171 | \newcommand\marginbox{% 172 | \collectboxcheckenv{marginbox}% 173 | \@ifstar 174 | \marginbox@s 175 | \marginbox@ 176 | } 177 | \def\marginbox@#1{% 178 | \@collectbox{\@trimclip\@marginbox{#1}}% 179 | } 180 | \def\marginbox@s#1{% 181 | \@collectbox{\@trimclip\@marginraisebox{#1}}% 182 | } 183 | % \end{macrocode} 184 | % \end{macro} 185 | % 186 | % 187 | % \begin{environment}{marginbox*}[1]{Margins as space separated values (like for 'trim')} 188 | % \begin{macrocode} 189 | \expandafter\newcommand\expandafter*\csname marginbox*\endcsname{% 190 | \@collectboxisenv{marginbox*}% 191 | \marginbox@s 192 | } 193 | % \end{macrocode} 194 | % \end{environment} 195 | % 196 | % 197 | % \begin{macro}{\@trimclip}[2]{}{} 198 | % General macro which parses the values and feeds it to the given lower-level macro. 199 | % Finally the box is typeset. This macro will always be used inside a group 200 | % created by \Macro\@collectbox. 201 | % \begin{macrocode} 202 | \def\@trimclip#1#2{% 203 | \tc@readvalues{#2}% 204 | #1% 205 | \collectedbox 206 | \tc@llx 207 | \tc@lly 208 | \tc@urx 209 | \tc@ury 210 | \usebox\collectedbox 211 | } 212 | % \end{macrocode} 213 | % \end{macro} 214 | % 215 | % 216 | % 217 | % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 218 | % \subsection{Low-level commands} 219 | % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 220 | % 221 | % 222 | % \begin{macro}{\tc@correctbaseline} 223 | % Adjust baseline if required by negative depth or height. 224 | % \begin{macrocode} 225 | \def\tc@correctbaseline#1{% 226 | % \end{macrocode} 227 | % If depth is negative lower the box to get zero depth 228 | % \begin{macrocode} 229 | \ifdim\dp#1<\z@ 230 | \raise\dp#1% 231 | \else 232 | % \end{macrocode} 233 | % Else if height is negative lower the box to get zero height 234 | % \begin{macrocode} 235 | \ifdim\ht#1<\z@ 236 | \lower\ht#1% 237 | \fi\fi 238 | \box#1% 239 | }% 240 | % \end{macrocode} 241 | % \end{macro} 242 | % 243 | % 244 | % \begin{macro}{\tc@correctdims} 245 | % Ensure that all dimensions are non-negative. 246 | % \begin{macrocode} 247 | \def\tc@correctdims#1{% 248 | \ifdim\dp#1<\z@ \dp#1=\z@ \fi 249 | \ifdim\wd#1<\z@ \wd#1=\z@ \fi 250 | \ifdim\ht#1<\z@ \ht#1=\z@ \fi 251 | } 252 | % \end{macrocode} 253 | % \end{macro} 254 | % 255 | % 256 | % \begin{macro}{\@trimbox}[5]{}{}{}{}{} 257 | % Removes the four length for the left, bottom, right and top from the official size of the box register. 258 | % \begin{macrocode} 259 | \def\@trimbox#1#2#3#4#5{% 260 | \setbox#1=\hbox{% 261 | % 262 | \tc@llx=#2\relax 263 | \tc@lly=#3\relax 264 | \advance\tc@lly-\dp#1% 265 | \tc@urx=#4\relax 266 | \advance\tc@urx-\wd#1% 267 | \tc@ury=#5\relax 268 | \advance\tc@ury-\ht#1% 269 | % 270 | % Set dimensions now. 271 | % This allows that the arguments can refer 272 | % to the original dimensions without issues. 273 | \hskip-\tc@llx 274 | \dp#1-\tc@lly 275 | \wd#1-\tc@urx 276 | \ht#1-\tc@ury 277 | % 278 | \tc@correctbaseline{#1}% 279 | }% 280 | \tc@correctdims{#1}% 281 | } 282 | % \end{macrocode} 283 | % \end{macro} 284 | % 285 | % 286 | % 287 | % \begin{macro}{\@marginbox} 288 | % Adds the given margins to the depth, width and height. 289 | % The left margin is created by an horizontal skip. 290 | % This implementation assumes that the margins are positive and no special checks are added. 291 | % While negative margins will trim some margin off, this will not lead to correct results if this amounts 292 | % are larger than the existing dimensions. For this the \Macro\@trimbox macro should be used. 293 | % \begin{macrocode} 294 | \def\@marginbox#1#2#3#4#5{% 295 | \setbox#1=\hbox{% 296 | % 297 | \tc@llx=#2\relax 298 | \tc@lly=#3\relax 299 | \advance\tc@lly\dp#1% 300 | \tc@urx=#4\relax 301 | \advance\tc@urx\wd#1% 302 | \tc@ury=#5\relax 303 | \advance\tc@ury\ht#1% 304 | % 305 | % Set dimensions now. 306 | % This allows that the arguments can refer 307 | % to the original dimensions without issues. 308 | \hskip\tc@llx 309 | \dp#1\tc@lly 310 | \wd#1\tc@urx 311 | \ht#1\tc@ury 312 | % 313 | \box#1% 314 | }% 315 | \tc@correctdims{#1}% 316 | } 317 | % \end{macrocode} 318 | % \end{macro} 319 | % 320 | % \begin{macro}{\@marginraisebox} 321 | % Like \Macro\@marginbox but raises the box accordant to the bottom margin, 322 | % so that the original depth is kept. 323 | % \begin{macrocode} 324 | \def\@marginraisebox#1#2#3#4#5{% 325 | \setbox#1=\hbox{% 326 | % 327 | \tc@llx=#2\relax 328 | \tc@lly=#3\relax 329 | \tc@urx=#4\relax 330 | \advance\tc@urx\wd#1% 331 | \tc@ury=#5\relax 332 | \advance\tc@ury\ht#1% 333 | % 334 | % Set dimensions now. 335 | % This allows that the arguments can refer 336 | % to the original dimensions without issues. 337 | \hskip\tc@llx 338 | \wd#1\tc@urx 339 | \ht#1\tc@ury 340 | % Copy original tty values (ury is taken as temp dimension) 341 | \tc@ury=\tc@lly 342 | \advance\tc@lly\dp#1% 343 | \dp#1\tc@lly 344 | % Raise bu original tty value (now in ury) 345 | \raise\tc@ury\box#1% 346 | }% 347 | \tc@correctdims{#1}% 348 | } 349 | % \end{macrocode} 350 | % \end{macro} 351 | % 352 | % \begin{macro}{\@trimbox}[5]{}{}{}{}{} 353 | % Removes the four length for the left, bottom, right and top from the official size of the box register. 354 | % \begin{macrocode} 355 | \def\@viewportbox#1#2#3#4#5{% 356 | \setbox#1=\hbox{% 357 | % 358 | % Assign values 359 | \tc@llx=#2\relax 360 | \tc@lly=#3\relax 361 | \tc@urx=#4\relax 362 | \tc@ury=#5\relax 363 | % 364 | % Set dimensions now. 365 | % This allows that the arguments can refer 366 | % to the original dimensions without issues. 367 | \hskip-\tc@llx 368 | \dp#1-\tc@lly 369 | \wd#1\tc@urx 370 | \ht#1\tc@ury 371 | % 372 | \tc@correctbaseline{#1}% 373 | }% 374 | \tc@correctdims{#1}% 375 | } 376 | % \end{macrocode} 377 | % \end{macro} 378 | % 379 | % 380 | % \begin{macro}{\@clipbox} 381 | % Clips the box using the given trim amounts. 382 | % For this the box is first trimmed and then clipped to its official size using a driver dependent macro. 383 | % \begin{macrocode} 384 | \def\@clipbox#1#2#3#4#5{% 385 | \@trimbox{#1}{#2}{#3}{#4}{#5}% 386 | \@cliptoboxdim{#1}% 387 | } 388 | % \end{macrocode} 389 | % \end{macro} 390 | % 391 | % 392 | % 393 | % \begin{macro}{\@clipvpbox} 394 | % Clips the box using the given trim amounts. 395 | % For this the box is first trimmed and then clipped to its official size using a driver dependent macro. 396 | % \begin{macrocode} 397 | \def\@clipvpbox#1#2#3#4#5{% 398 | \@viewportbox{#1}{#2}{#3}{#4}{#5}% 399 | \@cliptoboxdim{#1}% 400 | } 401 | % \end{macrocode} 402 | % \end{macro} 403 | % 404 | % 405 | % 406 | % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 407 | % \subsection{Driver loading} 408 | % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 409 | % The clipping support is output driver dependent. The driver selected by \pkg{graphics} is used and a definition file 410 | % is used if its exists. Otherwise either the default \texttt{pdftex} implementation or the \pkg{pgf} fall-back driver 411 | % is used. 412 | % 413 | % 414 | % 415 | % \begin{macro}{\tc@bezfacn} 416 | % The Bezier factor required to draw rounded corners in same drivers. 417 | % \begin{macrocode} 418 | \def\tc@bezfacn{0.44771525}% 419 | % \end{macrocode} 420 | % \end{macro} 421 | % 422 | % \begin{macrocode} 423 | \InputIfFileExists{\tc@driver}{% 424 | {\let\on@line\@gobble 425 | \PackageInfo{trimclip}{Using driver '\tc@driver'.}}% 426 | }{% 427 | \input{tc-pgf.def}% 428 | {\let\on@line\@gobble 429 | \PackageInfo{trimclip}{No clipping driver '\tc@driver' available.\MessageBreak Using fall-back PGF driver.}}% 430 | } 431 | % \end{macrocode} 432 | % 433 | % 434 | -------------------------------------------------------------------------------- /unixode.sty: -------------------------------------------------------------------------------- 1 | % ------------------------------------------------------------------------------ 2 | % (C) 2012-2013 Olivier Verdier 3 | % Unixode Package 4 | % XeTeX Unicode character definitions 5 | % ------------------------------------------------------------------------------ 6 | \NeedsTeXFormat{LaTeX2e} 7 | \ProvidesPackage{unixode}[2012/05/10] 8 | 9 | \RequirePackage{ifxetex} 10 | 11 | \ifxetex 12 | \RequirePackage{mathspec} 13 | \RequirePackage{fontspec} 14 | \defaultfontfeatures{Ligatures=TeX} 15 | \usepackage{newunicodechar} 16 | \newunicodechar{α}{\ensuremath{\mathrm{\alpha}}} 17 | \newunicodechar{β}{\ensuremath{\mathrm{\beta}}} 18 | \newunicodechar{γ}{\ensuremath{\mathrm{\gamma}}} 19 | \newunicodechar{δ}{\ensuremath{\mathrm{\delta}}} 20 | \newunicodechar{ε}{\ensuremath{\mathrm{\varepsilon}}} 21 | \newunicodechar{ζ}{\ensuremath{\mathrm{\zeta}}} 22 | \newunicodechar{η}{\ensuremath{\mathrm{\eta}}} 23 | \newunicodechar{θ}{\ensuremath{\mathrm{\theta}}} 24 | \newunicodechar{ι}{\ensuremath{\mathrm{\iota}}} 25 | \newunicodechar{κ}{\ensuremath{\mathrm{\kappa}}} 26 | \newunicodechar{λ}{\ensuremath{\mathrm{\lambda}}} 27 | \newunicodechar{μ}{\ensuremath{\mathrm{\mu}}} 28 | \newunicodechar{ν}{\ensuremath{\mathrm{\nu}}} 29 | \newunicodechar{ξ}{\ensuremath{\mathrm{\xi}}} 30 | \newunicodechar{π}{\ensuremath{\mathrm{\mathnormal{\pi}}}} 31 | \newunicodechar{ρ}{\ensuremath{\mathrm{\rho}}} 32 | \newunicodechar{σ}{\ensuremath{\mathrm{\sigma}}} 33 | \newunicodechar{τ}{\ensuremath{\mathrm{\tau}}} 34 | \newunicodechar{φ}{\ensuremath{\mathrm{\varphi}}} 35 | \newunicodechar{χ}{\ensuremath{\mathrm{\chi}}} 36 | \newunicodechar{ψ}{\ensuremath{\mathrm{\psi}}} 37 | \newunicodechar{ω}{\ensuremath{\mathrm{\omega}}} 38 | 39 | \newunicodechar{Γ}{\ensuremath{\mathrm{\Gamma}}} 40 | \newunicodechar{Δ}{\ensuremath{\mathrm{\Delta}}} 41 | \newunicodechar{Θ}{\ensuremath{\mathrm{\Theta}}} 42 | \newunicodechar{Λ}{\ensuremath{\mathrm{\Lambda}}} 43 | \newunicodechar{Σ}{\ensuremath{\mathrm{\Sigma}}} 44 | \newunicodechar{Φ}{\ensuremath{\mathrm{\Phi}}} 45 | \newunicodechar{Ξ}{\ensuremath{\mathrm{\Xi}}} 46 | \newunicodechar{Ψ}{\ensuremath{\mathrm{\Psi}}} 47 | \newunicodechar{Ω}{\ensuremath{\mathrm{\Omega}}} 48 | 49 | \newunicodechar{ℵ}{\ensuremath{\aleph}} 50 | 51 | \newunicodechar{≤}{\ensuremath{\leq}} 52 | \newunicodechar{≥}{\ensuremath{\geq}} 53 | \newunicodechar{≠}{\ensuremath{\neq}} 54 | \newunicodechar{≈}{\ensuremath{\approx}} 55 | \newunicodechar{≡}{\ensuremath{\equiv}} 56 | \newunicodechar{≃}{\ensuremath{\simeq}} 57 | 58 | \newunicodechar{≤}{\ensuremath{\leq}} 59 | \newunicodechar{≥}{\ensuremath{\geq}} 60 | 61 | \newunicodechar{∂}{\ensuremath{\partial}} 62 | \newunicodechar{∆}{\ensuremath{\triangle}} % or \laplace? 63 | 64 | \newunicodechar{∫}{\ensuremath{\int}} 65 | \newunicodechar{∑}{\ensuremath{\mathrm{\Sigma}}} 66 | \newunicodechar{Π}{\ensuremath{\mathrm{\Pi}}} 67 | 68 | \newunicodechar{⊥}{\ensuremath{\perp}} 69 | \newunicodechar{∞}{\ensuremath{\infty}} 70 | \newunicodechar{∂}{\ensuremath{\partial}} 71 | 72 | \newunicodechar{∓}{\ensuremath{\mp}} 73 | \newunicodechar{±}{\ensuremath{\pm}} 74 | \newunicodechar{×}{\ensuremath{\times}} 75 | 76 | \newunicodechar{⊕}{\ensuremath{\oplus}} 77 | \newunicodechar{⊗}{\ensuremath{\otimes}} 78 | \newunicodechar{⊞}{\ensuremath{\boxplus}} 79 | 80 | \newunicodechar{∇}{\ensuremath{\nabla}} 81 | \newunicodechar{√}{\ensuremath{\sqrt}} 82 | 83 | \newunicodechar{⬝}{\ensuremath{\cdot}} 84 | \newunicodechar{•}{\ensuremath{\cdot}} 85 | \newunicodechar{∘}{\ensuremath{\circ}} 86 | 87 | \newunicodechar{⁻}{\ensuremath{^{\textup{\kern1pt\rule{2pt}{0.3pt}\kern-1pt}}}} 88 | \newunicodechar{▸}{\ensuremath{\blacktriangleright}} 89 | 90 | \newunicodechar{∧}{\ensuremath{\wedge}} 91 | \newunicodechar{∨}{\ensuremath{\vee}} 92 | \newunicodechar{¬}{\ensuremath{\neg}} 93 | \newunicodechar{⊢}{\ensuremath{\vdash}} 94 | 95 | %\newunicodechar{⟨}{\ensuremath{\left\langle}} 96 | %\newunicodechar{⟩}{\ensuremath{\right\rangle}} 97 | \newunicodechar{⟨}{\ensuremath{\langle}} 98 | \newunicodechar{⟩}{\ensuremath{\rangle}} 99 | 100 | \newunicodechar{∀}{\ensuremath{\forall}} 101 | \newunicodechar{∃}{\ensuremath{\exists}} 102 | 103 | \newunicodechar{↦}{\ensuremath{\mapsto}} 104 | \newunicodechar{→}{\ensuremath{\rightarrow}} 105 | \newunicodechar{↔}{\ensuremath{\leftrightarrow}} 106 | \newunicodechar{⇒}{\ensuremath{\Rightarrow}} 107 | \newunicodechar{⟹}{\ensuremath{\Longrightarrow}} 108 | \newunicodechar{⇐}{\ensuremath{\Leftarrow}} 109 | \newunicodechar{⟸}{\ensuremath{\Longleftarrow}} 110 | 111 | \newunicodechar{∩}{\ensuremath{\cap}} 112 | \newunicodechar{∪}{\ensuremath{\cup}} 113 | \newunicodechar{⊂}{\ensuremath{\subseteq}} 114 | \newunicodechar{⊆}{\ensuremath{\subseteq}} 115 | \newunicodechar{⊄}{\ensuremath{\nsubseteq}} 116 | \newunicodechar{⊈}{\ensuremath{\nsubseteq}} 117 | \newunicodechar{⊃}{\ensuremath{\supseteq}} 118 | \newunicodechar{⊇}{\ensuremath{\supseteq}} 119 | \newunicodechar{⊅}{\ensuremath{\nsupseteq}} 120 | \newunicodechar{⊉}{\ensuremath{\nsupseteq}} 121 | \newunicodechar{∈}{\ensuremath{\in}} 122 | \newunicodechar{∉}{\ensuremath{\notin}} 123 | \newunicodechar{∋}{\ensuremath{\ni}} 124 | \newunicodechar{∌}{\ensuremath{\notni}} 125 | \newunicodechar{∅}{\ensuremath{\emptyset}} 126 | 127 | \newunicodechar{∖}{\ensuremath{\setminus}} 128 | \newunicodechar{†}{\ensuremath{\dag}} 129 | 130 | \newunicodechar{ℕ}{\ensuremath{\mathbb{N}}} 131 | \newunicodechar{ℤ}{\ensuremath{\mathbb{Z}}} 132 | \newunicodechar{ℝ}{\ensuremath{\mathbb{R}}} 133 | \newunicodechar{ℚ}{\ensuremath{\mathbb{Q}}} 134 | \newunicodechar{ℂ}{\ensuremath{\mathbb{C}}} 135 | \newunicodechar{⌞}{\ensuremath{\llcorner}} 136 | \newunicodechar{⌟}{\ensuremath{\lrcorner}} 137 | \newunicodechar{⦃}{\ensuremath{\{\!|}} 138 | \newunicodechar{⦄}{\ensuremath{|\!\}}} 139 | \newunicodechar{∣}{\ensuremath{\mid}} 140 | \newunicodechar{∥}{\ensuremath{\parallel}} 141 | 142 | \newunicodechar{₁}{\ensuremath{_1}} 143 | \newunicodechar{₂}{\ensuremath{_2}} 144 | \newunicodechar{₃}{\ensuremath{_3}} 145 | \newunicodechar{₄}{\ensuremath{_4}} 146 | \newunicodechar{₅}{\ensuremath{_5}} 147 | \newunicodechar{₆}{\ensuremath{_6}} 148 | \newunicodechar{₇}{\ensuremath{_7}} 149 | \newunicodechar{₈}{\ensuremath{_8}} 150 | \newunicodechar{₉}{\ensuremath{_9}} 151 | \newunicodechar{₀}{\ensuremath{_0}} 152 | \newunicodechar{ₙ}{\ensuremath{_n}} 153 | \newunicodechar{ₘ}{\ensuremath{_m}} 154 | \newunicodechar{↑}{\ensuremath{\uparrow}} 155 | \newunicodechar{↓}{\ensuremath{\downarrow}} 156 | \else 157 | \usepackage[utf8x]{inputenc} 158 | \SetUnicodeOption{mathletters} 159 | \DeclareUnicodeCharacter{952}{\ensuremath{\theta}} 160 | \fi 161 | -------------------------------------------------------------------------------- /xetex-inputenc.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `xetex-inputenc.sty', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% xetex-inputenc.dtx (with options: `package') 8 | %% 9 | %% ___________________________________ 10 | %% The xetex-inputenc override package 11 | %% (C) 2009 Will Robertson 12 | %% License information appended 13 | %% 14 | %% 15 | \ProvidesPackage{xetex-inputenc} 16 | [2009/03/09 v0.2 XeTeX-specific inputenc package] 17 | \def\xIE@encoding#1#2{% 18 | \DeclareOption{#1}{% 19 | \xIE@set{#2} 20 | }% 21 | } 22 | \DeclareOption*{% 23 | \PackageWarning{xetex-inputenc}{% 24 | Encoding "\CurrentOption" not recognised; attempting to use it anyway 25 | }% 26 | \xIE@set{\CurrentOption}% 27 | } 28 | \newcommand\xIE@set[1]{% 29 | \edef\xetex@inputenc{#1}% 30 | \AtEndOfPackage{% 31 | \XeTeXinputencoding "\xetex@inputenc" 32 | \XeTeXdefaultencoding "\xetex@inputenc" 33 | } 34 | } 35 | \xIE@encoding{ascii} {ascii} 36 | \xIE@encoding{latin1} {latin1} 37 | \xIE@encoding{latin2} {latin2} 38 | \xIE@encoding{latin3} {latin3} 39 | \xIE@encoding{latin4} {latin4} 40 | \xIE@encoding{latin5} {latin5} 41 | \xIE@encoding{latin9} {latin9} 42 | \xIE@encoding{latin10} {latin10} 43 | \xIE@encoding{decmulti} {dec} 44 | \xIE@encoding{cp850} {cp850} 45 | \xIE@encoding{cp852} {cp852} 46 | \xIE@encoding{cp858} {cp858} 47 | \xIE@encoding{cp437} {cp437} 48 | \xIE@encoding{cp865} {cp865} 49 | \xIE@encoding{applemac} {mac} 50 | \xIE@encoding{cp1250} {windows-1250} 51 | \xIE@encoding{cp1252} {windows-1252} 52 | \xIE@encoding{cp1257} {windows-1257} 53 | \xIE@encoding{ansinew} {windows-1252} 54 | \xIE@encoding{utf8} {utf8} 55 | \ExecuteOptions{utf8} 56 | \ProcessOptions 57 | \def\@input#1{% 58 | \IfFileExists{#1}{% 59 | \XeTeXdefaultencoding "utf8" 60 | \@@input\@filef@und 61 | \XeTeXdefaultencoding "\xetex@inputenc" 62 | }{\typeout{No file #1.}}% 63 | } 64 | \AtBeginDocument{% 65 | \immediate\write\@auxout{\string\XeTeXinputencoding "utf8"}% 66 | } 67 | %% 68 | %% Copyright (C) 2009 by Will Robertson 69 | %% 70 | %% Distributable under the LaTeX Project Public License, 71 | %% version 1.3c or higher (your choice). The latest version of 72 | %% this license is at: http://www.latex-project.org/lppl.txt 73 | %% 74 | %% This work is "maintained" (as per LPPL maintenance status) 75 | %% by Will Robertson. 76 | %% 77 | %% This work consists of the file xetex-inputenc.dtx 78 | %% and the derived files xetex-inputenc.sty, 79 | %% xetex-inputenc.ins, and 80 | %% xetex-inputenc.pdf. 81 | %% 82 | %% 83 | %% End of file `xetex-inputenc.sty'. 84 | -------------------------------------------------------------------------------- /xstring.sty: -------------------------------------------------------------------------------- 1 | \input xstring.tex 2 | \ProvidesPackage{xstring}[\xstringdate\space\space v\xstringversion\space\space String manipulations (C Tellechea)] 3 | \endinput 4 | --------------------------------------------------------------------------------