├── LICENSE ├── README-CAT.md ├── README-CZE.md └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README-CAT.md: -------------------------------------------------------------------------------- 1 | # Tàctiques Lean 4 per principiants 2 | 3 | En les taules que segueixen, *nom* sempre fa referència a un nom que Lean ja coneix 4 | mentre que *nom_nou* és un nom nou que podem escollir; 5 | *expr* denota una expressió, 6 | per exemple el nom d'un objecte en el context, 7 | una expressió aritmètica que depèn d'aquests objectes, 8 | una hipòtesi que tenim al context, 9 | o un lema aplicat a qualsevol d'aquests; 10 | *proposició* és una expressió de l'estil Prop (e.g. 0 < x). 11 | Quan una d'aquestes paraules apareix dues vegades a la mateixa cel·la, 12 | no vol dir que els noms o expressions hagin de ser les mateixes. 13 | 14 | | Símbol lògic | Apareix a l'objectiu | Apareix en una hipòtesi | 15 | |---------------------------------------|-----------------------------------------|---------------------------------------------------------------------------------------------------------------------------------| 16 | |   (per tot) | intro *nom_nou* | apply *expr* o specialize *nom* *expr* | 17 | |   (existeix) | use *expr* | obtain ⟨*nom_nou*, *nom_nou*⟩ := *expr* | 18 | |   (implica) | intro *nom_nou* | apply *expr* o specialize *nom* *expr* | 19 | |   (si i només si) | constructor | rw [*expr*] o rw [←*expr*] | 20 | |   (i) | constructor | obtain ⟨*nom_nou*, *nom_nou*⟩ := *expr* | 21 | |   (o) | left o right | cases *expr* with
\| inl *nom_nou* => ...
\| inr *nom_nou* => ... | 22 | | ¬  (no) | intro *nom_nou* | apply *expr* o specialize *nom* *expr* | 23 | 24 | A l'esquerra de la taula següent les parts entre parèntesis són opcionals. 25 | L'efecte d'aquestes parts també està escrit entre parèntesis. 26 | 27 | | Tàctica | Efecte | 28 | |-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 29 | | exact *expr* | demostra que l'objectiu es pot provar amb *expr* | 30 | | refine | Igual que exact *expr*, però podem deixar ?_ en algunes dades i crearà nous objectius | 31 | | convert *expr* | demostra l'objectiu transformant-lo en un fet ja existent *expr* i crea nous objectius per aquelles proposicions utilitzades en la transformació que no s'hagin demostrat automàticament | 32 | | convert_to *proposition* | transforma l'objectiu en el nou objectiu *proposició* i crea nous objectius per aquells proposicions utilitzades en la transformació que no s'hagin demostrat automàticament | 33 | | have *nom_nou* : *proposition* | introduceis un nom *nom_nou* enunciant que la *proposició* és certa; simultàniament, crea un nou objectiu per demostrar la *proposició* | 34 | | unfold *nom* (at *hyp*) | reescriu la definició de *nom* a l'objectiu (o a la hipòtesi *hyp*) | 35 | | rw [*expr*] (at *hyp*) | a l'objectiu (o a la hipòtesi *hyp*), canvia (totes es instàncies de) la part esquerra de la igualtat o equivalència *expr* per la part dreta | 36 | | rw [←*expr*] (at *hyp*) | a l'objectiu (o a la hipòtesi *hyp*), canvia (totes es instàncies de) la part dreta de la igualtat o equivalència *expr* per la part esquerra | 37 | | rw [*expr*, *expr*, ←*expr*, ←*expr*, *expr*] | fer diverses reescriptures l'una darrera l'altra (es pot fer servir a l'objectiu o a una hipòtesi donada; es pot alternar canvis esquerra-dreta amb dreta-esquerra) | 38 | | calc | comença una demostració per càlcul (i.e. una successió de proposicions que, al combinar-se fent servir transitivitat, demostraran l'objectiu) | 39 | | gcongr | TODO | 40 | | by_cases *nom_nou* : *proposició* | trenca la demostració en dues branques segons *proposició* sigui cert o fals, fent servir *nom_nou* com el nom de la hipòtesi respecriva en cada branca | 41 | | exfalso | aplica la regla "Fals implica qualsevol cosa", també coneguda com "ex falso quodlibet" (canvia l'objectiu a False) | 42 | | by_contra *nom_nou* | comença una demostració per reducció a l'absurd, fent servir *nom_nou* per la hipòtesi que és la negació de l'objectiu | 43 | | push_neg (at *hyp*) | simplifica les negacions a l'objectiu (o a la hipòtesi *hyp*),
e.g. canvia ¬ ∀ x, *proposició* to ∃ x, ¬ *proposició* | 44 | | linarith | demostra l'objectiu fent servir una combinació lineal de les hipòtesis (inclosos arguments basats en la transitivitat) | 45 | | ring | demostra l'objectiu combinant els axiomes d'un (semi)anell commutatiu | 46 | | simp (at *hyp*) | simplifica l'objectiu (o la hipòtesi *hyp*) combinant algunes igualtats i equivalències ja apreses | 47 | | simp? (at *hyp*) | mostra quines igualtats i equivalències es farien servir per simplificar l'objectiu (o la hipòtesi *hyp*); dona una llista d'expressions que poden utilitzar-se dins de simp only [...] (at *hyp*) | 48 | | exact? | busca un lema que demostri l'objectiu fent servir hipòtesis del context | 49 | | apply? | busca lemes la conclusió dels quals coincideixi amb l'objectiu; suggereix aquells que es poden fer servir amb apply o refine | 50 | | rw? | TODO | 51 | | aesop | TODO | 52 | -------------------------------------------------------------------------------- /README-CZE.md: -------------------------------------------------------------------------------- 1 | # Lean 4 — přehled taktik pro začátečníky 2 | 3 | V následujících tabulkách vždy *jmeno* označuje jméno, které už Lean zná, 4 | zatímco *pojmenovani* je nové jméno (právě poskytnuté); 5 | *term* je libovolný výraz, 6 | například jméno známého termu, 7 | funkce aplikovaná na term, 8 | aritmetický výraz, 9 | předpoklad z lokálního kontextu, 10 | nebo nějaké lemma aplikované na cokoliv z toho; 11 | *tvrzeni* je term typu Prop (například 0 < x). 12 | Když se některé z těchto slov objeví v jedné buňce vícekrát, 13 | jednotlivé výskyty označují odlišná jména nebo výrazy. 14 | 15 | ## Taktiky pro logické symboly 16 | 17 | Následující tabulka ukazuje, jak typicky reagujeme na který logický symbol v závislosti 18 | na jeho umístění (v čele cíle nebo v čele předpokladu). 19 | 20 | | Logický symbol | V cíli | V předpokladu | 21 | |-----------------------------------------|-------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------| 22 | |   (pro každé) | intro *pojmenovani* | apply *term* nebo specialize *jmeno* *term* | 23 | |   (existuje) | use *term* | obtain ⟨*pojmenovani*, *pojmenovani*⟩ := *term* | 24 | |   (implikuje) | intro *pojmenovani* | apply *term* nebo specialize *jmeno* *term* | 25 | |   (právě tehdy když) | constructor | rw [*term*] nebo rw [←*term*] | 26 | |   (AND) | constructor | obtain ⟨*pojmenovani*, *pojmenovani*⟩ := *term* | 27 | |   (OR) | left nebo right | cases *term* with
\| inl *pojmenovani* => ...
\| inr *pojmenovani* => ... | 28 | | ¬  (NOT) | intro *pojmenovani* | apply *term* nebo specialize *jmeno* *term* | 29 | 30 | ## Obecně užitečné taktiky 31 | 32 | Závorky v levém sloupci označují volitelné části. 33 | Účinek těchto částí je v pravém sloupci také napsán v závorkách. 34 | 35 | | Taktika | Co dělá | 36 | |-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 37 | | exact *term* | cíl je splněn pomocí *term* | 38 | | convert *term* | dokaž cíl tím, že ho převedeš na již známý fakt *term*, a vytvoř pomocné cíle pro ty transformace použité k převodu, které nebyly dokázány automaticky | 39 | | convert_to *tvrzeni* | dokaž cíl tím, že ho převedeš na jiný cíl *tvrzeni*, a vytvoř dodatečné cíle pro ty transformace použité k převodu, které nebyly dokázány automaticky | 40 | | have *pojmenovani* : *tvrzeni* | přidej do kontextu předpoklad *pojmenovani*, který tvrdí *tvrzeni*, a zároveň vytvoř a zaměř nový cíl dokázat *tvrzeni* | 41 | | unfold *jmeno* (at *hyp*) | rozbal definici *jmeno* v cíli (nebo v předpokladu *hyp*) | 42 | | rw [*term*] (at *hyp*) | v cíli (nebo v předpokladu *hyp*) nahraď všechny výskyty levé strany rovnosti nebo ekvivalence *term* za její pravou stranu | 43 | | rw [←*term*] (at *hyp*) | v cíli (nebo v předpokladu *hyp*) nahraď všechny výskyty pravé strany rovnosti nebo ekvivalence *term* za její levou stranu | 44 | | rw [*term*, *term*, ←*term*, ←*term*, *term*] | proveď několik přepisů v řadě za sebou (opět může být použito v cíli i v předpokladu; libovolná podmnožina *term* může být provedena zprava doleva) | 45 | | by_cases *pojmenovani* : *tvrzeni* | rozlož důkaz na dvě větve podle toho, jestli *tvrzeni* je splněn nebo ne, kde *pojmenovani* označuje kýženou hypotézu v obou větvích | 46 | | exfalso | použij pravidlo "ze sporu plyne cokoliv" neboli "ex falso quodlibet" (nahradí současný cíl za False) | 47 | | by_contra *pojmenovani* | zahaj důkaz sporem, kde *pojmenovani* bude jméno pro předpoklad, který je negací cíle | 48 | | push_neg (at *hyp*) | posuň negace směrem „dovnitř“ v cíli (nebo v předpokladu *hyp*),
například změň ¬ ∀ x, *tvrzeni* na ∃ x, ¬ *tvrzeni* | 49 | | linarith | dokaž cíl pomocí lineární kombinace předpokladů (zahrnuje argumenty z tranzitivity (ne)rovností) | 50 | | ring | dokaž cíl pomocí vlastností sčítání, odčítání, násobení a mocnin | 51 | | simp (at *hyp*) | zjednoduš cíl (nebo předpoklad *hyp*) pomocí nějaké kombinace známých rovností a ekvivalencí | 52 | | simp? (at *hyp*) | ukaž, které rovnosti a ekvivalence by mohly být použity ke zjednodušení cíle (nebo předpokladu *hyp*); dej seznam výrazů, které mohou být použity uvnitř simp only [...] (at *hyp*) | 53 | | exact? | najdi v knihovně (navíc s využitím lokálního kontextu) lemma, které uzavře cíl | 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lean 4 spellbook — tactics overview for beginners 2 | 3 | In the following tables, *name* always refers to a name already known to Lean 4 | while *new_name* is a new name provided by the user; 5 | *expr* means an expression, 6 | for example the name of an object in the context, 7 | an arithmetic expression that is a function of such objects, 8 | a hypothesis in the context, 9 | or a lemma applied to any of these; 10 | *proposition* is an expression of the type Prop (e.g. 0 < x). 11 | When one of these words appears twice in the same cell, 12 | the appearances do not designate the same name or the same expression. 13 | 14 | ## Tactics for logical symbols 15 | 16 | The following table shows usual responses to logical symbols based on their placement. 17 | 18 | | Logical symbol | Appears in goal | Appears in hypothesis | 19 | |---------------------------------------|-----------------------------------------|-----------------------------------------------------------------------------------------------------------------------------| 20 | |   (there exists) | use *expr* | obtain ⟨*new_name*, *new_name*⟩ := *expr* | 21 | |   (for all) | intro *new_name* | apply *expr* or specialize *name* *expr* | 22 | | ¬  (not) | intro *new_name* | apply *expr* or specialize *name* *expr* | 23 | |   (implies) | intro *new_name* | apply *expr* or specialize *name* *expr* | 24 | |   (if and only if) | constructor | rw [*expr*] or rw [←*expr*] | 25 | |   (and) | constructor | obtain ⟨*new_name*, *new_name*⟩ := *expr* | 26 | |   (or) | left or right | cases *expr* with
\| inl *new_name* => ...
\| inr *new_name* => ... | 27 | 28 | ## Generally useful tactics 29 | 30 | In the left-hand column, the parts in parentheses are optional. 31 | The effect of these parts in the right-hand column is also written in parentheses. 32 | 33 | | Tactic | Effect | 34 | |-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 35 | | exact *expr* | the goal is satisfied by *expr* | 36 | | refine *expr* | similar to exact but allows to leave any number of ?_ in the *expr* to denote holes that will be filled later | 37 | | convert *expr* | prove the goal by transforming it to an existing fact *expr* and create goals for propositions used in the transformation that were not proved automatically | 38 | | convert_to *proposition* | transform the goal into the goal *proposition* and create additional goals for propositions used in the transformation that were not proved automatically | 39 | | have *new_name* : *proposition* | introduce a name *new_name* asserting that *proposition* is true; at the same time, create and focus a goal for *proposition* | 40 | | unfold *name* (at *hyp*) | unfold the definition of *name* in the goal (or in the hypothesis *hyp*) | 41 | | rw [*expr*] (at *hyp*) | in the goal (or in the hypothesis *hyp*), replace (all occurrences of) the left-hand side of the equality or equivalence *expr* by its right-hand side | 42 | | rw [←*expr*] (at *hyp*) | in the goal (or in the hypothesis *hyp*), replace (all occurrences of) the right-hand side of the equality or equivalence *expr* by its left-hand side | 43 | | rw [*expr*, *expr*, ←*expr*, ←*expr*, *expr*] | perform several rewritings in a sequence (can again be used in the goal or in given hypothesis; any subset of *expr* can again be applied from right to left) | 44 | | calc | start a proof by calculation (i.e., a sequence of propositions that, when combined together using transitivity, will prove the goal) | 45 | | by_cases *new_name* : *proposition* | split the proof into two branches depending on whether *proposition* is true or false, using *new_name* as name for the respective hypothesis in both branches | 46 | | exfalso | apply the rule "False implies anything" a.k.a. "ex falso quodlibet" (replaces the goal by False) | 47 | | by_contra *new_name* | start a proof by contradiction, using *new_name* as name for the hypothesis that is the negation of the goal | 48 | | push_neg (at *hyp*) | push negations in the goal (or in the hypothesis *hyp*),
e.g. change ¬ ∀ x, *proposition* to ∃ x, ¬ *proposition* | 49 | | linarith | prove the goal by a linear combination of hypotheses (includes arguments based on transitivity) | 50 | | ring | prove the goal by combining the axioms of a commutative (semi)ring | 51 | | simp (at *hyp*) | simplify the goal (or the hypothesis *hyp*) by combining some standard equalities and equivalences | 52 | | simp? (at *hyp*) | show which equalities and equivalences would be used to simplify the goal (or the hypothesis *hyp*); give a list of expressions that can be used inside simp only [...] (at *hyp*) | 53 | | exact? | search for a single existing lemma which closes the goal, also using local hypotheses | 54 | | apply? | search for lemmas whose conclusion matches the goal; suggest those that may be used with apply or refine | 55 | | rw? (at *hyp*) | search for lemmas that can rewrite the goal (or the hypothesis *hyp*), irrespective of their practicality | 56 | | aesop | try to solve the goal using magic | 57 | | aesop? | try to solve the goal using magic and show what kind of magic was used (usually produces unreadable output but the names of relevant lemmas are there) | 58 | --------------------------------------------------------------------------------